大規模言語モデルを自分でホストして触ったことがあれば、生成が「1トークンずつ」しか進まないもどかしさを知っているはずだ。モデルがどれだけ賢くても、デコードは基本的に直列で、1回のフォワードパスで1トークンしか出てこない。GPUの演算能力は余っているのに、メモリ帯域とレイテンシで頭打ちになる。この「余った計算を使い切る」ための定番が投機的デコード(speculative decoding)で、8月3日にarXivへ出た PCTree は、その効率をもう一段引き上げる小さいが効く工夫だ。しかも既存の下書きモデルを再学習しない。
🌳 投機的デコードと、DeepSeekのDSparkがやったこと
投機的デコードの発想は単純だ。小さくて速い「下書き(draft)」モデルに次の数トークンをまとめて予測させ、本命の大きなモデルには「その予測で合っているか」を1回のフォワードパスでまとめて検証させる。当たっていたトークンはそのまま採用し、外れたところで打ち切る。検証は本命モデルが実際に出すトークンとの一致だけを採用するので、出力は本命モデル単体で生成したものと変わらない。速くなるが結果は劣化しない、というのがこの手法の肝だ。
問題は「下書きをどう速く・正確に作るか」にある。EAGLEなど従来の下書きは自己回帰的、つまり下書き自身も1トークンずつ生成するため、ブロックを長くするほど下書きの生成コストが積み上がる。ここに一石を投じたのが、DeepSeekが7月に公開した DSpark だ。DSparkは「セミ自己回帰」と呼ばれる作りで、並列バックボーンがブロック内の全位置(アンカートークンと B−1 個のマスク)を1回のフォワードパスでまとめて提案し、そのあと軽量な「Markovヘッド」が各位置を1つ前のトークンに条件づけて微修正する。ブロック丸ごとをほぼ1パスで下書きできるうえ、Markovヘッドがトークン間の依存を補うので精度も保てる。DeepSeekは自社のV4サービング基盤にこれを組み込み、スループットを保ったままユーザー体感の生成速度を60〜85%改善したと報告している(DeepSeekの解説)。
直線の下書きは、最初の1つを外すと全部無駄になる
PCTreeが目をつけたのは、DSparkのMarkovヘッドが下書きを「1本の鎖」として貪欲に選んでいる点だ。z_d = L_d + Markov(y_{d-1}) のように、各位置は直前のトークン1つだけに条件づけて最も確率の高い候補を選ぶ。結果は直線的なチェーンになる。
この直線構造は、早い位置で1トークン外すと、それ以降の下書きが全部無効になる弱点を抱えている。ブロック長 B を7から16へ伸ばしても期待したほど採用トークンが増えないのはこのためだ。長くするほど「途中で1回外して残りが丸ごと捨てられる」確率が上がる。
PCTree(Parent-Conditioned Drafting Tree)の答えは、この鎖を木に変えることだ。うまいのは、分岐に必要な材料がすでにDSparkの中にある点にある。Markovヘッドは「親トークン1つを与えれば子の分布を出す」関数なので、同じ位置に対して複数の親候補それぞれで別々に子をスコアリングできる。PCTreeは親 p ごとに z_d(p) = L_d + Markov(p) を計算し(全フロンティアの親を1回のMarkov呼び出しでまとめて処理する)、親ごとにローカル top-k の子を取り、経路全体の対数確率の和 s(c) = Σ log π(v|u) で候補を並べる。各段で top-k 枝刈りし、最後にグローバルな top-N 選択で「検証予算に収まる木」に絞り込む。この木を本命モデルの1回のフォワードパスでまとめて検証する。
重要なのは、これがすべて推論時のみの変更で完結することだ。バックボーンの追加パスもなければ、再学習も要らない。DSparkが元々持っていた「1つの親から子分布を出す」条件付けの力を、直線ではなく分岐に使い回しているだけである。
📊 数字で見る効き方
論文の Table 2/3 から、Qwen3系(4B/8B/14B)での代表値を抜き出すと次のようになる。いずれもDSparkとの比較で、B はブロック長。
| 指標 / ベンチ | DSpark | PCTree |
|---|---|---|
| 平均採用長 τ・GSM8K (B=7) | 6.31 | 7.24 (+14.8%) |
| 平均採用長 τ・HumanEval (B=7) | 5.60 | 6.78 (+21.2%) |
| 平均採用長 τ・MT-Bench (B=7) | 3.82 | 5.07 (+32.5%) |
| 対自己回帰の高速化・GSM8K (B=16) | 6.14× | 6.60× (+7.5%) |
| 対自己回帰の高速化・MT-Bench (B=7) | 2.48× | 3.20× (+29.3%) |
「平均採用長(τ)」は1ステップあたり本命モデルに受理されたトークン数で、大きいほど1回の検証で稼げる。B=7 での高速化の上乗せは3.1〜29.5%、ブロックを長くした B=16 では採用長の増加が18.6〜28.8%に達する。直感に反して長いブロックほど木構造の効果が大きいのは、枝分かれの余地が増えるからだ。直線では長さが仇になる場面が、木では武器に変わる。
比較対象として論文は EAGLE-3 の公表値(GSM8K で τ は EAGLE-3 が5.14、DSparkが6.31、PCTreeが7.24)も併記しているが、これは同一環境での厳密な比較ではないと明記しており、額面通りの優劣として読むべきではない。
現場から見た評価と、触り方
個人的にこの手の「推論時のみ・再学習なし」の改善は、コスパの観点で真っ先に試したい類のものだ。下書きモデルの学習は追加のGPU時間と運用を要するが、PCTreeは既存のDSpark下書きに対する検証段のロジック変更で乗る。検証予算(top-N の木のサイズ)というチューニング可能なノブが1つ増えるだけで、当たれば数%〜30%が上積みされる。
冷静に見るべき点もある。PCTree自体のコードは現時点で公開されておらず(論文はDSparkの下書きチェックポイントがHuggingFaceにある旨に触れるのみ)、追試のハードルは低くない。評価も Qwen3 の貪欲デコード前提で、温度サンプリングや他モデル族での挙動は別途確認が要る。上乗せ幅もベンチ依存で、コード生成やチャットのように分岐の恵みが大きいタスクと、そうでないタスクの差は大きい。
「まず投機的デコード自体を試したい」なら、土台のDSparkはすでに手を動かせる。NVIDIAの NeMo AutoModel にDSpark下書きを学習するレシピ があり、Qwen3(dense/MoE)と Gemma4 をターゲットにできる。
torchrun --standalone --nproc_per_node=2 \
-m nemo_automodel.recipes.llm.train_dspark \
-c examples/speculative/dspark/qwen3_0.6b_dspark.yaml
推論エンジン側でも、llama.cpp に DSpark 対応を入れる PR が出ている。PCTreeはこうした土台の「検証をどう組むか」に効く改良であり、投機的デコードを本気で詰めるフェーズに入ったチームには、検証予算の設計という新しい軸を示している点で読む価値がある。