RX 7900 XTでQwen3.6 35BをCodex用にチューニングした記録(KV Cache量子化が効いた話)

(久々にブログを書いた!)

背景

現在の環境

  • ローカルLLMサーバー

    • Windows 11
    • AMD Ryzen 5 7600X
    • Radeon RX 7900 XT 20GB
    • RAM 64GB
    • LM Studio 0.4.16 (Build 2)
  • Codex操作クライアント

    • M2 MacBook Air
    • Codex CLI 0.141.0

やりたかったこと

  • ChatGPT Goを使っているので、Codexも使ってみたい
  • たかがプライベートプログラミングにChatGPT Plus(月額3000円)はちょっと……
  • せっかくRX 7900 XTを持っているのでローカルLLMに使いたい

Codex CLIの推論サーバー切り替え

Codex CLIはprofileを指定すれば推論サーバーを切り替えられる。

developers.openai.com

推論サーバー(model_providers)の定義を追加する

~/.codex/config.toml

approval_policy = "on-request"
approvals_reviewer = "auto_review"
sandbox_mode = "workspace-write"

[model_providers.home-lmstudio] 
name = "Home LM Studio"
base_url = "http://<home-lm-studio-ip-address>:1234/v1"

プロファイル(qwen36)に対応するconfig.tomlを作る

~/.codex/qwen36.config.toml

model_provider = "home-lmstudio"
model = "unsloth/qwen3.6-35b-a3b"

profileを指定してCodex CLIを起動する

% codex --profile qwen36

発生した問題

単純に LM Studio 上でチャットする分には、20 tok/sec くらいで出て、まあまあ使える。

でも、実際にCodex CLIとして長時間使っていると、10 tok/sec くらいまで遅くなる。なぜ???

GPU側でCopyが頻発

タスクマネージャでGPUの利用状態を確認すると

Compute
Copy
Compute
Copy

を繰り返している。

ローカルLLM推論時にGPUでCopyが頻発

最初の仮説

  • VRAM が足りない?
  • ROCm の問題?
  • Qwen 固有の問題?

原因調査

タスクマネージャのスクショと LM Studio のログを ChatGPT に渡して聞いてみると、

これはほぼ間違いなく VRAM不足による共有GPUメモリ(システムRAM)へのページング発生 を疑います。 コンテキスト長が 262k tokens まで成長しています。

Qwen3 35Bでコンテキスト長肥大化はKV Cacheが巨大になります。

KV Cacheが 1GB10GB みたいになって、VRAMからあふれて共有GPUメモリに逃げてしまい、 VRAMとRAMの間でswapが発生します。

とのこと。

仮説

以下のような現象が起きているということらしい。なるほどなぁ。

巨大コンテキスト
↓
KV Cache肥大化
↓
VRAM不足
↓
PCIe転送
↓
Copy増加

Context Lengthを変更

ChatGPT に薦められた通り、コンテキスト長を 262k → 32k に変更してみる。

LM Studioのコンテキスト長を32768に変更

Copyはだいぶ減った。

タスクマネージャのGPU利用状況からCopyが減った

15分くらいぶん回した後でLM Studioのログを見ると、16 tok/sec くらい出ているし、prompt eval time(プロンプト解析時間)も 27秒 くらいと現実的。

prompt eval time = 27296.96 ms / 24143 tokens ( 1.13 ms per token, 884.46 tokens per second) 
eval time = 26720.13 ms / 432 tokens ( 61.85 ms per token, 16.17 tokens per second) 
total time = 54017.09 ms / 24575 tokens 
graphs reused = 10791

GPU Offload はどれくらいの値がいい?

モデルだけでVRAMが全部埋まるとキャッシュの類がRAMに逃げてしまうので、VRAMの空きがある程度あったほうがいいのかな?とおもい、GPU Offloadによって生成速度がどれくらい差があるのか調べてみた。

GPU Offload 生成速度(平均) 生成速度(最高) 相対評価
28 約18.4 tok/s 約19 tok/s ちょっと遅い
30 約20.6 tok/s 約21 tok/s 結構早い
32 約17.3 tok/s 約18 tok/s ちょっと遅い
38 約22 tok/s 約25 tok/s 一番早い

※同じ質問・同じモデル再ロード状態で比較したが、実行誤差もあるので参考値程度。

実行時の誤差があるので、あんまり細かい数字に意味はないけど、やっぱり GPU Offload=38 が一番早い。

ただし、コンテキスト長が増えて VRAM を圧迫してきたときに、 GPU Offload=38 で速度を維持できるのか? という問題もある。

今回は38が最速だったが、長時間運用時の安定性やコンテキスト増加時の余裕を考えると、30〜38の範囲で環境に合わせて調整するのが良さそう。

KV Cache量子化の検証

X(旧Twitter)で、KV Cache 量子化が F16 だの Q8 だのというのを見かけたので、ChatGPTに聞いてみた。

これは KV Cache(Attentionの過去トークン記憶領域)を量子化してメモリ使用量を減らす機能 です。

なるほどね。

KV Cacheを量子化してメモリ使用量を減らせれば、コンテキスト長を伸ばしても性能が維持できるのでは?

KV Cache量子化の比較

今回一番効果が大きかったのはKV Cache量子化だった。

前提

Context Length = 65536
GPU Offload = 38
KV Cache量子化 生成速度 コメント
F16/F16 11~15 tok/sec VRAMに収まらない。遅い。
Q8/F16 約12 tok/sec 予想外に遅い。ROCmの実装最適化不足?
Q8/Q8 20 tok/sec超 だいぶ早い。いいね!

K=Q8 / V=F16 が予想外に遅かった。ROCmの実装が最適化されていないとか、KとVで型が違うのが計算のボトルネックになってるとかあるんですかね?

K=Q8 / V=Q8 はコンテキスト長 65536 でもだいぶ早い。いい設定を見つけた。

現在の設定

最終的にこの設定に落ち着いた。

Context Length = 65536

GPU Offload = 38

K Cache = Q8_0
V Cache = Q8_0

Parallel = 1

Context Length

262,144トークンそのものが問題というより、巨大なKV Cacheが生成されてVRAMを圧迫するのが問題。

コンテキスト長を小さくしておくと、RAM⇔VRAMのコピーが発生しても短時間で終わるので、性能劣化が発生しづらい。あまり小さくするとLLMの記憶力が少なくなるので、 個人的には 32,76865,536 (KV Cache量子化前提)くらいがおすすめ。

GPU Offload

CPU側に層を寄せすぎると当然推論速度は下がるので、コンテキストの最大サイズを考慮しながら、利用可能な最大値を設定する。

Qwen3.6 35B A3B UD (Q4_K_M) はモデルのサイズが 約23.9GB (LM Studio上の表記)なので、私の環境では ちょうどVRAMに乗り切りそうな GPU Offload=38 を選択。

KV Cache 量子化設定

コンテキストが大きくなることに伴う KV Cache肥大化を抑える設定。

コンテキストがVRAMからあふれるのはまあしょうがないと割り切るとして、K=Q8/V=Q8 にするとコンテキストのキャッシュがコンパクトになるので、コンテキスト長 65536 でも RAM⇔VRAMのコピーが発生しても全体の処理性能に影響しづらい。

Parallel (Max Concurrent Predictions)

今までの話には出てこなかったけど、LM Studioサーバーの同時リクエスト処理数。

ベンチマークではParallel数の変更はほぼなかった。

しかし Codexは開始時に複数リクエストを投げるため、私の用途ではParallel=1の方が安定 した。Codex CLIは、処理の開始のタイミングで3~4個(auto-approvalも含む)のリクエストを同時に投げるので、デフォルト値の4だとLLM側でGPUリソースの取り合いが発生し、推論処理が輻輳してしまう。

今回の使い方では、ユーザーは私一人なので、1でリクエストをキューイングするようにしている。

Codex運用の工夫

最初

Codex上で設計→実装→テスト→デプロイまで全部やらせる

問題

  • コンテキスト肥大化
    • コンテキスト長 65536 とかだと、プロンプト再評価の処理時間が長くなる
  • auto-approval 遅延
    • Codex CLI が auto-approval を並行して投げることが多い
    • Codex CLI の auto-approval のタイムアウトが比較的短いのでタイムアウトしやすい

現在

ChatGPT
↓
調査
↓
ISSUE作成

Codex
↓
ISSUE実装
↓
PR作成

メリット

  • コンテキストリセットのタイミングが分かりやすい
    • ISSUE ごとに /new/compact でコンテキストをリセットできる
  • ChatGPT 側で GPT 5.5 を使って設計できる
    • GitHub 連携しておくと、GitHubのコードを見たり、ISSUEを作ったりできる

まとめ

LM Studioの設定

項目 設定
Context 64k
Offload 38
K Cache Q8
V Cache Q8
Parallel 1

LM Studioのqwen3.6の設定

学び

  • Context Length は思った以上に重要
  • KV Cache 量子化は効果大
  • Q8/F16よりQ8/Q8が速かった
  • Codex 運用ではコンテキスト管理も重要
  • ChatGPT と Codex の役割分担をしよう

ローカルLLMの速度改善も重要だったが、実際には

ChatGPTで設計(GPT 5.5)
↓
Codexで実装(Qwen 3.6)

の役割分担も大切。

結局のところオンラインLLMサービス(ChatGPT / Claude)が最強なのは周知の事実なので、ローカルLLMをオンラインLLMの代替として使うのではなく、得意分野で役割分担させるのが満足度が高くなってよいと思う。

今使ってる ASRock Radeon RX 7900 XT Phantom Gaming を張りたかったけど、Amazonに在庫無かった。

NNDD v2.4.0のリリース

どうもお久しぶりです。NNDD v2.4.0をリリースしました。
LAN上のNNDD同士でマイリスト一覧を同期できるようになっています。

以下のページからダウンロードできます。
http://sourceforge.jp/projects/nndd/releases/

以前のバージョンからアップデートできない

NNDD v2.3.1からアップデートインストールしようとすると、上記の画面が出てインストールできません。(上記画像はMacの画像ですが、Windowsでも同様です。)お手数ですが、一度古いNNDDをアンインストールしてから、NNDD v2.4.0をインストールしてください。
ニコニコ動画へのログイン情報(メールアドレス・パスワード)以外の各種設定は、アンインストールしても消えません。

MacBook Air (13" Mid 2012)買った

MacBook Air (13" Mid 2012) その1

MacBook Air (13" Mid 2012)を買いました。Core i5のモデルで、メモリのみ8GBに増設です。やっぱりこれからの時代、8GBは欲しいですよね。
私がMacBook Airでやりたいことは以下の4つ。

  • プログラミング(NNDDの開発とか)
  • NNDDでニコ動を見る
  • iTunesで音楽聞く
  • NEX-5で撮ったJPEGをちょこっといじる

MinecraftCeleronWindowsマシンが予想外にいい仕事をしてくれるので必須ではありません。
CPU性能はMid 2011のSandy Bridge世代Core iで十分満足していたので、今後の拡張性はUSB3.0対応で気にならなくなり、Safari+Flash Builder+仮想マシン+(iPhoto)の同時起動でスワップ大量発生してひーひー言ってたのも、メモリ8GBで不満点はなくなりました。
そして1kg台という軽さも魅力。バッテリ残量も7時間で、SDカードリーダーもついている。

MacBook ProRetina液晶も少し惹かれますが、Flash Builderとかその辺の対応に少なくとも今年いっぱいはかかりそうなので、急ぐほどでもないかなと。MacBook AirRetina対応してから考えます。

Apple MacBook Air 1.7GHz Core i5/13.3/4G/128G/802.11n/BT/Thunderbolt MC965J/A

Apple MacBook Air 1.7GHz Core i5/13.3/4G/128G/802.11n/BT/Thunderbolt MC965J/A

ギャラリー

MacBook Air (13" Mid 2012) その2

MacBook Air (13" Mid 2012) その3

MacBook Air (13" Mid 2012) その4

Air Mac Express

ついでと言っては何ですが、Air Mac Expressを買いました。ようやく我が家も11n対応です。
AirMac Express

久々に自作しようと思ってマザーボード買った(その3)

DSC07859

その2で作った自作マシンでMinecraftをやっていたわけですが、やはりIntel HD Graphicだと1920x1200でFar設定はきつい…。そんなわけでグラフィックカードがほしくなりました。
グラフィックカードを買うとなると、Mini-ITXのケースだとカードのファン部分が収まらないので、同時にケースも新調しなければなりません。
そんなわけで以下の商品を調達。

Sharkoon M-ATXケース ブラック SHA-MS140

Sharkoon M-ATXケース ブラック SHA-MS140

そんなわけで、Mini-ITXケースから新Micro-ATXケースにお引越ししました。

新しく調達したPCケース

電源の青色LEDがまぶしすぎるので、LEDの上に紙を3枚重ねたものを両面テープで張りました。あと正面のファンの青色LEDも中二臭い。(ファンの四隅にホットボンドでLEDが固定されててはずせなかった。)
ファンの性能そのものは申し分ないです。口径の大きいファンなので回転数はほとんど聞こえません。
PC全体としては、CPU・電源・グラフィックカード・ケース前面・ケース背面の5つのファンがついていますが、CPUはリテールファン、電源は玄人志向の静音電源、前面は140mm、背面は92mm。今回はかなりファンの音に気を使ったので、部屋の換気扇の音のほうがよっぽどうるさいレベルにできました。
(音は気にならないけど、むしろ前述のLEDの明るさが気になる。)

GeForce GTS 450に換装した結果、Windows エクスペリエンス インデックスは以下のようになりました。

GTS 450(1GB) Celeron G530(Intel HD Graphics)
プロセッサ 6.2 6.3
メモリ(RAM) 7.4 7.4
グラフィックス 7.2 5.1
ゲーム用グラフィックス 7.2 4.7
プライマリハードディスク 5.9 5.6

グラフィックスとゲーム用グラフィックスが7点台!わぁい!

Minecraft楽しい


Minecraftが1920x1200のFar+16設定でぬるぬる動くようになりました!

久々に自作しようと思ってマザーボード買った(その2)

先日のZotacさんマザーボードが2台とも起動せず、失意のどん底Amazonを巡回していたのですが、ふと、mini-ITXでもCore iシリーズのCPU(LGA 1155)が載るということに気づく。

BIOSTAR Intel Socket LGA1155 mini-ITXマザーボード TH61 ITX

BIOSTAR Intel Socket LGA1155 mini-ITXマザーボード TH61 ITX

「なるほどなー、SandyBridge世代とかだったらそろそろ安くなってるのかなー」と思いながらCPUの価格調査をしたところ、やたらとCeleronをプッシュされていることに気づく。

Celeronとかそんなブランドもありましたね・・・っていうかまだあったんですか・・・

で、何でこんなにプッシュされているのか調べたら、
Celeron G530購入 - まきまき工房
をはじめ、各所で「安い割りにいい性能」という評価。さすがに世代がひとつ進んだIvyBridgeと比較するとあれでしょうが、SandyBridge世代のCore i3と比較している記事もありました。

3000円代でSandyBridge世代のCPUを買えるならいいなぁ・・・と思い、Atom省電力PC計画から路線を変更。Celeron G530で安価にそこそこ動くPCを作ることにしました。

Intel Celeron G530さん

インテル Celeron G530 2.40GHz 2M LGA1155 SandyBridge BX80623G530

インテル Celeron G530 2.40GHz 2M LGA1155 SandyBridge BX80623G530

IvyBridge世代のCeleronもそろそろ出そうな気がするけど、まあ気にしない。

メモリ8GB(4GB×2)

メモリ安いなぁ・・・

実測

さて、動かします。今回は何も苦労することなく動きました。

Windows7のエクスペリエンス インデックスは以下のとおり。

項目 Celeron G530 Atom330(NVIDIA ION)
プロセッサ 6.3 3.3
メモリ(RAM) 7.4 4.4
グラフィックス 5.1 2.9
ゲーム用グラフィックス 4.7 4.9
プライマリハードディスク 5.6 5.6
基本スコア 4.7 2.9

プロセッサでの演算、メモリ操作、通常のグラフィックスは、Atom330と比較すると軒並み倍の性能!3000円代でこの性能はおいしすぎるでしょう。(まあ比較対象がおかしいけど)
ゲーム用グラフィックスはNVIDIA IONがちょっとがんばった感じがありますが、まあ世代が古すぎてIntel HD Graphicsに肉薄されています。

D2700-ITXがあまった

先日のブログへのコメントのおかげで、D2700-ITX(2台目)は初期不良じゃないことがわかったのですが、G530を買ってしまったので完全に余ってしまったD2700-ITX。とはいえきっと消費電力とか発熱とかからいうとAtom D2700のほうがいいんだろうなー。夏の省エネに向けてとりあえずキープしておきますかねぇ。