RTX 3060 12GBで35B級LLMを動かす ― FreeToken + Qwen3.6-35B-A3B-NVFP4を試してみた
ローカルLLMというと、RTX 3060 12GBでは7B〜14Bクラスあたりが現実的という印象があります。
自分の環境でもこれまではOllamaを使ってQwen系モデルを動かしていましたが、今回は別のアプローチとして FreeToken を試してみました。
目的
今回の目的はシンプルです。
RTX 3060 12GBで35Bクラスのモデルを実用的な速度で動かせるのか?
使用したモデルは Qwen3.6-35B-A3B-NVFP4。
結論から書くと、いくつかの問題には遭遇したものの、最終的にはRTX 3060 12GBで動かすことができました。
さらに設定を調整したところ、約1,850トークンの生成を約60秒、単純計算で 約30.8 tok/s まで高速化できました。
実行環境
今回使用したPCは以下です。
| 項目 | 環境 |
|---|---|
| OS | Windows 11 + WSL2 Ubuntu |
| CPU | Intel Core i5-12400F |
| メモリ | 32GB |
| GPU | NVIDIA GeForce RTX 3060 12GB |
| NVIDIA Driver | 591.74 |
| CUDA | 13.1 |
| Python | 3.12 |
| 推論エンジン | FreeToken |
| モデル | Qwen3.6-35B-A3B-NVFP4 |
決してLLM専用のハイエンドマシンではなく、数年前のミドルレンジGPUを搭載した一般的なPCです。
Qwen3.6-35B-A3B-NVFP4は総パラメータ数こそ35Bですが、MoEモデルです。
すべてのパラメータを常に使うわけではなく、一部のExpertだけを選択して推論するため、FreeTokenのCPUオフロードやGPUキャッシュと相性が良さそうです。
FreeTokenのインストール
今回はuvで仮想環境を作成しました。
uv venv --python 3.12
source .venv/bin/activate
FreeTokenをインストールします。
uv pip install "freetoken[accel]"
FreeTokenではCUDAカーネルのJITコンパイルも行われるため、NVIDIA DriverだけでなくCUDA Toolkitとnvccも必要です。
確認します。
nvidia-smi
Wed Sep 2 17:02:13 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.52.01 Driver Version: 591.74 CUDA Version: 13.1 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 3060 On | 00000000:01:00.0 On | N/A |
| 36% 33C P8 15W / 170W | 1777MiB / 12288MiB | 1% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2026 NVIDIA Corporation
Built on Fri_Apr_24_07:22:02_PM_PDT_2026
Cuda compilation tools, release 13.3, V13.3.33
Build cuda_13.3.r13.3/compiler.37862127_0
まずはFreeTokenでモデルを起動してみる
インストールが完了したので、まずはFreeTokenからQwen3.6-35B-A3B-NVFP4をそのまま起動してみます。
FreeTokenではft serveコマンドでOpenAI互換APIサーバーを起動できます。
ft serve \
--model nvidia/Qwen3.6-35B-A3B-NVFP4
正常に起動すれば、デフォルトでは以下のアドレスでAPIサーバーが待ち受けます。
http://127.0.0.1:1919
OpenAI互換APIなので、最終的には以下のようなエンドポイントからモデルを利用できます。
http://127.0.0.1:1919/v1/chat/completions
……と、ここまでは簡単に動くことを期待していたのですが、実際にはモデルのロード段階でいきなりエラーになりました。
最初の問題:model.safetensors.index.jsonがない
最初にft serveを実行したところ、以下のエラーが発生しました。
FileNotFoundError:
model.safetensors.index.json
FreeTokenが参照しているHugging Faceキャッシュを確認すると、必要なモデルファイルが揃っていませんでした。
そこで、モデルを明示的にローカルへダウンロードすることにしました。
mkdir -p ~/models
hf download \
nvidia/Qwen3.6-35B-A3B-NVFP4 \
--local-dir ~/models/Qwen3.6-35B-A3B-NVFP4
ダウンロード後、以下のようなファイルが揃っていることを確認します。
model-00001-of-00003.safetensors
model-00002-of-00003.safetensors
model-00003-of-00003.safetensors
model.safetensors.index.json
以降はHugging FaceのモデルIDではなく、ローカルパスをFreeTokenへ渡します。
ft serve \
--model ~/models/Qwen3.6-35B-A3B-NVFP4
これでmodel.safetensors.index.jsonのエラーは解消し、モデルのロードが開始されました。
ログも、
Loading Qwen3.5 NVFP4 experts: 100%
まで進むようになりました。
これで動くかと思ったのですが、今度はロード途中で別のエラーが発生します。
次の問題:cudaHostRegister failed
表示されたのが以下のエラーです。
RuntimeError: cudaHostRegister failed: out of memory
さらにログを見ると、
RuntimeError: cudaHostRegister failed for 0.2 GiB
となっています。
モデルファイルの問題は解決したものの、次はメモリ周りで詰まりました。
最初はRTX 3060の12GBというVRAM容量が足りないのではないかと疑いました。
しかし、調べてみるとこれはGPUのVRAM不足とは別の問題でした。
FreeTokenでは、GPUに収まりきらないMoE ExpertをCPU側のRAMへ配置できます。
その際、高速にGPUへ転送できるようにホストメモリをPinned Memoryとして登録します。
今回問題になっていたのは、
RTX 3060のVRAM不足
ではなく、
Windows / WSL2環境におけるPinned Host Memoryの上限
でした。
32GBのRAMが搭載されていても、そのすべてをCUDAのPinned Memoryとして利用できるわけではありません。
GitHub版のFreeTokenを使う
この問題について調べていくと、FreeToken側にはPinned Memory使用量を制限する仕組みが追加されていました。
そこでPyPI版だけでなく、GitHubのソースを直接使うことにしました。
git clone https://github.com/FlashML-org/FreeToken.git ~/FreeToken-src
cd ~/FreeToken-src
uv pip install -e ".[accel]"
バージョンを確認します。
ft --version
表示上は、
freetoken version 0.1.2
となりました。
一瞬、
GitHub版に切り替わっていない?
と思いましたが、パッケージ側のバージョン自体が0.1.2のため、この表示だけでは判断できません。
実際にどこのFreeTokenを読み込んでいるかは以下で確認できます。
python -c "import freetoken; print(freetoken.__file__)"
~/FreeToken-src/...を指していれば、editable installしたGitHub版を使用しています。
Pinned Memoryを制限する
FreeTokenでは環境変数でPinned Memoryの上限を指定できます。
今回は10GBに設定しました。
export FREETOKEN_PIN_BUDGET_GB=10
さらに、
export FREETOKEN_MAMBA_SSM_DTYPE=float16
も指定します。
これでWindows / WSL2側のPinned Memory上限を超えないように調整します。
まずはCPU MoEで起動
いきなり性能を追求するのではなく、まずは「この環境でモデルを最後まで起動できること」を確認することにしました。
そこで最初は安定動作を優先して、MoE ExpertをCPU側で処理します。
export FREETOKEN_PIN_BUDGET_GB=10
export FREETOKEN_MAMBA_SSM_DTYPE=float16
ft serve \
--model ~/models/Qwen3.6-35B-A3B-NVFP4 \
--memory-ratio 0.90 \
--num-tokens 512 \
--max-seq-len-override 1024 \
--attention-backend triton \
--moe-backend cpu \
--expert-load serial \
--moe-cpu-threads 8 \
--max-running-requests 1
この構成で、ようやくFreeTokenが起動しました。
OpenAI互換APIは以下です。
http://127.0.0.1:1919/v1
試しにcurlからリクエストしてみます。
curl http://127.0.0.1:1919/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.6-35B-A3B-NVFP4",
"messages": [
{
"role": "user",
"content": "Pythonでフィボナッチ数列を生成する関数を書いてください。"
}
],
"max_tokens": 2048
}'
無事に回答が返ってきました。
RTX 3060 12GB + RAM 32GBという環境で、35Bクラスのモデルが実際に動いています。
ここまで来ればひとまず成功です。
……ただ、動作中のGPUを見てみると少し気になる点がありました。
GPUメモリをあまり使っていない
Windowsのタスクマネージャーを見ると、GPUメモリ使用量は4GB台でした。
12GBあるVRAMの半分も使っていません。
そこで、WSL2側からnvidia-smiを監視してみます。
watch -n 0.5 nvidia-smi
推論中でもGPU使用率はそれほど高くありません。
原因として大きいのが、このオプションです。
--moe-backend cpu
この設定ではMoE Expertの計算をCPU側で行うため、モデルは動くもののRTX 3060のVRAMと演算性能を十分に活用できていません。
安定動作の確認には役立ちましたが、このままではRTX 3060を積んでいる意味が薄くなってしまいます。
そこで次は、CPU固定をやめてGPUをもっと使わせてみます。
--moe-backend cpuを外してGPUを使わせる
CPU固定をやめて、FreeToken側にGPUを利用させます。
export FREETOKEN_PIN_BUDGET_GB=10
export FREETOKEN_MAMBA_SSM_DTYPE=float16
ft serve \
--model ~/models/Qwen3.6-35B-A3B-NVFP4 \
--memory-ratio 0.90 \
--num-tokens 2048 \
--max-seq-len-override 4096 \
--attention-backend triton \
--expert-load serial \
--max-running-requests 1
この状態で再び推論中のGPUを確認すると、
Memory-Usage
10562MiB / 12288MiB
GPU-Util
35%
Power
62W / 170W
となりました。
VRAM使用量は約10.5GB。
先ほどの4〜5GB程度から大幅に増えています。
12GBのVRAMをかなり使えるようになりました。
GPU使用率自体は35%程度なのでGPUが常にフル稼働しているわけではありません。
残りのExpertをRAM側から利用するため、CPU処理やメモリ帯域、PCIe転送なども関係していると考えられます。
それでも、CPU固定時と比べると明らかにGPUを活用できています。
推論速度が約2倍になった
実際にどの程度速くなったのか、同じプロンプトをtime付きで実行して測定してみました。
time curl http://127.0.0.1:1919/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.6-35B-A3B-NVFP4",
"messages": [
{
"role": "user",
"content": "Pythonでフィボナッチ数列を生成する関数を書いてください。"
}
],
"max_tokens": 2048
}'
結果は以下です。
prompt_tokens: 25
completion_tokens: 1850
total_tokens: 1875
real 1m0.040s
約1,850トークンを60秒で生成しています。
単純計算すると、
1850 ÷ 60.04 ≒ 30.8 tok/s
約30.8 tok/sです。
CPU MoEで動かしていたときと比較すると、処理時間はおよそ半分になりました。
RTX 3060 12GBで35B級モデルが約31 tok/sという結果は、個人的にはかなり驚きました。
もちろん、これは「35B DenseモデルをRTX 3060だけで31 tok/s出している」という意味ではありません。
Qwen3.6-35B-A3B-NVFP4はMoEモデルであり、FreeTokenによってGPUとSystem RAMを組み合わせて動作しています。
概念的には以下のような構成です。
Qwen3.6-35B-A3B-NVFP4
│
├─ GPU
│ ├─ Attention
│ ├─ Hot Expert Cache
│ ├─ KV Cache
│ └─ VRAM 約10.5GB
│
└─ System RAM
└─ 残りのExperts
│
└─ PCIe経由でGPUと連携
それでも、12GBしかVRAMのないRTX 3060でこのクラスのモデルを実用的な速度で扱えるのは面白いところです。
OpenCodeと連携する
せっかく35B級モデルが動いたので、次は単純なチャットではなくCoding Agentとして使ってみます。
今回は軽量なCLIベースのCoding AgentであるOpenCodeを試しました。
FreeTokenからは以下のコマンドで起動できます。
ft launch opencode
FreeTokenのOpenAI互換APIを利用する形でOpenCodeが起動します。
ところが、ここでも問題が発生しました。
OpenCodeで単純に、
hello
と入力しただけなのに、
prompt is too long:
7812 tokens > 2048 maximum
(prompt + generation)
というエラーになります。
なぜhelloだけで7,812 tokensになるのか
最初は、
helloしか入力していないのに、なぜ7,812 tokens?
と思いました。
しかし、Coding AgentがLLMへ送っているのはユーザーが入力したhelloだけではありません。
裏側では、概ね以下の情報も一緒に送信されます。
- System Prompt
- Tool Definitions
- Agent Instructions
- Project Context
- Conversation History
つまり実際には、
ユーザー入力
+
System Prompt
+
Tool Definitions
+
Agent Instructions
+
Project Context
+
Conversation History
という巨大なプロンプトになります。
ユーザー入力が数トークンしかなくても、Coding Agentを経由すると実際のリクエストが数千トークンになるわけです。
今回のFreeTokenは、
--num-tokens 2048
で起動していたため、7,812 tokensのリクエストは当然入りません。
Coding Agent用途ではContext Windowが重要
通常のチャット用途とCoding Agent用途では、必要なContext Windowがかなり違うことが分かりました。
今回のOpenCodeでは、何もしていない状態でも約7,800 tokensが必要になっています。
そのため、次は、
--num-tokens 16384
--max-seq-len-override 16384
程度まで拡張して試していく予定です。
ただし、Context Windowを大きくするとKV Cacheも増えます。
RTX 3060 12GBでは、
MoE Cacheを増やす
↓
GPUに多くのExpertを置ける
↓
推論速度を上げやすい
KV Cacheを増やす
↓
長いContextを扱える
↓
Coding Agentで有利
しかしVRAMは12GB
というトレードオフがあります。
今回、約31 tok/sまで高速化できたのはVRAMを約10.5GB使用する構成です。
OpenCode用にContext Windowを大きくすると、その分KV CacheにもVRAMが必要になります。
つまりRTX 3060 12GB環境では、
推論速度を優先してMoE Cacheを増やすのか、Coding Agent用途を優先してContext Windowを確保するのか
というバランス調整が次の課題になりそうです。
今回分かったこと
今回FreeTokenを試してみて一番印象的だったのは、
VRAM容量だけでは、動かせるモデルサイズを判断できなくなってきた
という点です。
従来ならRTX 3060 12GBで35Bクラスはかなり厳しい印象でした。
しかし、
- MoE
- NVFP4量子化
- CPU RAMへのExpert Offload
- GPU側のExpert Cache
- Pinned Memory
- PCIe転送
を組み合わせることで、35Bクラスでも実際に動かせます。
しかも今回の環境では約31 tok/sまで出ました。
一方で、単純にモデルをロードすれば動くわけではありません。
今回だけでも、以下のような試行錯誤がありました。
FreeTokenをインストール
↓
ft serveでモデルを起動
↓
model.safetensors.index.jsonがない
↓
モデルをローカルへダウンロード
↓
再度ft serve
↓
cudaHostRegister failed
↓
WSL2のPinned Memory制約を調査
↓
FREETOKEN_PIN_BUDGET_GBを設定
↓
CPU MoEで起動成功
↓
GPU使用量が少ない
↓
CPU固定を解除
↓
VRAM 約10.5GB使用
↓
約31 tok/sまで高速化
↓
OpenCode接続
↓
Context Window不足
振り返ってみるとなかなかの試行錯誤です。
ただ、この「どこがボトルネックなのかを調べながら少しずつ動かしていく」過程も、ローカルLLMの面白いところだと思います。
まとめ
RTX 3060 12GB + RAM 32GBという構成で、FreeTokenを使ってQwen3.6-35B-A3B-NVFP4を動かしてみました。
現時点で確認できた結果は以下です。
| 項目 | 結果 |
|---|---|
| モデル | Qwen3.6-35B-A3B-NVFP4 |
| GPU | RTX 3060 12GB |
| System RAM | 32GB |
| VRAM使用量 | 約10.5GB |
| 生成トークン | 約1,850 tokens |
| 生成時間 | 約60秒 |
| 推論速度 | 約30.8 tok/s |
| API | OpenAI互換API |
| Coding Agent | OpenCodeで接続確認 |
特にFreeTokenのCPU/GPUオフロードを利用することで、RTX 3060の12GBという限られたVRAMでも35B級モデルを実用的な速度で動かせたのは興味深い結果でした。
ただし、OpenCodeのようなCoding Agentで実用するとなると、今度はContext Windowの問題が出てきます。
次は、
RTX 3060 12GBでQwen3.6-35B-A3BをOpenCodeのCoding Agentとしてどこまで実用的に使えるのか
を試してみたいと思います。
余談
それにしてもメモリーもグラフィックボードも高いですね・・・
RTX3060も買ったときは52,000円くらいだった記憶・・・
今使ってるやつは中古で54,000円て・・・
↓安くない!?ほかのRTX3060 12GBモデル軒並み50,000円越えな気がするんだけど・・・追加しようかな・・・
「PR」