【FastFlowLM】Ryzen AIのNPUをUbuntuで叩く! 果たして性能は? ~Dockerで環境構築も楽々 Qwen3.6 Gemma4対応~
こんにちはRcatです。
今回はとうとうNPUを触っていきます。
今まで一度も手を付けられていませんでしたが、やっとこの時が来ました。

はじめに
利用規約
情報や作品の活用時は事前に利用規約をご確認ください。
コメントについて
利用規約のガイドラインを確認の上コメントしてください。
則っていないコメントは削除します。
概要
FastFlowLMとは
XDNA特化の推論ランタイム。つまりRyzen AIのNPUのための専用推論ソフト。
Ubuntuにも対応しているため、今回はこれを使用する。
前提
マシンはEVO-X2 Ryzen AI MAX+ 395搭載です。
INT8で50TOPSのNPUを搭載しています。とはいえ、これがどの程度なのかわからないので動かしていきますか。
NPUはOSに認識されている前提です。
少なくとも、Ubuntu 26.04であれば、インストールするだけで認識される模様。
導入
環境構築
公式のやり方はこちらに載っています。
これを見る限り、Ubuntu26.04はなんか24に比べて面倒になってます。
そこでDockerの登場。
コンテナのベースイメージを24.04にすることで、そっちの簡単な手順で動かしてしまいます。
Dockerfile
公式の手順をほぼそのままイメージ化しただけw

docker-compose
ややこしいのはこっちですね
NPUをマウントしてやったりメモリ割り当て変えたりなど設定が多いです。

とはいえこれが準備できればあとは下記コマンドを打つだけ
docker compose build
docker compose up -dDockerは一度準備さえしてしまえば、その後自分やほかの人が使う時が楽なんですよね。

動作検証
前提
FastFlowLMはWEB UIがないので、何かフロントエンドを自前で用意する必要があります。
今回はいつも使ってるZooCodeの接続先をこれに切り替えることで検証します。
設定とモデル選定
設定はこんな感じ。
URLが正しく設定されると、モデル一覧が取得できます。
小さ目のモデルが多いですが、Qwen3.6とGPT OSSだけ巨大なのがあります。
gpt-ossってもう古くてほかに劣ってるんだからもういらないのでは?それよりGemma4 26B-A4のほうがまだ役に立つぞ。

Qwen3.6 35B-A3
これは私が普段から使っているのと同じ奴ですね。
NPUとGPUの差がわかりやすいので採用!
メモリは…26.5GB使用中。
入力25k時
P:154.7
D:9.8
うん、遅いね☆ GPUなら3倍以上出るハズ。
{
"id": "chatcmpl-df0c26202ae0b72cf0a32e1a",
"object": "chat.completion.chunk",
"created": 1785596728,
"model": "qwen3.6-moe:35b-a3b",
"system_fingerprint": "fp_bda01489569a79e9",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 25232,
"completion_tokens": 357,
"total_tokens": 25589,
"active_kv_tokens": 25589,
"max_kv_token_capacity": 128000,
"kv_token_occupancy_rate_percentage": 19.99140739440918,
"load_duration": 1.25e-06,
"prefill_duration_ttft": 163.0605312,
"decoding_duration": 36.447756,
"prefill_speed_tps": 154.7400821910238,
"decoding_speed_tps": 9.7948416906654
}
}参考 llama.cpp (Qwen3.6 35B-A3 Q8)
prompt eval time = 14515.38 ms / 11299 tokens ( 1.28 ms per token, 778.42 tokens per second)
eval time = 25655.38 ms / 953 tokens ( 26.92 ms per token, 37.15 tokens per second)
total time = 40170.75 ms / 12252 tokens
draft acceptance = 0.47342 ( 463 accepted / 978 generated), mean len = 1.95
Gemma4 E2B-it
軽そうでそこそこ要約程度なら長文でも期待したいモデル。
消費メモリは7.3GB
入力12k時
P:815
D:14.2
入力76k時
P:385
D:5.3
デコードが想像以上に遅いです。いつもはメモリ帯域が~とか言っていますが、そんなレベルではありません。帯域のせいではないですこれ。
{
"id": "chatcmpl-fb8aa0246ed0f0d40d3052cb",
"object": "chat.completion.chunk",
"created": 1785592305,
"model": "gemma4-it:e2b",
"system_fingerprint": "fp_6a00954e1ca94b1b",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 12600,
"completion_tokens": 435,
"total_tokens": 13035,
"active_kv_tokens": 13035,
"max_kv_token_capacity": 32768,
"kv_token_occupancy_rate_percentage": 39.7796630859375,
"load_duration": 5.766814208,
"prefill_duration_ttft": 15.458353152,
"decoding_duration": 30.517254,
"prefill_speed_tps": 815.0932946159154,
"decoding_speed_tps": 14.254231393165322
}
}{
"id": "chatcmpl-48b5e11d0e76889d5ee0b60e",
"object": "chat.completion.chunk",
"created": 1785594485,
"model": "gemma4-it:e2b",
"system_fingerprint": "fp_146218034f9b72cb",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 76220,
"completion_tokens": 781,
"total_tokens": 77001,
"active_kv_tokens": 77001,
"max_kv_token_capacity": 128000,
"kv_token_occupancy_rate_percentage": 60.15703201293945,
"load_duration": 6.061860864,
"prefill_duration_ttft": 197.619073024,
"decoding_duration": 145.112992,
"prefill_speed_tps": 385.6915166824176,
"decoding_speed_tps": 5.382012935134023
}
}Qwen3.5 0.8B
こうなったらもっと小さいのいきます
消費メモリは3.7GB
入力12k時
P:1326
D:27.9
入力76k時
P:951
D:13.1
12kの時は十分な速度が出てますね!とはいえ0.8B。
そして76kになると0.8Bとは思えないデコードの遅さ。
{
"id": "chatcmpl-4673520ca77f7cfa209ea9aa",
"object": "chat.completion.chunk",
"created": 1785598303,
"model": "qwen3.5:0.8b",
"system_fingerprint": "fp_e16d58b9e93912de",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 16220,
"completion_tokens": 660,
"total_tokens": 16880,
"active_kv_tokens": 16880,
"max_kv_token_capacity": 128000,
"kv_token_occupancy_rate_percentage": 13.187499046325684,
"load_duration": 255.035293696,
"prefill_duration_ttft": 12.225881088,
"decoding_duration": 23.692536,
"prefill_speed_tps": 1326.6937477349036,
"decoding_speed_tps": 27.85687441817119
}
}{
"id": "chatcmpl-de9d9ecb8c2c6f13d079c949",
"object": "chat.completion.chunk",
"created": 1785598392,
"model": "qwen3.5:0.8b",
"system_fingerprint": "fp_745b4cee65da5077",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 77109,
"completion_tokens": 380,
"total_tokens": 77489,
"active_kv_tokens": 77489,
"max_kv_token_capacity": 128000,
"kv_token_occupancy_rate_percentage": 60.53828048706055,
"load_duration": 6.9e-07,
"prefill_duration_ttft": 81.030848512,
"decoding_duration": 28.997508,
"prefill_speed_tps": 951.6005498644234,
"decoding_speed_tps": 13.104574365493752
}
}まとめ
50TOPSっていう処理能力って大したことないんですね。
copilot+pcの要件が確か40TOPSのはずなので、その程度で本当にいいのかと思ってしまう。何もできないぞw
確かRyzen AI Max+ 395の合計が126TOPS?とか言われてたはずですが、このうちのほぼ半分を持ってるとは到底思えない。
例えばこの結果を考えてください
Gemma4 E2B 4Bit `入力12k時 P:815 / D:14.2`ですが、別口でこんなパフォーマンスが出てます。
Gemma4 E4B IQ4NL 入力12k時 P:1436 / D:36.4`。これはllama.cpp(ROCm7.2)です。つまりGPUで倍近いです。しかもパラメータ数も倍。線形で考えるなら4倍。
残りの76TOPSがGPU?でも倍じゃない。さらに16C32TのCPUどこ行ったになります。
まぁものが違うので同列に比べてはいけないんでしょうけど、それにしても弱すぎません? ニューラルネットワーク特化ですよねあなた。
計算回数で50TOPSと言っている上にチップ合計126TOPSと言っている以上省電力で動くからは言い訳になりません。これ見たら仮にCPUがほぼ寄与してなくても7割くらいの能力はあるのではと考えてしまう。
しかし現実は半分どころか20%程度しか能力が出ない。
NPU闇が深そうです
それではまたお会いしましょう。
リンク集
感想投稿フォーム
コメントは公開で恥ずかしい!! Rcatだけに送りたい人向け
メンバーシップの説明
【Linux】Systemd管理画面
Docker-Composeマネージャー
【ローカルLLM】バイブコーディング完全ガイド
【ローカルLLM】自己成長AIエージェントHermesをホスト
ミニPCにLinuxをインストール
メンバーシップ特典
ここから先は
情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。
