問題の概要:ローカルLLMの推論速度が遅い、比較が難しい
ローカル環境で大規模言語モデル(LLM)を実行する際、多くの開発者が直面する課題の一つが「推論速度の評価」です。具体的には、以下のような問題が発生します。
- 「同じモデルでも、異なるツール(llama.cpp, Ollama, vLLMなど)で実行すると速度が大きく異なる。どれが最適か判断できない」
- 「モデルの量子化(4bit, 8bit)が速度にどのくらい影響するのか、定量的に比較したい」
- 「ハードウェア(CPU, GPU, RAM)のアップグレードが、実際にどれだけ推論速度を向上させるのか数値で知りたい」
- 「ベンチマークを取ろうとしたが、測定方法が統一されておらず、結果の再現性や公平な比較ができない」
これらの問題を解決するためには、標準化された方法で推論速度を測定・比較する「ベンチマーク」が不可欠です。本記事では、ローカルLLMの推論速度を正確に測定する方法と、そのための主要ツールを詳しく解説します。
原因の解説:なぜ推論速度の測定は難しいのか?
ローカルLLMの推論速度測定が複雑な理由は、主に以下の3点に集約されます。
1. 測定対象の多様性
推論速度は単一の数値では表せません。主要な指標としては以下のものがあり、それぞれ意味が異なります。
- トークン/秒(tokens/s): 1秒間に生成できるトークン数。生成速度の基本指標。
- Time to First Token(TTFT): プロンプト入力から最初のトークンが出力されるまでの時間。ユーザー体感の応答性に直結。
- レイテンシ: リクエストからレスポンス完了までの総時間。
- スループット: 同時複数リクエストを処理する場合の全体の処理能力。
用途によって重視する指標が異なるため、測定時には目的に合わせて指標を選択する必要があります。
2. 実行環境と設定の影響
推論速度はハードウェア(CPUコア数、GPU VRAM、メモリ帯域幅)だけでなく、ソフトウェア側の設定にも大きく依存します。
- コンテキスト長(context length)の設定
- バッチサイズ(batch size)
- 量子化ビット数(4bit, 8bit, 16bit)
- 推論エンジンの最適化レベル(例: llama.cppのBLAS設定)
これらの設定を統一しなければ、公平な比較はできません。
3. ワークロードの代表性
短いプロンプトでの測定結果と、長い文書を要約するような実際のワークロードでは、性能特性が全く異なる場合があります。現実的な使用シーンを反映したベンチマークプロンプトが必要です。
解決方法:標準的なベンチマーク実施手順
以下に、再現性と公平性を確保したベンチマーク測定のステップバイステップ手順を示します。
ステップ1: 測定環境の固定と記録
まず、比較の土台となる実行環境を明確に記録します。以下のコマンドでシステム情報を取得し、記録しておきましょう。
# CPU情報の確認 (Linux/macOS)
lscpu # Linux
sysctl -n machdep.cpu.brand_string # macOS
# GPU情報の確認 (NVIDIA)
nvidia-smi
# メモリ情報の確認
free -h # Linux
vm_stat # macOS
# Python環境の固定(推奨)
python -m pip freeze > requirements.txt
ステップ2: ベンチマークツールの選択とセットアップ
目的に応じて適切なツールを選択します。主要ツールは後述します。
ステップ3: 測定条件の設定
以下のパラメータを明確に設定し、すべての測定で統一します。
- 使用モデルとそのバージョン、ダウンロード元
- 量子化方式(例: GGUF Q4_K_M, AWQ 4bit)
- コンテキスト長(例: 4096トークン)
- 生成トークン数(例: 512トークン)
- プロンプトテンプレート(測定用の標準プロンプト)
ステップ4: ウォームアップ実行
初回実行はキャッシュやコンパイルの影響で遅くなるため、本測定前に数回ウォームアップ実行を行います。
ステップ5: 複数回測定と統計処理
単発の測定ではばらつきの影響が大きいため、少なくとも5〜10回は測定し、平均値と標準偏差を計算します。
ステップ6: 結果の記録と可視化
測定結果をスプレッドシートなどに記録し、必要に応じてグラフ化して比較します。
コード例・コマンド例:主要ベンチマークツールの実践的使用法
1. LM Evaluation Harness(EleutherAI)
学術研究でも広く使われる包括的な評価フレームワークです。推論速度だけでなく、モデル精度も評価できます。
# インストール
pip install lm-eval
# 基本的な実行例(GPT-2の評価)
lm_eval
--model hf
--model_args pretrained=gpt2
--tasks hellaswag
--device cuda:0
--batch_size 8
# カスタムタスクで推論速度を測定する例
# まず、シンプルな生成タスクを定義したJSONファイルを作成
# speed_benchmark.json
{
"task": "speed_benchmark",
"description": "推論速度測定用タスク",
"metrics": ["word_per_second"],
"examples": [{"input": "日本の首都は", "target": "東京です"}]
}
# カスタムタスクを指定して実行
lm_eval
--model hf
--model_args pretrained=elyza/ELYZA-japanese-Llama-2-7b
--tasks speed_benchmark
--num_fewshot 0
--limit 10 # 10サンプルで測定
出力例(エラーメッセージ):
CUDA out of memory. Tried to allocate 1.24 GiB...
# このエラーが発生した場合は、--batch_sizeを小さくするか、モデルを量子化する必要があります。
2. llama.cppの組み込みベンチマーク
llama.cppにはシンプルで高速なベンチマーク機能が組み込まれています。
# llama.cppのビルド(初回のみ)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make
# モデルのダウンロードとGGUF形式への変換(例: Llama 2 7B)
# 変換スクリプトの実行(Python環境が必要)
python convert.py ../models/ELYZA-japanese-Llama-2-7b/
# 量子化(4ビットへ)
./quantize ../models/ELYZA-japanese-Llama-2-7b/ggml-model-f16.gguf ../models/ELYZA-japanese-Llama-2-7b/ggml-model-q4_0.gguf q4_0
# ベンチマーク実行
./main -m ../models/ELYZA-japanese-Llama-2-7b/ggml-model-q4_0.gguf
-p "日本の首都は"
-n 512 # 生成トークン数
-t 8 # スレッド数
-ngl 999 # GPUレイヤー数(可能な限りGPUを使用)
--log-disable
# ベンチマーク専用コマンド(より詳細な測定)
./perplexity -m ../models/ELYZA-japanese-Llama-2-7b/ggml-model-q4_0.gguf
-f sample.txt # 評価用テキストファイル
-t 8
-ngl 999
出力例:
llama_print_timings: load time = XXXX ms
llama_print_timings: sample time = XXXX ms / 512 runs ( XX.XX ms per token, YYYY.YY tokens per second)
llama_print_timings: prompt eval time = XXXX ms / 14 tokens ( XXX.XX ms per token, ZZZ.ZZ tokens per second)
llama_print_timings: eval time = XXXX ms / 511 runs ( AA.AA ms per token, BBBB.BB tokens per second)
llama_print_timings: total time = XXXX ms
3. OpenCompassのベンチマーク機能
中国の上海人工知能研究所が開発した総合評価プラットフォームで、速度評価も可能です。
# インストール
git clone https://github.com/open-compass/opencompass.git
cd opencompass
pip install -e .
# 設定ファイルの作成(minimal_example.py)
from mmengine.config import read_base
with read_base():
from .datasets.collections.base_medium import datasets
from .models.hf_internlm.hf_internlm2_5_7b import models
# 実行
python run.py configs/minimal_example.py
4. 自作Pythonスクリプトによる測定
最も柔軟性が高く、特定のユースケースに特化した測定が可能です。
import time
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
# モデルとトークナイザーのロード
model_name = "elyza/ELYZA-japanese-Llama-2-7b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
# 測定用プロンプト
prompt = "日本の首都は"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
# ウォームアップ
_ = model.generate(**inputs, max_new_tokens=10)
# 本測定
num_runs = 5
generated_tokens = 100
times = []
for i in range(num_runs):
start_time = time.time()
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=generated_tokens,
do_sample=False
)
end_time = time.time()
elapsed = end_time - start_time
times.append(elapsed)
# トークン/秒の計算
tokens_per_second = generated_tokens / elapsed
print(f"実行 {i+1}: {elapsed:.2f}秒, {tokens_per_second:.2f}トークン/秒")
# 統計の計算
avg_time = sum(times) / len(times)
avg_tps = generated_tokens / avg_time
print(f"n平均: {avg_time:.2f}秒, {avg_tps:.2f}トークン/秒")
print(f"標準偏差: {torch.std(torch.tensor(times)):.2f}秒")
まとめ・補足情報
ローカルLLMの推論速度ベンチマークは、単に「速い・遅い」を比較するだけでなく、以下の点を考慮して実施することが重要です。
ベンチマーク実施のベストプラクティス
- 測定目的の明確化: インタラクティブなチャット(TTFT重視)か、バッチ処理(スループット重視)かで測定方法が異なります。
- 環境の完全な記録: 後で再現できるよう、OSバージョン、ドライバーバージョン、ライブラリバージョンまで詳細に記録します。
- 現実的なワークロードの模倣: 実際の使用シーンに近いプロンプト長、生成トークン数で測定します。
- 統計的有意性の確保: 十分な試行回数で測定し、ばらつきを考慮した評価を行います。
よくある落とし穴と対処法
エラー例1: 「VRAM不足でモデルがロードできない」
解決策: 量子化(4bitや8bit)を適用する、小さなモデルを使用する、CPUオフロードを検討する。
エラー例2: 「測定結果のばらつきが大きすぎる」
解決策: バックグラウンドプロセスを停止する、測定前にシステムを再起動する、より多くの試行回数で測定する。
エラー例3: 「異なるツール間で結果を比較できない」
解決策: 比較する場合は必ず同一ハードウェア、同一モデルファイル、同一プロンプトで測定する。
将来の展望
LLMの推論最適化は急速に進化している分野です。新しい推論エンジン(vLLM, TensorRT-LLM, SGLangなど)や、更に効率的な量子化手法(FP4, FP6)が登場しています。ベンチマークは一度実施して終わりではなく、定期的に見直し、最新の最適化技術を評価することが重要です。
最後に、ベンチマーク数値はあくまで一つの指標に過ぎません。実際のアプリケーションでのユーザー体験、モデルの出力品質、システム全体の安定性など、総合的な判断が求められることを忘れないでください。適切なベンチマークは、技術選定の重要な判断材料となりますが、唯一の基準ではないことを心に留めておきましょう。