こんにちは!zhackです。
先日、ローカルLLMの入門記事を書いたときに「GPUがあると毎秒30〜60トークンくらい出る」という数字を載せました。
調べて出てきた数字を、そのまま書きました。
そのあと実際に自分のPCで測ってみたのですが、87トークン/秒でした。
倍近く違います。
さらに設定を1つ変えたら40トークン/秒まで落ちました。同じモデル、同じ質問です。
つまりあの数字は、間違ってはいないけれど条件を書かないと意味がないものでした。
そこで今回は、自分の環境で測る方法をまとめます。
私が実際に測って、途中で何度かやり方を間違えた話も含みます。ご参考までに、、、
何を測るのか
ローカルLLMで見ておくと役に立つ数字は、だいたいこの3つです。
| 数字 | 意味 | どう効くか |
|---|---|---|
| 生成速度(tokens/秒) | 1秒あたり何トークン作れるか | 体感速度そのもの |
| VRAM使用量 | GPUのメモリをどれだけ使ったか | 大きいモデルが載るかどうか |
| GPU/CPUの分担 | 処理の何%をGPUがやったか | ここが崩れると一気に遅くなる |
3つ目が意外と大事です。モデルがGPUに載りきらないと、はみ出した分はCPUが処理します。そうなると速度が数分の1になります。
いちばん簡単な方法:--verbose を付ける
Ollamaには最初から計測機能が付いています。
ollama run qwen3.5:4b-q4_K_M --verbose "日本語で自己紹介してください"
回答のあとに、こんな数字が出ます。
total duration: 19.2378544s
load duration: 4.3280787s
prompt eval count: 15 token(s)
prompt eval rate: 131.63 tokens/s
eval count: 1641 token(s)
eval rate: 110.96 tokens/s
見るべきは eval rate です。これが生成速度で、この例だと毎秒110.96トークン。
load duration はモデルをディスクから読み込む時間で、2回目以降は0に近くなります(一度読み込むと5分間はメモリに残るため)。
VRAMは別のウィンドウで見る
生成中に、もう一つターミナルを開いてこれを打ちます。
ollama ps
nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv
ollama ps の出力がこれです。
NAME ID SIZE PROCESSOR CONTEXT
qwen3.5:4b-q4_K_M 2a654d98e6fb 3.2 GB 100% GPU 4096
PROCESSOR の欄が肝心です。100% GPU なら全部GPUに載っています。載りきらないと 47%/53% CPU/GPU のように表示が変わります。
なお生成が終わったあと5分間はモデルがメモリに残るので、慌てて打たなくても大丈夫でした。
ここで一度、つまずきました
上の方法で測った出力をログに残そうとしたら、こうなりました。
Qwen3[?25l[?25h.[?25l[?25hx [?25l[?25hor [?25l[?25hsimilar
制御文字だらけで読めません。
[?25l はカーソルを隠す指示で、文字を1つ出すたびに入っています。画面で見るぶんには問題ないのですが、ファイルに保存すると使い物になりません。
しばらく sed で消そうとしていたのですが、これは筋が悪い直し方でした。
正解:APIを直接叩く
Ollamaは裏でWebサーバーとして動いていて、localhost:11434 でリクエストを受け付けます。そちらを使えば、最初からきれいなJSONで返ってきます。
curl -X POST http://localhost:11434/api/generate -H "Content-Type: application/json" -d "{\"model\":\"qwen3.5:4b-q4_K_M\",\"prompt\":\"こんにちは\",\"stream\":false}"
返ってくるJSONにこういう項目が入っています。
| 項目 | 中身 |
|---|---|
response |
回答の本文 |
eval_count |
生成したトークン数 |
eval_duration |
生成にかかった時間(ナノ秒) |
done_reason |
なぜ終わったか(stop=正常、length=打ち切り) |
生成速度は eval_count ÷ (eval_duration ÷ 10億) で出せます。
--verbose と同じ数字ですが、こちらは機械が読める形なので、何回も測って比べるときに圧倒的に楽です。
そして done_reason が見られるのが大きいです。これが length だと、答えが途中で打ち切られています。画面を眺めているだけだと気づけません。
WSLを使っている場合
私はWindows上のWSLで開発しているのですが、WSLの中から curl http://localhost:11434 を叩いても届きませんでした。
WSLはWindowsとは別のOSとして動いているので、Windows側のlocalhostが見えないためです。
解決策は、Windows側の実行ファイルを直接呼ぶことでした。
/mnt/c/Windows/System32/curl.exe -X POST http://localhost:11434/api/generate ...
.exe を指定するとWindowsのプロセスとして起動するので、Windows側のlocalhostに届きます。ollama.exe も同じやり方で呼べました。
このあたりの詳しい経緯は別記事に書いています。→ WindowsでOllamaの環境構築!ローカルLLMに「回答はどれ?」と聞く羽目になった話
比べるときは、条件を揃える
ここが一番大事でした。最初は適当に測っていて、数字がばらついて何も言えない状態になりました。
揃えるべきものは3つです。
1. 前のモデルを降ろす
ollama stop 前のモデル名
モデルは載せっぱなしだとメモリに残り続けます。2つ載った状態で測ると、VRAMを食い合って「載りきらない」判定がおかしくなります。
2. 生成するトークン数を固定する
APIのリクエストに "options": {"num_predict": 300} を付けます。生成量が違うと、所要時間を比べても意味がありません。
3. コンテキスト長を固定する
同じく "num_ctx": 4096 のように指定します。これを揃えないと比較が壊れます。 理由は次で書きます。
測って分かったこと
条件を揃えて測り直したら、想像していなかったことが3つ分かりました。
① コンテキスト長を広げると、速度が半分になった
llama3.1:8b(ファイルサイズ4.9GB)で、コンテキスト長だけを変えた結果です。
| コンテキスト長 | 処理の分担 | 生成速度 |
|---|---|---|
| 4,096(初期設定) | 100% GPU | 87.30 トークン/秒 |
| 16,384 | 13%がCPUに流出 | 40.63 トークン/秒 |
コンテキストを広げると、その分の作業メモリ(KVキャッシュ)もVRAMを使います。4.9GBのモデルはVRAM 8GBに余裕で収まるはずなのに、設定次第で収まらなくなりました。
冒頭に書いた「87と40」はこれです。どちらも本当の数字でした。
② VRAM 8GBは、8GB使えなかった
何もしていない状態でも、デスクトップの表示だけで約0.7GB使われていました。実際に推論に回せたのは約7.4GBです。
nvidia-smi をアイドル状態で1回打っておくと、この差が分かります。
③ 量子化を上げても、正答率は変わらなかった
qwen3.5:9b の量子化違い(Q4_K_MとQ8_0)で、答えが一つに決まる問題を5種類×3回ずつ投げました。
| Q4_K_M(6.6GB) | Q8_0(10GB) | |
|---|---|---|
| 正答数 | 12/15 | 12/15 |
| 生成速度 | 56.8 トークン/秒 | 6.2 トークン/秒 |
正答率は同じで、速度は9倍違いました。
VRAM 8GBに10GBのモデルは載らないので、Q8_0は半分近くをCPUが処理していました。「メモリに余裕があれば高精度のほうがいい」とよく言われますが、余裕がなければ逆効果です。
さいごに
以上が、ローカルLLMの速度を自分で測る方法でした。
まとめるとこうなります。
- 手軽に見たいなら
ollama run --verboseのeval rate - 記録して比べるなら APIを叩いてJSONで受け取る(
done_reasonも見られる) - 比べるときは モデルを降ろす・生成量を固定・コンテキスト長を固定
- WSLからは
.exeを直接呼ぶ
そして一番言いたいのは、公開されている数字は自分の環境では当てにならないことがある、ということです。
私は自分で書いた記事の数字を、あとから自分で測り直して驚きました。設定ひとつで倍以上変わるものを、条件抜きで書いていたわけです。
ローカルLLMは自分のPCで動くので、気になったらその場で測れるのが良いところだと思います。5分あれば終わります。
ではでは!
参考文献
関連記事



コメント