最近、毎回のコーディング実験のたびに有料のクラウドモデルに依存するのに疲れてきました。
クラウドモデルは素晴らしいです。速いし、便利だし、たいてい非常に高性能です。
ただし、いつもの「お荷物」も一緒に付いてきます。コスト、レート制限、インターネットへの依存、プライバシーに関する疑問、そして「真面目なコーディングのワークフローはすべて、誰かのGPUをレンタルしているだけだ」という小さな感覚です。
そこで、ローカルLLMをちゃんと検証し始めました。
カジュアルに「小さめのチャットモデルなら動く?」という話ではありません。
知りたかったのは次のことです:
- ローカルのコーディング用モデルは今、どれくらい賢いのか?
- 実際のコード生成、デバッグ、リファクタリング、リポジトリのQ&Aに役立つのか?
- OpenAI互換APIを通じて、エディタのエージェントに組み込めるのか?
- そして最も重要なのは、何が結局それを「役に立つ」状態にできないのか?
十分に調べた結果、答えはかなり明白になりました。
壁はハードウェアです。
より具体的に言うと、VRAMです。
モデルファイルは用意できます。ランタイムも用意できます。Dockerも用意できます。スクリプトも用意できます。ですが、モデルの重み、ルーテッド・エキスパート、KVキャッシュ、コンテキストウィンドウ、計算バッファがGPUメモリを奪い合い始めると、すべてがあっという間に厳しくなります。
それで私は考えました。
実用的な回避策はあるのか?
幸運なことに、非常に普通のコンシューマ向け構成が手元にありました。
ハードウェアはとても普通です:
- GPU: NVIDIA RTX 3060 Ti
- VRAM: 8 GB
- OS: Windows
- RAM: 約32 GB
- CPU: Intel i5-14600KF
これは4090搭載機ではありません。ワークステーションでもありません。まさに、多くの人が「7Bモデルを動かして済ませよう」と言いそうなマシンです。
そこで、私はチャレンジにしました:
コンシューマ向けのハードウェアで、実際に役に立つだけのコンテキスト量を確保しつつ、ちゃんとした30Bのコーディングモデルをローカルで動かせるか?
狙ったモデルは野心的でした:
Qwen3-Coder-30B-A3B-Instruct
具体的には、次のGGUFです:
unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF
私が使った量子化(quant)は:
Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf
これは「30B級」のコーディング特化MoEモデルです。重要なのはMoEです。Mixture of Experts(エキスパートの混合)。総パラメータ数は大きいですが、トークンごとに有効になるのは一部のエキスパート重みだけです。
これにより、ローカル推論の戦略全体が変わります。
密な30Bモデルなら、8GBのVRAMから始めるのは私なら避けます。ですが、コンパクトなMoEのコーディングモデルでは、話が面白くなります:
常に動いている部分は高速に保ち、ルーテッド・エキスパートは主にシステムRAMに置いて、それでも使える速度が得られるのか?
短い答え:はい。
長い答え:いくつも試行錯誤が必要でした。
最初に退屈な監査
何か巨大なものをダウンロードする前に、マシンを確認しました。
これは当然のように聞こえますが、ローカルAIのセットアップはこれを飛ばすと急に混乱します。
私は次を確認しました:
- Windowsのバージョン
- GPUの型番
- NVIDIAドライバ
-
nvidia-smiをPowerShellで - WSL2
- Docker Desktop
- DockerのGPUパススルー
- CUDAコンテナからGPUへアクセスできるか
- システムRAM
- ディスク容量
- CPU
DockerのGPUパススルーは動きました:
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
つまり、最初にまっすぐ行ける道はこれでした:
Docker + llama.cpp CUDA server
最初のサーバー用イメージ:
ghcr.io/ggml-org/llama.cpp:server-cuda
また、インターネット上のどんなコマンドも信じる前に、llama-server --help も確認しました。
これが、繰り返し出てくるテーマになりました。
そのフラグが存在すると決めつけないでください。バイナリに聞きましょう。
モデルのダウンロード
対象のモデルリポジトリは:
unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF
ダウンロード前に、実際のファイル名を確認しました:
Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf
ダウンロードされたファイルサイズは:
17,665,334,432 bytes
すべてを1つのローカルなプロジェクトフォルダ配下に置きました:
local-qwen-coder/
models/
scripts/
configs/
docs/
グローバルな謎フォルダはなし。「この17GBのファイルはどこに行った?」みたいな瞬間もなし。
小さな勝利です。
最初の本当の詰まり:Dockerのメモリ
最初の深刻な問題はGPUではありませんでした。
Dockerのメモリでした。
Windowsでは約32GBのRAMが使えますが、Docker DesktopはLinux VMに対してRAMを約16GBしか公開しておらず、さらにスワップは4GBです。
これは重要でした。というのも、私の最初の直感が次のようにすることだったからです:
--no-mmap
--mlock
これは、後でディスクからページフォルトさせるのではなく、モデルをRAMにロードしたいときには良い発想です。
しかし、そのコンテナには十分なRAMがありませんでした。
プロセスが殺されました。
終了コード:
137
Docker inspectで確認すると:
OOMKilled=true
なので、最初の修正は華やかなものではありません:
Dockerのパスではmmapを有効のままにする。
「技術的により良い」フラグは、実際のコンテナのメモリ上限には合っていませんでした。
安定したデフォルトのllama.cppサーバーを動かす
標準のllama.cppを使うDockerでは、モデルはロードされ、OpenAI互換のエンドポイントとして提供できました。
ベースURL:
http://127.0.0.1:8080/v1
重要なMoEフラグは:
--cpu-moe
これにより、MoEのエキスパート重みをCPUに置きます。
モデルは使えるようになりましたが、まだ十分に速くはありません。
ベースライン:
| モード | プロンプト評価 | 生成 |
|---|---|---|
--cpu-moe |
~2.78 tok/s | ~13.38 tok/s |
生成はまあ良いです。ですがプロンプト評価がつらい。
次のつまみが登場しました:
--n-cpu-moe N
これは最初のN個のMoE層をCPUに置き、GPU上に置けるエキスパートの重みを増やします。
Nを下げるほど、通常はGPU常駐が増え、速度が上がり、VRAMの余裕(headroom)が減ります。
そこでベンチマークしました。
MoEオフロードのチューニング
役に立つ結果は次のとおりです:
| モード | 使用VRAM | 空きVRAM | プロンプト評価 | 生成 |
|---|---|---|---|---|
--cpu-moe |
4388 MiB | 3637 MiB | 2.78 tok/s | 13.38 tok/s |
--n-cpu-moe 48 |
4392 MiB | 3633 MiB | 2.51 tok/s | 13.83 tok/s |
--n-cpu-moe 46 |
5224 MiB | 2801 MiB | 6.03 tok/s | 18.75 tok/s |
--n-cpu-moe 44 |
5893 MiB | 2132 MiB | 38.36 tok/s | 29.40 tok/s |
--n-cpu-moe 42 |
6568 MiB | 1457 MiB | 44.49 tok/s | 30.26 tok/s |
--n-cpu-moe 40 |
7265 MiB | 760 MiB | 51.63 tok/s | 32.49 tok/s |
--n-cpu-moe 38 |
7664 MiB | 361 MiB | 53.14 tok/s | 33.64 tok/s |
テストした中で最も速かった値は:
--n-cpu-moe 38
しかし、それだと空きVRAMが約361 MiBしか残りませんでした。
きつすぎる。
実用上の勝ち手は:
--n-cpu-moe 40
これにより、空きVRAMが約760 MiBの状態で生成が約32.49 tok/sになりました。
この時点で、ローカルのコーディング用バックエンドは良い感じになっていました。
ただ、私は実際に欲しかったものを持っていませんでした。
実際の目標:262Kコンテキスト
Qwen3-Coder-30B-A3Bは、長いコンテキストをネイティブにサポートしています。
モデルのメタデータには次が表示されていました:
n_ctx_train = 262144
そこで問題になったのは:
8 GBのVRAMで、実際に262Kコンテキストとして動かせるのか?
標準のDockerビルドでは、思った通りにそこへ到達できませんでした。
通常のllama.cppの型を使ってKVキャッシュの精度を下げれば、次のようにできます:
q8_0
q4_0
iq4_nl
ただ、見ていた動画ではTurboQuantの話をしていました。
それが決定的な違いでした。
そしてここで、私はほぼ自分をだましそうになりました。
私はまだ実際にはTurboQuantを使っていなかった
標準のDockerイメージを確認しました:
docker run --rm --gpus all ghcr.io/ggml-org/llama.cpp:server-cuda --help
サポートされているKVキャッシュの型は:
f32, f16, bf16, q8_0, q4_0, q4_1, iq4_nl, q5_0, q5_1
turbo3なし。
turbo4なし。
tbq3_0なし。
tbq4_0なし。
つまり答えは明確でした:
標準のランタイムはTurboQuantを実行していない。
TurboQuantはモデル重みの量子化ではありません。GGUFモデルファイルの変更は不要です。
ランタイムがKVキャッシュをどう保持するかを変えるのです。
同じモデル。
別のランタイム。
別のキャッシュ形式。
これが本当の転機でした。
TurboQuant対応ランタイムの発見
Windows向けのCUDAランタイムビルドを見つけました:
atomicmilkshake/llama-cpp-turboquant-binaries
ダウンロードしたファイル:
llama-turboquant-triattention-win-cu13-x64.zip
それを次の場所に展開しました:
runtimes/turboquant/win-cu13
そして試しました:
.\llama-server.exe --help
即座に失敗しました。
有用な出力はありません。
プロセスの終了コードは:
0xc0000135
通常これは、WindowsでDLLが見つからないことを意味します。
READMEでも、想定される問題が確認できました:
cublasLt64_13.dll
このビルドは、CUDA 13のcuBLASLtランタイムを必要としていました。
その1つのDLLのためだけに、CUDA Toolkit全体をグローバルにインストールしたくありませんでした。
そこで公式のNVIDIA cuBLASホイールを取得しました:
python -m pip download nvidia-cublas==13.4.0.1 --only-binary=:all:
次に展開しました:
cublasLt64_13.dll
そしてllama-server.exeの隣にあるローカルのランタイムフォルダへコピーしました。
その後:
.\llama-server.exe --help
動きました。
そして今度は、キャッシュの型として次が含まれていました:
turbo2, turbo3, turbo4
どちらでも:
--cache-type-k
--cache-type-v
これがきっかけで、セットアップは「通常のllama.cppチューニング」から「本当のTurboQuantの道筋」へ切り替わりました。
最終的な262K起動
最終的なコマンドの形は:
.\runtimes\turboquant\win-cu13\llama-server.exe `
-m .\models\qwen3-coder-30b-a3b\Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf `
--alias qwen3-coder-30b-a3b-turbo-262k `
--host 127.0.0.1 `
--port 8080 `
--jinja `
--gpu-layers all `
--cpu-moe `
--flash-attn on `
--ctx-size 262144 `
--cache-type-k turbo4 `
--cache-type-v turbo3 `
--parallel 1 `
--batch-size 256 `
--ubatch-size 64 `
--temp 0.3 `
--top-p 0.8 `
--top-k 20 `
--repeat-penalty 1.05 `
--fit off `
--cache-ram 0 `
--no-mmap `
--mlock
私は強制しました:
--fit off
llama.cppがこっそりコンテキストを縮めて、それでいてすべて問題ないふりをするのを避けたかったからです。
読み込むなら、262144を本当に読み込ませる必要がありました。
そして、そうなりました。
The proof
ランタイムのログにはこう表示されました:
llama_context: n_ctx = 262144
llama_context: n_ctx_seq = 262144
llama_context: n_batch = 256
llama_context: n_ubatch = 64
KVキャッシュの行が本当の証拠でした:
llama_kv_cache: size = 5664.00 MiB (262144 cells, 48 layers, 1/1 seqs), K (turbo4): 3264.00 MiB, V (turbo3): 2400.00 MiB
ロード後のVRAM:
7525 MiB used
500 MiB free
かなりギリギリです。
それでも読み込みました。
次に、OpenAI互換エンドポイント経由で小さなコーディング用プロンプトを送りました。
応答が返ってきました。
所要時間:
prompt eval time = 1125.54 ms / 46 tokens = 40.87 tokens per second
eval time = 3672.56 ms / 107 tokens = 29.13 tokens per second
これが勝因でした。
Qwen3-Coder-30B-A3B。
262Kコンテキスト。
8 GB VRAM。
ローカルのエンドポイント。
同じモデルファイル。
TurboQuantのKVキャッシュ。
The repeatable script
TurboQuantの起動を次にラップしました:
scripts/run-qwen-coder-turboquant.ps1
つまり、反復可能なコマンドは次のとおりです:
.\scripts\run-qwen-coder-turboquant.ps1 -Replace
標準のDockerフォールバックも引き続きあります:
.\scripts\run-qwen-coder-docker.ps1 -Profile daily-fast
Dockerルートは、より安全な日次プロファイルに役立ちます。
TurboQuantルートは、フルコンテキストのプロファイルです。
Important caveats
これは魔法ではありません。
262KプロファイルはVRAMがかなり逼迫します。
私のRTX 3060 Tiでは、おおよそ500 MiBしか空きがありません。つまり:
- 単一クライアントのみ
- 複数のエディタエージェントを同時に動かさない
- GPUヘビーなアプリを閉じる
- 32Kプロファイルより融通が利かないと考えてください
また、このセットアップが実際のコーディング作業で優れていることは、まだ証明できていません。
インフラは動きます。
エンドポイントは動きます。
コンテキストはロードされます。
スモークテストは通ります。
ただし次のテストは、実開発作業です:
- 実際のリポジトリをリファクタリングできるか?
- UnityのC#を、まともにデバッグできるか?
- 複数ファイルのコンテキストを扱っても、話がそれないか?
- 長いセッションにわたって安定できるか?
それが次のマイルストーンです。
What I learned
大きな学びは、ローカルAIインフラは単にこういうものではないということです:
download model
run server
profit
デフォルト設定がボトルネックになることが多いです。
このセットアップでは:
- MoEの配置が重要でした。
- Dockerのメモリ制限が重要でした。
- KVキャッシュの形式が重要でした。
- ランタイムのビルドが重要でした。
-
llama-server --helpがとても重要でした。
30Bモデル自体が全ての問題ではありません。
ランタイム戦略が問題でした。
そして場合によっては、「不可能」と「動く」の違いは、1つ足りないDLLと、正しいKVキャッシュタイプです。
Repo
私はセットアップを、次の内容でGitHubリポジトリとして公開しました:
返却形式: {"translated": "翻訳されたHTML"}- 起動スクリプト
- ベンチマークのメモ
- トラブルシューティングのドキュメント
- クライアント設定
- 再現可能なセットアップのメモ
GitHubリンク:
UpayanGhosh
/
local-qwen-coder-turboquant
8GB VRAMでのコーディングワークフロー向け Local Qwen3-Coder 30B TurboQuant セットアップ
Local Qwen Coder TurboQuant セットアップ
8GBのNVIDIA GPU上で、Qwen3-Coder-30B-A3B-Instruct をローカルの「コーディング専用」OpenAI互換バックエンドとして実行するための、実用的なWindows向けセットアップ手順とスクリプトです。
このリポジトリは、安定した標準の llama.cpp Docker セットアップから、フルコンテキストの TurboQuant KV-cache ランタイムへ至るまでの道のりを記録しています:
- RTX 3060 Ti、8 GB VRAM
- Windows
- Qwen3-Coder-30B-A3B-Instruct GGUF
- MoE の専門家(expert)における CPU/GPU 常駐(residency)チューニング
- OpenAI互換のローカルエンドポイント
- TurboQuant KVキャッシュで
262144コンテキストを検証済み
含まれているもの
- バックエンドの起動とテストのためのPowerShellスクリプト
- Cline、Continue、Roo Code、OpenCode、および汎用のOpenAI互換クライアント向けのクライアント設定
- ベンチマークのメモ
- TurboQuant の調査とトラブルシューティングのメモ
- ビルドの物語を説明する LinkedIn 投稿下書き
含まれていないもの
このリポジトリは意図的に次のものを追跡しません:
- GGUFモデルファイル
- CUDA/ランタイムDLL
- ダウンロード済みのホイール/zip
- ログ
- ローカルキャッシュ
それらのファイルは大きいおよび/またはマシン固有です。.gitignore を参照してください。
主な結果
検証済み TurboQuant プロファイル:
Context: 262144
KV cache: K=turbo4, V=turbo3
VRAM: ~7525 MiB 使用 /…このリポジトリには、GGUFモデル、CUDA DLL、ホイール、またはダウンロード済みのバイナリは含まれません。それらは大きすぎて、かつマシン固有のためです。
終わりにひとこと
これは最初、こういう発想でした:
「役に立つローカルのコーディング用バックエンドを作れる?」
そして次に、こうなりました:
「8GB VRAMでフルの262Kコンテキストを動かせる?」
最初のバージョンは、ただ動くだけでした。
最終バージョンは、実際に目標を達成しました。
私はこれを勝ちだと思っています。


