12GB VRAM で Qwen3.6-35B-A3B を高速に動かす

12GB VRAM で Qwen3.6-35B-A3B を高速に動かす

MOE の活用により、GPUメモリに乗り切らなくても、そこそこ高速に動くようになってきた、、、という記事を読んだので試してみました。

きっかけ

Reddit のこの投稿です。

ちょうど私の保有しているGPUが NVIDIA GeForce RTX 3060 なので、バッチリです。

早速試すことにしました。

何がすごい?

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
OSUbuntu 24.04.4 LTS
KernelLinux 6.17.0-29-generic
CPUIntel Core i5-12400
CPU構成6コア / 12スレッド
メモリDDR5 32GB、16GB × 2
メモリ実動作4800 MT/s
GPUNVIDIA GeForce RTX 3060
VRAM12GB、12288 MiB
NVIDIA Driver580.159.03
CUDA Driver表示13.0
CUDA Toolkit12.0 / nvcc V12.0.140
ストレージNVMe 1TB
LLM実行基盤ik_llama.cpp
ik_llama.cpp commitb3d39cff8bffbd67296d6badd4076a1486a0715c
ik_llama.cpp version4533
モデルQwen3.6-35B-A3B-IQ4_XS-4.19bpw.gguf
モデルサイズ約18GB
context131072
KV cacheq8_0
MTP有効
draft-max3
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)」とありますが、それは第一次ベビーブームですね。

他にも色々と怪しい点がありますが、想像以上にきちんと作り上げてきました。

不満は残りますが、役に立ちそうです!

bancom Avatar