12GB VRAM で Qwen3.6-35B-A3B を高速に動かす
MOE の活用により、GPUメモリに乗り切らなくても、そこそこ高速に動くようになってきた、、、という記事を読んだので試してみました。
きっかけ
Reddit のこの投稿です。
ちょうど私の保有しているGPUが NVIDIA GeForce RTX 3060 なので、バッチリです。
早速試すことにしました。
何がすごい?
- Qwen3.6-35B-A3B は MoE なので、推論時に動くのは約3B相当
- ただし重み全体は35Bぶん存在するので、全部をVRAMに置くには12GBでは足りない
- 使っている GGUF は
IQ4_XS-4.19bpwで、モデルサイズは約18.6GB - 実際には VRAM 約11GB + RAM 約10GB のハイブリッド実行
- 18層を完全にVRAM、23層をVRAM/RAMハイブリッドにしている
- ik_llama.cpp は CPU/GPUハイブリッド、MoE、量子化カーネル、CPU側処理が強い
- MTP により、1回の forward で複数トークン候補を進められるため、生成速度が上がる
- GUIにGPUを使わせないことで、12GB VRAMのほぼ全量をLLMに渡している
MoE(Mixture of Experts)とは?
通常の(密な)LLM は、1トークンを生成するたびにモデルの全パラメータを使って計算します。これに対して MoE は、モデル内部を多数の「エキスパート」と呼ばれる小さなサブネットワークに分割し、入力トークンごとに「ルーター」がそのうちの一部だけを選んで動かす仕組みです。
MTP(Multi-Token Prediction)とは?
LLM の推論は本来、1回の forward 計算で1トークンずつ、自己回帰的に生成します。そして LLM 推論の速度は、計算能力よりもメモリ帯域で頭打ちになりがちです。巨大な重みを VRAM から演算ユニットへ運ぶ時間が支配的で、たった1トークンを生むためにモデル全体を読み出す、という非効率が起きるためです。
MTP は、この1回の forward で複数トークンの候補をまとめて予測してしまう手法です。予測した先読み(ドラフト)トークンを本体モデルが検証し、当たっていれば一気に採用、外れた分だけやり直す。これは投機的デコーディング(speculative decoding)の一種で、MTP の場合は別の小さなドラフトモデルを用意するのではなく、モデル自身にこの先読み機構が組み込まれているのが特徴です。
セットアップ
基本的にはRedditの手順そのままなので、細かいセットアップ手順は割愛しますが、いくつか重要なポイントがあります。
GPUメモリを限界までLLMに使う
12GB VRAMでは余裕がありません(むしろ本来は足りません)。
デスクトップレンダリングやブラウザ、VSCodeなどがGPUメモリを消費していると、モデルに割り当てられるVRAMが目減りします。
そのため、可能であれば画面出力を内蔵GPU側に逃がし、RTX側のVRAMをできるだけLLM専用に近い状態にします。
ただし、VRAMを完全に使い切るのではなく、--fit-margin のような余白も必要です。ギリギリまで詰めすぎると、起動できても長いコンテキストや実行中の負荷でOOMしやすくなります。
ik_llama.cpp をコンパイルする
今回、通常の llama.cpp ではなく ik_llama.cpp を使う理由は、Qwen3.6-35B-A3B のようなMoEモデルを、12GB VRAMのGPU/CPUハイブリッド構成で効率よく動かすためです。
35B級の重みをすべてVRAMに置くことはできないため、一部をGPUに、一部をCPU/RAM側に配置します。ik_llama.cpp は、このようなハイブリッド推論、MoE expert のoffload、tensor単位の配置制御、MTP利用に向いた実装が進んでいます。
なお、Redditの構成では、どのレイヤーをCPU/GPUへ置くかを細かく手動固定するのではなく、--fit と --fit-margin によって、起動時に利用可能なVRAMへ収まるよう自動調整する形です。推論中に毎回配置が変わるわけではなく、起動時に決まった配置で実行されます。
つまり今回のポイントは、単に「35Bモデルを動かす」ことではなく、MoE、量子化、GPU/CPUハイブリッド、MTPを組み合わせて、12GB VRAMでも実用的な速度を狙うことです
起動コマンド
当面の動作確認は Cli coding Agent の pi でやることにしたので、
下記で起動します。
$ ./build/bin/llama-server \
-m ~/models/qwen36/Qwen3.6-35B-A3B-IQ4_XS-4.19bpw.gguf \
--jinja \
--fit \
--fit-margin 1664 \
--ctx-size 131072 \
--cache-type-k q8_0 \
--cache-type-v q8_0 \
--cache-type-k-draft q8_0 \
--cache-type-v-draft q8_0 \
--multi-token-prediction \
--draft-p-min 0.75 \
--draft-max 3 \
--no-mmap \
--mlock \
--threads 8 \
--temp 0.0 \
--host _WG_IP_ \
--port 8080
動作環境
| 項目 | 内容 |
|---|---|
| マシン | Thirdwave MagnateIM |
| OS | Ubuntu 24.04.4 LTS |
| Kernel | Linux 6.17.0-29-generic |
| CPU | Intel Core i5-12400 |
| CPU構成 | 6コア / 12スレッド |
| メモリ | DDR5 32GB、16GB × 2 |
| メモリ実動作 | 4800 MT/s |
| GPU | NVIDIA GeForce RTX 3060 |
| VRAM | 12GB、12288 MiB |
| NVIDIA Driver | 580.159.03 |
| CUDA Driver表示 | 13.0 |
| CUDA Toolkit | 12.0 / nvcc V12.0.140 |
| ストレージ | NVMe 1TB |
| LLM実行基盤 | ik_llama.cpp |
| ik_llama.cpp commit | b3d39cff8bffbd67296d6badd4076a1486a0715c |
| ik_llama.cpp version | 4533 |
| モデル | Qwen3.6-35B-A3B-IQ4_XS-4.19bpw.gguf |
| モデルサイズ | 約18GB |
| context | 131072 |
| KV cache | q8_0 |
| MTP | 有効 |
| draft-max | 3 |
| GPU使用VRAM | 約11102MiB |
| 長めベンチ生成 | 512 tokens |
| prompt速度 | 約245.5 tok/s |
| 生成速度 | 約68.5 tok/s |
| draft採用 | 294 / 354 |
| draft採用率 | 約83.1% |
性能テスト
Web search tool を与える
性能テストの前、 web search の機能を足しておきましょう。
環境変数に OLLAMA_API_KEY を設定し
pi install npm:@cltec/pi-ollama-web-search
チャットテスト
$ curl -s http://_WG_IP_:8080/v1/models
{"object":"list","data":[{"id":"/home/kiyo/models/qwen36/Qwen3.6-35B-A3B-IQ4_XS-4.19bpw.gguf","object":"model","created":1779794637,"owned_by":"llamacpp","meta":{"vocab_type":2,"n_vocab":248320,"n_ctx_train":262144,"n_embd":2048,"n_params":35505251456,"size":18594316800},"max_model_len":131072}]}
$ curl -s http://_WG_IP_:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "/home/kiyo/models/qwen36/Qwen3.6-35B-A3B-IQ4_XS-4.19bpw.gguf",
"messages": [
{
"role": "user",
"content": "こんにちは。1文で自己紹介してください。"
}
],
"chat_template_kwargs": {
"enable_thinking": false
},
"temperature": 0,
"max_tokens": 64,
"stream": false
}' | jq '.choices[0].message | {content, reasoning_content}'
{
"content": "私はあなたの知的なパートナーであり、多様な質問やタスクに柔軟に対応してサポートするAIアシスタントです。",
"reasoning_content": null
}
日本の山のテスト
日本の山を、標高の高い順に3つ教えてください。
WEB調査してから回答してください。
WEB調査の結果、日本の山を標高の高い順に上位3つは以下の通りです。
────────────────────────────────────────────────────────────────────────────────
### 1位:富士山(ふじさん)
- 標高:3,776m
- 山系:独立峰
- 都道府県:山梨県・静岡県 日本最高峰。世界遺産でもあり、誰でも知る有名な山ですね。 2位:北岳(きただけ)
- 標高:3,193.2m
- 山系:赤石山脈(南アルプス)
- 都道府県:山梨県 日本第二の高峰。南アルプスに位置し、百名山の一つです。 3位:奥穂高岳(おくほたかだけ)/間ノ岳(あいのだけ)
- 標高:3,190m(同率3位)
- 奥穂高岳:飛騨山脈(北アルプス)/長野県・岐阜県
- 間ノ岳:赤石山脈(南アルプス)/山梨県 両山とも3,190mで同率3位です。奥穂高岳は北アルプスの代表的な高峰、間ノ岳は南アルプスの隠れた名峰として知られています。 ──────────────────────────────────────────────────────────────────────────────── まとめ: ┌──────┬───────────────────┬──────────┬─────────────────────────┐
│ 順位 │ 山名 │ 標高 │ 山系 │
├──────┼───────────────────┼──────────┼─────────────────────────┤
│ 1 │ 富士山 │ 3,776m │ 独立峰 │
├──────┼───────────────────┼──────────┼─────────────────────────┤
│ 2 │ 北岳 │ 3,193.2m │ 南アルプス │
├──────┼───────────────────┼──────────┼─────────────────────────┤
│ 3 │ 奥穂高岳 / 間ノ岳 │ 3,190m │ 北アルプス / 南アルプス │
└──────┴───────────────────┴──────────┴─────────────────────────┘ ※出典:国土地理院「日本の主な山岳標高」、Wikipedia「日本の山一覧 (高さ順)」─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────
MS パワーポイント作成テスト
Python のライブラリーを使いこなして、PPTX を作成可能です。
どこまでできるのか、テストしてみます。
テストプロンプト
日本の戦後の人口の推移に関する資料を、3ページのパワーポイントで作成してください。
生成物



評価
スライドの2ページ目に「第二次ベビーブーム(1947-49)」とありますが、それは第一次ベビーブームですね。
他にも色々と怪しい点がありますが、想像以上にきちんと作り上げてきました。
不満は残りますが、役に立ちそうです!