0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RX9060xt+Qwen3.8-27B-llamaserver+実測

0
Last updated at Posted at 2026-08-19

Windows + RX 9060 XT×2でQwen3.8-27BをOllamaからllama.cppへ移行した実測記録

VulkanではOllamaより遅く、ROCm/HIPでは最大28.68 tok/sを確認するまで

はじめに

Windows環境で、AMD Radeon RX 9060 XT 16GBを2枚使用し、Qwen3.8-27B をローカル推論した。

もともとの目的は単純で、

Ollamaからllama.cppへ変更すると推論速度が上がるのか

を実機で確認することだった。

最終的には、同じハードウェア・同じ unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL を使用して、

  • Ollama:12.89 tok/s
  • llama.cpp Vulkan:最大8.96 tok/s(MTP使用時)
  • llama.cpp ROCm/HIP:28.68 tok/sを確認
  • ROCm/HIPで別run:29.25 tok/sを確認

となった。

ただし、28〜29 tok/sは常に出る値ではない。MTP(Multi-Token Prediction)のdraft acceptanceによって速度が大きく変動した。

また、調査途中でベンチマーク方法を変更している。

この記事では、その点を隠さず、

  1. llama-bench
  2. llama-server /completion
  3. Ollama /api/generate
  4. qwen38-mtp/probe.py

を使ったフェーズを分けて記録する。


実行環境

GPU

AMD Radeon RX 9060 XT × 2
VRAM: 16GB × 2

llama.cpp Vulkan版からは次のように認識された。

Available devices:
  Vulkan0: AMD Radeon RX 9060 XT (16304 MiB, 15443 MiB free)
  Vulkan1: AMD Radeon RX 9060 XT (16304 MiB, 15443 MiB free)

AMD公式のWindows HIP SDK対応表では、RX 9060 XTはRDNA4のgfx1200としてサポート対象になっている。

AMDドライバ

PowerShellで確認した値。

Get-CimInstance Win32_VideoController |
Select-Object Name, DriverVersion, DriverDate

結果:

Name                  DriverVersion   DriverDate
----                  -------------   ----------
AMD Radeon RX 9060 XT 32.0.31035.1003 2026/07/24
AMD Radeon RX 9060 XT 32.0.31035.1003 2026/07/24

PCIe

WindowsのPnPプロパティで確認した。

GPU 1
CurrentWidth = x16
MaxWidth     = x16
CurrentSpeed = 5
MaxSpeed     = 5

GPU 2
CurrentWidth = x16
MaxWidth     = x16
CurrentSpeed = 5
MaxSpeed     = 5

少なくともWindowsが報告するPCIeリンク幅・速度について、片方だけx4/x1等へ落ちている状態ではなかった。

llama.cpp

検証に使用したbuild:

build: 9d77fa172 (10488)

使用したWindows配布物:

llama-b10488-bin-win-vulkan-x64
llama-b10488-bin-win-rocm-7.14-x64

モデル

全検証の中心として使用したモデル:

unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL

llama-bench上では以下のサイズとして表示された。

size   : 16.68 GiB
params : 27.32 B

なお、llama-benchのモデル名表示は、

qwen35 27B Q4_K - Small

となっていたが、実際に-hfで指定しているファイルは、

Qwen3.8-27B-UD-Q4_K_XL.gguf

だった。


きっかけ

当初はOllamaでコード生成時におよそ、

約10 tok/s

だった。

WindowsでOllamaからllama.cppへ変更して高速化した事例を調べたことから、llama.cppへの移行を試した。

最初に選択したbackendはVulkanだった。

理由は単純で、Windows版llama.cppのVulkan buildではRX 9060 XTが2枚とも即座に認識された一方、ROCm 7.14版では最初はGPUを認識しなかったためである。


1. Vulkanで2GPUを認識

.\llama-cli.exe --list-devices

結果:

Available devices:
  Vulkan0: AMD Radeon RX 9060 XT (16304 MiB, 15443 MiB free)
  Vulkan1: AMD Radeon RX 9060 XT (16304 MiB, 15443 MiB free)

そこで最初はVulkanで進めた。


2. Qwen3.8-27BをVulkanで起動

最初のサーバー起動例:

.\llama-server.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  -ngl 100 `
  -sm layer `
  -ts 1,1 `
  -fa on `
  -c 32768 `
  --parallel 1 `
  --host 127.0.0.1 `
  --port 8080

モデル本体とmmproj-BF16.ggufが自動ダウンロードされ、サーバー自体は正常起動した。

model loaded
listening on http://127.0.0.1:8080

Qwen3.8の追加blockについて、

model has unused tensor blk.64....

という警告も出た。

後にMTPを明示的に有効化すると、このモデルに含まれるMTP用contextが使用可能であることを確認した。


3. 「GPUが1枚しか使われていない」と見えた問題

サーバー起動後に、

.\llama-cli.exe --list-devices

を実行すると、

Vulkan0: ... 7045 MiB free
Vulkan1: ... 15455 MiB free

となった。

この表示だけを見ると、Vulkan1にはモデルがロードされていないように見えた。

しかしWindowsのプロセス単位GPUカウンターを確認すると結果が異なった。

$pid_llama = (Get-Process llama-server).Id

Get-Counter '\GPU Process Memory(*)\Dedicated Usage' |
Select-Object -ExpandProperty CounterSamples |
Where-Object {$_.InstanceName -match "pid_$pid_llama"} |
Select-Object InstanceName,
@{N="VRAM_GB";E={[math]::Round($_.CookedValue/1GB,2)}}

結果:

pid_13100_luid_...06db7d1a...   8.25 GB
pid_13100_luid_...06dd78d9...   7.50 GB

異なる2つのLUIDにVRAM使用量が計上されていた。

したがって、少なくともWindows側ではllama-serverが2つのGPUアダプタにDedicated GPU Memoryを確保していた。

この時点で、

llama-cli --list-devicesのfree表示だけを見て「2枚目を使用していない」と判断するのは適切ではない

ことが分かった。


4. 最初のベンチマーク:llama-bench

ここから最初の速度測定を行った。

注意:この時点の測定方法

ここでは、

llama-bench

を使っている。

後半のllama-serverprobe.pyとは測定方法が違うので、数値を完全な同条件比較として扱わない。

測定内容:

pp512 = Prompt Processing 512 tokens
tg256 = Token Generation 256 tokens

Vulkan / layer split / 1:1 / FA ON

.\llama-bench.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  -dev Vulkan0/Vulkan1 `
  -ngl 999 `
  -sm layer `
  -ts 1/1 `
  -fa on `
  -p 512 `
  -n 256 `
  -r 1

結果:

pp512 = 27.91 tok/s
tg256 =  4.68 tok/s

これは、当初Ollamaで見ていた約10 tok/sより明確に遅かった。


Vulkan / layer / 自動split

-ts 1/1を外した。

結果:

pp512 = 26.58 tok/s
tg256 =  4.70 tok/s

ほぼ変わらなかった。


Vulkan / layer / FA OFF

pp512 = 26.19 tok/s
tg256 =  4.88 tok/s

Flash Attentionを無効化しても生成速度はほぼ同じだった。


Vulkan / tensor split

.\llama-bench.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  -dev Vulkan0/Vulkan1 `
  -ngl 999 `
  -sm tensor `
  -ts 1/1 `
  -fa on `
  -p 512 `
  -n 256 `
  -r 1

結果:

pp512 = 45.56 tok/s
tg256 =  5.35 tok/s

Prompt Processingは大きく伸びた。

一方、Token Generationは、

4.68 → 5.35 tok/s

に留まった。


5. VulkanでMTPを有効化

ここで測定方法を変更した。

ベンチマーク方法変更①

それまで:

llama-bench

ここから:

llama-server
↓
HTTP /completion
↓
response.timings.predicted_per_second

を使用した。

したがって、llama-bench tg256/completionのTPSは同じ測定器による値ではない。


MTPを有効化した。

--spec-type draft-mtp
--spec-draft-n-max N

サーバーログには、

creating MTP draft context against the target model

と表示された。


Vulkan / tensor + MTP

同じ256-token生成でn-maxを変更した。

n-max 生成速度 Draft acceptance
2 7.50 tok/s 71.8%
5 8.52 tok/s 52.1%
6 8.96 tok/s 48.1%
7 8.77 tok/s 45.0%
9 8.79 tok/s 35.2%
12 7.45 tok/s 27.9%

このVulkan環境ではn-max=6が測定した中で最速だった。

それでも、

8.96 tok/s

であり、Ollamaの約10 tok/sを上回らなかった。


6. Ollamaを同一GGUF・同一リクエストで測定

ここまでのOllama約10 tok/sという値は、普段のコード生成時に確認していた速度だった。

より厳密に比較するため、Ollamaにも同じUnsloth GGUFを読み込ませた。

hf.co/unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL

Unslothのモデルページでも、このGGUFをOllamaから直接使用する方法が案内されている。

測定条件:

model             = UD-Q4_K_XL
num_ctx           = 8192
num_predict       = 256
temperature       = 0
draft_num_predict = 6

PowerShell:

$model = "hf.co/unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL"

$body = @{
    model  = $model
    prompt = "Write a Python program that implements a thread-safe LRU cache with detailed comments and example usage."
    stream = $false
    options = @{
        num_ctx           = 8192
        num_predict       = 256
        temperature       = 0
        draft_num_predict = 6
    }
} | ConvertTo-Json -Depth 5

結果:

Tokens  = 256
Seconds = 19.87
TPS     = 12.89

つまり、この時点の同一GGUF比較では、

Ollama                   12.89 tok/s
llama.cpp Vulkan + MTP    8.96 tok/s

となった。

この環境ではVulkan版llama.cppへの変更は高速化にならなかった。


7. ROCm/HIPの高速事例を知る

その後、2026年8月のコミュニティ情報として、

RX 9060 XT ×2
Qwen3.8-27B UD-Q4_K_XL
ROCm/HIP
layer split
MTP

で約30 tok/sという事例を参照した。

共有されていた設定は以下。

env:
  - "HIP_VISIBLE_DEVICES=0,1"

cmd: |
  llama-server
  -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL
  -ngl 999
  -sm layer
  -ts 0.5,0.5
  -c 131072
  -ctk q8_0
  -ctv q8_0
  -fa on
  --spec-type draft-mtp
  --spec-draft-n-max 3
  --jinja

ここで重要なのは、

-sm layer
-ts 0.5,0.5

は「tensor parallel」ではないという点。

llama.cppのmulti-GPU仕様では、

-sm layer

がlayer/pipeline parallelismで、

-ts 0.5,0.5

は各GPUへ割り当てる比率。

tensor parallelismそのものは、

-sm tensor

で指定する。


8. qwen38-mtpの公開データ

sudoingX/qwen38-mtpにはQwen3.8-27BのMTP測定結果が公開されている。

RX 9060 XT 16GBのコミュニティ行には、

Baseline : 15.2 tok/s
MTP      : 28.7 tok/s
n-max    : 2
Acceptance: 0.62 - 0.93

という値が掲載されていた。

これは今回のdual GPU構成と同一条件ではない。

ただし、

RX 9060 XT
ROCm
Qwen3.8
MTP

で高い速度が出る例が存在することを確認する材料になった。


9. Windows ROCm 7.14版が最初はGPUを認識しなかった

Vulkanでは即座に2GPUを認識したが、

llama-b10488-bin-win-rocm-7.14-x64

は最初GPUを認識しなかった。

同時期のllama.cpp Issue #26996では、Windows ROCm 7.14配布物について、

ggml-hip.dll
↓
hipblas.dll を要求
↓
配布zipに hipblas.dll が存在しない
↓
--list-devices が空になる

という問題が報告されていた。

Issueで確認されているbuildはb10400であり、今回使用したb10488と完全に同じbuildではない。

ただし、

ROCm 7.14版単体ではGPUを認識しない

という症状は一致していた。


10. WindowsにTheRock / ROCm 7.14 runtimeを追加

AMDのROCm 7.14 multi-arch tarballを使用した。

New-Item -ItemType Directory -Force C:\TheRock
New-Item -ItemType Directory -Force C:\TheRock\build

cd C:\TheRock

curl.exe -L `
  -o therock-dist-windows-multiarch-7.14.0.tar.gz `
  "https://repo.amd.com/rocm/tarball-multi-arch/therock-dist-windows-multiarch-7.14.0.tar.gz"

展開:

tar -xzf `
  C:\TheRock\therock-dist-windows-multiarch-7.14.0.tar.gz `
  -C C:\TheRock\build `
  --strip-components=1

確認:

Get-ChildItem C:\TheRock\build -Recurse -Filter "hipblas.dll"
Get-ChildItem C:\TheRock\build -Recurse -Filter "rocblas.dll"

PATHへ追加:

$env:PATH = "C:\TheRock\build\bin;$env:PATH"

その後、hipInfo.exeとllama.cpp ROCm版の両方でRX 9060 XTを認識した。

$env:HIP_VISIBLE_DEVICES="0,1"

.\llama-cli.exe --list-devices

ここでWindows上のROCm/HIP 2GPU環境が使用可能になった。


11. ROCmで最初の速度測定

最初は切り分けのためcontext 8192で測定した。

.\llama-server.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  --no-mmproj `
  -ngl 999 `
  -sm layer `
  -ts 0.5,0.5 `
  -c 8192 `
  -fa on `
  --spec-type draft-mtp `
  --spec-draft-n-max 3 `
  --parallel 1 `
  --jinja `
  --host 127.0.0.1 `
  --port 8080

同じ19-token prompt / 256-token生成で:

prompt_per_second    = 57.19
predicted_per_second = 18.50
draft_n              = 354
draft_n_accepted     = 136

Acceptance:

136 / 354 = 38.4%

ここで初めて、

llama.cpp ROCm 18.50 tok/s
>
Ollama        12.89 tok/s

となった。


12. 元の128K設定へ寄せる

コミュニティ事例に合わせ、

-c 131072
-ctk q8_0
-ctv q8_0

を追加した。

結果:

predicted_per_second = 13.61 tok/s
draft_n              = 467
draft_n_accepted     = 98
Acceptance           = 21.0%

つまり、自環境では128K設定にしただけでは30 tok/sにならなかった。

むしろ8K時の18.50 tok/sから低下した。


13. 8KのままKV cacheだけQ8_0へ変更

128KとQ8 KVを同時に変更していたため、原因を分離した。

context = 8192
K cache = q8_0
V cache = q8_0

結果:

predicted_per_second = 19.05 tok/s
draft_n              = 344
draft_n_accepted     = 139
Acceptance           = 40.4%

つまり、

8K + F16 KV = 18.50 tok/s
8K + Q8 KV  = 19.05 tok/s

だった。

この測定ではQ8 KV自体は速度低下の原因ではなかった。

128Kへ拡張した時の方が大きく速度が落ちていた。


14. ROCmでMTP n-maxを再探索

Vulkanで最適だったn-max=6をそのまま使わず、ROCmで再測定した。

条件:

ROCm
layer
0.5/0.5
context 8192
KV q8_0

結果:

n-max TPS Acceptance
2 17.69 34.2%
3 19.05 40.4%
4 13.13 19.6%
5 14.27 25.3%

この条件ではn-max=3が測定した中で最速だった。

Vulkanでn-max=6が最速だった結果とは異なる。


15. PCIeと2GPU使用率を確認

PCIeリンク:

GPU0: x16 / x16
GPU1: x16 / x16
CurrentSpeed = MaxSpeed = 5

推論中のWindows GPU Engineカウンターでは、

GPU LUID A
VRAM    ≈ 8.506 GB
Compute ≈ 36 - 39%

GPU LUID B
VRAM    ≈ 9.517 GB
Compute ≈ 50 - 53%

を確認した。

両GPUともROCm推論中にCompute Engineが動作していた。


16. layer split比率を変更

50:50から、

0.6 / 0.4

へ変更した。

使用コマンド:

.\llama-server.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  --no-mmproj `
  -ngl 999 `
  -sm layer `
  -ts 0.60,0.40 `
  -c 8192 `
  -ctk q8_0 `
  -ctv q8_0 `
  -fa on `
  --spec-type draft-mtp `
  --spec-draft-n-max 3 `
  --parallel 1 `
  --jinja `
  --host 127.0.0.1 `
  --port 8080

ここからMTP acceptanceによる速度変動がはっきり見えるようになった。

同じ256-token系の実測ログには、

17.99 tok/s
Acceptance 36.5%
29.25 tok/s
Acceptance 81.1%
12.19 tok/s
Acceptance 13.8%

が含まれていた。

同じハードウェア・同じサーバー設定でも、MTPのacceptanceにより速度が大きく変化していた。


17. ベンチマーク方法変更②:qwen38-mtp probe.py

ここで再びベンチマーク方法を変更した。

それまで

/completion
1つの固定prompt
256-token生成
llama-serverが返すtimingsを使用

ここから

sudoingX/qwen38-mtpprobe.pyを使用。

このprobeは、

/v1/chat/completions
stream = true
enable_thinking = false

を使用し、

3種類のpromptをそれぞれ3回実行する。

RUNS       = 3
MAX_TOKENS = 400

各promptの中央値を出し、最後に全runのmeanとmedianを出力する。

つまり、ここからの値は前の/completion 256 tokenと同じ測定方法ではない。


18. probe.py / split 0.6,0.4

結果:

14.8 tok/s median
runs: [14.8, 14.7, 18.1]

11.6 tok/s median
runs: [11.6, 10.5, 22.3]

19.4 tok/s median
runs: [21.1, 16.4, 19.4]

全体:

OVERALL: mean 16.5 median 16.4

したがって、

29.25 tok/s

という単発値と、

probe.py overall median 16.4 tok/s

は両方実測値だが、同じ意味の数値ではない。

29.25は高acceptanceだった1回の256-token生成。

16.4は3prompt×3runのストリーミング測定中央値。


19. probe.py / split 0.5,0.5

確認できた途中結果:

10.0 tok/s median
runs: [10.0, 9.8, 18.2]

10.5 tok/s median
runs: [10.8, 0.0, 10.5]

その後、

KeyError: 'choices'

probe.pyが停止した。

したがって0.5/0.5については、このrunではOVERALL mean/medianを取得できなかった。


20. chat parser / 出力破損も発生

一部のprobe/chat実行では、

common_chat_peg_parse: unparsed peg-native output

が発生した。

実際のログにも文字化け・不正な出力が記録された。

したがって、この状態のrunについて速度値だけを採用して「高速化した」とは扱わなかった。


21. ROCm tensor splitも試した

layer以外に、

-sm tensor

も試した。

起動ログでは、

internal AllReduce init failed
falling back to meta-backend butterfly

さらに、

backend sampling not supported with SPLIT_MODE_TENSOR; using CPU
backend offload failed ... using CPU sampler

が出た。

実行例:

-sm tensor
-ts 0.5,0.5

および、

-sm tensor
-ts 0.6,0.4

を試した。

一部runでは、

7.06 tok/s
draft acceptance = 0%

となり、文字化けした出力も発生した。

このため、ROCm tensor modeは今回の有効な最高速結果には含めていない。

llama.cppのmulti-GPUドキュメントでもtensor modeはexperimentalとされている。


22. --spec-draft-p-min 0.5

MTPの無駄draftを減らす目的で、

--spec-draft-p-min 0.5

を試した。

実機では、

約8 tok/s

まで低下した。

この値はユーザー観測値であり、詳細なtimingsログは保存していない。

少なくとも今回の環境では、p-min=0.5を採用する理由になる結果は得られなかった。


23. 最終的に28.68 tok/sを確認した設定

p-minを0へ戻した。

使用コマンド:

.\llama-server.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  --no-mmproj `
  -ngl 999 `
  -sm layer `
  -ts 0.6,0.4 `
  --fit off `
  -c 8192 `
  -ctk q8_0 `
  -ctv q8_0 `
  -fa on `
  --spec-type draft-mtp `
  --spec-draft-n-max 3 `
  --spec-draft-p-min 0 `
  --parallel 1 `
  --jinja `
  --host 127.0.0.1 `
  --port 8080

結果:

prompt_n               : 19
prompt_per_second      : 63.17

predicted_n            : 256
predicted_ms           : 8892.282
predicted_per_second   : 28.6766

draft_n                : 226
draft_n_accepted       : 179

Acceptance:

179 / 226
= 79.2%

llama-serverログ:

eval time = 8892.28 ms / 256 tokens
28.68 tokens per second

draft acceptance = 0.79204
179 accepted / 226 generated
mean len = 3.36

この256-token測定では、

28.68 tok/s

を確認した。

別runでは、

29.25 tok/s
Acceptance 81.1%

も確認している。


24. MTP acceptanceと速度

今回のログでは、MTP acceptanceが高いrunほどTPSも高い例が多数確認された。

例えば:

Acceptance TPS
5.8% 10.02
13.8% 12.19
36.5% 17.99
37.6% 18.02
53.9% 22.21
57.7% 23.31
79.2% 28.68
81.1% 29.25

これは今回取得したサンプルの対応関係であり、一般的な変換式を意味しない。

ただし、本環境で28〜29 tok/sが出たrunはいずれもMTP acceptanceが約80%だった。


25. backend samplingを無効化

最終基準設定に、

--no-spec-draft-backend-sampling

だけを追加した。

結果:

predicted_per_second = 24.22
draft_n              = 270
draft_n_accepted     = 165
Acceptance           = 61.1%

28.68 tok/sを記録したrunより低かった。

サーバー起動時には、

ROCm1 does not have support for op TOP_K needed for sampler 'top-k'

という警告が出ていたが、今回の実測ではbackend samplingを明示的に無効化したrunの方が速くはならなかった。


26. MTP draft側KV cacheをQ8_0へ変更

次に、

--spec-draft-type-k q8_0
--spec-draft-type-v q8_0

だけを追加した。

結果:

predicted_per_second = 21.59
draft_n              = 298
draft_n_accepted     = 154
Acceptance           = 51.7%

このrunも28.68 tok/sより低かった。


27. backend sampling無効 + draft KV Q8_0

両方を同時に指定した。

結果:

predicted_per_second = 21.49
draft_n              = 301
draft_n_accepted     = 154
Acceptance           = 51.2%

今回測定した範囲では、

--no-spec-draft-backend-sampling

も、

draft KV q8_0

も、28.68 tok/sを記録した基準runを上回らなかった。


ベンチマーク方法を途中で変更した点のまとめ

この記事で最も重要な注意点の一つ。

Phase 1: llama-bench

使用した指標:

pp512
tg256

主にVulkan backendの基礎性能を見るために使用。

代表値:

Vulkan layer  : tg256 4.68 tok/s
Vulkan tensor : tg256 5.35 tok/s

Phase 2: llama-server /completion

固定promptを投げ、

predicted_per_second
draft_n
draft_n_accepted

を測定。

主にMTPの調整に使用。

代表値:

Vulkan MTP6 : 8.96 tok/s

ROCm        : 18.50 tok/s
ROCm Q8 KV : 19.05 tok/s

ROCm high-acceptance run:
28.68 tok/s
29.25 tok/s

Phase 3: Ollama /api/generate

同じUnsloth GGUFをOllamaから直接実行。

256 tokens
12.89 tok/s

これはOllamaとの比較をそれまでの「約10 tok/s」より厳密にするために行った。


Phase 4: qwen38-mtp probe.py

測定方法:

/v1/chat/completions
streaming
thinking disabled

3 prompts
×
3 runs

max_tokens = 400

0.6/0.4の結果:

OVERALL mean   = 16.5 tok/s
OVERALL median = 16.4 tok/s

したがって、

28.68 tok/sと16.4 tok/sは矛盾している

わけではない。

測定対象が違う。

28.68:
固定prompt
256 token
高MTP acceptanceだった単発run

16.4:
3種類のprompt
各3回
最大400 token
streaming
全9 runのmedian

である。


主要結果一覧

llama-bench系

Backend Split FA 測定 TPS
Vulkan layer 1:1 ON pp512 27.91
Vulkan layer 1:1 ON tg256 4.68
Vulkan layer auto ON pp512 26.58
Vulkan layer auto ON tg256 4.70
Vulkan layer 1:1 OFF pp512 26.19
Vulkan layer 1:1 OFF tg256 4.88
Vulkan tensor 1:1 ON pp512 45.56
Vulkan tensor 1:1 ON tg256 5.35

llama-server / Ollama系

実行系 主な条件 TPS
Ollama 普段のコード生成 初期観測 約10
llama.cpp Vulkan tensor + MTP6 8.96
Ollama 同一UD-Q4_K_XL / 8K / 256 tokens / MTP6 12.89
llama.cpp ROCm 8K / layer / MTP3 18.50
llama.cpp ROCm 8K / Q8 KV / layer / MTP3 19.05
llama.cpp ROCm 128K / Q8 KV / MTP3 13.61
llama.cpp ROCm 8K / Q8 / 0.6:0.4 / high acceptance 29.25
llama.cpp ROCm 8K / Q8 / 0.6:0.4 / p-min 0 28.68
ROCm + backend sampling無効 同じ256-token prompt 24.22
ROCm + draft KV Q8 同じ256-token prompt 21.59
ROCm + 上記2つ併用 同じ256-token prompt 21.49

probe.py系

split 0.6 / 0.4

14.8 median
11.6 median
19.4 median

OVERALL mean   16.5
OVERALL median 16.4

split 0.5 / 0.5

途中まで:

10.0 median
10.5 median

その後、

KeyError: 'choices'

で停止。

OVERALL値なし。


最終的に確認できた事実

1. Vulkan版llama.cppはこの環境ではOllamaより遅かった

同一GGUFを使用した後半の比較では、

Ollama                  12.89 tok/s
llama.cpp Vulkan + MTP   8.96 tok/s

だった。

したがって、

Ollamaからllama.cppに変更すれば必ず速くなる

とは言えない。

少なくとも、

Windows
RX 9060 XT ×2
Qwen3.8-27B UD-Q4_K_XL
llama.cpp b10488
Vulkan

ではOllamaを下回った。


2. 同じllama.cppでもROCm/HIPでは結果が大きく変わった

Vulkan + MTP : 8.96 tok/s
ROCm         : 18.50~19.05 tok/s

まで上昇した。

高いMTP acceptanceになった256-token runでは、

28.68 tok/s
29.25 tok/s

も確認した。


3. Ollama 12.89 tok/sに対し、ROCmの28.68 tok/s runは約2.22倍

28.68 / 12.89 ≈ 2.22

ただし、28.68は単発の高acceptance runであり、全promptで常に出る値ではない。


4. probe.pyによる複数prompt測定では16.4 tok/s medianだった

split = 0.6 / 0.4

OVERALL median = 16.4 tok/s

したがって、

最高観測値 ≈ 29 tok/s

と、

複数prompt median = 16.4 tok/s

は分けて記録する必要がある。


5. 128Kで30 tok/sは今回の測定では再現できなかった

128K / Q8 KV / MTP3の256-token測定:

13.61 tok/s

だった。

今回約29 tok/sが出たのは8K contextでMTP acceptanceが約80%になったrunだった。


6. MTP acceptanceによる変動が大きかった

同じサーバー構成でも、

Acceptance 13.8% → 12.19 tok/s
Acceptance 36.5% → 17.99 tok/s
Acceptance 57.7% → 23.31 tok/s
Acceptance 79.2% → 28.68 tok/s
Acceptance 81.1% → 29.25 tok/s

という実測になった。


7. n-maxの最適値はbackendによって異なった

今回の実測では、

Vulkan → n-max 6が最速
ROCm   → n-max 3が最速

だった。


8. p-min=0.5は今回の環境では遅くなった

観測値:

約8 tok/s

だった。


9. backend sampling無効化とdraft KV Q8化も最高値を更新しなかった

基準high-acceptance run       28.68 tok/s
backend sampling無効          24.22 tok/s
draft KV Q8                   21.59 tok/s
両方                           21.49 tok/s

10. ROCm tensor splitは今回採用しなかった

ログには、

AllReduce init failed
falling back to meta-backend butterfly

backend sampling not supported with SPLIT_MODE_TENSOR
using CPU sampler

が出た。

さらに出力破損も確認した。

そのため、この記事のROCm最高値はすべて、

-sm layer

で得た結果である。


現時点で28.68 tok/sを記録したコマンド

Windows PowerShell:

$env:PATH = "C:\TheRock\build\bin;$env:PATH"
$env:HIP_VISIBLE_DEVICES="0,1"

cd Downloads\llama-b10488-bin-win-rocm-7.14-x64

.\llama-server.exe `
  -hf "unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL" `
  --no-mmproj `
  -ngl 999 `
  -sm layer `
  -ts 0.6,0.4 `
  --fit off `
  -c 8192 `
  -ctk q8_0 `
  -ctv q8_0 `
  -fa on `
  --spec-type draft-mtp `
  --spec-draft-n-max 3 `
  --spec-draft-p-min 0 `
  --parallel 1 `
  --jinja `
  --host 127.0.0.1 `
  --port 8080

256-token測定時:

28.6766 tok/s
Acceptance 79.2%

まとめ

今回の検証結果を一文にすると、

Windows + RX 9060 XT 16GB×2 + Qwen3.8-27B UD-Q4_K_XLでは、llama.cpp VulkanはOllamaより遅かったが、ROCm/HIPへ切り替えることでOllamaを上回り、高MTP acceptanceのrunでは約29 tok/sまで確認できた。

ただし、

29 tok/s = 常時性能

ではない。

qwen38-mtp/probe.pyで複数promptを測った0.6/0.4構成のoverall medianは、

16.4 tok/s

だった。

したがって今回の結果は、

最高観測値
定型promptの256-token速度
複数promptのmedian

を区別して扱う必要がある。

また、検証中に明確だったのは、

Ollama vs llama.cpp

というランタイム名だけで性能が決まるのではなく、

Vulkan / ROCm
multi-GPU split mode
split ratio
context size
KV cache形式
MTP n-max
MTP acceptance

によって結果が大きく変化したことだった。


参考資料

llama.cpp multi-GPU documentation

https://github.com/ggml-org/llama.cpp/blob/master/docs/multi-gpu.md

layerがpipeline parallel、tensorがexperimental tensor parallelであること、-tsがGPUごとの割当比率であることを確認できる。

llama.cpp speculative decoding documentation

https://github.com/ggml-org/llama.cpp/blob/master/docs/speculative.md

MTP speculative decodingの仕様。

llama.cpp server documentation

https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md

--spec-draft-p-min、backend sampling、draft device等のserver option。

Windows ROCm 7.14 hipblas.dll issue

https://github.com/ggml-org/llama.cpp/issues/26996

Windows ROCm 7.14版でhipblas.dll不足により--list-devicesが空になる問題報告。

AMD ROCm Windows system requirements

https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html

RX 9060 XT / gfx1200のWindows HIP SDK対応状況。

AMD ROCm multi-arch tarball

https://repo.amd.com/rocm/tarball-multi-arch/

今回TheRock / ROCm 7.14 runtime取得に使用。

Unsloth Qwen3.8-27B GGUF

https://huggingface.co/unsloth/Qwen3.8-27B-GGUF

UD-Q4_K_XLをllama.cppおよびOllamaから使用可能。

qwen38-mtp

https://github.com/sudoingX/qwen38-mtp

Qwen3.8-27BのMTPコミュニティ測定値とチューニング情報。

probe.py

https://github.com/sudoingX/qwen38-mtp/blob/master/probe.py

この記事後半で使用した複数prompt・streamingベンチマーク。

GPU割り当てを0.7,0.3では、片方のGPUが100%となり、13t/sまで低下。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?