サマリ
背景
まとまった時間が有るときは(業務で全く使わない)Rustを少しずつ触っていこう、という活動を偶にやっている。 前はWebフレームワーク(Rocket)を触ってみたが、今回はRustの可能性を語る上でよく名前が出てくるWebAssemblyことWASMについて、実際どんなもんなのかを知りたかったので動かしてみた。かつ、普段はデータサイエンス周りを生息地にしているので、Rust×MLを色々探ってみて、今回は形態素解析エンジンを動かすことにした。
感想は最後に述べるとして、ざっとやったことの記録をまず載せる。
やったこと
WASMでHello World
まずはWebAssemblyを動かしてみる。これはMozilla公式ドキュメントが結構丁寧なチュートリアルを要ししてくれていた。ふだんRust慣れしていない人向けに書いているらしく、Rust自体の登場人物についても逐一説明してくれている。最終的に、index.html
をロードするとアラートを表示するようなページが作成できる。
日本語でのやってみた記事も参考に。
細かい手順については本エントリでは今更明記しない。ざっくり建て付けとしては、
wasm-pack
というcrateをcargo installしておけば、WASM用のバイナリをビルドできる。- WASMそのものはJavaScriptから呼び出せるバイナリーコード環境
- Rustのお作法としては
#[wasm_bindgen]
内の関数を経由してJavaScript側の処理を呼び出したり渡したりする $ wasm-pack build --target web
でビルドすることで、.wasm
ファイルとそれを呼び出す.js
ファイルを生成してくれる
こんな感じと理解した(厳密な所や細かな選択肢はいずれ理解していきたい)
Hello Lindera
次にWASMで動かすコードだが、Hello worldだけでは面白みがない。自分が多少は見知っている領域にしたかったので、形態素解析エンジン、具体的にはLindera
を動かすことにした。
PythonistaであればMecab
とかJanome
が思い浮かぶと思うが(Mecabは厳密にはC++実装というのはさておき)、Rustにおける選択肢の一つがLindera
になる。構造や立ち位置の説明などはメンテナの方の記事がわかりやすい。
Linderaそのものを動かしたい場合は、上記にも記載の通りcargo intall lindera-cli
で操作感を確認することが出来る。
(個人的にはSudachi.rs
もTryしてみたかったのだが、今回は上手にWASMで呼び出すコードが書けなかったので、見送った)
LinderaをJavaScriptから呼ぶ
最後に、Hello worldで使ったコードを上手いこと書き換えながら、WASMでLinderaを呼び出すようなRust側のコードとJavaScriptを書いていく。出来上がりとしては↓のような感じで、入力した文章を形態素解析して画面に返してくれる。
大した内容はないが、コードは下記。
個人的なRust力&JavaScript力不足で時間は食ったが、やり方自体はわかってみれば簡単。
cargo.toml
にlinderaとlindera-coreを追加する
[dependencies] lindera = "0.7.1" lindera-core = "0.7.1" wasm-bindgen = "0.2"
lib.rs
でTokenizer
を使ってtokenize
した結果をJSValue
で返す
use lindera::tokenizer::Tokenizer; use lindera_core::core::viterbi::Mode; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn greet(text: &str) -> JsValue { // create tokenizer let mut tokenizer = Tokenizer::new(Mode::Normal, ""); // tokenize the text let tokens = tokenizer.tokenize(&text); // JSに対応した戻り値を返すので JsValue::from_serde(&tokens).unwrap() }
- 1つポイントが有るとすると、
#[wasm_bindgen]
内で戻り値を返すときにJsValue
を使うところだろうか。最初は前にRocketでJsonを返した時のノリでVec<String>
をunwrap()
して返そうとしたりしていたのだがJS側で何も受け取れず、確かによくよく考えたらJavaScriptとのやり取りになるんだから専用のStructがあるような…と思ってググったらズバリの記事があった。感謝。
- もろもろ完成したら
index.html
で参照できる場所にバイナリとjsを置いてScriptで呼び出す。詳細はリポジトリを参照。
所感(考察)
という訳でやったこととしては以上なのだが、結構ここに至るまで色々調べたりして思ったことも有るのでざっと書いておく。
WebAssembly自体は幅広くマジョリティに、というよりは特定用途でポツポツいずれガッツリ、みたいに使われそうに感じた。
- 個人的にはML系の問題で量子化とか諸々モデル軽量化で腐心しているところには補助的な選択肢としてハマる瞬間が有る気がする。
- ただ、WASIと呼ばれる、WASMをOSから使う(つまりコンテナ等でも使えるようにする)技術があるらしい。ここまで来るとマイクロサービスのパーツの選択肢になる可能性が出てくる。面白い。
Rust × 形態素解析については、本稿の途中でも触れたがSudachi.rsにも注目してる。
ちなみに本記事に至るまでRust×MLについて調べてたが、実質は皆大好きばんくし氏がのblogをほーんほんほんと読むだけになった。RustってMLにどんくらい使えるのかなー、という話は氏のBlogと紹介されているエムスリーテックブログを読めば大体わかるのでおすすめ。 vaaaaaanquish.hatenablog.com
というかWASM×Rust×NLPに興味持ったのは氏の↓に大きく影響を受けてる。
WebAssemblyで機械学習Webアプリ「俺か俺以外か」をつくった - Stimulator
というわけでやったこととしては小さいが色々と勉強になった。そして今回Rustの事をかなり忘れていることも自覚したので、ちょくちょく関連書籍を読みつつまとまった時間が有れば何かまた作ってみたい。
以上