社内で LLM を複数人に配る時は、サーバーのソフトと設定で、同じ GPU から出せる速さが大きく変わります。AIコンパスを運営する ALLFORCES の編集部は、Qwen3 14B を H200 1 基で動かし、Ollama・llama.cpp の llama-server・vLLM の 3 つで、同時に使う人数を 1〜128 人に増やして測りました。
同時 16 人で使うと、全体の出力は vLLM が1,403〜1,404、llama-server(枠 16)が404〜413、Ollama(並列 16)が175〜179トークン/秒だった
利用者は「返事を受け取ったらすぐ次を送る」動きで、依頼は約 640 トークンの文書(800 字前後)の要約です。60 秒の測定を、全設定で 2 巡しました。vLLM だけ重みが違い(元の重み。Ollama と llama-server は 4 ビット量子化の Q4_K_M)、サーバーの差に重みの差が混ざっています。 効果は測りましたが、原因は確認していません。原因に触れる所には「(推定)」と付けています。結論は 5 つです。
- 1 人で使う時:1 人あたりの速さは、llama-server が 149〜153、vLLM が 116、Ollama が 84〜94 トークン/秒でした。Ollama と llama-server は同じファイルですが、llama-server が Ollama の 1.58〜1.73 倍でした(同じ枠の数の設定どうしを、回ごとに比べた 6 組の幅)。原因は確認していません。
- 人数を増やした時:vLLM は同時 128 人で、全体の出力が 3,459〜3,462 トークン/秒、1 人あたり 27.9 トークン/秒でした。同時 128 人を超えると伸びなくなり、256 人で編集部の線を割りました(追加の測定)。llama-server(-np 16)は同時 16 人で 404〜413(1 人あたり 26.4〜27.1)、Ollama(並列 16)は 175〜179(11.3〜11.6)です。
- 枠の数:枠を超えた依頼は順番待ちになりました。逆に、同時 16 人と 32 人では、枠を 64 に増やすと全体の出力が枠 16 の約半分に下がり、同時 16 人で llama-server は 404〜413 から 178〜195、Ollama は 175〜179 から 84〜95 トークン/秒になりました。GPU メモリも 19GiB 台から 49GiB 台に増えました。llama-server の -np 16 は、同時 8 人で
--kv-unifiedを付けると全体の出力が 1.62〜1.69 倍、-np を 8 に合わせると 1.54〜1.58 倍になりました(追加の測定。別の GPU)。 - 数秒の遅れ:llama-server の既定は、同時 4 人以下で、新しく処理する依頼文が 512 トークンを少し超えると、最初の文字まで数秒かかることがありました(この測定では、依頼文が 580〜599 トークンの依頼)。計算の単位(
-ub。1 回の計算で処理するトークン数の上限で、既定は 512)を-b 2048 -ub 2048に上げた設定では、この長さの依頼のうち遅い依頼(最初の文字まで 1 秒を超えた依頼)は 30 件中 1 件でした。既定のままの 3 設定の合計は 93 件中 50 件です(追加の測定)。 - 量子化:Q4_K_M・Q5_K_M・Q6_K・Q8_0 と元の重みで、日本語の正答率は JCommonsenseQA が 94.0〜94.5%、MGSM が 82.8〜85.2%、文章校正で直せた文が 54.0〜60.5% でした。Q8_0 と比べて、補正後に差があるとは言えませんでした。
用語は次の意味で使います。
- 枠:サーバーが同時に処理できる依頼の数。Ollama は並列数(
OLLAMA_NUM_PARALLEL)、llama-server は-np、vLLM は--max-num-seqs。記事の「枠 16」は、Ollama の並列 16 と llama-server の -np 16 を指す。 - 同時利用:負荷の道具が模した利用者の数。「同時 16 人」のように書く。
- 順番待ち:枠を超えた依頼が、空きができるまでサーバーで待つこと。
- 全体の出力:測る 60 秒の間に届いた出力トークンの数 ÷ 60(トークン/秒)。
- 1 人あたりの速さ:依頼ごとの(出力トークン − 1)÷(最初の文字から最後の文字までの秒)の中央値(トークン/秒)。順番待ちの時間を含まない。
- 最初の文字までの時間(英語では TTFT):送信から最初の出力が届くまでの時間。順番待ちの時間を含む。
- 95% 点:全依頼を短い順に並べて 95% 目の値。遅い方から 5% の依頼は、この値より時間がかかった。
- 遅い依頼:最初の文字まで 1 秒を超えた依頼。送信が測定の開始 5 秒より後の依頼を数える(集計の対象外の、助走の依頼を含む)。
- 計算の単位(
-ub):llama-server が 1 回の計算で処理するトークン数の上限。既定は 512。 - KV キャッシュ:処理済みの文脈を GPU に保存する領域。
- 本走:実測表の元になった測定(9 設定・53 測定を 2 巡)。
- 追加の測定:本走とは別の GPU(同じ型の H200)で別の日に、設定を足して測った補足。本走の値と同じ表・同じ棒に並べない。
- 対照:追加の測定で、比べる基準にした設定(llama-server の -np 16。本走と同じ引数)。
- 編集部の線:最初の文字まで 95% 点が 2 秒以内で、かつ 1 人あたりの速さの中央値が毎秒 10 トークン以上。編集部が置いた線で、実測表の ○ はこの線を 2 巡とも満たした測定を示す。
用途別の候補
根拠は、実測表以降の各節にあります。
1 人で試す
- 候補:Ollama の既定(並列 1)か、llama-server
- 根拠:1 人あたりの速さは llama-server が 149〜153、Ollama が 84〜94 トークン/秒。Ollama の並列 1 は同時 1 人で線を満たした
- 向かない場面:Ollama の並列 1 は、2 人が同時に使うと最初の文字まで 95% 点が 2.9〜3.0 秒になり、線を割った
数人〜十数人で共有する
- 候補:llama-server の -np 16(Q4_K_M)か、Ollama の並列 16
- 根拠:同時 16 人で、どちらも線を満たした。全体の出力は llama-server が 404〜413、Ollama が 175〜179 トークン/秒、1 人あたりは 26.4〜27.1 と 11.3〜11.6
- 設定の注意:llama-server は、-np を同時利用の人数に合わせるか
--kv-unifiedを付ける(-np 16 の同時 8 人で、全体の出力が 1.54〜1.69 倍。追加の測定)。既定の計算の単位(-ub 512)では、同時 4 人以下で、新しく処理する依頼文が 512 トークンを少し超えると数秒の遅れが出ることがあり、-b 2048 -ub 2048にした設定では、この長さの依頼の遅れは 30 件中 1 件だった(既定のままの 3 設定の合計は 93 件中 50 件。追加の測定) - 向かない場面:枠を超える同時 32 人では、最初の文字まで 95% 点が llama-server で 6.5〜6.8 秒、Ollama で 13.1〜13.6 秒になった。枠を 64 に増やすと順番待ちは短くなるが、1 人あたりの速さが毎秒 10 トークンの線を下回り、全体の出力も約半分になった。Ollama の 1 人あたりの速さは、毎秒 10 トークンの線に近い。llama-server の -np 16 は、同時 4 人の 2 巡目で最初の文字まで 95% 点が 3.2 秒になった(数秒の遅れの節を参照)
数十人以上で使う・API として配る
- 候補:vLLM(元の重み)
- 根拠:同時 128 人まで、2 巡とも線を満たした(別の GPU の追加の測定では 192 人まで満たした)。同時 128 人で全体の出力が 3,459〜3,462 トークン/秒、最初の文字まで 95% 点が 0.21〜0.24 秒
- 向かない場面:1 人あたりの速さは、1 人の時の 116 から同時 128 人の 27.9 トークン/秒まで下がる。1 人で使うなら llama-server の方が速かった。GPU メモリを 49.4GiB 確保した(
--gpu-memory-utilization 0.35)。同時 256 人では最初の文字まで 95% 点が 3.6〜3.8 秒になり、線を割った(追加の測定)
実測表:全体の出力と、編集部の線を満たした範囲
実測表:全体の出力(トークン/秒)。同時 16 人で編集部の線を満たした設定は 5 つ(Ollama 並列 16・llama-server の -np 16・-np 64・Q8_0・vLLM)、同時 64 人で満たしたのは vLLM だけだった
| 設定 | 同時 1人 | 同時 4人 | 同時 16人 | 同時 64人 |
|---|---|---|---|---|
| Ollama 並列 1 | 62〜 64○ | 63〜 65 | — | — |
| Ollama 並列 4 | 71〜 72○ | 130〜 137○ | 145 | — |
| Ollama 並列 16 | 68〜 72○ | 94〜 99○ | 175〜 179○ | 192〜 197 |
| Ollama 並列 64 | 71〜 75○ | 81〜 92○ | 84〜 95 | 153〜 187 |
| llama-server -np 4 | 98〜 117 | 208〜 211○ | 247〜 259 | — |
| llama-server -np 16 | 106〜 111○ | 96〜 161 | 404〜 413○ | 367〜 371 |
| llama-server -np 64 | 110〜 121○ | 123〜 128○ | 178〜 195○ | 439〜 445 |
| llama-server -np 16(Q8_0) | 109〜 117○ | — | 393〜 418○ | — |
| vLLM(元の重み) | 113○ | 423○ | 1,403〜 1,404○ | 2,964〜 2,976○ |
線を満たした範囲は、設定で大きく違いました。vLLM は測った同時 128 人までの全部で満たしました。llama-server の -np 16 と Ollama の並列 16 は同時 16 人まで、枠を 64 にした設定は、満たす最大の人数が llama-server で 16 人、Ollama で 8 人でした。人数が少なくても線を割る例外があります。llama-server の -np 16 は、同時 4 人の 2 巡目で最初の文字まで 95% 点が 3.2 秒になって線を割り、同時 8 人と 16 人では満たしました。そのため「最大で何人」は 1 つの数字で言い切らず、○ を付けた測定の表で見てください。
全部の値(設定 × 同時利用)を表示
実測表(全部の値):設定 × 同時利用の、全体の出力・1 人あたりの速さ・最初の文字までの時間
| 設定 | 同時 | 全体の出力 (tok/s) | 1 人あたり (tok/s) | 最初の文字まで 中央値(秒) | 最初の文字まで 95% 点(秒) | 対象の依頼 (件) | 線 |
|---|---|---|---|---|---|---|---|
| Ollama 並列 1 | 1 | 62〜64 | 84.4〜89.0 | 0.4〜0.5 | 0.7 | 28 | ○ |
| Ollama 並列 1 | 2 | 67〜69 | 85.2〜87.1 | 2.3〜2.4 | 2.9〜3.0 | 30〜31 | |
| Ollama 並列 1 | 4 | 63〜65 | 85.9〜86.9 | 6.3〜6.4 | 8.2〜11.0 | 28〜30 | |
| Ollama 並列 1 | 8 | 53〜64 | 84.3〜92.6 | 14.6〜14.9 | 18.3〜20.7 | 25〜28 | |
| Ollama 並列 4 | 1 | 71〜72 | 89.6〜89.7 | 0.3〜0.4 | 0.6 | 31〜32 | ○ |
| Ollama 並列 4 | 2 | 87〜90 | 58.8〜61.1 | 0.4 | 0.7 | 38〜41 | ○ |
| Ollama 並列 4 | 4 | 130〜137 | 39.5〜39.6 | 0.5 | 1.0〜1.1 | 58〜62 | ○ |
| Ollama 並列 4 | 8 | 143〜144 | 39.4〜40.4 | 4.0〜4.1 | 4.8〜5.0 | 63〜66 | |
| Ollama 並列 4 | 16 | 145 | 40.0〜42.5 | 11.2〜11.6 | 12.3〜12.4 | 64 | |
| Ollama 並列 16 | 1 | 68〜72 | 88.4〜88.7 | 0.4〜0.5 | 0.5〜0.7 | 30〜32 | ○ |
| Ollama 並列 16 | 2 | 66〜89 | 42.8〜46.3 | 0.3 | 0.6 | 30〜41 | ○ |
| Ollama 並列 16 | 4 | 94〜99 | 24.0〜27.7 | 0.4 | 0.6 | 42 | ○ |
| Ollama 並列 16 | 8 | 81〜99 | 10.6〜13.0 | 0.5〜0.6 | 0.9〜1.1 | 35〜44 | ○ |
| Ollama 並列 16 | 16 | 175〜179 | 11.3〜11.6 | 0.5〜0.6 | 1.2〜1.5 | 74〜78 | ○ |
| Ollama 並列 16 | 32 | 182〜190 | 12.4〜12.6 | 11.9〜12.1 | 13.1〜13.6 | 82〜83 | |
| Ollama 並列 16 | 64 | 192〜197 | 12.5〜13.7 | 31.8〜32.6 | 33.0〜34.3 | 89〜90 | |
| Ollama 並列 64 | 1 | 71〜75 | 87.5〜94.5 | 0.3〜0.4 | 0.5〜0.6 | 31〜34 | ○ |
| Ollama 並列 64 | 2 | 66〜78 | 41.3〜42.9 | 0.3〜0.4 | 0.7〜1.0 | 29〜35 | ○ |
| Ollama 並列 64 | 4 | 81〜92 | 23.1〜23.7 | 0.5〜0.6 | 1.0〜1.4 | 35〜41 | ○ |
| Ollama 並列 64 | 8 | 91〜102 | 12.1〜13.1 | 0.8〜0.9 | 1.3〜1.4 | 39〜43 | ○ |
| Ollama 並列 64 | 16 | 84〜95 | 5.3〜6.0 | 1.0〜1.1 | 1.6 | 35〜41 | |
| Ollama 並列 64 | 32 | 93〜105 | 2.4〜2.9 | 1.0 | 1.7〜1.8 | 32〜33 | |
| Ollama 並列 64 | 64 | 153〜187 | 2.3〜2.7 | 0.7〜0.9 | 1.4〜1.6 | 65〜75 | |
| llama-server -np 4 | 1 | 98〜117 | 151.6〜152.7 | 0.2 | 0.2〜2.7 | 41〜49 | |
| llama-server -np 4 | 2 | 113〜126 | 101.8〜107.9 | 0.2 | 2.5〜3.7 | 47〜52 | |
| llama-server -np 4 | 4 | 208〜211 | 69.0〜69.4 | 0.2 | 0.4 | 85〜86 | ○ |
| llama-server -np 4 | 8 | 234〜241 | 70.3 | 2.5 | 3.3〜6.4 | 97〜99 | |
| llama-server -np 4 | 16 | 247〜259 | 69.6〜71.3 | 6.9〜7.1 | 7.5〜7.7 | 103〜106 | |
| llama-server -np 16 | 1 | 106〜111 | 150.9〜153.2 | 0.2 | 0.2〜1.8 | 45 | ○ |
| llama-server -np 16 | 2 | 113〜116 | 67.3〜67.5 | 0.2 | 0.3〜0.4 | 46〜47 | ○ |
| llama-server -np 16 | 4 | 96〜161 | 34.6〜41.8 | 0.3 | 0.5〜3.2 | 40〜66 | |
| llama-server -np 16 | 8 | 162〜198 | 23.0〜26.6 | 0.3〜0.4 | 0.5〜0.6 | 68〜81 | ○ |
| llama-server -np 16 | 16 | 404〜413 | 26.4〜27.1 | 0.3 | 0.6 | 159〜169 | ○ |
| llama-server -np 16 | 32 | 400〜405 | 26.7〜27.2 | 6.0〜6.2 | 6.5〜6.8 | 162〜169 | |
| llama-server -np 16 | 64 | 367〜371 | 24.0〜24.3 | 18.9〜19.4 | 19.9〜20.1 | 150〜154 | |
| llama-server -np 64 | 1 | 110〜121 | 149.3〜149.4 | 0.2 | 0.2〜0.3 | 45〜51 | ○ |
| llama-server -np 64 | 2 | 99〜115 | 64.7〜68.0 | 0.3 | 0.5〜2.2 | 40〜47 | |
| llama-server -np 64 | 4 | 123〜128 | 34.8〜39.8 | 0.3〜0.6 | 1.0〜1.5 | 49〜53 | ○ |
| llama-server -np 64 | 8 | 143〜170 | 19.9〜22.9 | 0.5〜0.6 | 1.0〜1.4 | 59〜71 | ○ |
| llama-server -np 64 | 16 | 178〜195 | 11.1〜13.0 | 0.6〜0.7 | 1.0〜1.1 | 70〜77 | ○ |
| llama-server -np 64 | 32 | 201〜211 | 5.8〜6.8 | 0.9〜1.0 | 1.5〜1.7 | 71〜84 | |
| llama-server -np 64 | 64 | 439〜445 | 7.1〜7.2 | 0.8 | 1.4 | 180〜187 | |
| llama-server -np 16(Q8_0) | 1 | 109〜117 | 138.8〜139.7 | 0.2 | 0.2 | 44〜48 | ○ |
| llama-server -np 16(Q8_0) | 8 | 184〜193 | 23.4〜25.3 | 0.3〜0.4 | 0.5〜0.6 | 72〜75 | ○ |
| llama-server -np 16(Q8_0) | 16 | 393〜418 | 26.2〜27.9 | 0.3 | 0.5〜0.6 | 159〜174 | ○ |
| vLLM(元の重み) | 1 | 113 | 116.4 | 0.0 | 0.0 | 49 | ○ |
| vLLM(元の重み) | 2 | 219〜220 | 113.9〜114.0 | 0.0 | 0.1 | 96〜97 | ○ |
| vLLM(元の重み) | 4 | 423 | 109.9〜110.0 | 0.0 | 0.1 | 184〜186 | ○ |
| vLLM(元の重み) | 8 | 788〜789 | 102.4〜102.5 | 0.0 | 0.1 | 343〜346 | ○ |
| vLLM(元の重み) | 16 | 1,403〜1,404 | 91.2 | 0.1 | 0.1 | 609〜613 | ○ |
| vLLM(元の重み) | 32 | 2,216〜2,219 | 71.7〜71.8 | 0.1 | 0.1 | 964〜966 | ○ |
| vLLM(元の重み) | 64 | 2,964〜2,976 | 47.8〜48.0 | 0.1 | 0.1 | 1,289〜1,295 | ○ |
| vLLM(元の重み) | 128 | 3,459〜3,462 | 27.9 | 0.1 | 0.2 | 1,507〜1,524 | ○ |
1 人で使う時は、同じファイルでも llama-server が Ollama の 1.58〜1.73 倍速かった
1 人で使う時、同じファイルでも llama-server の速さは Ollama の1.58〜1.73倍だった(149〜153対84〜94トークン/秒)
- llama-server
- Ollama
- vLLM(元の重み)
Ollama と llama-server は、同じ GGUF(llama.cpp の重みの形式)のファイル(Ollama の qwen3:14b の blob、Q4_K_M)を読ませました。Ollama は中で llama.cpp のサーバー(llama-server)を起動することを、起動のログで確認しています。それでも 1 人あたりの速さは 1.58〜1.73 倍違い、原因は確認していません。Ollama が中で起動する llama-server は、単体の llama-server と版・起動の引数・チャットのテンプレートが違い(測定の条件を参照)、どれが効いているかは分かっていません。vLLM(116)は元の重みのため、この 2 つとは並べて順位を付けません。llama-server の Q8_0 は 138.8〜139.7 で、Q4_K_M の 0.91〜0.92 倍でした。
人数を増やすと、vLLM は同時 128 人まで全体の出力が伸びた
人数を増やすと、vLLM の全体の出力は同時 128 人の3,459〜3,462トークン/秒まで伸びたが、llama-server(枠 16)は同時 16 人の404〜413が最大で、Ollama(並列 16)は同時 64 人で192〜197だった
vLLM の全体の出力は、同時 1 人の 113 から同時 128 人の 3,459〜3,462 トークン/秒まで、測った範囲で人数とともに伸び続けました。llama-server(枠 16)は同時 16 人を超えると伸びなくなり、同時 32 人で 400〜405、64 人で 367〜371 でした。Ollama(並列 16)は同時 64 人でも 192〜197 です。
1 人あたりの速さは、vLLM が同時 1 人の116から同時 128 人の28トークン/秒に下がった。llama-server(枠 16)は同時 16 人で26〜27、Ollama(並列 16)は11〜12
1 人あたりの速さは、vLLM が同時 128 人でも 27.9 トークン/秒で、毎秒 10 トークンの線を上回りました。llama-server と Ollama は、枠の数を超えた人数で使っても 1 人あたりの速さは大きくは変わりません。1 人あたりの速さは最初の文字から最後の文字までで測るので、順番待ちの時間を含まないためです。同時 16・32・64 人の 1 人あたりは、llama-server(-np 16)が 26.4〜27.1・26.7〜27.2・24.0〜24.3、Ollama(並列 16)が 11.3〜11.6・12.4〜12.6・12.5〜13.7 トークン/秒です。枠を超えた時に伸びたのは、最初の文字までの時間だけでした。同時 32 人の最初の文字まで 95% 点は、llama-server が 6.5〜6.8 秒、Ollama が 13.1〜13.6 秒でした(次の節)。
vLLM は同時 128 人を超えると全体の出力が伸びなくなり、256 人で線を割った
vLLM は同時 128 人を超えると、全体の出力が3,349〜3,457トークン/秒に収まり、伸びなくなった。同時 192 人までは編集部の線を満たし、256 人は最初の文字まで 95% 点が3.6〜3.8秒で割った
本走の vLLM は同時 128 人までの測定でした。上限を探すため、別の GPU で同時 64・128・192・256 人を測り直しました(追加の測定。本走の値と同じ表には混ぜません)。192 人までは 2 巡とも編集部の線を満たし(最初の文字まで 95% 点 0.81〜0.82 秒、1 人あたり 19.3 トークン/秒)、256 人は最初の文字まで中央値が 3.1 秒で、線を割りました。
全体の出力が伸びなくなった原因は確認していません。起動のログの KV キャッシュは 122,160 トークン分で、依頼 1 件が約 780 トークン(依頼文 約 640 + 出力 約 138)なので、KV キャッシュに載る依頼は約 156 件です。全体の出力が伸びなくなった同時 128 人超に近い値です(推定)。--gpu-memory-utilization 0.35 の指定での結果で、指定を上げた時の上限は測っていません。
枠を超えた依頼は順番待ちになり、枠を 64 に増やすと順番待ちは短くなったが 1 人あたりの速さが線を下回った
枠を超えた依頼は順番待ちになった。Ollama の既定(並列 1)に 4 人が来ると最初の文字まで中央値6.3〜6.4秒、並列 16 に 64 人が来ると31.8〜32.6秒かかった
- 枠と同じ人数
- 枠の 2 倍の人数
- 枠の 4 倍の人数
Ollama は、並列数を超えた依頼を断らずに順番待ちにしました(失敗は 0)。順番待ちの時間は、同時利用が枠の 2 倍、4 倍になるにつれて伸びました。llama-server も同じ形で、-np 4 に 16 人が来ると最初の文字まで中央値が 6.9〜7.1 秒でした。
同時 32 人で枠を 16 から 64 に増やすと、順番待ちは短くなりました。最初の文字まで 95% 点は、llama-server が 6.5〜6.8 秒から 1.5〜1.7 秒、Ollama が 13.1〜13.6 秒から 1.7〜1.8 秒です。一方で 1 人あたりの速さは、llama-server が 26.7〜27.2 から 5.8〜6.8、Ollama が 12.4〜12.6 から 2.4〜2.9 トークン/秒に下がり、毎秒 10 トークンの線を下回りました。全体の出力も llama-server が 400〜405 から 201〜211、Ollama が 182〜190 から 93〜105 に下がり、編集部の線は満たしませんでした。
同時 16 人と 32 人では、枠を 64 に増やすと全体の出力が枠 16 の約半分に下がった
同時 16 人の全体の出力は、枠が 16 の時が最も高く、64 に増やすと llama-server は404〜413から178〜195、Ollama は175〜179から84〜95トークン/秒に下がった
同時 16 人で枠の数だけを変えると、枠が 16 の時が最も高くなりました。枠 64 は枠 16 の約半分で、同時 16 人と 32 人の 8 つの比(2 つのサーバー × 2 つの人数 × 2 巡)は、全部が 0.4〜0.6 に入ります(図の倍率は同時 16 人、同時 32 人は上の節の数字)。
ほかの人数では、同じ形になりません。同時 64 人では llama-server の -np 64 が -np 16 を上回り(439〜445 と 367〜371)、Ollama は並列 64 の方が低いままでした(153〜187 と 192〜197)。同時 8 人以下は、2 巡の幅が重なる設定と重ならない設定があるので、図に任せます。
llama-server の -np 16 を同時 8 人で使う時は、–kv-unified を付けるか -np を 8 にすると全体の出力が 1.54〜1.69 倍になった
本走で llama-server の -np 16 は、同時 8 人と 16 人で 1 人あたりの速さがほぼ同じ(8 人 23.0〜26.6、16 人 26.4〜27.1 トークン/秒)なのに、全体の出力は 16 人(404〜413)が 8 人(162〜198)の 2 倍以上でした。-np 4 の同時 8 人は 234〜241 で、-np 16 の同時 8 人より高い値です。-np 64 の同時 32 人と 64 人、Ollama の並列 16 の同時 8 人と 16 人でも、人数が枠に近づくと全体の出力が大きく上がります。そこで同じ llama-server を別の GPU で、設定を 1 つずつ変えて測りました(追加の測定)。
同時 8 人の全体の出力は、--kv-unified を付けると対照(173〜184)の1.62〜1.69倍の293〜298トークン/秒になった。同時 16 人では差が見えなかった(0.98〜1.01倍)
- -np 16(対照)
- --kv-unified
- -np 8
- -t 8
同時 8 人では、--kv-unified を付けると全体の出力が対照の 1.62〜1.69 倍、-np を 8 にすると 1.54〜1.58 倍になりました。全部の枠が埋まる同時 16 人では、--kv-unified を付けても対照の 0.98〜1.01 倍で、差は見えませんでした。同時 16 人で差が出ないことと、-np を 8 に下げると同時 8 人で同じ効果が出ることは、次のソースコードの 3 つの処理と整合します。スレッド数(-t 8)は全体の出力を増やしませんでした(同時 8 人で 0.93〜0.96 倍、16 人で 1.01〜1.04 倍)。llama.cpp の commit 3b4d6ab3f(測ったイメージの版)で確認した処理を説明する前に、2 つの語を補います。llama-server の枠には 0 から順に番号が付いています(コードでは枠を sequence と呼びます)。1 回の計算(コードでは ubatch)は、複数の枠の依頼をまとめて処理します。
tools/server/server.cpp126〜130 行:-npを指定しない(自動)時だけ、4 枠でkv_unified = true(KV キャッシュを全部の枠で 1 つにする)にする。-npを指定すると枠ごとに分かれ、起動のログもkv_unified = 'false'だった。src/llama-kv-cache.cpp762 行とsrc/llama-batch.cpp686〜689 行:枠ごとに分かれている時、1 回の計算にまとめる枠は番号が連続したものだけ(コメントはaccept only increasing sequence ids)。tools/server/server-context.cpp1819〜1861 行・1870〜1877 行・2655〜2668 行:空き枠は、依頼文の先頭が似ている枠を先に選ぶ(slot_prompt_similarity、既定 0.1)。無ければ最も長く使われていない枠を選ぶ。番号が連続するようには選ばれない。
枠が飛び飛びに埋まると、1 回の計算にまとめられる依頼が減る(推定)。1 回の計算の時間の内訳は測っていないので、確認できたのは「ソースコードの処理と測定結果が整合する」ところまでです。確認したのは効果(--kv-unified で 1.62〜1.69 倍、-np 8 で 1.54〜1.58 倍)で、原因は推定です。設定を決める時の要点と、確認していない範囲を次に並べます。
- llama-server を枠より少ない人数で使う時は、
-npを同時利用の人数に合わせるか、--kv-unifiedを付ける(効果を確認したのは-np 16・同時 8 人)。 --kv-unifiedを付けると、起動のログで枠ごとの上限(n_ctx_slot)が 4,096 から 40,960 トークンに変わり、65,536 トークン分を全部の枠で分け合う形になった。長い依頼が混ざった時の動きは測っていない。- Ollama は中の llama-server を
-np <並列数>で起動し、kv_unified = falseだった。Ollama からkv_unifiedを変更できるかは確認していない。 - 効果を確認したのは
-np 16・同時 8 人だけ。-np 64の同時 16 人と Ollama の並列 64 が下がった原因にも、同じ処理が当てはまると考えられる(推定)が、設定を変えて確認していない。
--kv-unified の同時 1〜16 人の値を表示
--kv-unified を付けた -np 16 は、同時 1 人で 1 人あたり142.6〜143.7、同時 8 人で39.6〜40.1トークン/秒だった
| 同時 | 全体の出力 (tok/s) | 1 人あたり (tok/s) | 最初の文字まで 95% 点(秒) |
|---|---|---|---|
| 1 人 | 88〜112 | 142.6〜143.7 | 0.2〜2.5 |
| 2 人 | 174〜183 | 112.7〜115.8 | 0.2〜0.3 |
| 4 人 | 178〜209 | 69.0〜71.9 | 0.4〜1.6 |
| 8 人 | 293〜298 | 39.6〜40.1 | 0.5 |
| 16 人 | 370〜377 | 24.4〜24.9 | 0.6〜0.7 |
llama-server は、同時 4 人以下で新しく処理する依頼文が 512 トークンを少し超えると最初の文字まで数秒かかることがあり、-ub 2048 にした設定では遅い依頼が 30 件中 1 件だった
実測表で、人数が少ないのに ○ が抜ける測定があります。本走の llama-server で、同時 4 人以下の最初の文字まで 95% 点が、どちらかの回で 2 秒を超えたマスは 4 つあります(1 巡目/2 巡目の順)。
- -np 4 の同時 1 人:2.69/0.22 秒
- -np 4 の同時 2 人:3.68/2.53 秒
- -np 16 の同時 4 人:0.50/3.22 秒
- -np 64 の同時 2 人:0.46/2.20 秒
遅い依頼の多くは、依頼文が 580〜599 トークンの時でした。この時、先頭の共通部分(約 67 トークン)は前の依頼の計算が残っていて、新しく処理するのは 513〜530 トークンです。これが計算の単位 512 をわずかに超えます。以後は「580〜599 トークンの依頼」と書きます。-np 4 の同時 1 人の 1 巡目では遅い依頼 4 件が全部、-np 16 の同時 4 人の 2 巡目では 4 件中 3 件が 580〜599 トークンの依頼でした(もう 1 件は 690 トークン)。
本走:llama-server の同時 1・2 人では、580〜599 トークンの依頼 50 件のうち 31 件が、最初の文字まで 1 秒を超えた
| 設定・同時利用 | 依頼文 580〜599 トークン 遅い/件数 | それ以外 遅い/件数 |
|---|---|---|
| llama-server(全設定)同時 1・2 人 | 31/50 | 5/667 |
| Ollama(全設定)同時 1 人 | 3/20 | 0/267 |
| vLLM 同時 1 人 | 0/9 | 0/105 |
本走の記録では、llama-server の同時 1・2 人で、580〜599 トークンの依頼 50 件のうち 31 件が最初の文字まで 1 秒を超え(2.1〜11.6 秒)、それ以外の長さは 667 件中 5 件でした。Ollama は同時 1 人で 287 件中 3 件で、3 件とも 580〜599 トークンの依頼です(580〜599 トークンの依頼は 20 件中 3 件、それ以外は 267 件中 0 件)。vLLM は同時 1 人で 114 件中 0 件です。
Ollama の遅い依頼 3 件は、全部が -ub 512 で起動した並列 1 で起きました。Ollama が中で起動する llama-server の -b・-ub は並列数で変わり(並列 1 は 512、並列 4 は 1024、並列 16 と 64 は 2048)、-ub が 1024・2048 の 3 設定は、同時 1 人で、580〜599 トークンの依頼 15 件中 0 件です(全部の長さでは 222 件中 0 件)。件数は少ないですが、llama-server の結果と整合します。
条件を絞るため、別の GPU で llama-server の設定を 1 つずつ変えて、同じ数え方で数えました(追加の測定)。
追加の測定(別の GPU):同時 4 人以下で、580〜599 トークンの依頼は、既定の計算の単位(-ub 512)の 3 設定では 50/93 が最初の文字まで 1 秒を超え、-ub 2048 の設定では 1/30 だった
| 設定・同時利用 | 依頼文 580〜599 トークン 遅い/件数 | それ以外 遅い/件数 |
|---|---|---|
| -np 16(対照) 同時 8 人 | 7/16 | 9/149 |
| -np 16(対照) 同時 16 人 | 0/33 | 6/306 |
| --kv-unified 同時 1 人 | 7/8 | 0/84 |
| --kv-unified 同時 2 人 | 6/18 | 1/147 |
| --kv-unified 同時 4 人 | 10/26 | 1/150 |
| --kv-unified 同時 8 人 | 0/27 | 0/264 |
| --kv-unified 同時 16 人 | 0/35 | 4/332 |
| -np 8 同時 4 人 | 11/16 | 1/94 |
| -np 8 同時 8 人 | 3/21 | 6/239 |
| -t 8 同時 8 人 | 6/14 | 5/137 |
| -t 8 同時 16 人 | 0/35 | 8/313 |
| --cache-ram 0 同時 1 人 | 7/8 | 0/91 |
| --cache-ram 0 同時 4 人 | 9/17 | 0/103 |
| --cache-ram 0 同時 16 人 | 1/40 | 14/360 |
| -ub 2048 同時 1 人 | 0/10 | 0/112 |
| -ub 2048 同時 4 人 | 1/20 | 2/118 |
| -ub 2048 同時 16 人 | 4/35 | 14/302 |
遅い依頼が出るのは、同時利用が少ない時です。追加の測定の同時 16 人では、既定の -ub 512 でも該当の帯はほぼ遅くならず(対照 0/33、--kv-unified 0/35、-t 8 0/35、--cache-ram 0 1/40)、同時 8 人は設定で割れました(対照 7/16、-np 8 3/21、-t 8 6/14、--kv-unified 0/27)。この違いの原因は確認していません。
サーバーのログでは、遅いのは依頼文の処理(prompt eval time)の時間でした。枠を選んでから処理を始めるまでは、設定ごとの中央値が 0.04〜0.05 秒(--cache-ram 0 の設定は 0.001 秒未満)、最大 0.24 秒です。次の条件に当てはまる回について、依頼文の処理が 1 秒を超えた数を数えました。
- 処理を始めた時に、処理中の枠が自分を含めて 2 つ以下
- 新しく処理するトークンが 513〜530
結果は、--kv-unified の設定で 13/26、--cache-ram 0 で 7/8、-ub 2048 で 0/10 でした。llama-server の計算の単位(-ub)の既定は 512 で(出典は llama.cpp の同じ commit の common/common.h 473 行と tools/server/README.md 53 行)、新しく処理する部分が 512 を少し超えた依頼文は、512 トークンと数トークンの 2 回に分けて処理される(推定)。512 を超えた数トークンだけの処理が、なぜ 2 秒以上かかるかは確認していません。
-b 2048 -ub 2048 で動かすと、同時 4 人以下で、580〜599 トークンの依頼のうち 1 秒を超えたのは 30 件中 1 件で、0 にはなっていません(--kv-unified・--cache-ram 0・-np 8 の 3 設定は 93 件中 50 件)。追加の測定では、既定のままの対照を同時 4 人以下で測っていないので、比べる相手はこの 3 設定の合計です。同時 1 人の最初の文字まで 95% 点は 0.22〜0.23 秒、GPU メモリは 19.5GiB(対照は 19.1GiB)でした。ただし同時 16 人では、遅い依頼が対照より多く(該当の帯で 4/35 と、対照の 0/33)、全体の出力は対照の 0.94〜1.04 倍で、差は見えませんでした。
依頼文のキャッシュをメモリに退避する機能(--cache-ram)を切っても、遅い依頼は残りました(同時 1 人の最初の文字まで 95% 点が 2 巡で 0.19〜2.99 秒)。切っても残ったので、退避が主な原因とは言えません。
なお同時 16 人の全体の出力は、--cache-ram 0 が 452〜454 トークン/秒で、対照の 368〜384 の 1.18〜1.24 倍、1 人あたりは 29.4〜29.9 対 24.6〜25.3 でした。この測定は依頼ごとに先頭の行を変えていて、退避したキャッシュが使われない条件です。退避の処理の時間が全体の出力を下げていた可能性があります(推定)。会話の続きのようにキャッシュが効く使い方では逆になりうるので、この結果は依頼文が毎回違う使い方に限ります。
GPU メモリは、枠を増やすほど増えた
GPU メモリは枠を増やすほど増え、枠 64 では Ollama が49.5GiB、llama-server が49.1GiB と、枠 16 の約2.5倍になった
- llama-server
- Ollama
- vLLM(元の重み)
GPU メモリが増えたのは、Ollama も llama-server も 1 依頼あたりのコンテキスト長を 4,096 に固定していて、枠の数に応じて KV キャッシュ(処理済みの文脈を GPU に保存する領域)が増えるためと考えられます(推定)。枠 16 から 64 に増やすと、llama-server は 19.1 から 49.1GiB、Ollama は 19.5 から 49.5GiB で、どちらも 2.5〜2.6 倍です。枠の数に比例して 4 倍にはなっておらず、増え方の内訳は確認していません。
量子化は、Q4_K_M でも日本語の正答に差があるとは言えなかった
量子化の 4 段階と元の重みで、日本語の正答は JCommonsenseQA が94.0〜94.5%、MGSM が82.8〜85.2%、文章校正で直せた文が54.0〜60.5%の範囲に収まった
| 対象 | JCommons enseQA (%) | MGSM (%) | 校正 直せた (%) | 校正 書き換え (%) |
|---|---|---|---|---|
| Q4_K_M | 94.5 | 84.4〜85.2 | 54.0〜54.5 | 8.0 |
| Q5_K_M | 94.0〜94.1 | 83.2〜83.6 | 57.5〜58.0 | 4.0 |
| Q6_K | 94.4〜94.5 | 83.6〜84.8 | 60.5 | 5.0 |
| Q8_0 (基準) | 94.4 | 82.8〜83.6 | 59.0 | 6.0 |
| 元の重み (vLLM) | 94.3〜94.4 | 83.2〜84.0 | 60.0〜60.5 | 6.0 |
Q8_0 を基準に、問いごとの対の検定をしました。補正前の p(小さいほど、差が測定の揺れでは説明しにくい)が 0.05 を下回ったのは、校正で直せた文の Q4_K_M だけです(0.041〜0.049)。補正後(4 つの比較をしたことの補正)は 0.17〜0.20 で、差があるとは言えません。なお校正で直せた文の Q4_K_M は、Q8_0 より 4.5〜5.0 ポイント低い値でした。
Q8_0 と比べて、補正後の p が 0.05 を下回った組み合わせは無かった(最小は校正の Q4_K_M で0.17〜0.20)
| 課題・比べた対象 | Q8_0 だけ正解 対 比較側だけ正解 (1 回目) | Q8_0 だけ正解 対 比較側だけ正解 (2 回目) | 補正後 p (2 回) |
|---|---|---|---|
| JCommonsenseQA Q4_K_M | 8 対 10 | 7 対 8 | 1.00 |
| JCommonsenseQA Q5_K_M | 9 対 5 | 9 対 6 | 1.00 |
| JCommonsenseQA Q6_K | 3 対 5 | 3 対 3 | 1.00 |
| JCommonsenseQA 元の重み(vLLM) | 6 対 5 | 5 対 5 | 1.00 |
| MGSM Q4_K_M | 3 対 7 | 4 対 8 | 1.00 |
| MGSM Q5_K_M | 6 対 8 | 6 対 5 | 1.00 |
| MGSM Q6_K | 4 対 6 | 2 対 5 | 1.00 |
| MGSM 元の重み(vLLM) | 2 対 3 | 3 対 4 | 1.00 |
| 校正:直せた Q4_K_M | 13 対 4 | 15 対 5 | 0.17〜0.20 |
| 校正:直せた Q5_K_M | 7 対 5 | 6 対 3 | 1.00 |
| 校正:直せた Q6_K | 3 対 6 | 2 対 5 | 1.00 |
| 校正:直せた 元の重み(vLLM) | 4 対 6 | 2 対 5 | 1.00 |
| 校正:書き換え Q4_K_M | 2 対 4 | 3 対 5 | 1.00 |
| 校正:書き換え Q5_K_M | 2 対 0 | 2 対 0 | 1.00 |
| 校正:書き換え Q6_K | 1 対 0 | 1 対 0 | 1.00 |
| 校正:書き換え 元の重み(vLLM) | 1 対 1 | 1 対 1 | 1.00 |
温度 0 でも、1 回目と 2 回目で答えが一致した割合は95.6〜99.9%で、100% にならなかった
| 対象 | JCommons enseQA (%) | MGSM (%) | 校正 (%) |
|---|---|---|---|
| Q4_K_M | 99.8 | 97.6 | 98.0 |
| Q5_K_M | 99.9 | 95.6 | 99.3 |
| Q6_K | 99.8 | 96.0 | 99.7 |
| Q8_0 (基準) | 99.7 | 95.6 | 97.0 |
| 元の重み (vLLM) | 99.9 | 97.2 | 99.0 |
温度 0 でも、同じ問いの答えは 2 回で完全には一致しませんでした。1 回だけの測定では揺れが分からないため、この実測表は 2 回の範囲で読んでいます。
測っていない対象と理由
- SGLang・TGI・LM Studio:今回は Ollama・llama-server・vLLM の 3 つに絞った。TGI はリポジトリが 2026年3月21日からアーカイブ(読み取り専用)で、README にはメンテナンスモードと書かれている。最新のリリースは v3.3.7(2025年12月19日)。
- 複数の GPU:H200 1 基だけを測った。
- 長い文脈:1 依頼あたり 4,096 トークンに固定した。長い文書では、枠あたりのメモリが変わる。
- ほかのモデル:Qwen3 14B だけを測った。
- AWQ・GPTQ などの量子化:vLLM の元の重みと、llama-server の GGUF だけを測った。
- 会話の続きのように、依頼文のキャッシュが効く使い方:依頼ごとに先頭の行を変え、文書の部分にはキャッシュが効かない条件にした(先頭の共通部分 約 67 トークンには効く)。
- 開ループの負荷:利用者が返事を受け取ってから次を送る方式(閉ループ)だけを測った。人数とは別に、決まった頻度で依頼が届く方式(開ループ)は測っていない。
ほかの実測表は実測表の一覧、モデルごとの日本語の性能はローカル LLM の実測表、文章校正の問いは文章校正の実測表にあります。
測定の条件
下の欄を開くと、版・起動の引数・依頼文・測り方・差の判定・2 巡で大きく違った測定が表示されます。
測定の条件の詳細を表示
環境:Qwen3 14B(Apache-2.0)を、共用の計算ノードの NVIDIA H200 1 基で動かしました。ほかの利用者のプロセスが GPU に載っていたため、測定ごとにほかのプロセスの使用率を見て、5% 以上の標本が 2 つ以上あった測定は捨てて測り直しました(捨てたのは 2 件。llama-server の -np 64、同時 1 人と 4 人の 1 巡目)。サーバーのコンテナの CPU は 8、負荷の道具は別の 8 です。llama-server のスレッド数は、起動のログで 96 と表示されました。本走は GPU 3、追加の測定は GPU 1 で、どちらも同じ型の H200 です。
サーバーと重み:Ollama 0.40.16(OLLAMA_NUM_PARALLEL 1・4・16・64、OLLAMA_CONTEXT_LENGTH=4096)、llama-server(イメージ ghcr.io/ggml-org/llama.cpp:server-cuda13、0.9.0-dev・build 12242。-np 4・16・64、-c は 4,096 × 枠の数)、vLLM 0.33.0(--max-num-seqs 256・--max-model-len 4096・--gpu-memory-utilization 0.35)。Ollama と llama-server は、Ollama の qwen3:14b と同じ GGUF(Q4_K_M)のファイルです。llama-server の Q8_0 は、公式の Qwen/Qwen3-14B-GGUF の Q8_0(-np 16)。vLLM は元の重み Qwen/Qwen3-14B です。考える過程は 3 つとも止め(Ollama は reasoning_effort: "none"、vLLM は enable_thinking: false、llama-server は --reasoning-budget 0)、混入は 0 件でした。
測ったサーバー 3 つ(9 設定)の版・イメージの digest・起動の引数
| 設定 | 設定ごとに違う引数・環境変数 |
|---|---|
| Ollama 並列 1 | OLLAMA_NUM_PARALLEL=1 中の llama-server:-c 4096 -np 1 -b 512 -ub 512 |
| Ollama 並列 4 | OLLAMA_NUM_PARALLEL=4 中の llama-server:-c 16384 -np 4 -b 1024 -ub 1024 |
| Ollama 並列 16 | OLLAMA_NUM_PARALLEL=16 中の llama-server:-c 65536 -np 16 -b 2048 -ub 2048 |
| Ollama 並列 64 | OLLAMA_NUM_PARALLEL=64 中の llama-server:-c 262144 -np 64 -b 2048 -ub 2048 |
| llama-server -np 4 | -np 4 -c 16384 |
| llama-server -np 16 | -np 16 -c 65536 |
| llama-server -np 64 | -np 64 -c 262144 |
| llama-server -np 16(Q8_0) | -np 16 -c 65536 |
| vLLM(元の重み) | --gpu-memory-utilization 0.35 --max-model-len 4096 --max-num-seqs 256 |
| サーバー | イメージ・版・digest |
|---|---|
| Ollama | ollama/ollama:0.40.16 sha256:910d0d8107b538fb0894e63163eb195de0cc7aefcbc666dc62d3b18f71124592 |
| llama-server | ghcr.io/ggml-org/llama.cpp:server-cuda13 0.9.0-dev(build 12242、commit 3b4d6ab3f) sha256:4f27e30d776de6f162eaa9befed2c17fe05d51caffb74bbf276a897d3897bba7 |
| vLLM | vllm/vllm-openai:v0.33.0 sha256:d825baf9ce4b1b6bfc5ecc7b79880c7e6748c65a72d697ce3d47607aafa84c6e |
Ollama が中で起動する llama-server は、単体の llama-server と引数が違います。起動のログ(msg="starting llama-server" の行)では、--no-jinja --chat-template chatml、--flash-attn auto、-b・-ub は並列数で 512・1024・2048・2048(並列 1・4・16・64)で、並列 16 の時は -c 65536 -np 16 -b 2048 -ub 2048 でした。版も違い、起動のログの表示は build 1 (6c01da627) で、単体の llama-server は build 12242・コミット 3b4d6ab3f です。どちらも kv_unified = false(KV キャッシュを枠ごとに分ける設定)でした。
負荷:自作の負荷の道具(asyncio と httpx)で、OpenAI 互換の /v1/chat/completions にストリーミングで依頼しました(max_tokens は 256、温度は 0)。利用者は返事を受け取ったらすぐ次を送ります。依頼は、AIコンパスの公開済みの記事の段落から作った 400 本の文書(800 字前後。依頼文(プロンプト)は中央値 623〜673 トークン、測定ごとの出力の平均は 129〜150 トークン)の要約で、システムプロンプトには、業務文書を正確に要約する役割を指示する 1 文を入れ、指示は「次の文書を、要点を3つにまとめて200字程度で要約してください。」です。指示の後・文書の前に、依頼ごとに違う番号の行を入れ、先頭が同じ依頼にならないようにしました(システムプロンプトと指示文は全依頼で同じなので、この部分にはキャッシュが効きます)。
測り方:全部の利用者が 1 本目の依頼を終え、かつ 15 秒たつまで測定開始前の助走(暖機)をし、その後の 60 秒に送った依頼を集計の対象にしました(対象が 20 件未満なら参考値とします。最少は 25 件)。60 秒が過ぎても負荷は止めず、対象の依頼が全部終わるまで続けます。失敗は、HTTP のエラー・120 秒のタイムアウト・出力 0 トークンで、全測定で 0 件でした。全体の出力は、集計の 60 秒間に届いたトークンの数 ÷ 60(断片ごとの到着時刻に、応答に含まれる出力トークン数を割り振った値)です。同時 32 以上では負荷の道具を 4 プロセスに分け、CPU の使用が 0.7 を超えた測定に印を付ける設計でしたが、印が付いた測定は 0 件でした。全設定を順に 1 巡し、もう 1 巡しました(53 測定 × 2 巡)。
量子化と日本語の正答:公式の GGUF(Q4_K_M・Q5_K_M・Q6_K・Q8_0)を llama-server で、元の重みを vLLM で動かし、JCommonsenseQA の検証用 1,119 問、MGSM の日本語 250 問、文章校正の自作 300 文(誤りを入れた 200 文と、誤りの無い 100 文。依頼文は「指示のみ」)を各 2 回測りました。依頼文と採点は、ローカル LLM の実測表と文章校正の実測表の台本を使っています。Q8_0 と各対象を、同じ問いで 2 つの設定の正誤を比べる検定(問いごとの対の正確な符号検定)と、比較を 4 回行うための p の補正(Holm 法。課題ごとに 4 比較)で比べました。
2 巡で大きく違った測定:3 つの指標のどれかが 2 割以上違った測定は 53 件のうち 18 件でした。大きい順に 10 件を示します。
2 巡で 3 つの指標のどれかが 2 割以上違った測定は、53 件のうち18件。差の大きい 10 件
| 設定 | 同時 | 全体の出力 (tok/s) 1 巡目→2 巡目 | 1 人あたり (tok/s) 1 巡目→2 巡目 | 95% 点(秒) 1 巡目→2 巡目 |
|---|---|---|---|---|
| llama-server -np 16 | 4 | 161→96 | 41.8→34.6 | 0.5→3.2 |
| llama-server -np 64 | 2 | 99→115 | 64.7→68.0 | 0.5→2.2 |
| llama-server -np 4 | 1 | 98→117 | 152.7→151.6 | 2.7→0.2 |
| llama-server -np 16 | 1 | 111→106 | 153.2→150.9 | 1.8→0.2 |
| llama-server -np 4 | 8 | 234→241 | 70.3→70.3 | 6.4→3.3 |
| llama-server -np 64 | 4 | 123→128 | 34.8→39.8 | 1.0→1.5 |
| Ollama 並列 64 | 4 | 92→81 | 23.7→23.1 | 1.0→1.4 |
| Ollama 並列 16 | 2 | 66→89 | 42.8→46.3 | 0.6→0.6 |
| llama-server -np 64 | 8 | 143→170 | 19.9→22.9 | 1.4→1.0 |
| Ollama 並列 64 | 2 | 66→78 | 42.9→41.3 | 1.0→0.7 |
追加の測定:本走の後に、別の GPU(同じ型の H200)で 7 設定・21 測定を 2 巡(42 測定)しました。GPU と日が違うと、同じ設定でも値が変わります(対照の同時 16 人の全体の出力は本走の 0.89〜0.95 倍、同時 8 人は 0.87 倍と 1.14 倍、vLLM の同時 128 人は 0.98〜0.99 倍)。この幅があるため、追加の測定の値は追加の測定の中だけで比べ、設定の効果や順位を本走の値と比べて読みません。失敗は 0 件、ほかのプロセスの混入は 0 件、負荷の道具の CPU の比は最大 0.17 です。同じ llama-server のイメージとファイルを使い、引数は下の表のとおりです。対象の依頼は 36〜1,496 件。2 巡で 2 割以上違った測定は 21 組中 6 組でした(対照の同時 8 人など、人数が少ない所)。vLLM は起動のログで KV キャッシュが 122,160 トークン分でした。遅い依頼の件数は、送信が開始 5 秒より後の依頼(対象外の助走の依頼を含む)のうち、最初の文字まで 1 秒を超えた数で、依頼文の長さは応答に含まれる入力トークン数です。
追加の測定(別の GPU)の起動の引数。-np 16 --kv-unified は、枠ごとの上限が 4,096 から 40,960 トークンに変わった
| 設定 | 起動の引数(-m と共通の引数は省略) | 枠あたりの上限 (n_ctx_slot) |
|---|---|---|
| llama-server -np 16(対照) | -np 16 -c 65536 | 4,096 |
| llama-server -np 16 --kv-unified | -np 16 -c 65536 --kv-unified | 40,960 |
| llama-server -np 8 | -np 8 -c 32768 | 4,096 |
| llama-server -np 16 -t 8 | -np 16 -c 65536 -t 8 | 4,096 |
| llama-server -np 16 --cache-ram 0 | -np 16 -c 65536 --cache-ram 0 | 4,096 |
| llama-server -np 16 -b 2048 -ub 2048 | -np 16 -c 65536 -b 2048 -ub 2048 | 4,096 |
| vLLM(元の重み) | serve --max-num-seqs 256 --max-model-len 4096 --gpu-memory-utilization 0.35 | KV キャッシュ 122,160 トークン |
公開データ:全部の値は /assets/data/llm-serving-benchmark/concurrency.json(設定 × 同時利用)、extra_concurrency.json(追加の測定と、その遅い依頼の件数。本走の遅い依頼の件数は concurrency.json)、quantization.json(量子化)にあります。
この実測表で分からないこと
- GPU と環境:共用ノードの H200 1 基だけの結果。ほかの GPU、複数の GPU、ほかの利用者の負荷が違う時の値は、この表から言えません。
- モデルと重み:Qwen3 14B 1 種。vLLM だけ元の重みで、サーバーの差と重みの差を分けられません。
- 追加の測定:別の GPU で別の日に測ったため、本走の値とは直接比べていません。追加の測定の中の設定どうしを比べました。
- 使い方:約 640 トークンの文書の要約を、文書の部分にはキャッシュが効かない条件で、返事を受け取ったらすぐ次を送る利用者が続ける使い方。会話の続き、長い文脈、決まった頻度で依頼が届く使い方では結果が変わりうる。
- 少ない人数の値:2 巡で 2 割以上違った測定が 18 件あり、対象の依頼が 25〜99 件の測定でした。順位を言い切らず、範囲で読んでください。
- vLLM の上限:追加の測定で同時 256 人まで測り、128 人を超えると全体の出力が伸びなくなった。
--gpu-memory-utilizationを上げた時の上限は測っていません。 - 枠を 64 にして下がった原因:
-np 16・同時 8 人は--kv-unifiedで効果を確認しました。-np 64の同時 16 人と Ollama の並列 64 は、同じ処理が当てはまると考えられます(推定)が、設定を変えて確認していません。 --kv-unifiedと長い依頼:枠ごとの上限が 40,960 トークンに変わります。長い依頼が混ざった時の動きは測っていません。- 新しく処理する部分が 512 トークンを少し超えた依頼文が遅い原因:512 を超えた数トークンだけの処理に、なぜ 2 秒以上かかるかは確認していません。
- 1 人で使った時に Ollama が遅い原因:同じファイルで 1.58〜1.73 倍違いましたが、版・起動の引数・テンプレートが違い、どれが効いているかは確認していません。
- 量子化の差:校正(直せた)は問いが 200 文で、Q4_K_M の差が無いとは確認できていません。速さは Q8_0 を同時 1・8・16 人で測っただけです。
よくある質問
社内で LLM を使う人数が増えた時、1 台の GPU で何人まで同時に使えますか。
1 つの数字では言い切れず、設定で変わります。編集部の線(最初の文字まで 95% 点が 2 秒以内、かつ 1 人あたりの速さの中央値が毎秒 10 トークン以上)を 2 巡とも満たしたのは、vLLM が同時 128 人まで、llama-server(-np 16)と Ollama(並列 16)が同時 16 人までです。枠の数を超える同時 32 人では、最初の文字まで 95% 点が 6.5〜6.8 秒(llama-server)、13.1〜13.6 秒(Ollama)に伸びました。Qwen3 14B・H200 1 基の結果で、vLLM は元の重み、Ollama と llama.cpp は Q4_K_M です。
Ollama の並列数(OLLAMA_NUM_PARALLEL)や llama-server の -np は、大きく取っておけば安全ですか。
安全とは言えません。同時 16 人と 32 人では、枠を 64 に増やすと全体の出力が枠 16 の約半分に下がりました(同時 16 人で llama-server は 404〜413 から 178〜195、Ollama は 175〜179 から 84〜95 トークン/秒)。枠を超えた人数で使っても 1 人あたりの速さはほぼ変わらず、最初の文字までの時間が伸びます。llama-server の -np 16 は、同時 8 人で –kv-unified(KV キャッシュを全部の枠で共有する指定)を付けるか -np を 8 にすると、全体の出力が 1.54〜1.69 倍になりました。効果は確認しましたが、原因はソースコードからの推定です。
vLLM は、Ollama や llama.cpp より常に速いですか。
常にとは言えません。人数が増えた時の全体の出力は、測った範囲では vLLM が最も高く、同時 128 人で 3,459〜3,462 トークン/秒でした。128 人を超えて伸びなくなったことは、別の GPU の追加の測定の中で確認しています(128 人 3,407〜3,413、192 人 3,349〜3,376、256 人 3,450〜3,457)。256 人は最初の文字までが中央値 3.14 秒で、編集部の線を割りました。ただし 1 人で使った時の 1 人あたりの速さは、llama-server が 149〜153、vLLM が 116、Ollama が 84〜94 トークン/秒の順です。vLLM だけ重みが違い(元の重み。ほかは 4 ビット量子化の Q4_K_M)、この差にも重みの違いが含まれます。
量子化(Q4_K_M など)をすると、日本語の正答は落ちますか。
測った範囲では、Q8_0 と比べて差があるとは言えませんでした。Q4_K_M・Q5_K_M・Q6_K・Q8_0 と元の重みの 5 対象で、JCommonsenseQA の正答率は 94.0〜94.5%、MGSM(日本語)は 82.8〜85.2%、文章校正で直せた文は 54.0〜60.5% です。校正で直せた文だけ、Q4_K_M が Q8_0 より 4.5〜5.0 ポイント低く、補正前の p は 0.041〜0.049 でしたが、補正後は 0.17〜0.20 で、差があるとは言えません。なお問いが 200 文と少なく、差が無いと確認できたわけではありません。温度 0 でも、同じ問いの答えが 2 回で一致した割合は 95.6〜99.9% でした。
自社の環境でも同じ結果になりますか。
同じになるとは言えません。測ったのは Qwen3 14B 1 種を、共用ノードの H200 1 基で動かした結果で、複数の GPU、長い文脈、ほかのモデル、AWQ・GPTQ の量子化、SGLang・TGI・LM Studio は測っていません。依頼ごとに先頭の行を変えて、文書の部分にはキャッシュが効かない条件(先頭の共通部分 約 67 トークンには効く)にしたため、会話の続きのようにキャッシュが効く使い方では結果が変わりえます。2 巡で 2 割以上違った測定が 18 件あり(対象の依頼が 25〜99 件の測定)、少ない人数の値は揺れます。自社の GPU と依頼で、人数を変えて測ることを勧めます。