2026/10/22 INFINITIX Product Dep.
はじめに:「このサーバーで同時に何人さばけるか」にどう答えるか
GPUサーバーにオープンソースのLLM(大規模言語モデル)を入れて、curlでプロンプトを送ると、1秒ほどで答えが返り始めます。速く見えますが、それだけでは次の問いに答えられません。同時に何人まで使えるのか(10人か、200人か)。最初の文字が何秒以内に出れば合格か。文字がどのくらいの速さで出れば快適か。
こうした問いに答えるのがLLMベンチマーク(性能テスト)です。本記事ではツールの入れ方ではなく、テストの考え方を説明します。何を測るか、なぜ1つの数字では足りないか、負荷をどうかけるか、結果がずれる原因は何か、の4点です。例として、NVIDIAのオープンソースツール「AIPerf」も紹介します。
1. LLMベンチマークとは
「LLMベンチマーク」には2つの意味があります。1つは能力ベンチマーク(MMLUやHumanEvalなど)で、モデルの答えが正しいかを測ります。もう1つは推論性能ベンチマークで、特定のハードウェアと推論エンジンで動かしたときの速さと、同時に使える人数を測ります。本記事で扱うのは後者です。
ただし、一般的なWebサービスの負荷テストと同じ方法では測れません。LLM推論には次のような違いがあるためです。
- 答えは1トークンずつ届く。最初のトークンが届くまでの時間(Time to First Token、TTFT)、トークンとトークンの間隔(Inter-Token Latency、ITL)、回答全体が終わるまでの時間(End-to-End Request Latency、E2E Latency)は、それぞれ別の時間です。
- リクエストごとに仕事量が違う。出力が長いほど、GPUを長く使います。出力の長さがそろっていないと、2つのテスト結果をそのまま比べられません。
- 処理はprefillとdecodeの2段階。prefillは入力全体を読み込み、decodeは出力を1トークンずつ作ります。必要なリソースも、ボトルネックも違います。
- リクエスト同士が影響し合う。推論エンジンは、複数のリクエストをまとめて処理します(continuous batching)。そのため1件あたりの速さは、同時に動くほかのリクエストに左右されます。
- GPUメモリーが先に足りなくなることがある。処理中のリクエストはKVキャッシュというメモリーを使い、文章が長いほど多く使います。上限に近づくと、遅延は少しずつではなく一気に悪化します。
テストの前に、次の5つを決めておきます。テスト対象(エンドポイント、モデル、ストリーミングの有無)、ワークロード(プロンプトの種類、入力の長さISLと出力の長さOSL)、負荷モデル(同時リクエスト数と送り方)、測る指標、合格ラインとなるSLO(サービスレベル目標)です。一度に変える条件は1つだけにすると、結果が変わった理由がわかりやすくなります。
2. 1つの数字だけでは判断できない理由
2.1 同じ時間軸で見る4つの指標
どの指標も、1本の時間軸から計算します。t₀はリクエストを送った時刻、t₁は最初のトークンが届いた時刻、tₙは最後のトークンが届いた時刻です。

図1 クライアント側から見た時間軸と、4つの指標が表す区間
- TTFT(time to first token)= t₁ − t₀。ネットワーク、サーバーでの待ち時間、prefillの時間を含みます。「反応があった」と感じるまでの時間で、プロンプトが長いほど、また同時アクセスが増えるほど悪化しやすい指標です。
- ITL(inter-token latency)= (request latency − TTFT) ÷ (OSL − 1)。トークンが平均何秒おきに届くかを表し、文字の出方の滑らかさがわかります。TPOTとも呼ばれます。1つ目のトークンはTTFTに含まれるため、OSLから1を引きます。
- Request latency = tₙ − t₀。回答全体にかかった時間です。同じ時間でも「待たされるが、出始めると速い」場合と「すぐ出るが、ゆっくり」の場合では体験が違うため、TTFTやITLと一緒に見ます。
- ユーザーあたりの出力速度 = 1 ÷ ITL。1人が1秒に受け取るトークン数です。1秒に10トークンを下回ると、多くの人が「遅い」と感じます。
2.2 スループット:システム全体の処理量
- Benchmark duration:最初のリクエストを送ってから、最後の応答が届くまでの時間です。スループットの計算に使います。
- Output token throughput = 全出力トークン数 ÷ duration。システム全体が1秒に出力するトークン数(Tokens Per Second、TPS)です。
- Request throughput = 完了したリクエスト数 ÷ duration。システム全体が1秒に処理できるリクエスト数(Requests Per Second、RPS)です。TPSとの関係は、1件あたりの出力の長さで決まります。
「1人あたり毎秒20トークン」と「システム全体で毎秒2,000トークン」は、まったく別の数字です。同時アクセスが増えると、全体の量は増えても、1人あたりの速度は下がることがあります。tokens/sを見たら、「1人あたり」か「全体」かをまず確認しましょう。
2.3 平均値だけでは足りない理由
遅延の分布には「長いすそ」があります。ほとんどのリクエストはすぐ終わりますが、一部は待ち行列やメモリー不足で何倍も遅くなります。平均値はこうした遅い処理に引っ張られる一方で、遅いケースがどれほど遅いかは見えません。AIPerfの資料の例では、p99が平均値より7割以上高くなっています。p50は「普通のリクエスト」の遅延、p95は「95%のリクエストがこれ以下」、p99は「99%がこれ以下」という意味です。SLOにはp95やp99を使うのが一般的なので、テストツールは1件ごとの記録を残し、あとから計算し直せるのが理想です。
2.4 Goodput:速さと品質を同時に測る
遅延とスループットは、一方を良くするともう一方が悪くなりがちです。そこで両方をまとめて見るのが、goodput = すべてのSLOを満たしたリクエスト数 ÷ durationです。たとえば「TTFT < 500 msかつITL < 50 ms」を満たしたリクエストだけを数えるので、goodputがrequest throughputを超えることはありません。AIPerfの資料の例では、throughputで計算すると38台で足りるはずのサーバーが、goodputで計算すると135台必要でした。本当に必要な台数を示すのは、goodputのほうです。
| 指標 | 計算式 | 意味・注目点 |
|---|---|---|
| TTFT | t₁ − t₀ | 反応が速いと感じるか |
| ITL(TPOT) | (request latency − TTFT) ÷ (OSL − 1) | 文字が滑らかに出るか |
| Request latency | tₙ − t₀ | バッチ処理、エージェントのワークフロー |
| Output token throughput | Σ OSL ÷ duration | 運用コスト、GPU利用率 |
| Goodput | SLOを満たしたリクエスト数 ÷ duration | 容量計画とサービス品質 |
2.5 ストリーミングを使わないとTTFTとITLが測れない理由
ストリーミングを使わない場合、サーバーは回答が全部できてからまとめて返します。クライアントにはt₀とtₙしか見えず、最初と最後のトークンが同時に届きます。そのためTTFTはrequest latencyと同じになり、ITLは計算できません。TTFT、ITL、1人あたりの出力速度は、ストリーミング時だけ使える指標です(AIPerfでは「streaming-only」と表示)。逆に、裏側でまとめて要約する処理のように、もともとストリーミングを使わないサービスなら、これらを気にする必要はありません。指標は、実際の使い方に合わせて選びましょう。
特に結果がずれやすい設定が2つあります。1つ目は出力の長さです。モデルが早めに終了記号を出して止まると、OSLが想定より短くなり、スループットやITLが正しく測れません。ignore_eosやmin_tokensなどで、決めた長さまで出力させましょう。サービスによっては今もmax_tokensという項目名を使っていたり、使えないパラメーターを何も言わずに無視したりするので注意が必要です。2つ目はトークナイザーです。ISLとOSLはクライアント側のトークナイザーで数えるため、モデルと合っていないと、トークン単位の指標がすべてずれます。
3. 負荷モデル:負荷のかけ方で、結果が変わる
負荷モデルとは、負荷の「大きさ」だけでなく、リクエストを「いつ、どんなルールで送るか」を決める仕組みです。

図2 クローズドループ(同時実行数を固定)とオープンループ(到着レートを固定)の違い
Concurrency(同時実行数を固定、クローズドループ):N人の仮想ユーザーが、それぞれ1件送っては応答を待ち、届いたら次を送ります。処理中のリクエストは常にN件以下です。システムが遅くなると送るペースも自然に落ちるので、結果は安定し、再現しやすくなります。「N人が使い続けたときの能力」を測るのに向いていますが、急なアクセス集中に比べると負荷はやさしめです。
Request rate(到着レートを固定、オープンループ):前のリクエストが終わったかどうかに関係なく、毎秒λ件を送り続けます。処理が追いつかないと、未処理のリクエストがたまり、遅延が急に悪化します。実際のアクセスに近く、「ピーク時でもSLOを守れるか」の確認に向いています。ただしλの設定に敏感で、処理能力をわずかに下回れば問題なくても、わずかに上回るだけで待ち行列がたまり続けます。
2つの方法は、答える問いが違います。「最大何人まで同時に使えるか」ならクローズドループ、「毎秒50件来たときのp99遅延は?」ならオープンループです。よくある失敗は、クローズドループで「同時100件でTTFTのp99は800 ms」と確認したのに、本番で毎秒100件が来ると耐えられないケースです。クローズドループでは、システムが遅くなると、実際の送信数が毎秒30件程度まで下がることがあるためです。
リクエストの届き方:オープンループでは、リクエストの間隔も決めます。Constantモードは1/λ秒ごとに等間隔で送ります。Poissonモードは平均すると同じ1/λ秒間隔ですが、間隔がランダム(指数分布)なので、まとまって届く時と、来ない時ができます。ばらばらに使う利用者の様子を再現したもので、AIPerfの初期設定です。Poissonでは同じ1秒に5件届くこともあり、遅延の「すそ」が伸びます。そのため、Constantだけで測ったp99は、実際より良く見えがちです。
3.1 負荷を段階的に上げて、限界点(knee)を探す
1つの負荷だけでは、「その負荷での結果」しかわかりません。限界を知るには、同時実行数を1、2、4、8……と増やしながら、それぞれでテストを行い、スループットと遅延のグラフを作ります。

図3 同時実行数を増やしたときのスループットと遅延:スループットは頭打ちになり、遅延は急に悪化することがある(左)。SLOの線との交点から能力を判断できる(右)
同時実行数を増やすと、スループットは伸び続けますが、伸び方はしだいに小さくなり、やがて横ばい、またはわずかに下がります。遅延は最初はあまり変わらず、ある点を超えると急に悪化します。この曲がり角をknee(変曲点)と呼び、その少し手前が理想の運用ポイントです。グラフにSLOの線を引けば、遅延の曲線と交わる点が「SLOを守れる最大の同時実行数」です。そのときのgoodputとあわせて見れば、性能をより正しく評価できます。
3.2 ウォームアップと、テスト同士の干渉
ウォームアップ:起動直後の推論サービスは、最初の数十秒だけ動きが安定しません。モデルの読み込み、CUDAカーネルの初回コンパイル、KVキャッシュの準備、接続の確立などがあるためです。AIPerfの資料の例では、最初の10秒のTTFTが通常より約41%長くなりました。この時間を含めるとp99が悪く見え、しかもテスト時間の長さによって結果が変わります。まずウォームアップを行い、その間のデータを除いてから本番の測定を始めましょう。
テストは同時に走らせない:2人のエンジニアが同じエンドポイントに、それぞれ同時実行数32でテストをかけると、サーバーには64件分の負荷がかかります。GPUもバッチ処理もKVキャッシュも共有するため、どちらの結果も実際より悪くなり、しかもレポートを見ても原因がわかりません。同じエンドポイントのテストは一度に1つだけにし、口頭の声かけに頼らず、開始前に確認しましょう。負荷をかける側のマシンも同じです。CPU不足、ポート不足、JSON処理の詰まりがあると、測った遅延にクライアント側の問題が混ざってしまいます。
結果を比べるときに注意したい点が3つあります。1つ目はサンプル数です。p99を信頼するには、負荷ごとに数百件以上のリクエストが必要です。100件では、p99はほぼ「一番遅い1件」になってしまいます。2つ目はデータの種類です。長さを固定した合成データは条件をそろえやすく、実際の会話ログは長さのばらつきが大きいため、合成データでは見えない問題が出てきます。どちらも試す価値がありますが、直接は比べられません。3つ目は再現性です。乱数シードを固定すれば、プロンプトの内容とPoissonの間隔は再現できますが、遅延自体にはばらつきが残ります。設定を比べるときは数回ずつ実行して中央値で比べ、モデル、推論エンジンのバージョン、ハードウェア、トークナイザー、負荷モデル、ウォームアップ設定、SLOを記録しておきましょう。
4. AIPerf:実際のツールではどうなっているか
AIPerfは、NVIDIA Dynamoチームが公開しているオープンソースのLLM性能テストツールです(Apache 2.0ライセンス、GenAI-Perfの後継)。ここでは使い方ではなく、3つの設計を通して、これまでの考え方がツールにどう表れているかを見ていきます。

図4 AIPerfの3つの層:コントロールプレーンが負荷のかけ方を決め、データプレーンが測定し、分析プレーンが集計する
複数のプロセスとcredit:AIPerfは約10のサービスを別々のプロセスで動かし、ZeroMQで連携させます。役割は3つに分かれています。コントロールプレーン(いつ何件送るかを決める)、データプレーン(workerがHTTPリクエストを送り、時刻を記録する)、分析プレーン(指標を計算して結果を出す)です。負荷を制御する仕組みの1つが「credit」で、リクエストの通行証のようなものです。workerはcreditを持っているときだけ1件送れます。同時実行数を固定するモードでは、最初にN枚を配り、1枚戻るたびに1枚を補充します(クローズドループ)。Request rateモードでは、Poissonのスケジュールに沿って、戻りを待たずにcreditを配ります(オープンループ)。つまり負荷モデルとは、「どんな条件で次の通行証を出すか」のルールなのです。
タイムスタンプとトークナイザー:workerは、リクエストを送った時刻と、ストリーミングの各チャンクが届いた時刻を記録します。TTFT、ITL、request latencyはこの時刻の差から、benchmark durationはテスト全体の経過時間から計算します。ISLとOSLはトークナイザーで数えるため、サーバーが実際に使っているモデルと同じトークナイザーを指定する必要があります。
スイープと自動探索:標準のグリッドスイープでは、同時実行数1、3、7、19、52、139、373、1000の8点をテストします。各点を何回か繰り返して、結果のばらつきの幅(信頼区間)を見ることもできます。「SLOを守れる最大の同時実行数」を直接知りたい場合は、max-concurrency-under-slaなどのsearch recipeを使います。まず負荷を上げて、初めてSLOを超える点を見つけ、範囲を絞ります。次に、等張回帰(isotonic regression)で測定のノイズを減らして交点を推定し、範囲の幅が5%未満になるまで境界付近を追加でテストします。13〜25回ほどで終わります。8点だけのテストでは、「139〜373の間」までしかわからないこともあります。「SLOを守りつつスループットを最大にしたい」場合は、ベイズ最適化(Bayesian optimization)を使えます。ガウス過程(Gaussian process)で同時実行数とスループットの関係を予測し、良さそうな点や、まだよくわからない点を選んで試します。何回か改善がなければ終了です。調べる条件の数が多いほど、グリッドスイープより効率的です。
まとめ
性能の問いは、まず測れる形に言い換えることが大切です。たとえば「このモデル、推論エンジン、ISL/OSLの条件で、クローズドループで同時実行数を上げていき、ウォームアップを除いたとき、TTFTのp95がX ms未満、ITLのp95がY ms未満を守れる最大の同時実行数はいくつか。そのときのgoodputはいくらですか。答えは、スループットと遅延のグラフ、SLOの線、その交点で示せます。
テストを始める前に、次の5点を確認しましょう。
- ストリーミングを使っているか(TTFTとITLを測れるかが決まる)。
- 出力の長さをそろえているか。トークナイザーはモデルと同じか。
- 能力を知りたいならクローズドループ、ピーク時の遅延を確かめたいならオープンループを使う。オープンループではPoissonの届き方も選べる。
- ウォームアップを除いているか。同じエンドポイントで別のテストが動いていないか。
- 平均だけでなくp95・p99を、throughputだけでなくgoodputも見ているか。設定と1件ごとの記録を残しているか。
ツールもGPUも変わっていきますが、このチェックリストはこれからも使えます。
参考資料
- AIPerfのソースコードとドキュメント:https://github.com/ai-dynamo/aiperf(architecture、metrics-reference、comprehensive-llm-benchmarking、timing-modes-reference、search-recipesなどのドキュメントを含む)
- Yu et al., “Orca: A Distributed Serving System for Transformer-Based Generative Models”, OSDI 2022(continuous batching)
- Zhong et al., “DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving”, OSDI 2024(goodput)