Rust言語で機械学習、PyTorchそして日本語BERT

Rustプログラミング言語でPyTorchを使って日本語BERTを試してみた。
GPU(CUDA)が使用できるようにした。
機械学習ではPythonインタープリター言語などが人気があるが、長年、C++などのコンパイラー言語を使ってきた人には
Pythonに限界を感じることもあるだろう、かく言う私もだが。
Rustではどうかな。 

RustとCargoがインストールされてる前提です。使用環境はUbuntu20.04ですが他の環境でも動作するでしょう。
Rustのバージョンは1.55。
RustでPyTorchを使うにはTorchのC++バインデイング・ライブラリを利用するので
PyTorchのサイトからLibTorchをインストールする。

私の環境はCUDA11.2だが、CUDA 11.1バージョンでも動作している。
GPU(CUDA)が無くても、CPUで動作するので、構わずcxx11 ABIをダウンロードしよう。
解凍してホームフォルダにlibtorchフォルダを展開する。
libtorchのPathを通すため.bashrcに以下の2行を追加する。ホームフォルダ名は各自の環境に合わせる。


以下のコマンドで上記の環境を反映させる。
source .bashrc

これだけではlibtorchがsystem-wideでは使えないので、GPU(CUDA)を使うには
/usr/libにリンクを貼る。
sudo ln -s /home/mycat/libtorch/lib/libtorch.so /usr/lib/libtorch.so

これでGPUが存在すれば、利用できる。
Rustでtorchを利用するにはtch-rs クレイト(いわゆるライブラリ)を使う。

それでは早速使って見よう。
適当な名前で新規プロジェクトを作成する。

cargo new libtorch
src/main.rsを書き替える。
-----------------------------------------------------------------------------------------------
use tch::{kind, Tensor};
fn grad_example() {
    let mut x = Tensor::from(2.0).set_requires_grad(true);

    let y = &x * &x + &x + 36;
    println!("{}", y.double_value(&[]));
    x.zero_grad();
    y.backward();
    let dy_over_dx = x.grad();
    println!("{}", dy_over_dx.double_value(&[]));
}
fn main() {
    tch::maybe_init_cuda();
    let t = Tensor::of_slice(&[3, 1, 4, 1, 5]);
    t.print();
    let t = Tensor::randn(&[5, 4], kind::FLOAT_CPU);
    t.print();
    (&t + 1.5).print();
    (&t + 2.5).print();
    let mut t = Tensor::of_slice(&[1.1f32, 2.1, 3.1]);
    t += 42;
    t.print();
    println!("{:?} {}", t.size(), t.double_value(&[1]));
    grad_example();
    println!("Cuda available: {}", tch::Cuda::is_available());
    println!("Cudnn available: {}", tch::Cuda::cudnn_is_available());
    println!("Cuda device available: {:?}", tch::Device::cuda_if_available());
}
-----------------------------------------------------------------------------------
Cargo.tomlに追加する。
---------------------------------------------------------------------------------------
[package]
name = "libtorch_gpu"
version = "0.1.0"
edition = "2018"
 
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
[dependencies]
tch = "*"
------------------------------------------------------------------------------------------------- 

ビルド&実行する。 
cargo run
結果が出ればOK

機械学習でお馴染みのMNISTをやって見よう。
tch-rsをgithubからクローンする。
git clone https://github.com/LaurentMazare/tch-rs.git

cd tch-rs
//MNISTのデータセットをダウンロードします。
mkdir data
cd data

gzip -d *.gz

convolution(畳み込み)でmnistをデープラーニング
cargo run --release --example mnist conv

GPUがあれば高速に99%の精度が出る。
プログラムのソースコード(src/main.rs)を見ると分かるが、Pythonと較べても遜色のないシンプルなコードで書ける。

今回はこのくらいにして、いつか次回はNLP 自然言語処理で日本語BERTをやってみよう。