1. 結論: 現時点の推奨構成
現時点(2026年8月、llama.cpp b10588 時点)の EVO-X2 上の Qwen3.8-27B の推奨構成は次の通りになる。
- 個人利用(c≦4)は llama.cpp Vulkan + MTP。c=1 で 16.65 tok/s(MTP なしの +69%)、c=4 でも 24.13 tok/s と、体感を左右する低並列域で最も速い
- チーム利用(c≧8)は vLLM + MTP。継続バッチングが効き、c=32 で合計 57.73 tok/s と全系列中の最高域に達する
- 両者の逆転点は c=4〜8 の間(実測。3章参照)
- HIP は現時点では多並列運用を薦めない。複数スロット(c≧2)で異常が出るバグがあり——出力破損は c=8/16/32 で実測、MTP 受理率の崩壊は c=2 から実測——修正 PR がレビュー中である(4章参照)。今すぐ必要な場合の回避策も4章末尾に書いた
本稿で繰り返し出てくる c は「同時に処理するリクエスト数(並列数)」 である。利用シーンに置き換えるとこうなる。
- c=1: 自分ひとりでチャットする使い方
- c=2〜4: 個人利用の上限イメージ。チャットの裏でコーディングエージェントやバッチ要約を数本並走させる使い方
- c=8〜32: チーム・社内サービスとしての利用。複数人の同時アクセス、RAG のバックエンド、大量ドキュメントの並列処理など
llama.cpp(Vulkan)の起動例。GGUF は ggml-org 配布の3ファイル構成(本体 Q4_K_M 17.67GB / mtp Q8_0 2.95GB / mmproj Q8_0)を使う。
./llama-server \
-m Qwen3.8-27B-Q4_K_M.gguf \
-md mtp-Qwen3.8-27B-Q8_0.gguf \
--mmproj mmproj-Qwen3.8-27B-Q8_0.gguf \
--spec-type draft-mtp \
-ngl 999 -fa on \
--jinja --reasoning off \
-c 32768 -np 4 \
--host 0.0.0.0 --port 8080
(本稿の測定条件そのままの構成。-c と -np は用途に合わせて調整してほしい)
ポイントは3つ。
-
--spec-type draft-mtp: Qwen3.8 は MTP(Multi-Token Prediction。1ステップで複数トークン先を予測するドラフトヘッド)を別 GGUF として配布しており、-mdで渡して投機デコードに使う。c=1 で +69% と効果が大きい -
--reasoning off: Qwen3.8 は thinking が既定 ON かつ最大強度で、放っておくと思考トークンを延々と生成する。用途が対話・API サーバなら明示的に切る -
-np(並列スロット数)は想定並列数に合わせる。スロット充填率(c ÷ -np)が性能を左右することは Spark 記事で確認済み
vLLM 側は、Ryzen AI Max+ 395 (gfx1151) では次の2点がほぼ必須になる(詳細は5章)。
# 要点のみ。投機デコード設定等は5章参照
vllm serve <Qwen3.8-27B> \
--enforce-eager \
--mm-processor-kwargs '{"max_pixels": 262144}'
2. 検証環境 — なぜ Ubuntu 26.04 か
EVO-X2 は 2026年4月に Ubuntu 26.04 LTS へ移行済。正確に書いておくと、Ryzen AI Max+ 395 (gfx1151) 自体は ROCm 7.2 で既に正式サポート対象だった(当時の公式サポート OS は Ubuntu 24.04 系)。26.04 を選んだのは、標準(inbox)カーネルの amdgpu ドライバでそのまま動き、DKMS を入れずに運用できるためで、2026年7月の ROCm 7.14 からは Ubuntu 26.04 自体も公式サポート OS に入っている。なお本稿の「Ubuntu 26.04 + ROCm 7.2.2」という組み合わせは同一リリースの公式検証済みの組み合わせではなく、24.04(noble)用パッケージの流用である——このとき必要になる lld 周りの手当ては5月記事に書いた。
| 項目 | 値 |
|---|---|
| ハードウェア | EVO-X2 (AMD Ryzen AI Max+ 395 / Radeon 8060S, gfx1151, 128GB UMA) |
| OS | Ubuntu 26.04 LTS |
| ROCm | 7.2.2 ランタイム(HIP コンパイラのみ 7.14.0。経緯は7章コラム参照) |
| llama.cpp | master b10588 (70adb1b4c)、Vulkan / HIP 双方をビルド |
| vLLM | ROCm 対応ビルド(TheRock / 最新 main)、BF16 |
| モデル | Qwen3.8-27B(GGUF は ggml-org Q4_K_M + mtp Q8_0、vLLM は BF16) |
| 測定方式 |
vllm bench serve(ShareGPT、200問/条件)。全条件 --reasoning off 相当 |
llama.cpp は、着手時点の最新を都度採用している。後述するが、この方針が5月記事からの結論変化を語る上でも意味を持つ。
3. 速度比較: 4系列 × 出力検証
llama.cpp Vulkan、素 HIP(rocBLAS)、チューンド HIP(hipBLASLt 有効化)、vLLM(BF16)の4系列で比較した。全条件に 出力検証(--save-detailed で実際の生成テキストを保存し、機械判定で破損の有無をチェック)を付けている。理由は次章で明らかになる。なお llama.cpp 側は Q4_K_M、vLLM 側は BF16 と量子化形式が異なる。推論エンジン単体の優劣を測る統制比較ではなく、それぞれの実運用構成(各エンジンで現実的に選ぶ形式)同士の比較として読んでほしい。
3.1 並列数と生成速度 — 逆転点は c=4〜8
図1: 合計 output tok/s(全リクエスト合算)の並列数 c 依存性(MTP ON)。黄色帯が Vulkan と vLLM の逆転点。HIP は破損出力による参考値として点線で示した。
本稿の output tok/s はすべて 合計スループット(同時に走る全リクエストの出力トークンの合算) である。c=32 の 57.73 tok/s は「1リクエストあたり 57.73 tok/s」ではない点に注意してほしい(1リクエストあたりの体感は TPOT で別途見る必要がある)。見ての通り、低並列では Vulkan、高並列では vLLM という素直な構図で、Vulkan / vLLM 比(MTP ON 系列)は c=1: 2.53倍 → c=2: 1.89倍 → c=4: 1.28倍 → c=8: 0.90倍と推移して c=4〜8 の間で vLLM が逆転する。1章の「個人利用(c≦4)なら Vulkan、チーム利用(c≧8)なら vLLM」という境界線はこの実測に基づく。そして灰色の点線——HIP——がなぜ「参考値」なのかが、本章後半から4章にかけての本題である。
数値の全体は次の表の通り。
| c | Vulkan OFF | Vulkan ON(MTP) | HIP素 OFF | HIP素 ON(MTP) | HIP+hipBLASLt OFF | HIP+hipBLASLt ON(MTP) | vLLM OFF | vLLM ON(MTP) |
|---|---|---|---|---|---|---|---|---|
| 1 | 9.84 | 16.65 | 10.51 | 15.30 | 10.52 | 15.68 | 4.19 | 6.58 |
| 2 | — | 23.09 | — | — | — | — | — | 12.23 |
| 4 | — | 24.13 | — | — | — | — | — | 18.87 |
| 8 | 29.62 | 29.42 | 29.25 | 20.36 | 29.56 | 19.81 | 23.06 | 32.86 |
| 16 | 30.42 | 30.61 | 42.20 | 20.43 | 42.45 | 19.49 | 38.89 | 48.70 |
| 32 | 33.48 | 27.60 | 41.30 | 17.19 | 42.16 | 16.70 | 58.25 | 57.73 |
(c=2/4 は逆転点を埋めるための追加測定で、推奨構成である Vulkan/vLLM の MTP ON 系列のみ実施。HIP は c=8/16/32 で出力破損を、c=2 で受理率崩壊を確認済みだったため対象外とした)
注記が本表の背骨である。HIP 系列の数値は次の通り実測と推定を分けて読んでほしい。
- 素 HIP(rocBLAS): c=8/16/32 の全条件(OFF/ON とも)で、後述する出力検証により破損した出力に基づく数値であることを実測で確認した。c=2/4 の生成テキストは個別検証していないが、MTP 受理率が c=2 の時点で 0% に崩壊していること(4章)から、複数スロット全域で同じ問題を抱えていると考えている
- HIP + hipBLASLt: 出力破損を個別に機械判定したわけではない(未検証)。ただし破損の原因(4章参照)は GEMM カーネルの選択とは無関係な層で起きるため、素 rocBLAS と同様に破損していると推定している
- c=16 の HIP素 42.20 tok/s という、Vulkan を +38.7% 上回る好成績は、実は出力が
/の反復などに壊れた状態で生成されたトークン数の見かけのスループットであり、実用上意味のある数値ではない。速度の参考値としては掲載するが、まともに読める出力を返すことを実測で確認できたのは Vulkan と vLLM のみ というのが実態である。
チューンド HIP(hipBLASLt)についても触れておく。コミュニティの定番チューニングとして「hipBLASLt 有効化で prefill が Vulkan 並みに改善する」という主張があったが、実測では素 rocBLAS との差は全条件で 1〜2% 程度、標準的な測定ばらつきの範囲に収まった。効果はほぼ検出できず、かつ上記の通り複数スロットの数値そのものが破損の疑いを抱えている(素 rocBLAS は実測、hipBLASLt は推定)ので、そもそも「速いか遅いか」を論じる土台がなかった、というのが正確なところである。
3.2 出力検証結果
出力検証の中身を先に説明しておく。各条件につき20問、--save-detailed で実際の生成テキストをファイルに保存し、同一トークン・同一記号の反復(例: / が延々と続く)といった退化パターンを機械判定にかけた。表の flagged/20 は「20問中、破損と判定された問数」 で、PASS は 0件=全問がまともなテキストを返したことを意味する。tok/s のような速度指標は出力が壊れていても普通に計上されてしまうので、この検証を挟まない限り「壊れた出力を高速に吐いている構成」と「本当に速い構成」を区別できない。
| Backend | c | MTP | 出力検証 | flagged/20 |
|---|---|---|---|---|
| Vulkan | 1/2/4/8/16/32 | ON | PASS(全条件) | 0/0/0/0/0/0 |
| HIP | 1 | ON | PASS | 0 |
| HIP | 8/16/32 | ON | FAIL(全条件) | 20/17/15 |
| HIP | 8/16/32 | OFF | FAIL(全条件) | 18/20/15 |
| vLLM | 1/2/4/8/16/32 | ON | PASS(全条件) | 0/0/0/0/0/0 |
Vulkan と vLLM は全並列数・MTP 込みで一問も破損しなかった。一方 HIP は c=1(単一スロット)では無傷なのに、複数スロットになった途端、MTP の有無にかかわらず大半の問で破損する。この対称性の崩れ方が、4章の調査の入口になった。
3.3 品質検証: JamC-QA
速度だけでなく品質も見ておく。JamC-QA(SB Intuitions 公開の日本語知識 QA 評価セット、2,309問)を今回の推奨構成である Vulkan/MTP で実測したところ、スコアは 53.49%。Spark 記事(CUDA/GB10)実績の 53.44% とほぼ完全に一致した。少なくとも今回の Vulkan/MTP 構成に、ベンチマーク上の顕著な品質劣化は見られなかった、というのが正確な言い方である(vLLM や修正後の HIP を同一条件で測ったわけではないので、「あらゆるバックエンドで品質不変」とまでは主張しない)。破損は生成テキストの表層的な崩壊であり、破損さえなければ回答品質は保たれる——次章のバグ調査をする上でも重要な確認事項だった。
参考までに、当ラボがこれまで同条件(nothink)で測ってきた他モデルとの位置関係も載せておく。

図2: JamC-QA スコアの比較(当ラボ実測・nothink)。測定時期・ハードは記事ごとに異なるため大まかな位置関係として見てほしい。
Qwen3.8-27B の 53% 台は、284B 級 MoE の DeepSeek-V4-Flash(63.92%)や dense 31B の Gemma4(61.28%)には及ばないが、27B というサイズと本稿の速度を考えれば妥当な位置である。JamC-QA を日本語ベンチマークの主軸に据えた経緯と大型モデル側の測定は 過去記事 に、Qwen3.8 の Spark 側の測定は Spark 記事 に、Muse Glimmer 30B の測定は Muse Glimmer 記事 にまとめてある。
3.4 コミュニティの論争との整合
事前情報として、Ryzen AI Max+ 395(Strix Halo)上の llama.cpp 性能についてコミュニティで見解が割れていた(Vulkan 優位派と HIP 優位派)。今回の実測は、少なくとも部分的にこの対立を説明する——HIP 側の好成績(OFF 系列 c=16/32)は破損出力の見かけ上のスループットであり、実際に使い物になる出力を比較すれば Vulkan が優位 という構図である。
この評価は独自のものではない。llama.cpp Discussion #10879 で JJJJJovi 氏が 2026年8月18日に投稿した同一ハードウェア(Ryzen AI Max+ 395 / gfx1151、128GB UMA)での検証でも「Vulkan wins across the board — bare +2–25%, with MTP +15–21%」と、素の状態でも Vulkan が優位、MTP 併用でその差がさらに広がると報告されている。第三者による独立した観測が、我々の実測(破損を除いた実質的な比較で Vulkan/vLLM が優位)と方向性が一致している。
4. HIP を薦めない理由 — 出力破損バグを追った記録
4.1 発端から機構解明まで
きっかけは3章の表だった。HIP素の c=16 が 42.20 tok/s と Vulkan を +38.7% 上回った一方で、MTP を有効にすると逆に -51.6% と大幅に落ち込む。MTP の受理率をサーバログから全数集計すると、c=1 では 55.41% と Vulkan(55.30%)とほぼ同じなのに、c=2 になった瞬間に 0.00%(0 / 136,713 ドラフトトークン)へ崩壊する という、on/off に近い二値的な挙動が出てきた。徐々に劣化するのではなく、単一スロットから複数スロットになった瞬間に壊れる——スケジューリングコストでは説明がつかない形状である。
そこで全条件の生成テキストを保存して機械判定にかけたところ(3.2節の出力検証)、より深刻な事実が判明した。MTP を一切使わない素のバッチ生成(OFF)でも、c=8/16/32 の全条件で出力が / の反復などに破損していた(出力検証を実施したのはこの3点。受理率は前段の通り c=2 から崩壊しており、複数スロット全域で同根の問題と見ている)。つまり「MTP のバグ」ではなく、HIP バックエンドの複数スロットバッチ生成そのものが壊れており、好成績に見えた OFF 系列の数値は壊れた出力を高速に吐いているだけだった。速すぎる数字は疑え、である。
ここから調査は GitHub(llama.cpp 本家リポジトリ)へ向かう。既存 issue を洗うと、症状の合う報告が複数見つかった(#27506: ROCm で b10040 以降 PPL が悪化・Vulkan は無事、#27579: gfx1151 ほかで HIP/ROCm の出力破損・MTP 無関係)。「b10040 以降」の証言を起点に git bisect run を回し(9反復、機械判定)、第一の犯人コミット c7d8722(PR #24233、HIP ビルドで prop.integrated の実値を復元する変更) を特定した。gfx1151 のような APU/UMA 機でホスト(pinned)バッファ経路を新たに有効化する変更である。
並行して、issue #27572 の報告者 ByungHyun21 氏が独立に本当の原因へ到達していた。llama_context::process_ubatch() 内の H2D 入力書き込みレース——前の ubatch のグラフ計算が実行中のうちに、次の ubatch の入力書き込み(非同期コピー)が競合しうる。同期ガードは複数 GPU 構成でのみ発火する実装になっており、単一 GPU では素通りする、という穴だった。
両者は矛盾しない。検証マトリクス(素 HIP / Vulkan 対照 / integrated=false パッチ / 土台修正のみ、の組み合わせ)を回した結果、「土台 = process_ubatch の書き込みレース、増幅器 = c7d8722 が有効化したホストバッファ経路」という二層モデル で、我々の多スロット破損と、別の報告者による単一スロット・深い文脈でのツール呼び出し配列破損の両方が統一的に説明できることを確認した。どちらか一方を止めるだけでも症状は消えるが、恒久解はレースそのものを閉じる修正側にある。
4.2 GitHub でのやり取り(6スレッド・計9投稿)
この過程で、llama.cpp の6つのスレッドに計9通の報告・検証を投稿した。
| スレッド | 内容 | 当ラボの投稿 | その後の動き |
|---|---|---|---|
| issue #27579 | HIP/ROCm が gfx1151 ほかで出力破損(MTP 無関係) | 主報告 + 統一機構仮説(二層モデル)の追補 + PR 検証の相互参照(計3通) | 破損報告の本流スレッドとして議論が集約 |
| issue #27572 | draft-mtp の受理率が -np N でゼロに収束 |
受理率の全数集計(c=1: 55% → c=2: 0%)による裏付けを相互参照 | 報告者 ByungHyun21 氏が本当の原因(process_ubatch のレース)を特定。当初の同期挿入案を自ら取り下げ、リングバッファ方式(PR #27311)を本命に |
| issue #27506 | ROCm で b10040 以降 PPL が悪化、Vulkan は無事 | bisect 結果(犯人コミット c7d8722)との整合を相互参照 | 「b10040 以降」の証言が bisect の起点になった |
| issue #27556 | HIP が Qwen3.5-27B(GDN)の推論を gfx1151 で静かに破損させる(古い文脈から失われていく。Vulkan は同一コミットで正常) | 相互参照 + 追加コメント: DeMaulwurfn 氏の別 gfx1151 機での独立再現(needle test 13/30→30/30)への返信、n_ubatch < n_batch 回避則への反例(VLM + mmproj 構成)の指摘 |
独立した再現報告が集まり、一機種固有の問題ではないことが確認されつつある |
| issue #27612 | 配布バイナリ(lemonade server の ROCm 版)+ cline でツール呼び出しが部分的に失敗、Vulkan は正常 | 再ビルド不要の回避策(-b = -ub)を相互参照 |
— |
| PR #27311 | Scheduler UMA ring buffer — グラフ入力テンソルのリングバッファ化(恒久修正の本命) | 検証結果を投稿: thread sanitizer のレース検出が ring off 3,597件 → ring on 0件、多スロット破損・ツール配列破損とも解消 | 本稿執筆時点(2026-08-30 確認)で レビュー中・未マージ。より変更量の小さい代替として PR #25863(HIP 統合 GPU でのホストバッファ直接計算の回避)もあり、複数の報告者が両者とも有効と確認 |
表の通り、この調査は当ラボ単独の成果ではない。#27579 の OP である Biggles10-claude 氏、独立に同じ結論へ収束した Rcat999 氏、機構を特定し修正を書いた ByungHyun21 氏、議論と検証に加わった alankila 氏をはじめとする報告者たちとの、スレッド越しの共同作業だった。発覚から機構特定・修正 PR まで数日というこの速度感は、OSS コミュニティの良さそのものだと思う。
4.3 教訓と、今すぐ HIP が必要な場合の回避策
教訓は一つに集約できる。HTTP 200 と tok/s だけを見てベンチマークを信じるな。出力検証(生成テキストの保存と機械判定)を全条件に付けていなければ、我々は「HIP が最速」という誤った結論を記事にしていたはずである。
どうしても今すぐ HIP で多並列が必要な場合、ワークアラウンドは2つある。
-
再ビルド不要:
-b(batch-size)と-ub(ubatch-size)を同じ値にし、プロンプト全体が単一の ubatch に収まるようにする。破損はn_ubatch < n_batchのときに現れるという規則が複数の報告者によって gfx1151 上で確認されている(ただし VLM + mmproj 構成での反例あり、上表 #27556 参照)。大きな-ubは compute buffer のメモリを消費するので、実際のプロンプト長を測ってから値を決めるとよい -
再ビルドできるなら:
ggml-cuda.cuの1行パッチ(HIP でもintegrated=falseを強制し、増幅器のホストバッファ経路を止める)
いずれも恒久策ではなく、PR #27311 のマージ待ちが本筋である。
5. vLLM を Ryzen AI Max+ 395 (gfx1151) で動かす際の注意点
vLLM(ROCm 対応)での Qwen3.8-27B は、事前調査で懸念していた GDN 実装や MTP 投機デコード周りではなく、まったく別の場所でつまずいた。VL モデルのメモリプロファイリングがデフォルトの巨大画像解像度でダミー画像を生成し、ROCm/eager SDPA が数百 GiB 級のメモリを要求して OOM する、という罠である。--mm-processor-kwargs '{"max_pixels": 262144}' でダミー画像の解像度を制限することで解消し、テキスト生成の実応答まで確認できた。懸念していた Ryzen AI Max+ 395 (gfx1151) の AITER 非対応(GDN kernel が Triton/FLA へフォールバックするハンデ)は、今回のテキスト専用ベンチでは阻害要因にならなかった。
もう一つ、起動そのものに関わる注意点がある。vLLM のウォームアップ(起動〜受付可能になるまで)が、全条件を通じて一貫して約200秒 かかっている。AMD 自身が ROCm 7.14.0 release notes で既知問題として挙げている「Radeon で warmup が非常に長い」を、当ラボの実測で定量化したものである——release notes は「長い」としか書いておらず、具体的な秒数は書かれていない。実測ではモデルロード(約35秒)に加え、profile_run(メモリプロファイリング、上記の OOM 罠が起きる箇所でもある)ほかの初期化が主な内訳と推定される(詳細なプロファイル分解までは未実施。なお当ラボの vLLM 運用は HIP graph のフリーズ対策で --enforce-eager 固定のため、グラフのキャプチャ・初期化はこの内訳には含まれない)。llama.cpp の起動が数秒〜十数秒であるのに対して一桁上であり、コールドスタートを想定する運用ではこの200秒を織り込む必要がある。vLLM のバージョンによって改善しているとの情報も読者からいただいたが、AMD の公式ドキュメント上で修正済みとの記載は確認できておらず(7.14.0 時点で既知問題として現役掲載)、本稿の約200秒は上記バージョン(main ソースビルド、commit c8602c790)での実測値として読んでほしい。
性能面では 3.1 節の表の通り、低並列(c=1)では llama.cpp 勢に大きく見劣りする(4.19 vs 9.84〜10.52 tok/s)が、継続バッチングの効果で並列数が上がるほど強くなり、c=32 では OFF で 58.25 tok/s と全系列中最速に達する。MTP 込みでも c=8 で 32.86 tok/s(+42.5%)と、投機デコードの効果は一貫して確認できた。低並列で不利・高並列で有利という傾向は、継続バッチング方式のアーキテクチャ的な特性として素直に読める結果である。
再現情報
vLLM 側の測定構成をまとめておく。
環境: vLLM は main ブランチのソースビルド(バージョン 0.1.dev1+gc8602c790.rocm723、commit c8602c790。PYTORCH_ROCM_ARCH=gfx1151 を指定してビルドした Docker イメージを使用し、バージョンはイメージ内で import vllm と pip show vllm の両方から実測確認した)。モデルは Qwen/Qwen3.8-27B の BF16 チェックポイント(52GB、18分割 safetensors)をローカル取得して使った。
サーバ起動(測定時の実コマンド):
docker run --rm --network host \
--device=/dev/kfd --device=/dev/dri --group-add video --group-add render \
--security-opt seccomp=unconfined \
-v /home/data:/home/data:ro \
--entrypoint vllm vllm-rocm-strix:latest \
serve /home/data/models/qwen38-27b-hf-bf16 \
--enforce-eager \
--max-model-len 16384 \
--max-num-seqs 64 \
--gpu-memory-utilization 0.85 \
--limit-mm-per-prompt '{"image": 1, "video": 0}' \
--mm-processor-kwargs '{"max_pixels": 262144}' \
--port 8100 --host 0.0.0.0
MTP(投機デコード)の有効化: 上記に次を追加する。
--spec-method mtp \
--spec-model /home/data/models/qwen38-27b-hf-bf16 \
--spec-tokens 1
Qwen3.8 の MTP ヘッドは本体チェックポイントに同梱の自己完結型で、--spec-model には target と同じパスを渡す。起動ログに「Detected MTP model. Sharing target model embedding/lm_head weights with the draft model」と出れば正しく認識されている。
負荷のかけ方: vLLM には llama.cpp の -np に相当する起動時オプションが無いため、並列数 c はクライアント側の vllm bench serve --max-concurrency <c> で制御した(サーバ側は --max-num-seqs 64 にしてボトルネックにならないようにしてある)。プロンプトは ShareGPT 由来の 200 リクエスト/条件で、llama.cpp 側も含む全系列で同一のプロンプト集合を使っている(llama-server は OpenAI 互換 API なので同じ vllm bench serve がそのまま使える)。測定は各条件 200 リクエスト × 1 実行(cold 起動から)で、実行間のばらつき評価は行っていない。出力検証(3.2節)は各条件 20 問を --save-detailed で保存して機械判定にかけている。
データセットの正確な出所は次の通り。ローカルファイルの Hugging Face メタデータと当該 revision への直接アクセス、および再取得ファイルの SHA256 一致で照合済みである。
| 項目 | 値 |
|---|---|
| リポジトリ |
anon8231489123/ShareGPT_Vicuna_unfiltered(Hugging Face Datasets) |
| ファイル | ShareGPT_V3_unfiltered_cleaned_split.json |
| revision | 192ab2185289094fc556ec8ce5ce1e8e587154ca |
| SHA256 | 35f0e213ce091ed9b9af2a1f0755e9d39f9ccec34ab281cd4ca60d70f6479ba4 |
huggingface-cli download anon8231489123/ShareGPT_Vicuna_unfiltered \
ShareGPT_V3_unfiltered_cleaned_split.json \
--revision 192ab2185289094fc556ec8ce5ce1e8e587154ca \
--local-dir ./sharegpt
1リクエストあたりの体感(TPOT): 3章の output tok/s は全リクエスト合算の合計スループットなので、1リクエストあたりの生成ペースは TPOT(Time Per Output Token)で別途示しておく(MTP ON、単位 ms、結果 JSON からの転記。この版の vllm bench serve は p95 を出力しないため p99 を併記)。
| Backend | c | mean | median | p99 |
|---|---|---|---|---|
| Vulkan | 1 | 50.0 | 49.3 | 83.4 |
| Vulkan | 8 | 282.6 | 249.3 | 780.1 |
| Vulkan | 32 | 1,143.4 | 1,070.1 | 2,834.7 |
| vLLM | 1 | 145.0 | 146.2 | 167.3 |
| vLLM | 8 | 221.4 | 222.2 | 365.6 |
| vLLM | 32 | 476.1 | 477.3 | 748.3 |
読み方の例を一つ。c=32 の vLLM は合計では 57.73 tok/s と全系列最速だが、TPOT は約 476ms——つまり 1リクエストあたりの生成ペースは約 2 tok/s である。高並列の「速さ」は全体の捌けの速さであって、個々のユーザーの体感速度ではない。逆に c=1 の Vulkan は TPOT 50ms(1リクエストで約 20 tok/s)で、個人利用の体感はこちらが圧倒的に良い。1章の「個人利用は Vulkan、チーム利用は vLLM」という使い分けは、この2つの見方の両方に支えられている。TPOT の悪化は c 増加に伴い両系列で起きるが、vLLM の方が高並列域で緩やかで、3章の合計スループット逆転と整合する。
なお TTFT(最初のトークンまでの時間)も記録してあるが、本測定は 200 リクエストを一斉投入する方式のため、TTFT には後続リクエストのキュー待ち時間が混入する(特に llama.cpp は同時ストリーム数を -np で厳密に切るため、待ち行列の影響が極端に出る)。対話的な応答速度の指標としては使えない数値なので、本文には載せず、生データはリポジトリ公開時に JSON ごと出す。
6. 5月記事からの結論変化とまとめ
5月記事(b8966 時点、llama-bench 計測)では「prefill 支配のワークロードなら HIP が有利、generation 支配なら Vulkan が有利」という条件分岐の結論だった。今回(b10588、出力検証込み)はこの結論を更新する——実用に足る出力を返す範囲で見る限り、prefill/generation の支配関係によらず Vulkan/vLLM が優位 というのが現在の結論である。ただし5月は llama-bench(純粋な prefill/decode 速度計測)、今回は vllm bench serve による end-to-end 計測であり、測定方式そのものが異なるため数値の直接対比はしない。あくまで結論の方向性の話である。
一点、脚注を付けておく。「Vulkan なら絶対安全」と言い切れるほどの網羅的検証はできていない。issue #27579 のコメントでは、Vulkan でも超長文脈(80〜170k トークン、4スロット)下で稀に破損が観測されたという報告がある。我々自身の実測は 32k / c=32 までは clean だが、それを超える領域は未検証である——という限定付きでの推奨と理解してほしい。
まとめ。
- 個人利用(c≦4)は Vulkan + MTP、チーム利用(c≧8)は vLLM + MTP。逆転点は c=4〜8 の実測で確定
- HIP は PR #27311 がマージされるまで多並列運用を待つ(回避策は4.3節)
- Vulkan/MTP 構成の JamC-QA は 53.49% で、Spark(CUDA)の 53.44% と一致。今回の推奨構成に品質面の劣化は見られなかった
- ベンチマークには出力検証を付けよう。HTTP 200 と tok/s だけでは、壊れた出力を高速に吐いているだけの構成を「最速」と誤認する
7. コラム: 環境構築の失敗談
最後に、本編から外した環境構築の失敗談を2つ。同じ罠を踏む人のために書いておく。
その1: ROCm の版数迷路。事前情報では「ROCm 7.14.0 が stable としてリリースされた」とあったが、pip の whl-multi-arch チャンネル(TheRock 配布)には 7.14.0 という確定タグは存在せず、dev スナップショットのままバージョン番号が 7系から 10系へ飛んでいた。apt 経路(repo.radeon.com)はというと、ROCm 本体の版数と Radeon Software for Linux ドライバスタックの版数(25.30.1〜)が同じリポジトリに混在していて一見齟齬に見える(採番系の重複であって齟齬ではない)。AMD は 7.14 について apt / pip / tarball / Runfile の4方式を公式に案内しているが、当環境の目的——既存の 7.2.2 を残したまま 7.14 を分離して共存させる——には、ROCm Runfile Installer(7.14 で新規導入された自己完結型インストーラ、複数バージョン併存可・ドライバ導入は任意)が最も明確だった。
その2: 切り替えたつもりで切り替わっていなかった。その 7.14.0 を指定してビルドした HIP バイナリが、ldd で実体を辿ると 実行時には一貫して 7.2.2 のランタイムにリンクされていた。cmake の HIP コンパイラ設定は正しく 7.14.0 を指していたが、バイナリに ROCm ライブラリへの RUNPATH が設定されず、共有ライブラリは SONAME 経由でシステムデフォルト(/opt/rocm シンボリックリンク、常に 7.2.2 を指す)から解決されていた。つまりコンパイラだけが 7.14.0 で、ランタイムは終始 7.2.2。以前「7.2.2 と 7.14.0 の差は 2.2%、誤差範囲」と結論づけた比較は、実質同一ランタイム同士の比較だったことになり、撤回した(なお本稿の測定はすべて同一環境同士の比較なので、内部妥当性には影響しない)。複数バージョンの ROCm を併存させるときは、「コンパイラがどれを指すか」と「実行時にどのランタイムがリンクされるか」は別問題で、後者は ldd で実バイナリを見るまで分からない。
教訓はどちらも同じである。測定環境の思い込みは、測定結果より先に疑ってかかるべき。この記事を書いている我々自身が踏んだのだから、同じ罠を踏んでいる人は確実に他にもいるはずだ。
本記事のベンチマーク生データ・測定スクリプト・パッチは nabe2030/qwen38-evo-x2 で公開しています。関連する過去記事: DGX Spark での Qwen3.8-27B 検証、EVO-X2 ROCm 7.2.2 HIP vs Vulkan(2026年5月)、日本語ベンチマークと JamC-QA 採用の経緯
