「LLMの推論速度、もう少し速くならないかな…」
LLMの開発やサービス提供において、推論速度は常に気になるポイントですよね。
今回は、そんな課題を解決する選択肢の一つとして注目されている「投機的デコード」について、NVIDIAのTensorRT Model Optimizerを使って簡単に試す方法をまとめてみました。
TensorRT Model Optimizerって、どんなツール?
TensorRT Model Optimizerは、NVIDIAが提供するAIモデル最適化のためのライブラリです。
量子化や枝刈りといった、モデルをより速く、より効率的に動かすための様々な機能が提供されています。そして名前の通り、TensorRT(NVIDIAが開発したAI向けの最適化ツール)で扱いやすい形にモデルを整えてくれます。
公式サイト
高速化のキーポイント、「投機的デコード」とは?
「投機的デコード」は、LLMの応答速度を上げるための一つのテクニックです。
まず、軽量な「ドラフトモデル」がトークンをいくつか先読みして生成します。その後ろから、賢くて精度の高い「ターゲットモデル」が予測が合っているかどうか答え合わせをしながらついていきます。
もし予測が間違っていたら、その地点でターゲットモデルが修正してくれるので、モデル本来の精度を保ったまま高速化が期待できます。
この仕組みは、Google Researchのブログにある動画がとてもわかりやすいです。
(ページの下の方に動画があります)
参考:Looking back at speculative decoding
出典:Looking back at speculative decoding
TensorRT Model Optimizerで選べる2つのアプローチ
TensorRT Model Optimizerでは、現在2つの投機的デコード手法がサポートされています。
1. Medusa
Medusaは、ベースモデルの最後に小さな予測ヘッド(MLPヘッド)を複数追加して、未来のトークンを並行して予測する手法です。
- ベースモデルの構造はそのままに、少しのパラメータを追加するだけ
- ドラフトモデルを別で用意しなくてよい
2. EAGLE
EAGLEは、ベースモデルの中間層から得られる特徴量(隠れ状態)を使い、軽量なTransformerデコーダが次のトークン列を予測する手法です。
- モデルの内部情報(特徴量)を使うため、より精度の高い予測が期待できる
- ドラフトモデルは軽量なTransformerブロック
やってみよう!TensorRT Model Optimizerで投機的デコード
では、実際にTensorRT Model Optimizerで投機的デコードを使ってみましょう。
今回は、より精度が期待できるEAGLEをTinyLlama-1.1Bに適用する手順を見ていきます。
※実行にはTensorRT Model OptimizerやTensorRT-LLMの環境構築が必要ですが、今回の記事では割愛します。
1. EAGLEモジュールの付与と学習
まず、ベースとなるモデルにEAGLEモジュールを追加します。
from copy import deepcopy
from transformers import AutoModelForCausalLM, AutoTokenizer
import modelopt.torch.speculative as mtsp
# ベースモデルを読み込み
model = AutoModelForCausalLM.from_pretrained(model_name, dtype=torch.bfloat16, device_map="cuda")
# EAGLEモジュールの設定をモデルに合わせて更新
eagle_config = deepcopy(mtsp.EAGLE1_DEFAULT_CFG)
eagle_config["config"]["eagle_architecture_config"].update({
"hidden_size": model.config.hidden_size,
"vocab_size": model.config.vocab_size,
# ... その他モデルに合わせた設定
})
model = mtsp.convert(model, [("eagle", eagle_config["config"])])
次に、追加したEAGLE部分を学習させます。(今回は学習済みのEAGLEヘッドがなかったので、自分で学習させてみました)
学習するのはEAGLE部分だけなので、Hugging FaceのTrainerをそのまま活用できます。
import modelopt.torch.opt as mto
from transformers import Trainer, TrainingArguments
# EAGLEモジュールのみを学習対象に
for name, param in model.named_parameters():
if "eagle" not in name:
param.requires_grad = False
mto.enable_huggingface_checkpointing()
# 学習の実行
training_args = TrainingArguments(
output_dir="eagle_tinyllama_v2",
num_train_epochs=3,
# ... その他学習パラメータ
)
trainer = Trainer(model=model, args=training_args, train_dataset=dataset)
trainer.train()
trainer.save_model("eagle_tinyllama_v2")
学習データには、ultrachat_200kの10,000サンプルを使用しています。
2. TensorRT-LLMエンジンのビルド
学習したモデルを、TensorRT-LLMで動く「エンジン」形式に変換します。
EAGLEを使ったモデルの場合、 --speculative_decoding_mode eagle というオプションを指定するのがポイントです。
# チェックポイントへの変換
python3 -m tensorrt_llm.commands.convert_checkpoint \
--model_dir eagle_tinyllama_v2_hf \
--output_dir trtllm_eagle_ckpt \
--dtype float16 \
--speculative_decoding_mode eagle
# エンジンのビルド
trtllm-build \
--checkpoint_dir trtllm_eagle_ckpt \
--output_dir trtllm_eagle_engine \
--gemm_plugin float16 \
--max_batch_size 1 \
--speculative_decoding_mode eagle \
--max_draft_len 63
3. 推論
推論は、TensorRT-LLMを使って行います。DecodingConfig に EagleConfig を渡す必要があるので注意です。
import tensorrt_llm.bindings.executor as tllm
# EAGLE用の設定を追加
eagle_config = tllm.EagleConfig(use_dynamic_tree=True, dynamic_tree_max_topK=10)
decoding_config = tllm.DecodingConfig(
decoding_mode=tllm.DecodingMode.Eagle(),
eagle_config=eagle_config,
)
executor_config = tllm.ExecutorConfig(max_beam_width=1, decoding_config=decoding_config)
# エンジンを読み込んで推論を実行
executor = tllm.Executor("trtllm_eagle_engine", tllm.ModelType.DECODER_ONLY, executor_config)
request = tllm.Request(input_ids, max_tokens=100, end_id=eos_id, pad_id=eos_id)
request_id = executor.enqueue_request(request)
responses = executor.await_responses(request_id)
結果:速度はどれくらい変わった?
さて、気になる結果です。EAGLEを使った場合と使わなかった場合で、トークン生成の速度を比べてみました。
- 使用GPU: NVIDIA GeForce RTX 4050 Laptop GPU (6GB)
- プロンプト: "Sea otters is" (ラッコは…)
トークン生成速度[token/s]:
| 投機的デコードなし | 投機的デコードあり | 倍率 |
|---|---|---|
| 87.7 | 107.0 | 1.22x |
他のプロンプトでも試したところ、約1.2~1.4倍の高速化を確認できました。
ただし、生成する文章が非常に短い場合など、シナリオによってはドラフト生成のオーバーヘッドで逆に遅くなるケースもありました。ある程度まとまった文章を生成する際に、特に効果を発揮する手法と言えそうです。
ちなみに生成された文章は下記でした。いい感じですね。
Sea otters is a fascinating and unique species that has adapted to
life in the Pacific Northwest. They are known for their unique fur,
which is a combination of brown and white, and their ability to live
in the water for extended periods.
日本語訳
ラッコは、太平洋岸北西部の環境に適応した、魅力的でユニークな種です。
茶色と白が混ざり合った独特の毛皮と、長時間水中で生活できる能力で知られています。
最後に
いかがでしたでしょうか。
今回は、TensorRT Model Optimizerを使って投機的デコード(EAGLE)による推論の高速化を試してみました。
LLMの推論高速化には様々なアプローチがありますが、投機的デコードは非常に強力な選択肢の一つだと思います。
皆さんも、ぜひお手元のモデルで試してみてはいかがでしょうか。この記事が、参考になれば幸いです。

