前提
やりたかったこと
Phi-3.5-mini-instruct を ONNX で動かしてみたい!(あわよくば ONNX Runtime GPU とか ONNX Runtime DirectML でハードウェアアクセラレーションがかかったらどうなるか見てみたい)
現状
Hugging Face の Phi-3.5-mini-instruct の公式リポジトリには、今のところ safetensors 形式しかない…。→ (2024/09/18 追記) Microsoft から AWQ 量子化済みの公式な ONNX のモデルがでました!
待ちに待った公式モデルがでました!こちらからダウンロードしましょう!
https://huggingface.co/microsoft/Phi-3.5-mini-instruct-onnx
解決策
ONNX Runtime の Model Builder で、任意の Hugging Face のリポジトリにある safetensors 形式のモデルを ONNX 形式に変換して、ローカルで動作させることが出来ました!
手順
前提条件
Python のインストール
まずは Python を入れましょう!自分の手元の環境はいつ入れたか定かでない Python 3.12.5 でした。
インストールが終わったらコマンドプロンプトで Python がちゃんと動くことを確認。
python --version
Hugging Face CLI のインストール
Model Builder 内部で Hugging Face CLI を使って、変換元のモデルをダウンロードしてきますので、インストールとログインが必要です。下記 URL の手順に従って、インストールとログイン作業を済ませましょう。また、Hugging Face のアカウントを持っていない人はこの作業を始める前に作りましょう。
以下のコマンドを CLI インストール後に入力すると、Hugging Face のポータルで生成できるトークンを入力せよ、と言われるので、ここも指示通りにやります。
huggingface-cli login
Add token as git credential? (Y/n)
という選択肢が出てくるはずなので、そこは y
で進めましょう。
Login successful
の出力がでたら、Hugging Face CLI の準備は完了です。
作業用ディレクトリと venv を作る。ついでに必要なパッケージも入れる。
わかりやすいところどこでもいいので、ディレクトリを一つ掘って、その下で作業を進めます。例えば D:\modelBuild
とかでもいい気がします。
python -m venv .venv
.venv\Scripts\Activate
pip install torch transformers onnx onnxruntime
pip install --pre onnxruntime-genai
Model Builder の動作確認
以下のコマンドを打って、ヘルプが読めることを確認しましょう。
Usage がでてきたら、とりあえずインストールは終わっているはずです。
python -m onnxruntime_genai.models.builder --help
usage: builder.py [-h] [-m MODEL_NAME] [-i INPUT] -o OUTPUT -p {int4,fp16,fp32} -e {cpu,cuda,dml,web} [-c CACHE_DIR]
[--extra_options KEY=VALUE [KEY=VALUE ...]]
options:
-h, --help show this help message and exit
<以下略>
いよいよお目当てのモデルを変換!
以下のコマンドで、Phi-3.5-mini-instruct のモデルを CPU だけで動作する ONNX のモデルに変換可能です。
ついでなので int 4bit で量子化もかけておきます。(この辺はお好み)
python -m onnxruntime_genai.models.builder -m "microsoft/Phi-3.5-mini-instruct" -o Phi-3.5-mini-Instruct-onnx-cpu-int4 -p int4 -e cpu -c cachedir
例えば CUDA 対応のモデルを作るならこんな感じです。オプションの多少の違いでしかないので、あとは Help を読んでお好みの設定にしましょう。
python -m onnxruntime_genai.models.builder -m "microsoft/Phi-3.5-mini-instruct" -o Phi-3.5-mini-Instruct-onnx-cuda-int4 -p int4 -e cuda -c cachedir
DirectML 対応のモデルにするならこんな感じ。
python -m onnxruntime_genai.models.builder -m "microsoft/Phi-3.5-mini-instruct" -o Phi-3.5-mini-Instruct-onnx-dml-int4 -p int4 -e dml -c cachedir
いずれのコマンドでも、完走までにしばらくかかりますので待ちましょう!
ONNX モデルとご対面
ここまで済ませると、作業用ディレクトリの下に、先ほどのコマンドの -o
オプションで指定したディレクトリ内に ONNX ファイルが生成されているはずです。これを、利用したいアクセラレーション方式に対応する ONNX Runtime を組み込んだアプリにロードすれば OK です!
SLM で Completion を試す簡単なサンプル(日本語解説付き)
ONNX 形式の Phi-3 モデルをロードして Completion を試す簡単なサンプルは、同僚の物江さんが作ったものに日本語解説までついているので、こちらをご参照ください!サンプルの解説では Phi-3 の話をしていますが、Phi-3.5 でも同様の手順でモデルだけ差し替えれば動きました。
このサンプルコードを使って、GeForce RTX 4080 Mobile な環境で動かしてみたときの出力例はこんな感じです。
まとめ
ONNX 形式のモデルが提供されてなくたって、変換できそうだってことがわかったのはかなり嬉しい。
補足
今回変換したモデルについて
int 4bit 量子化はかけているものの、それ以外はツールのなすまま特に最適化などかけずに変換しているのみとなります。したがって今回作ったモデルでベストパフォーマンスとなるかどうかは保証の限りではありませんので、その点について了承の上、参考にしてください。
同僚より Microsoft が提供している Phi3 の ONNX モデルについては、AWQ を用いて量子化されているとの情報を得ました。もし Phi3 Microsoft 公式モデルと同等の最適化をご要望であれば、量子化を別途 AWQ で行ってから ONNX に変換することが出来れば良いかもしれません。
https://arxiv.org/abs/2306.00978
今回うまくいかなかったこと
モデル変換コマンドで DirectML のモデルに変換するコマンドを紹介しなかったところでお気づきの方もいらっしゃるかもしれませんが、今回 DirectML 対応の形で変換したモデルをサンプルアプリに読み込ませても、推論時にエラーになってしまいました。CUDA 版が動いたのでそれ以上深追いはしていない状況なのですが、今後の課題とします。
2024/08/31 追記
その後、別の DirectML を使うアプリにモデルを食わせたら動きました。当初使っていたサンプルの実装の問題だったようです。なので、変換コマンドの例として DirectML 用の ONNX に変換するものも追記しました。
Model Builder を動作させるときにちょっと引っ掛かったエラーについて
Model Builder を走らせるときに Numpy のバージョンが新しすぎて対応していないようでエラーとなりました。(ちょっとエラーをメモし忘れてしまったのですが、Numpy 1.x 系デコンパイルされたモジュールがあるから、Ver.2 以上のものはダメよ、って感じだったと記憶しています。)
んで、以下のコマンドで無理やり Numpy をダウングレードして対応しました。
pip install numpy=1.26.4