ステータス:ドラフト(2026-10-06)、原理に関する記事です。 原理の説明は各モデルの公式資料(記事末尾にリンク)と一般的な推論理論に基づいており、検証に使用した数値は 第20回で筆者が実際に測定した値です。計算式は現象を理解するために単純化したものであり、どの部分が検証済みでどの部分が推測であるかは章ごとに明らかにしています。 作成ルール:実測データを基本とし、測定できなかったものは「未実測」と表記します。
目次
- 1. ひと目でわかる:パーツごとに時間を決定する要素が異なる
- 2. 対話LLM:トークンを1つ生成するたびにモデル全体を読み込む
- 3. 音声合成:作成するパッチ数だけ繰り返す
- 4. ストリーミング音声認識:一度計算したものは再計算しない
- 5. 繋ぎ合わせると:ボトルネックの種類がパーツごとに異なる
- 6. 面接で出そうな質問
- 外部的根拠:論文と公式資料で確認した内容
- 確認できなかったこと
- 参考文献
- 確認したバージョンと日付
1. ひと目でわかる:パーツごとに時間を決定する要素が異なる
第20回の値は「どれくらいかかったか」であり、この記事は「なぜそれだけかかるのか」です。
| パーツ | 時間を決定する要素 | 原理から予測した値 | 実際に測定した値 | 一致 |
|---|---|---|---|---|
| 対話LLM、トークン生成 | トークンごとに重み全体をメモリから読み込む時間 | 上限 約129 tok/s(測定された帯域幅に基づく) | 85.6 tok/s | 上限の66% |
| 対話LLM、入力処理 | 演算量 | 生成よりもはるかに高速 | 700 tok/s(67トークン)、1,024トークン以上では演算限界の約75〜80% | 一致、短い入力は遅い |
| 生成速度の帯域幅上限 | 重みバイト数 × 速度 ≤ 帯域幅 | 測定された帯域幅 250GB/s | 4つのモデルで86〜98% | 一致 |
| 音声合成(VoxCPM2) | 作成すべきパッチ(ステップ)数 | 音声1秒 = 6.25パッチ(1パッチ = 160ms分) | 1秒あたり0.475秒、パッチあたり約76ms | 計算につながっており、論文の構造と一致 |
| ストリーミング音声認識 | チャンク = フレーム数 × 80ms | 5種類のチャンク | カードの5つの値と検証が一致 | 一致 |
2. 対話LLM:トークンを1つ生成するたびにモデル全体を読み込む
原理
トランスフォーマーが次のトークンを1つ計算するには、すべての層の重みを1回ずつ使用する必要があります。リクエストが1つだけの場合、重み1つにつきかけ算を1、2回行うだけで終わるため、GPUの演算装置は遊んでしまい、 重みをメモリから取得する速度(メモリ帯域幅) が時間を決定します。そのため、トークン生成速度の理論的上限は次のようになります。
초당 토큰 수 ≤ 메모리 대역폭 ÷ 가중치 바이트 수
反対に、入力(プロンプト)を処理する段階では数十個のトークンを一度に計算するため、同じ重みを複数のトークンで再利用し、このときは演算能力が限界となります。同じモデルであるにもかかわらず、入力処理が生成よりもはるかに高速である理由がこれです。
検証
| 項目 | 値 | 出典 |
|---|---|---|
| GPUメモリ帯域幅 | 約905GB/s(24GBクラスのコンシューマー向けGPU、読み取り専用の合計、3回繰り返し 903〜905) | 直接測定(PyTorchによる1GiBテンソルの読み取りテスト)。コピー(読み取り+書き込み)は865GB/s。仕様書の約936GB/sは記憶に頼った値であるため使用しない |
| 重み(4bit QAT) | 7.0GB | モデルファイルサイズを公開APIで確認 |
| 理論上の上限 | 905 ÷ 7.0 ≈ 129 tok/s | 計算 |
| 測定された生成速度 | 85.6 tok/s(1トークンあたり11.6ms) | 第20回の測定、サーバーの計測と一致 |
| 効率 | 85.6 ÷ 129 ≈ 66% | 計算 |
| 入力処理速度 | 700 tok/s(67トークンで95.7ms) | サーバーの計測 |
- 上限の66%を使用しています。 残りはアテンションが読み込むKVキャッシュ、量子化区間を元に戻す計算、層ごとにカーネルを起動する間隔などに分かれていると考えられますが、それぞれがどれくらいであるかは分解していません(推測)。
- 入力処理は生成の8.2倍です(700 ÷ 85.6)。原理が示す方向性と一致しており、そのため入力が長くても最初のトークンが大きく遅れることはありません。逆に、長い回答はトークン数に正比例して遅くなります。ただし、67トークンは短いため、リクエストごとに発生する固定費用が混ざった値です。入力を長さ別に測定した際の値は、以下の「入力処理は演算がボトルネックであり、短い入力は遅く出力される」にあります。
- 量子化が速度に直接表れます。 同じモデルを16bitにすると重みが約25GB(130億パラメータ × 2バイト、計算)になるため、同じ式の限度が 905 ÷ 25 ≈ 36 tok/s と3分の1以下に低下します。このGPUのメモリ24GBには収まらないため、4bitは選択ではなく前提となります。このモデルの16bit速度は測定していません(未実測、計算)。小さなモデルで精度を半分に減らすと、計算が示す利益よりも少し小さく(1.7倍ではなく1.54倍)現れたため(以下の直接検証)、4bitと16bitの差も計算値より小さくなる可能性が高いです。
- 思考トークンも同じ速度で生成されます。 第20回の思考において、80トークンをすべて思考に費やした応答は約1.0秒かかりました(80 ÷ 85.6 ≈ 0.93秒と一致)。音声対話においてモデルがN個の思考トークンを使用すると、ユーザーは N ÷ 85秒 の間沈黙を聞くことになります。思考をオフにすべき理由が、感覚ではなく計算によって導き出されます。
直接検証:サイズと精度が異なるモデルで上限を確認する
上記の検証は帯域幅の値を仕様書から取得したため、上限そのものが正しいかは確認できませんでした。そのため、8GBクラスのGPU 1枚で 帯域幅をまず直接測定し、サイズと精度が異なる4つのモデルの生成速度を同じ方法で測定しました(vLLM 0.31.0、同時リクエスト1件、128トークン生成の5回の中央値)。
- GPUの読み取り専用帯域幅: 250GB/s(PyTorchで大きなテンソルを読み取って合計、中央値)、コピー 227GB/s
- fp16行列積 4096³: 31.8 TFLOPS(中央値)
| モデル | ロードされた重み | 生成速度 | 重み × 速度 | 測定された帯域幅に対する比率 |
|---|---|---|---|---|
| 0.6B, bf16 | 1.12GiB | 180.4 tok/s | 217GB/s | 87% |
| 1.7B, bf16 | 3.22GiB | 68.8 tok/s | 238GB/s | 95% |
| 1.7B, fp8 | 1.90GiB | 105.7 tok/s | 216GB/s | 86% |
| 4B, fp8 | 4.32GiB | 52.7 tok/s | 244GB/s | 98% |
重みのサイズはサーバーログのロードメモリであり、「重み × 速度」はトークンを1つ生成する間に重みを1回ずつ読み込んだと仮定した計算です。
- 原理は正しいです。 モデルのサイズが異なっていても、「重み × 速度」が帯域幅付近(86〜98%)に集まります。速度を決定するのはパラメータ数ではなく、読み込む必要があるバイト数であるという意味です。
- 精度を半分に減らした効果は計算よりも小さかったです。 1.7Bをbf16からfp8に変更すると、重みは1.7倍小さくなりますが(3.46GB対2.04GB、計算)、速度は1.54倍(68.8対105.7)しか向上しませんでした。トークンあたりにかかる時間で見ると、読み取り時間以外にトークンごとに0.4〜1.3msが余分にかかります(計算:1 ÷ 速度 − 重み ÷ 250GB/s)。アテンション、層ごとのカーネル起動、8bit値を元に戻す計算が含まれていると推測されますが、それぞれがどれくらいであるかは分解していません(推測)。
- 24GBクラスのGPUの帯域幅も同じ方法で測定しました。 読み取り専用で905GB/s(仕様値として知られている約936GB/sの約97%)であり、12B 4bitモデルの生成速度 × 重み(85.6 × 7.0)は約599GB/sとなり、測定された帯域幅の 66% でした。つまり、先ほど仕様値で計算した64%は、測定値でもほぼ同じ66%となります。帯域幅を仮定したために生じた差ではないということであり、8GBクラスのGPUのvLLM結果(86〜98%)よりも低いのは、エンジン(llama.cppとvLLM)、4bit形式(区間ごとのデコード計算)、モデル構造の違いのどれに起因するかを切り分けることができませんでした(未確認)。同じGPUで同じモデルを2つのエンジンで測定するテストが今後の課題です。
同時リクエストが増えても遅くならない理由と限界
重みを読み込むコストはリクエスト数に関係なく1回であるため、複数のリクエストをまとめて処理する(連続バッチ処理)ことで読み込みコストを分散させます。第20回で同時に2件送信したときの最初のトークンは0.206秒、4件の場合は中央値0.352秒でした。このサーバーはスロットを2つしか開けていなかったため、4件のときは2件ずつ列に並んだ値であり、バッチ処理のメリットを明確に示す実験ではありませんでした。
そのため、上記の4つのモデルを16スロットで開き、同時リクエスト数を増やして総スループットを測定しました(リクエストごとに128トークン生成、3回の中央値)。
| 同時リクエスト | 0.6B bf16 | 1.7B bf16 | 1.7B fp8 | 4B fp8 |
|---|---|---|---|---|
| 1 | 180 | 69 | 106 | 53 |
| 4 | 670 | 264 | 405 | 205 |
| 16 | 2,484 | 1,007 | 1,544 | 775 |
| 16件のときは1件の何倍か | 13.8倍 | 14.6倍 | 14.6倍 | 14.7倍 |
| 16件のときのリクエストあたりの速度 | 155(86%) | 63(91%) | 97(91%) | 48(92%) |
単位は総スループット(tok/s)であり、最後の2行は上の表から計算しました。リクエストを16倍に増やしたにもかかわらず、1つのリクエストは8〜14%遅くなるだけで、総量はほぼ14〜15倍になりました。重みを読み込むコストを分散させるという原理がそのまま現れています。
このメリットが終了するポイントは計算でのみ見積もりました。1つのトークンはパラメータあたり2回の演算を行うため、測定された演算スループット(31.8 TFLOPS)と測定された帯域幅(250GB/s)に基づくと、bf16では同時リクエストが約130件を超えたとき、fp8では約64件を超えたときに演算がボトルネックへと切り替わります(計算、アテンションとKVキャッシュの読み込みは無視した単純化)。今回は16件までしか開かなかったため、そのポイントは確認できておらず(未実測)、16件時点の4Bモデルも演算は測定された限界の約18%(2 × 3.6B × 775 ≈ 5.6 TFLOPS)であり、依然として帯域幅側の領域にあります。
入力処理は演算がボトルネックであり、短い入力は遅く出力される
入力処理は同じサーバーを使用し、プレフィックスキャッシュをオフにし、リクエストごとに異なるランダムな入力で測定しました。
| 入力長 | 1.7B bf16 | 4B fp8 |
|---|---|---|
| 256トークン | 5,709 tok/s(45ms) | 3,129 tok/s(82ms) |
| 1,024トークン | 8,634 tok/s(119ms) | 3,438 tok/s(298ms) |
| 2,048トークン | 8,730 tok/s(235ms) | 3,365 tok/s(609ms) |
| 3,500トークン | 8,244 tok/s(425ms) | 3,182 tok/s(1.10秒) |
- 1,024トークン以上で速度が一定になります。 同じモデルの生成(69、53 tok/s)よりもそれぞれ約127倍、約65倍速いです。計算で合わせると、1.7Bは埋め込みを除いたパラメータが1.4Bなので8,730 tok/sが約24 TFLOPS(2 × 1.4B × 8,730)、4Bは3.6Bなので3,438 tok/sが約25 TFLOPSです。どちらのモデルも計測した行列積のスループット31.8 TFLOPSの約75〜80%であるため、入力処理は演算がボトルネックになるという原理と数値が一致しています。
- 短い入力はトークン当たりのコストが高くなります。 256トークンで速度が、1.7Bは約35%、4Bは約9%低下しました。リクエストごとに発生する固定費は、短い入力では割り当てるトークンが少なく相対的に大きく見えるためです。音声対話の入力は通常短いため、上記の12Bの測定における700 tok/s(67トークン)もこの影響を受けた値として読み取る必要があります。
- 最初の測定が間違っており、演算の限界と対比してそれに気づきました。 最初は同じ文を繰り返して送信したところ、4Bが約91,000 tok/sという結果になりました。これは約660 TFLOPS(2 × 3.6B × 91,240)に相当し、GPUが出力できない値です。プレフィックスキャッシュがヒットして入力を計算しなかったためであり、キャッシュをオフにしてリクエストごとに異なる入力で再測定し、上記の表を得ました。測定値をハードウェアの限界値と比較するだけでフィルタリングできるエラーです。
3. 音声合成:作成するパッチの数だけ繰り返す
原理
どちらの合成モデルも、音声を一度に出力せず、 短い単位(VoxCPM2は160ms分のパッチ、Magpieはコーデックフレーム)を先頭から1つずつ 作成していきます(自己回帰)。そのため、時間はオーディオの長さに正比例し、文の開始時には長さに関係のない固定費が付加されます。第20編で12個のポイントに合わせた式がその形状を示しています。
합성 시간 ≈ 0.475 × 오디오 길이(초) + 0.23초
VoxCPM2:パッチあたり76ms
VoxCPM2の技術報告書によると、このモデルは離散トークンを使用せず、 連続的な潜在表現を拡散と自己回帰によって生成する 構造です。音声を1秒あたり25個の潜在フレーム(40ms)に縮小し、フレーム4つを 1つのパッチとしてまとめてパッチを1回に1つずつ作成します。そのため、自己回帰の1ステップは160msのオーディオに相当し、1秒あたり 6.25ステップになります。この数値を測定結果と結びつけると次のようになります。
| 項目 | 値 |
|---|---|
| オーディオ1秒に必要なステップ(パッチ) | 6.25 |
| オーディオ1秒を作成する時間(測定の傾き) | 0.475秒 |
| 1つのステップ(パッチ)にかかる時間 | 0.475 ÷ 6.25 ≈ 76ms |
| サーバー設定の拡散反復回数 | 10(inference_timesteps=10、サーバーコードで確認) |
| 拡散1回あたり(上記の76msを10で割った値) | 約7.6ms(上限。ステップあたりの時間には言語モデルの1ステップとデコーディングが含まれており、論文によると拡散ステップごとに拡散モジュールを2回計算する分類器不含ガイダンス(CFG)も含まれているため、実際の1回あたりの値はさらに小さい可能性がある) |
ステップごとに 言語モデルの1ステップと拡散10回を実行するコストが76msであるということであり、この構造では拡散の反復回数を減らすとほぼ比例して高速化すると予想できます。反復回数を減らしたときの速度と品質はテストしていません(未測定)。固定費の0.23秒は論文でも根拠を見つけることができませんでした。論文のリアルタイム係数は固定費を含む壁時計時間であり、長さが長くなるほど傾きに近づきますが、この0.23秒が文のエンコーディング、参照音声の処理、デコーダーの初期化、サーバーラッパーのどれに起因するのかはどの資料も示しておらず、分解されていません(未確認)。
公式の説明では、このモデルがストリーミング生成(generate_streaming)をサポートしているとしており、技術報告書(表11)では、コンシューマー向けハイエンドGPU(24GBクラス)1基でのPyTorch実装のリアルタイム係数0.30(ピークVRAM約8GB)、サービングエンジン(Nano-vLLM)使用時は0.13と報告されています。我々が測定した傾き0.475は論文の0.30よりも約1.6倍遅いですが、GPUの種類、文全体を合成して返すサーバー方式、ラッパーのオーバーヘッドのどれに起因するのかを特定できませんでした(未確認)。VRAM(6,600〜6,900MiB)は論文の約8GBと同じ範囲です。
Magpie TTS:一度に2フレーム
Magpie TTS Multilingualは、パラメータが3億6,400万個のエンコーダー・デコーダーTransformerです。公式説明の核心は2つあります。 フレームスタッキングは、デコーダーが1ステップで音声フレームを2つ同時に予測して反復回数を半分に減らす方法であり、 ローカルTransformerはそのように作成したフレーム間の依存関係を整えて低下した品質を取り戻す小さなモジュールです。同じ長さの音声を作るのに必要なデコーダーのステップ数が半分になるわけです。
| 項目 | VoxCPM2 | Magpie TTS |
|---|---|---|
| パラメータ | 約20億 | 約3億6,400万 |
| 生成方式 | 連続潜在表現を拡散と自己回帰によって | コーデックフレームを自己回帰によって(2フレームずつ) |
| GPUメモリ(測定) | 約6,600〜6,900MiB | 約750MiB |
| リアルタイム係数(測定) | 0.494〜0.582、中央値0.521 | 0.447〜0.541、中央値0.466(韓国語を除く) |
- パラメータが5倍以上小さく、メモリが9倍小さいにもかかわらず、速度は同等です。 時間を決定するのはパラメータ数ではなく、「作成すべきステップ数 × ステップあたりのコスト」であるという解釈と一致します。ただし、2つのモデルを異なるGPUで測定し、Magpieのフレーム比率を確認できなかったため、VoxCPM2のようにフレームあたりの時間を計算することはできませんでした(未確認)。
- 公式の初声遅延(H100で47msなど)はストリーミング基準です。 測定で使用したのは文全体を合成して受け取る方式であるため、同じ数値で比較することはできません。
- 韓国語はこの環境では正常に生成されませんでした(第20編 3-2)。構造の問題なのか設定の問題なのかは確認できませんでした。
ストリーミング合成が初声を短縮する原理
パッチを先頭から作成するため、文の最後まで待つ必要なく、 最初のパッチが出力され次第 再生を開始できます(VoxCPM2のレポートでは、生成したパッチを即座に音声に変換する構造だと説明されています)。最初の音声までの時間が「文全体の合成時間」(第20編の測定:1.2〜2.1秒)から「文あたりの固定費と最初のパッチ1つ分の時間」(0.23秒 + 0.08秒、約0.3秒)に短縮されます。これは計算上の数値であり、測定に使用したサーバーではテストしていません。再生が合成よりも遅いため(リアルタイム係数0.5)、後続の音声が途切れないという条件も必要です。
4. ストリーミング音声認識:一度計算したものは再計算しない
原理
音声認識モデルのNemotron 3.5 ASRは、FastConformerエンコーダーの24層とRNNTデコーダーで構成されています。2つの要素が遅延を引き起こします。
- フレーム長。 エンコーダーが音声を8分の1に縮小し、エンコーダーフレーム1つが 80ms になります(特徴量を10ms間隔で抽出する一般的な設定基準であり、モデルカードのチャンク値80msはこの解釈と一致します)。
- 右側のコンテキスト(先読みの量)。 現在のフレームの意味を確定するために、 少し先のフレームまで見たいと考えます。そのフレームが到着するまで待つ必要があるため、先読みの量がそのまま遅延になります。
モデルは att_context_size = [왼쪽, 오른쪽] によってこれら2つを決定します。左側の56フレームは過去4.48秒(56 × 80ms)を記憶する量であり、右側がチャンクを決定します。一度に処理するチャンクの長さは(右側 + 1)× 80ms です。
att_context_size |
計算:(右側 + 1)× 80ms | モデルカードのチャンク値 | 一致 |
|---|---|---|---|
| [56, 0] | 1 × 80 = 80ms | 80ms | 一致 |
| [56, 1] | 2 × 80 = 160ms | 160ms | 一致 |
| [56, 3] | 4 × 80 = 320ms | 320ms | 一致 |
| [56, 6] | 7 × 80 = 560ms | 560ms | 一致 |
| [56, 13] | 14 × 80 = 1,120ms | 1.12秒 | 一致 |
5つの値すべてがカードの表と一致するため、「チャンク = (右側コンテキスト + 1)× 80ms」という解釈が正しいと言えます。
キャッシュの役割
従来のストリーミング方式(バッファ方式)は、直近の音声を重複するウィンドウで切り分けて毎回最初から再エンコーディングしていました。重複区間を何度も計算していることになります。キャッシュ認識方式は、 すべてのセルフアテンション層と畳み込み層のエンコーダー表現をキャッシュに保存し、新しい音声が来ると新しいフレームのみを計算してキャッシュを更新します。公式の説明通り、各フレームが正確に1回だけ処理されます。その結果、計算量が音声の長さではなく、 新しく入力された長さに比例します。スループットはベンダーの数値であり、多言語3.5モデルカードではH100が1基の場合、チャンク80msの設定で同時ストリーム約240個(バッファ方式のベースラインであるParakeet 1.1Bは約14個)、1.12秒の設定で約2,400個(ベースラインは約400個)と記載されており、英語専用モデルのNVIDIAブログでは320msチャンクで560ストリームと記載されています(2つのモデルの値であるため混同してはなりません)。「確定結果まで中央値24ms」は、英語モデルのブログにおけるパートナー企業のパイプラインの値です。筆者の実験環境では再現していません。
RNNTデコーダーは、エンコーダーフレームが1つ出力されるたびに文字(または「まだなし」を意味する空のシンボル)を出力する構造であるため、フレームが到着するにつれて文字がつながっていきます。そのため、発話が終わる前に結果が流れ出し、発話が終われば最後のチャンクを確定させるだけで済みます。
チャンクサイズを大きくすると精度は向上するのか
右側のコンテキストが長いほど、モデルがより多くの未来を見て判断するため、一般的に精度が向上し、遅延も同時に増加します。同じ12個の音声にチャンクサイズ別の設定を適用して平均文字エラー率を測定すると次のようになります(ファイル全体に設定を適用した近似値であり、実際のストリーミングではありません)。
| チャンク | 80ms | 160ms | 320ms | 560ms | 1,120ms |
|---|---|---|---|---|---|
| 平均文字エラー率 | 4.3% | 4.0% | 3.9% | 3.9% | 11.3% |
- 80msから320msにかけて4.3%から3.9%へ少し改善し、その後は同じです。 この合成音声12個においては、320ms以上のコンテキストはこれ以上役に立たなかったということです。遅延を最も短くする80〜160msに変更しても、精度の損失は0.4〜0.3パーセントポイントでした。合成音声であるためクリアであるという点が、この結果を楽観的なものにした可能性があります。
- 1,120msにおける11.3%は説明できませんでした。 1つの音声が空の結果になったためであり、2回測定しても同じでした。モデルカードの韓国語FLEURSの文字エラー率のほうがむしろ1.12秒の設定で最も低く(7.12%)、我々の値とはカードと逆の傾向を示しています。人間が読み上げた韓国語FLEURSの30文で再測定したところ、チャンクサイズに関係なく空の結果が0個であり、文字エラー率が5.6〜6.2%と平坦であったため(第20編 4-3節)、この現象はモデルの一般的な性質ではなく、合成音声12個のサンプルにおいてのみ現れたものとみられます。原因は分解していません。
5. 連結した場合:ボトルネックの種類がパーツごとに異なる
| パーツ | ボトルネックの種類 | 削減方法の方向性 |
|---|---|---|
| 音声認識 | 計算(新しいフレーム数に比例)、非常に軽量 | ほとんど手を加える必要なし |
| 対話LLM | メモリ帯域幅 | 重みを小さくする(量子化)、より広帯域なGPU、思考のスキップ |
| 音声合成 | フレームを順番に生成するループ | ストリーミング、短いフレーズの先行出力、ループ回数の調整 |
20篇の1ターンの計算において合成が60〜85%を占めていた理由はここにあります。音声認識は軽い計算であり、LLMは帯域幅上限の66%まで使用しておりこれ以上絞り出す余地が小さく、合成のみが 「オーディオの長さに応じてループ」 という構造になっているため、文章が長いほど線形に増加します。
6. 面接で出そうな質問
- LLMのトークン生成速度の上限はどのように見積もるか? メモリ帯域幅を重みのバイト数で割る。4ビットの12Bモデルは、測定された帯域幅905GB/s ÷ 7.0GB ≈ 129 tok/s であり、実測値は85.6 tok/s(66%)であった。
- 同じモデルで入力処理が生成よりもはるかに速い理由は? 入力は重みを1回読み込んで複数のトークンで再利用するため演算がボトルネックになり、生成はトークンごとに重みを再度読み込むため帯域幅がボトルネックになる(1.7Bモデルで8,730対69 tok/s)。
- リクエストを16個に増やすと、1つのリクエストはどれくらい遅くなるか? 小さいモデル4つで8〜14%しか遅くならず、総スループットは約14〜15倍になった。重みを読み込むコストを分散できるためである。
- 測定値が正しいかどうかをどのように疑うべきか? ハードウェアの限界と比較する。入力処理の91,000 tok/sはGPUが出せる演算量ではないため、プレフィックスキャッシュがヒットしたことに気づいた。
- 量子化はなぜ速度の向上にも役立つのか? 重みのバイト数が減れば、帯域幅の上限がその分向上する。4ビットは16ビットの約3.5倍(計算値)。小さいモデルで16ビットから8ビットに変更したときは計算上の効果が1.7倍であるのに対し、実測値は1.54倍であり、トークンごとにかかる固定コストの分だけ利益が減少した。
- キャッシュを考慮したストリーミング音声認識がバッファ方式と異なる点は何か? オーバーラップするウィンドウを再エンコードせず、層ごとの表現をキャッシュに保持して各フレームを1回だけ計算する。チャンクは(右側のコンテキスト + 1)× 80ms である。
- 自己回帰型音声合成において最初の音声の遅延を減らす方法は? ストリーミングで最初の数フレームが出たらすぐに再生する。再生が合成よりも遅ければ(リアルタイム係数 < 1)途切れない。
外部の根拠:論文と公式資料で確認した内容
この記事の数値は直接測定したものであり、原理の説明は以下の資料と突合しました。外部の数値はモデル、GPU、負荷が異なるため直接比較はせず、 構造と方向性の合致のみを判定しました。
| 主題 | 資料と確認した箇所 | 確認した内容と条件 | この記事との関係 |
|---|---|---|---|
| デコードのメモリ帯域制限 | Pope他、「Efficiently Scaling Transformer Inference」、arXiv 2211.05102、第2節。Yuan他、「LLM Inference Unveiled: Survey and Roofline Model Insights」、arXiv 2402.16363、第3.1.1節 | バッチとコンテキストが小さい場合は重みの読み込み時間が支配的になり、バッチが大きい場合は演算ボトルネックに変わる。重みを圧縮しても演算ボトルネックの区間では時間は減らない(Llama-2-13b、コンテキスト1,024) | 支持。 第2節の原理と同じ。「上限 = 帯域幅 ÷ 重みバイト数」という式を1行で記述した論文は見つからず、この記事の式はKV読み込み項を省いた単純化したもの |
| 帯域幅の活用率 | Databricks技術ブログ「LLM Inference Performance Engineering: Best Practices」(2023-10-12) | モデル帯域幅活用率(MBU)がバッチ1のとき2×H100で60%、4×A100-40GBで55%(TensorRT-LLM、テンソル平行)。バッチが大きくなると低下する | 限定的に支持。 分母が 仕様書の最高帯域幅であるため、我々の86〜98%(分母は直接測定した読み込み帯域幅)とは同じ尺度ではない |
| 活用率のばらつき | Chen、「Memory-Bound but Not Bandwidth-Limited」、arXiv 2605.30571(2026年、単独著者プレプリント、査読未確認) | バッチ1においてPyTorchのデフォルト経路基準でL4で約81%、H100で約27%を報告し、実行開始コストのためと説明 | 限定的に支持。 高帯域幅GPUでは同じ到達率が出ない可能性がある。我々の数値は8GB級と24GB級の2つのGPUでのみ確認 |
| VoxCPM2の構造 | 「VoxCPM2 Technical Report」、arXiv 2606.06928、第3.1節、第3.7節、第4.6節の表11 | 25Hzの潜在フレーム4つを1つのパッチにまとめて6.25Hzの自己回帰(1ステップ = 160ms)。拡散ステップごとに拡散モジュールを2回計算(CFG)。コンシューマー向けハイエンドGPU(24GB級)1枚でPyTorchのリアルタイム係数0.30、ピークVRAM約8GB、サービングエンジン0.13 | 限定的に支持。 長さに比例する構造は合っている。ステップごとの時間の内訳と固定コスト0.23秒は論文に根拠がなく、我々の傾き0.475は論文より1.6倍遅い |
| フレームスタッキング | Fejgin他(NVIDIA)、「Frame-Stacked Local Transformers for Efficient Multi-Codebook Speech Generation」、arXiv 2509.19592、ICASSP 2026 | NanoCodec(秒間21.5フレーム、コードブック8個)ベースの英語モデルにおいてスタッキング係数が2のとき、自己回帰型ローカルトランスフォーマーが並列予測のベースラインより2.1倍高速 | 関連。 Magpieの「一度に2フレーム」の説明と同じ方法だが、公開されている多言語モデルと同じ実験モデルであるかはモデルカードに記載されていない |
| キャッシュを考慮したストリーミングASR | Noroozi他、「Stateful Conformer with Cache-based Inference for Streaming ASR」、arXiv 2312.17279、ICASSP 2024、表1、表2 | 約1.14億パラメータ、LibriSpeech test-other、RNN-Tの単語誤り率が先読み量0msで9.5%、240msで7.8%、520msで7.5%、1,360msで6.3%。バッファ方式のベースライン(RNN-T 11.3%、平均遅延2,000ms)より遅延が短く正確 | 支持。 コンテキストが長いほど正確になる傾向。論文の「遅延」はチャンクサイズとは異なる定義 |
| チャンク別の韓国語の精度 | nvidia/nemotron-3.5-asr-streaming-0.6b モデルカード(FLEURS、言語指定モード) |
韓国語の文字誤り率が80msで7.59、160msで7.70、320msで7.27、560msで7.18、1.12秒で7.12(%)。チャンク値の80、160、320、560、1,120msが att_context_size の(右側+1)×80ms と一致 |
支持。 第4節の表のチャンク解釈と方向性は同じ。人間の音声FLEURSの30文で再測定したところ、韓国語の文字誤り率はチャンク1,120から80msまで5.8、5.9、5.6、6.2、6.1%と平坦であり、カードの数値(7.12〜7.70%)と矛盾しない。合成音声12個のうち1,120msのみが悪かったという現象は再現されなかった |
| 非ネイティブの音声 | McGuire、arXiv 2503.06924、表2、3(L2-ARCTICの朗読音声)。Kim他、LearnerVoice、Interspeech 2024、arXiv 2407.04280。Oh他、ETRI Journal 42(5)、2020 | 朗読音声においてWhisper large-v3の誤り率がネイティブで0.007、韓国人話者で0.033(約4.7倍)、中国人話者で0.053、ベトナム人話者で0.124。韓国人学習者の英語自発発話のWERは19.18%(ネイティブの会話と同程度の水準であり、自発会話の特性も大きな要因)。旧式の韓国語モデルはネイティブで3.42%、非ネイティブで36.74%(音節誤り率) | 支持。 合成音声の値楽観的であるという記述の根拠。合成音声の値に乗じる一般的な倍率は根拠がない。韓国語・日本語・中国語学習者の音声に関する現代モデルの測定値は、アクセス可能な資料からは見つからなかった |
ベンダーの数値(モデルカードのH100同時ストリームなど)は条件がカードに一部しか記載されていないため、方向性のみを引用しました。PNASや一部のモデルカードはアクセスが制限されているため他のコピーや論文で代読し、閲覧できなかった資料の数値は使用していません。
確認できなかったこと
- 66%と86〜98%の差の原因。 帯域幅は両方のGPUで直接測定したが、24GB級はllama.cppの4ビットモデル、8GB級はvLLMのbf16・fp8モデルであり、エンジンとフォーマットが異なる。同じGPUで同じモデルを両方のエンジンで測定して切り分ける必要がある。
- 66%の残りの34%がどこに行っているのか。 KVキャッシュの読み込み、アテンション、カーネル間のギャップに分解していない。
- VoxCPM2のフレームあたり76msの内訳と、拡散のループ回数を減らした際の効果、固定コスト0.23秒の正体。
- ストリーミング合成の最初の音声の時間と、ストリーミング音声認識の実際の確定遅延。 測定においてストリーミング経路を使用しなかった。
- 12Bモデルの16ビットの速度(37 tok/sは計算値)。 小さいモデルでは精度の効果が計算値よりも小さかった。
- 同時リクエストが16個を超える区間。 演算がボトルネックに変わるポイント(bf16は約130個、fp8は約64個)は計算値であり、測定していない。
- 入力処理における短い入力の固定コストの正体。 256トークンで速度が低下する理由(リクエスト処理、カーネルの起動など)を分解していない。
- 他の推論エンジンとの比較。 直接検証はvLLMという1つのエンジンで行い、上記の12Bの測定(llama.cpp)とエンジンを統一しなかった。
- モデル構造に関する説明は公式ドキュメントの記述に従っており、論文の原文までは読んでいない。
参考資料
- Nemotron Speech ASRのキャッシュを考慮したストリーミングの説明:https://huggingface.co/blog/nvidia/nemotron-speech-asr-scaling-voice-agents
- Nemotron 3.5 ASRモデルカード:https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
- VoxCPM:https://github.com/OpenBMB/VoxCPM
- Magpie TTSの説明:https://huggingface.co/blog/nvidia/magpie-tts-multilingual-voice-agents
- 本シリーズの第20篇(実測値)、第8篇(KVキャッシュサイズの計算)、第4篇(vLLMの内部)
確認したバージョンと日付
2026-10-06時点。llama.cpp b11429、Gemma 4 12B QAT q4_0、vLLM 0.31.0(Qwen3 0.6B・1.7B・4B-Instruct-2507 FP8で帯域幅・同時性・入力処理を検証)、VoxCPM2(voxcpm 2.0.3)、Nemotron 3.5 ASR Streaming 0.6B、NeMo 3.0.0。