RTX 3060 Ti(VRAM 8GB)のPCで、35B の MoE モデル Qwen3.6-35B-A3B を動かしています。
LM Studio で使っていて「遅いな」と思っていたのですが、まったく同じ GGUF ファイルを Ollama に読み込ませたら、生成速度が 6.2 tok/s → 19.1 tok/s になりました。
この記事では、計測の条件と結果、それから LM Studio 側で設定を変えて試したこと(どれもほぼ効かなかったこと)をまとめます。
LM Studio で使っていて不満だったのは2つです。応答が遅いことと、Ctrl+Enter を押して進める場面が多すぎることでした。
結論
| 実行環境 | コンテキスト長 | 生成速度(3回・平均/最小〜最大) | GPU全体のVRAM使用量 |
|---|---|---|---|
| LM Studio 0.4.25 | 32768 | 6.15 tok/s(5.75〜6.38) | 約3.8GB |
| Ollama 0.34.3 | 32768 | 19.07 tok/s(18.96〜19.21) | 約7.4GB |
- 同じファイル・同じコンテキスト長・同じリクエストで 約3.1倍 の差(LM Studio は既定の設定のまま)
- LM Studio は VRAM を半分ほどしか使っていない。Ollama はほぼ使い切っている(
ollama psの表示は73%/27% CPU/GPU) - LM Studio 側で「エキスパート層を GPU に載せる」「CPU スレッドを増やす」「並列数を1にする」を試したが、どれも 4.5〜6 tok/s の範囲から抜け出せなかった
差が出た原因は特定できていません。分かっているのは「下の条件で測るとこの差になった」という事実までです。
環境
| 項目 | 内容 |
|---|---|
| GPU | NVIDIA GeForce RTX 3060 Ti(VRAM 8GB)・ドライバ 610.62 |
| CPU | AMD Ryzen 5 4500(6コア12スレッド) |
| RAM | 64GB |
| OS | Windows 11 Home |
| LM Studio | 0.4.25(バックエンド: llama.cpp CUDA12 2.61.0) |
| Ollama | 0.34.3 |
| モデル | unsloth/Qwen3.6-35B-A3B-GGUF の Qwen3.6-35B-A3B-UD-Q4_K_M.gguf(22.1GB) |
計測方法
比べる条件がずれないように、両方とも同じやり方で測りました。
-
同じ API: どちらも OpenAI 互換の
/v1/chat/completionsに、ストリーミングで同じmessagesを送る(どちらもモデル内蔵のチャットテンプレートを通る) - 同じ時計: tok/s はツールの自己申告値を使わず、最初のトークンが届いてから最後のトークンまでの時間で計算
- プロンプト: 「TypeScriptで、配列を指定サイズのチャンクに分割する関数 chunk を実装し、使い方の例とテストケースを3つ書いてください。」
- 生成は最大512トークン、temperature 0.2
- thinking はどちらも既定のまま。今回はどちらも 512トークンすべてを thinking に使っていたので、生成した中身の条件も揃っている
- 各4回実行して、1回目はウォームアップとして捨てる(Ollama の1回目はモデル読み込みを含む)
- VRAM は計測直後に
nvidia-smiで取得(GPU 全体の値なので、デスクトップの描画などの分も含む) - 計測中はゲームなど重いアプリを閉じる(理由は後述)
Ollama に同じ GGUF を読ませる Modelfile はこれだけです。
FROM C:\Users\<ユーザー名>\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-GGUF\Qwen3.6-35B-A3B-UD-Q4_K_M.gguf
PARAMETER num_ctx 32768
ollama create bench-same-gguf -f Modelfile
計測の中心部分です。LM Studio(http://127.0.0.1:1234)と Ollama(http://127.0.0.1:11434)に、同じ関数で投げています。
def stream(base, model):
body = {"model": model, "messages": [{"role": "user", "content": PROMPT}],
"max_tokens": 512, "temperature": 0.2, "stream": True,
"stream_options": {"include_usage": True}}
first = last = None
for d in sse(base + "/v1/chat/completions", body): # SSE を1行ずつ読む
if d.get("usage"):
usage = d["usage"]
for c in d.get("choices", []):
delta = c.get("delta", {})
if delta.get("content") or delta.get("reasoning_content") or delta.get("reasoning"):
now = time.time()
first = first or now
last = now
n = usage["completion_tokens"]
return (n - 1) / (last - first) # 生成フェーズだけの tok/s
結果1: LM Studio で設定を変えてみた
LM Studio のモデルごとの設定ファイル(~/.lmstudio/.internal/user-concrete-model-default-config/...)を見ると、こうなっていました。
{ "key": "llm.load.llama.acceleration.offloadRatio", "value": 1 },
{ "key": "llm.load.numCpuExpertLayersRatio", "value": 1 },
{ "key": "llm.load.llama.cpuThreadPoolSize", "value": 6 }
通常の層は全部 GPU、MoE のエキスパート層は全部 CPU、CPU スレッドは6本、という設定です。
「エキスパートを GPU に寄せれば速くなるのでは」と思って試しました。
| 設定 | 生成速度(3回平均) | GPU全体のVRAM |
|---|---|---|
| エキスパート全部CPU・6スレッド(元の設定) | 5.31 tok/s | 約3.8GB |
| エキスパート全部CPU・12スレッド | 5.47 tok/s | 約3.8GB |
| エキスパート半分GPU・6スレッド | 4.54 tok/s | 約7.6GB |
| エキスパート7割CPU・12スレッド | 4.89 tok/s | 約7.6GB |
元の設定+並列数1(lms load --parallel 1) |
5.82 tok/s | 約3.7GB |
※この表だけは、上の公平版より前に、各ツールが返す tok/s(LM Studio の stats.tokens_per_second)で測った値です。設定どうしの比較に使ってください。
分かったこと:
- スレッドを6→12にしても誤差。Ryzen 5 4500 は物理6コアなので、そこで頭打ちになっているのだと思います
- エキスパートを GPU に載せると、VRAM は埋まるのに遅くなった。ただし VRAM が約7.6GB、つまり8GBの上限にほぼ張り付いています。Windows は VRAM があふれると、はみ出した分を共有GPUメモリ(システムRAM)に逃がすので、「GPU に載せたから遅い」ではなく「VRAM があふれて遅くなった」可能性があります
-
lms psで並列数が4になっていたので1にしてみたが、ほぼ変わらず
結果2: 同じGGUFをOllamaで
| 実行 | 生成速度 | 最初のトークンまで |
|---|---|---|
| 2回目 | 19.04 tok/s | 0.28秒 |
| 3回目 | 18.96 tok/s | 0.24秒 |
| 4回目 | 19.21 tok/s | 0.26秒 |
| 平均 | 19.07 tok/s |
ollama ps の表示はこうでした。
NAME SIZE PROCESSOR CONTEXT
bench-same-gguf:latest 23 GB 73%/27% CPU/GPU 32768
23GB のうち27%(約6GB)を GPU に載せています。LM Studio の既定の設定(GPU 全体で約3.8GB)より、GPU に載っている量が明らかに多いです。
正直に書くと、19 tok/s になっても Claude Code と比べるとまだ遅く、微妙です。速さだけで選ぶなら、クラウドのほうが上でした。
計測で気づいたこと: ほかのアプリを開いたままだと数字が崩れる
最初に LM Studio を測ったとき、元の設定で1回目だけ 4.9 tok/s、2回目以降は 約2.1 tok/s まで落ちました。時間をおいて測り直したら 5.3 tok/s です。
最初の計測のときは、ゲームのクライアントなどほかのアプリが立ち上がっていました。VRAM の使用量も、あとの計測より約400MB多くなっています。CPU だけでなく GPU もほかのアプリと取り合っていたのだと思います。計測するときは、重いアプリを閉じてからにしたほうが正確です。
分かっていないこと
- なぜ LM Studio と Ollama でここまで差が出るのかは特定できていません。どちらも中身は llama.cpp 系ですが、バージョンや既定のオプション(Flash Attention、KV キャッシュの型、エキスパートの置き方、バッチサイズなど)が違う可能性があります
- LM Studio の GUI にある設定をすべて試したわけではありません。もっと良い設定があるかもしれません
- 計測は1台・1つのプロンプトだけです
llama.cpp を直接 --n-cpu-moe を指定して動かせば、どこで差が出ているか切り分けられそうなので、次に試すつもりです。原因を知っている方がいたら、コメントで教えてもらえるとうれしいです。
まとめ
- VRAM 8GB でも、35B の MoE は Ollama なら 19 tok/s で動いた
- 同じ GGUF・同じ条件でも、実行環境が違うだけで約3.1倍の差が出た
- LM Studio でエキスパートを GPU に載せても、スレッドを増やしても、並列数を減らしても速くならなかった
- ローカルLLMが遅いと感じたら、モデルを小さくする前に、実行環境を変えて測ってみる価値がある
速さではクラウドにかなわないので、これからはクラウドに出したくない情報や、プライベートな内容を扱うときにローカルLLMを使っていくつもりです。そのときに 6 tok/s と 19 tok/s では待ち時間がまるで違うので、実行環境は測ってから選ぶのがおすすめです。