0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

16GB VRAMでローカルAIエージェントを作る

0
Posted at

Qwen3.6-27Bの量子化モデルを RTX 5070 Ti 16GB 環境でOpencode用に調整する

VRAM 16GBにおける課題

2026年初頭、Qwen3.6シリーズ(27B dense、35B MoE)のリリースは、ローカルLLM界隈で大きな話題になった。
SNS上では、RTX 40905090(VRAM 24〜32GB)を持つ層が「ローカル環境のエージェントワークが劇的に快適になった」と盛り上がっていた。

しかし、筆者のマシン環境は以下の通りである。

そんな高価なグラボは買えないため、最初は指をくわえて見ているだけだった。
本来なら、27Bクラスのモデルを16GB VRAMに収めて実用することには、手間がかかるからだ。

「それならLLMプロバイダのAPIを使えばいいのでは?」と思うかもしれない。しかし、Opencodeのような自律型エージェント用途ではコンテキストと推論量が膨大になり、APIの従量課金がすぐに数万円規模に膨れ上がる恐怖がつきまとう。気兼ねなく、いくらでも試行錯誤させられるタダの優秀な頭脳がどうしても手元に欲しかったのだ。

そこで、「噂のモデルを自分の環境でもどうにか使えないか」と、まずは手軽な Ollama を使い、ダメ元で 27B モデルを試してみた。

案の定、単発のチャットならともかく、裏で大量のシステムプロンプトやファイルを読み込む Opencode(AIエージェント)との組み合わせでは、以下の壁にぶつかった。

  • VRAMスパイクによるクラッシュ
    プロンプト投入時のメモリ消費を抑えきれず、16GBの上限を突破する。
  • コンテキスト容量の不足
    エージェント作業には最低でも12K程度のコンテキストが欲しいが、実際には6K程度で頭打ちになる。
  • ハードウェアへの過負荷
    簡単な応答だけでもGPUファンが激しく回転し、高温のまま応答不能に陥る。

結論:16GB VRAMでも設定次第では実用的なローカルエージェントは作れる

結論から言うと、量子化を強めたモデル(Q3_K_M)による多少の品質低下を許容できれば、16GB VRAMでもQwen3.6-27Bをエージェント用途で実用できる

本来のサイズのモデルは16GB環境では動作しない。
しかし、手軽なOllamaから離れ、モデルの重み・KVキャッシュ・推論スパイクというVRAMを消費する要素をチューニングすれば、ローカル環境でエージェント支援を受けながらコーディングができるようになる。

今回構築した環境では、以下の結果が得られた。

  • 64Kコンテキストの確保: 複数ファイルの行き来や巨大なログの読み込みでもクラッシュしなくなった。
  • プロバイダLLMに近いコーディング性能: 今回実施した簡易的なベンチマークの範囲内では、プロバイダLLMに近いコーディング能力を示した。
  • 実運用での動作: Markdown記事ポータルサイトのバックエンドからフロントエンドまで、スクラッチ開発を最後まで進められた。

「16GBでは27Bは無理」と諦める前に、本記事の内容を参考にするのも良いかもしれない。

本記事の全体フロー

実運用に耐える環境を、以下の手順で作っていく。

1. 基礎知識: なぜエージェント用途だと16GBでは足りなくなるのか

モデルの選び方や設定を考える前に、「なぜVRAMを節約しなければならないのか」を理解しておく必要がある。

まず大前提として、Qwen3.6-27BはDense(密な)モデルである
MoE(Mixture of Experts)モデルのように推論時に一部のパラメータだけを動かす仕組みを持たず、推論のたびに 27B すべてのパラメータをメモリ上で計算しなければならない。もし「16GBに入り切らない分をメインメモリ(RAM)に逃がす(部分オフロード)」という運用をすると、毎トークンごとにVRAMとRAMの間で地獄のようなデータ転送が発生し、生成速度が実用不可能なレベル(数 tok/s 以下)まで落ち込んでしまう。

つまり、エージェント用途で実用的な速度を出すには、必要なデータすべてを「16GBのVRAMの中」に完全に収めきる必要があるのだ。

VRAMを奪い合う「3つの要素」

しかし、Opencodeのようなエージェントは、過去の会話履歴、ツールの定義、大量のソースコードなどを毎回の推論でまとめてモデルに送信してくる。
この「長く複雑な入力」を処理するとき、VRAMの中では以下の3つが激しく領域を奪い合う。

  1. モデル本体: LLMの重みそのもの。(量子化レベルでサイズが決まる、常にVRAMを占有する)
  2. KVキャッシュ: 過去の文脈を保持しておくためのメモリ。(コンテキストが長くなるほどジワジワ増える)
  3. 一時的な中間データ: 長い入力(プリフィル)をまとめて計算する際の作業領域。(入力が長いほど一気にスパイクして増える)

LLMの推論において、すべての入力トークンを並列で処理する初期段階(プリフィル)は最も計算負荷が高く、この過程で生成されたKeyとValueのテンソルが「KVキャッシュ」としてGPUメモリに書き込まれる。長いコンテキストを扱う場合、エンジニアはこの永続的なKVキャッシュだけでなく、**プリフィルフェーズ中のピークメモリ使用量(スパイク)**にも対処しなければならない。

(参考: What is GPU Memory and Why it Matters for LLM Inference - BentoML などの解説より要約)

図1: 16GB VRAM の中身とデータの流れ

この図の通り、実用的な速度でエージェントを動かすには、「モデル本体」「KVキャッシュ」「一時データ(スパイク)」の合計を常に16GB未満に抑え込むための戦略が必要になる。この前提を踏まえた上で、モデル選定とパラメータ調整を見ていこう。

2. モデルの選定: Ollamaを卒業する

Ollamaは手軽だが、限界ギリギリのVRAMで動かすための細かな制御には向いていない。
そこで、モデルの選定から起動パラメータまで自分で管理できる llama.cpp / llama-server に切り替えることにした。

使用したモデルは、Hugging Faceで配布されている bartowski/Qwen_Qwen3.6-27B-GGUFQ3_K_M(量子化モデル)である。

先ほどの基礎知識の通り、VRAMには「KVキャッシュ」や「スパイク用の一時領域」の余白を残さなければならない。
Ollama公式が提供するQ4レベルの量子化は品質が高いものの、モデル本体だけでVRAMの大部分を食いつぶしてしまう。Opencodeで必須となる「長い会話履歴(コンテキスト)」の余白を確保するため、今回は品質と空き容量のバランスを見て Q3_K_M を選択した。

pip install -U "huggingface_hub[cli]"
hf download "bartowski/Qwen_Qwen3.6-27B-GGUF" \
  "Qwen_Qwen3.6-27B-Q3_K_M.gguf" \
  --local-dir "/mnt/wsl_data/llm_models/qwen36-27b"

3. VRAM節約と応答安定化のためのパラメータ調整

モデルを選んだら、残る「KVキャッシュ」と「一時データ(スパイク)」を llama-server の起動パラメータで押さえ込み、さらに GPU offload や推論フォーマットも含めて実運用向けに固める。

調整のポイント

この問題を回避するため、以下の2軸でパラメータを調整した。

① VRAM制御(クラッシュを防ぐ)

  • GPUへの全面オフロード (-ngl 99): Dense 27B を実用速度で動かすため、計算レイヤーをGPU側に寄せる。
  • Flash Attention の有効化 (-fa on): 長文コンテキスト時のメモリ効率を改善する。
  • KVキャッシュの量子化 (-ctk q4_0 -ctv q4_0): 過去の文脈データのサイズを圧縮し、64Kのコンテキスト長を確保する。
  • バッチサイズの抑制 (-b 512 -ub 128): 一度に処理するトークン数を絞り、プリフィル時のVRAMスパイクを抑える。
  • 並列処理の無効化 (--parallel 1): 1つのセッションにリソースを集中させる。
  • メモリマップ無効化 (--no-mmap): この構成では明示的に無効化して起動を安定させている。

② 出力制御(エージェントとしての応答を安定させる)
VRAM節約のために量子化を強めると、回答の質が不安定になりやすい。それをカバーするための設定である。

  • チャット・推論形式の固定 (--jinja, --reasoning auto, --reasoning-format deepseek): モデルが期待するフォーマットを強制し、reasoning出力の形式崩れを防ぐ。
  • 出力の揺らぎ防止 (--temp 0.2 --top-p 0.9, --repeat-penalty 1.12): コード生成など、正確性が求められるタスク向けに設定。

4. エージェントツールとの接続 (llama-swap)

調整したパラメータを使ってモデルを起動し、Opencodeから利用できるようにする。
ここでは llama-swap というツールを間に挟む。これにより、Opencodeからは通常のOpenAI APIのように扱うことができ、裏側のモデル起動・停止はllama-swapが自動管理してくれる。

今回の構成は次の通りだ。

図2: llama-swapを用いたシステム構成

llama-swap の設定 (config.yaml)

前述したパラメータを cmd にすべて記述する。

healthCheckTimeout: 600
logLevel: info

models:
  Qwen_Qwen3.6-27B-Q3_K_M-64K.gguf:
    ttl: 1800
    cmd: >-
      llama-server
      -m /models/qwen36-27b/Qwen_Qwen3.6-27B-Q3_K_M.gguf
      -c 65536 -ngl 99 -fa on -ctk q4_0 -ctv q4_0 -b 512 -ub 128
      --parallel 1 --jinja --reasoning auto --reasoning-format deepseek
      --temp 0.2 --top-p 0.9 --repeat-penalty 1.12
      --no-mmap --host 0.0.0.0 --port ${PORT}

Opencode 側の設定(opencode.json

Opencode側にも「このモデルは64Kまで文脈を読める」と教えてあげる必要がある。これを忘れると、Opencode側で勝手に短いコンテキストで切り詰められてしまう。
(※設定ファイルは通常 ~/.config/opencode/opencode.json にある)

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "llama-swap": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "llama-swap",
      "options": {
        "baseURL": "http://127.0.0.1:8090/v1",
        "apiKey": "sk-swap"
      },
      "models": {
        "Qwen_Qwen3.6-27B-Q3_K_M-64K.gguf": {
          "name": "Qwen3.6-27B Q3_K_M (64k)",
          "limit": {
            "context": 65536,
            "output": 16384
          },
          "modalities": {
            "input": ["text"],
            "output": ["text"]
          }
        }
      }
    }
  }
}

5. このチューニングでどこまで実用できたか

ここまで設定した 16GB VRAM 環境の Qwen_Qwen3.6-27B-Q3_K_M-64K.gguf が、実際にエージェントとしてどこまで使えるかを検証した。

1. 動作確認

  • 評価したこと: 連続操作での安定性
  • 方法: Qwen_Qwen3.6-27B-Q3_K_M-64K.gguf の 64K プロファイルを llama-swap 経由で起動し、Opencode から短い指示(検索・編集・保存・修正)を連続で送り、応答可否・応答速度・途中停止の有無を確認した。
  • 結果: 起動から応答まで問題なし。連続操作中の停止やタイムアウトは発生せず、応答速度も実用に耐える水準だった。

2. 実運用での検証

  • 評価したこと: 単なるコード生成にとどまらない、実装〜運用〜障害対応までのシステム構築能力

  • 方法: Opencodeに「QXXta風のMarkdown記事ポータル」の開発からサーバー公開までの一連の作業を丸投げした。

  • 結果: 懸念していたVRAMスパイクによるクラッシュは起きず、ローカルLLM単独で以下のプロセスをすべて完遂した。

    1. Web実装: Node/Expressを用いて、ローカルのMarkdown記事を再帰スキャンし、Mermaid図やシンタックスハイライト付きで表示するポータルサイトを生成。
    2. Docker Compose統合: 既存の docker-compose.yml にサービスを追加し、他サービスと競合しないよう /QXXta へルーティングを設定してコンテナ起動。
    3. LANアクセス障害の切り分け: 起動後、「ホストPCからは見れるが、LAN内の別端末からアクセスできない」という事象が発生。LLM自ら原因をネットワーク層に切り分け、ホストOS側のファイアウォール・ネットワーク設定の不備を突き止めてコマンドから設定を変更し、無事復旧させた。
    4. 再発防止策の文書化: 復旧して終わりではなく、自らこのネットワークトラブルの原因と復旧手段を troubleshooting/ 配下にMarkdownの手順書として保存した。

コンテキストを64K確保したことで、これらの一連の作業(複数ファイルの編集、コマンド実行、ログ確認、文書化)を同一セッション内で文脈を崩さず進行できていた。ただし、opencodeのauto compactが数回自動で入っていた。

生成されたWebページ(トップ)
図3: 生成されたWebページ(トップ)

生成されたWebページ(記事一覧)
図4: 生成されたWebページ(記事一覧)

生成されたWebページ(記事本編)
図5: 生成されたWebページ(記事本編)

3. ベンチマーク評価

  • 目的: 大幅に量子化(Q3_K_M)し、メモリを削った状態でも、エージェントの頭脳として十分なコーディング能力を維持できているかを確認する。
  • 対象モデル: 今回構築した Qwen3.6-27B Q3_K_M 64K と、比較対象となるクラウドAPI(OpenRouter qwen/qwen3.6-27b、z.ai GLM-5.1)、およびMoEや下位クラスのローカルモデルを含む全7モデル。
  • 方法: 下表(表1)の3タスクを、評価対象の全7モデルに同一プロンプトで解かせた。返ってきた回答に対し、z.ai (GLM-5.1) と DeepSeek (DeepSeek-V4-Pro) のAPIを呼び出すPythonスクリプトによる自動採点および Gemini CLI と Codex の手動採点を行った。
  • 補足: これら4つのLLMにそれぞれ5点満点でブラインド採点させた平均を「総合評価」としている(表2、表3)。また、生成されたコードを手元で実行し、完動した数(最大 2/2)も記録した。特に金融タスクでは、yfinance を使った株価取得から移動平均(SMA)の交差判定、バックテストのグラフ描画まで一連の流れを実行させた。

表1: 評価に用いた3つのタスクと具体的なプロンプト要件

タスク 実際のお題(プロンプトの要件) 確認観点
日本語論理 「AIの自動化で職業教育は不要になる」という主張の論理的妥当性の評価。
・暗黙の仮定を2つ指摘
・演繹的/帰納的な反論の構築
・代替案の提示
要件読解力
説明の一貫性
論理的思考力
RateLimiter実装 トークンバケットを用いたスレッドセーフなAPIレートリミッターのPython実装。
・1秒あたりのリクエスト制御とバースト許容
threading.Lock の使用
・タイムアウト時のカスタム例外処理
・マルチスレッドでのテストコード
並行処理の堅牢性
アルゴリズム実装力
金融テスト Pythonコードによる日経平均の過去10年データを用いたバックテスト。
・25日/75日移動平均を計算
・ゴールデンクロスで買い、デッドクロスで売り
・Buy&Holdとの累積リターン比較
・データに応じたグラフ出力
データ処理
売買ロジックの正確性
データの可視化
数値要件の遵守
  • 結果: Qwen3.6-27B Q3_K_M 64K は総合 4.3、実行成功 2/2 となり、ローカルモデルの中ではトップクラス(MoEモデルである35BのQ4版と同等以上)の成績だった。
    強めに量子化(Q3_K_M)したにもかかわらず、クラウドAPIである Z.ai GLM-5.1 に近いスコアを出し、生成コードも確実に動作した上で、生成速度 36.1 tok/s という実用上十分なレスポンスの速さも確保できている。この性能を、16GB VRAMのローカル環境(通信費ゼロ)で使い倒せるのは大きなメリットだ。

評価に使った各LLMの総評は次の通りである。

  • z.ai: 全体に高評価。論理・実装・金融とも水準は高く、特にコードの正確性は強い。一方で、代替案の抽象性や実装の細部にはやや甘さがあると見られた。
  • DeepSeek-V4-Pro: かなり高評価。特に RateLimiter 実装は満点評価で、論理面も良好。ただし金融タスクは Parse failed で総評が不完全。
  • Gemini: ローカルモデルでは最強クラスという評価。コードロジック、スレッドセーフ性、バックテスト構成を強く評価した一方、初期資産1000万円を100万円で実装した要件ミスを明確に指摘した。
  • Codex: 実装力そのものは高く、特に RateLimiter は非常に優秀と評価。ただし金融タスクの数値要件違反を重く見て、手動で明確に減点した。

表2: 評価者別の平均スコアと実行成功数

順位 モデル Z.ai DeepSeek Gemini Codex 総合評価 実行成功 生成速度
1 OpenRouter qwen/qwen3.6-27b (API) 5.0 4.7 4.8 4.7 4.8 1/2* -
2 Z.ai GLM-5.1(API) 3.7 4.7 5.0 4.6 4.5 2/2 58.7 tok/s
3 Qwen3.6-27B Q3_K_M 64K 4.0 4.5 4.7 3.9 4.3 2/2 36.1 tok/s
4 Qwen3.6-35B-A3B Q4_K_M 3.3 4.3 4.6 4.4 4.2 2/2 34.7 tok/s
5 Qwen3.6-35B-A3B Q3_K_M 3.0 3.0 3.1 2.9 3.0 1/2 26.9 tok/s
6 GLM-4.7-Flash-Q4_K_M-GPUHOT 2.7 3.3 3.0 3.0 3.0 1/2 50.8 tok/s
7 GLM-4.7-Flash Q4_K_M 1.7 3.0 2.5 2.4 2.4 1/2 25.4 tok/s

OpenRouter1/2 は、金融コード実行時の外部データ取得(DNS)エラーによるもの。
※ 総合評価は各モデルの「全12スコア(3タスク×4評価者)の平均値」であり、各表の行平均とは一致しない。

表3: タスク別の平均スコア

モデル 日本語論理 RateLimiter 金融テスト 総合評価
OpenRouter qwen/qwen3.6-27b (API) 5.0 4.5 5.0 4.8
Z.ai GLM-5.1(API) 4.0 4.0 4.5 4.5
Qwen3.6-27B Q3_K_M 64K 4.0 4.5 4.0 4.3
Qwen3.6-35B-A3B Q4_K_M 3.5 4.0 4.0 4.2
Qwen3.6-35B-A3B Q3_K_M 4.0 3.5 2.0 3.0
GLM-4.7-Flash-Q4_K_M-GPUHOT 4.5 2.0 2.5 3.0
GLM-4.7-Flash Q4_K_M 4.0 1.5 1.5 2.4

移動平均バックテストのグラフ
図6: 金融タスクでQwen3.6 27B Q3_K_M 64Kが自動生成した移動平均バックテストのグラフ
一発のプロンプトでここまで出力できるのは好ましいが、売買シグナルのプロット位置やグラフの縦横比など細かいところには、まだ手直しの余地がある。

6. まとめと注意点

16GB VRAM環境であっても、チューニングすれば Qwen3.6-27Bの量子化モデル をOpen codeでエージェント用途で実用できる。

もちろん、大手LLMプロバイダのハイスペックモデルには劣る部分が多々ある。例えば、今回の検証や実運用の中でも、数値条件の取り違えなどが発生した。ローカルLLMを実作業に使うなら、「動いたか」だけでなく、「要件を守っているか」まで人間側が確認する仕組みは引き続き必要になる。

それでも、ほぼ電気代のみでローカルでここまで複雑な作業を行えるのは非常に有用だ。VRAM不足で27Bモデルを諦めていた方は、ぜひ試してみてほしい。

参考リンク

ツール / リポジトリ 概要
Opencode AI によるコード支援ツール
llama.cpp / llama-server C++ 実装の LLM 推論エンジン
llama-swap llama-server のオンデマンドプロキシ
bartowski/Qwen_Qwen3.6-27B-GGUF 今回使用した GGUF モデルファイル
Z.ai (GLM Coding Plan) 今回の評価・比較で活躍したコーディング向けAPI(招待リンク: ここから契約すると少し割引になる)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?