NPUのRyzenAIでLLMのベンチマークが取れたのでその記録をする。
前提
RyzenAIの開発環境はすでに整っている前提で進める。
https://github.com/amd/RyzenAI-SW/blob/main/example/transformers/models/llm/docs/README.md
リンクのReadmeがあるので参考にする。
Anacondaの環境作成
Anacondaプロンプトで以下を実行
cd examle/transformers
set TRANSFORMERS_ROOT=%CD%
conda env create --file=env.yaml
conda activate ryzenai-transformers
build_dependencies.bat
AnacondaにLLMを使用する”ryzenai-transformers”の名前で仮想環境ができる。
量子化後の重みをダウンロード
AWQ量子化1したモデルの重みを以下の手順でクローンする。
git lfs install
cd %TRANSFORMERS_ROOT%\ext
git clone https://huggingface.co/datasets/mit-han-lab/awq-model-zoo awq_cache
Ryzen 8600GはPhoenix(PHX)アーキテクチャのNPUなので、デバイス用のセットアップは以下になる。
.\setup_phx.bat
pip install ops\cpp --force-reinstall
pip install ops\torch_cpp --force-reinstall
モデルのダウンロード&量子化
HuggingFaceからモデルをダウンロードを行う。
Huggingfaceアクセストークンの発行
ダウンロードを実行する前にHuggingfaceのアクセストークンを登録を行う。
Setting>AccessTokensからCreate new tokenを選択。アクセストークンあが発行されるので、Copyを選択する。
TokenNameを適当に設定したらCreate Tokenを選択すると
MyTokenを先程取得したアクセストークンに書き換えてAnacondaプロンプトで実行する。
pip install huggingface_hub
python -c "from huggingface_hub.hf_api import HfFolder; HfFolder.save_token('MyToken')"
モデルの実行
今回のモデルはfacebook/opt-125m2を使用してベンチマークを取得する。
CPU編
CPUでモデルを実行する。
cd %TRANSFORMERS_ROOT%\models\llm
python run_awq.py --model_name facebook/opt-125m --task benchmark --target cpu --precision bf16
実行の様子
結果
CPU
Example# | Prompt Length (tokens) | New Tokens Generated | Total Time (s) | Prefill Phase (ms) | Time/Token (ms) | Tokens/Sec |
---|---|---|---|---|---|---|
1 | 4 | 60 | 1.02051 | 16.6604 | 14.5602 | 68.6805 |
2 | 8 | 60 | 1.01043 | 22.3398 | 14.276 | 70.0475 |
3 | 16 | 60 | 1.04301 | 24.0747 | 14.5868 | 68.5553 |
4 | 32 | 60 | 1.04084 | 34.6069 | 14.4603 | 69.1549 |
5 | 37 | 60 | 1.04375 | 37.164 | 14.3523 | 69.6755 |
6 | 64 | 60 | 1.0907 | 49.8432 | 14.789 | 67.6177 |
7 | 128 | 60 | 1.20454 | 86.1557 | 15.6887 | 63.7403 |
8 | 256 | 60 | 1.39375 | 185.498 | 16.7364 | 59.75 |
NPU
モデルの量子化
python run_awq.py --model_name facebook/opt-125m --task quantize
実行の様子
#実行
python run_awq.py --model_name facebook/opt-125m --task benchmark --target aie
結果
NPU
Example# | Prompt Length (tokens) | New Tokens Generated | Total Time (s) | Prefill Phase (ms) | Time/Token (ms) | Tokens/Sec |
---|---|---|---|---|---|---|
1 | 4 | 60 | 3.41484 | 240.269 | 51.3045 | 19.4915 |
2 | 8 | 60 | 3.40065 | 249.519 | 50.8792 | 19.6544 |
3 | 16 | 60 | 3.29651 | 227.827 | 49.432 | 20.2298 |
4 | 32 | 60 | 3.32855 | 339.804 | 48.1029 | 20.7888 |
5 | 37 | 60 | 3.49163 | 282.403 | 51.9017 | 19.2672 |
6 | 64 | 60 | 3.3468 | 365.029 | 47.6896 | 20.9689 |
7 | 128 | 60 | 4.15262 | 839.629 | 52.8952 | 18.9053 |
8 | 256 | 60 | 4.52478 | 1409.11 | 49.0471 | 20.3886 |
他のモデルで試したい場合は、モデルごとに利用規約の同意が求められることがあるので、同意してモデルのリポジトリ管理者に承認されないと試せない。
結果比較
Example# | Prompt Length (tokens) | New Tokens Generated | NPU合計時間 (秒) | CPU合計時間 (秒) | NPU Time/Token (ms) | CPU Time/Token (ms) | NPU Tokens/Sec | CPU Tokens/Sec |
---|---|---|---|---|---|---|---|---|
1 | 4 | 60 | 3.41484 | 1.02051 | 51.3045 | 14.5602 | 19.4915 | 68.6805 |
2 | 8 | 60 | 3.40065 | 1.01043 | 50.8792 | 14.2760 | 19.6544 | 70.0475 |
3 | 16 | 60 | 3.29651 | 1.04301 | 49.4320 | 14.5868 | 20.2298 | 68.5553 |
4 | 32 | 60 | 3.32855 | 1.04084 | 48.1029 | 14.4603 | 20.7888 | 69.1549 |
5 | 37 | 60 | 3.49163 | 1.04375 | 51.9017 | 14.3523 | 19.2672 | 69.6755 |
6 | 64 | 60 | 3.34680 | 1.09070 | 47.6896 | 14.7890 | 20.9689 | 67.6177 |
7 | 128 | 60 | 4.15262 | 1.20454 | 52.8952 | 15.6887 | 18.9053 | 63.7403 |
8 | 256 | 60 | 4.52478 | 1.39375 | 49.0471 | 16.7364 | 20.3886 | 59.7500 |
考察と感想
CPUよりNPUの方が実行速度が遅かった。NPUは16TOPSの性能なので、CPUより遅くなるだろうと思っていたが予想通りの結果になった。NPUを使えばCPUやGPUの負荷をある程度分散できるととは思うが、現実的な実行速度にはならなさそう。
実行するまでの時間が長く恐らくメモリにモデルを展開していると考えられるので、機能ごとにモデルを切り替えながらアプリケーションを作成するのは難しそう。
これからのNPUデバイスの性能向上に期待する。
- Activation-aware Weight Quantization:通常の量子化手法と異なり、AWQ量子化は重みだけでなくアクティベーション(モデルが入力に対して出力する中間値)にも配慮した量子化方法。量子化された重みが実際のアクティベーション分布により適した形で表現され、精度の低下が抑えられ、計算コストを抑えることができる手法 ↩︎
- Meta(旧Facebook)が開発した大規模言語モデル「Open Pretrained Transformers(OPT)」シリーズの一部で、約1億2500万(125M)のパラメータを持つモデル。このモデルは、GPT-3と同様のデコーダー専用のトランスフォーマーアーキテクチャを採用しており、主に英語のテキストデータを用いて事前学習されている。 ↩︎
コメント