3構成の結果

IQuest-Coder-V1-40B を CPU(EPYC 9175F)、GPU(vLLM + nvfp4)、Aider の whole-edit で比較しました。開発パイプラインに使うため、入力と生成の速度、終端制御を確認しています。

今回の CPU 構成は長い入力の待ち時間が大きく、GPU は25–28 tok/sでした。GPU でも whole-edit は全ファイルの出力が長くなるため、待ち時間が増えました。

実験環境

項目仕様
CPUAMD EPYC 9175F(Zen 5, 16C, L3 512MB)
GPUNVIDIA RTX PRO 6000 Blackwell Max-Q(96GB VRAM)
メモリDDR5-6400 768GB(12ch)
OSUbuntu 24.04 LTS

検証構成

構成Runtime量子化配置
A: CPU推論llama.cpp server(Podman)Q5_K_M(GGUF)CPU RAM
B: GPU推論vLLMnvfp4GPU VRAM
C: Aider利用vLLM(Loop-Instruct variant)nvfp4GPU VRAM

CPU構成の待ち時間

IQuest-Coder-V1-40B-Instructは40B級のDense(非MoE)コーディング特化モデルです。MoEモデルと違い推論時に全パラメータを使うため、計算量がそのままモデルサイズに比例します。

最初に試したのは、IQuest-Coder-V1-40B-Instruct.q5_k_m.gguf を Podman 上の llama.cpp server を用いて、GPUを使わずにCPU(AMD EPYC 9175F, 16コア)のみで起動する構成です。コンテキスト長は 8192 に設定し、AiderやエージェントシステムなどTTFT(Time To First Token)と低レイテンシが求められる「待たない」パイプライン処理を想定していました。

CPU では次の問題を確認しました。

  • CPU 使用率: Dense 40B は各 token で全層を計算し、コアが高い使用率を維持しました
  • TTFT: 4k〜5k tokens を超える入力(例: task.n_tokens=4640)では Prompt evaluation の待ち時間が長くなりました
  • SSD: ロードは短くなりましたが、生成と Prompt eval の速度はほぼ変わりませんでした
  • batch 設定: llama-server の batch-size 2048、ubatch-size 512 は throughput 寄りで、低レイテンシ用途に合いませんでした

NUMA bind、スレッド指定、mlock は適用済みでした。この構成では、Dense 40B の CPU 処理が主な制約と考えています。

構成A 計測結果

項目実測値
TTFT(4k-5kプロンプト時)数十秒(体感破綻)
CPU使用率全コア100%張り付き
問題の本質40B全層を毎トークン計算、省略不可

GPU(nvfp4)環境への移行と実測

CPUでの限界を踏まえ、GPUを利用した構成(vLLM + nvfp4)へと移行しました。比較対象として、111Bクラスの推論モデルである command-a-reasoning も並行して評価しています。

実測スループット

vLLMのログから得られた実測値は以下の通りです。

指標実測値
PP速度(Prompt throughput)1,100-2,300 tok/s
TG速度(Generation throughput)25-28 tok/s(安定)
KVキャッシュ使用率2-12%
Prefixキャッシュヒット率20-45%

vLLMログからの連続計測(抜粋):

  Engine 000: Avg generation throughput: 28.3 tokens/s, KV cache usage: 2.0%, Prefix cache hit rate: 22.8%
Engine 000: Avg generation throughput: 28.0 tokens/s, KV cache usage: 2.3%, Prefix cache hit rate: 22.8%
Engine 000: Avg generation throughput: 27.8 tokens/s, KV cache usage: 2.8%, Prefix cache hit rate: 22.8%
Engine 000: Avg generation throughput: 27.4 tokens/s, KV cache usage: 3.5%, Prefix cache hit rate: 22.8%
  
  • Prompt throughput は約1100〜2300 tok/sでした
  • Generation throughput は25〜28 tok/sで、111Bの command-a-reasoning より約2.3〜2.5倍速くなりました
  • KV cache usage は2〜12%でした
  • Prefix cache hit rate は20〜45%でした。system prompt と tool schema の固定で改善する余地があります

Running: 1 reqs の間は生成が続いていました。ログの「0 tok/s」は集計窓のタイミングと考えられ、ハングやデッドロックの兆候は見られませんでした。

TG 25–28 tok/sから見積もった、出力長ごとの待ち時間です。

  • 200トークン: 約7-8秒
  • 400トークン: 約14-16秒
  • 800トークン: 約30秒

111Bモデルより半分以下の待ち時間です。agent やテスト生成に使う際の差になります。

Aider whole-edit形式での検証

Aider の whole-edit では、出力全体の長さが問題になりました。

指標実測値
TG速度0.6-8 tok/s(不安定)
KVキャッシュ使用率7-13%(急激に増加)
Prefixキャッシュヒット率6%(ほぼ無効)

whole-edit は全ファイルを生成します。repo-map と添付ファイルで入力も増え、KV cache が増加しました。毎回 context が変わるため、prefix cache hit rate は6%でした。

比較サマリ

構成TG速度(tok/s)実用判定用途
A: CPU Q5_K_M測定不能(TTFT破綻)不可-
B: GPU nvfp425-28実用agent/テスト生成/CI
C: Aider whole-edit0.6-8非実用-

Performance Factor(PF)の定義

実務での体感に直結する指標として、モデル規模(パラメータ数)あたりの生成トークン数を「PF(Performance Factor)」として定義しました。

PF ≒ generation tok/s ÷ モデル規模(B)

モデルパラメータTG速度tok/s per B相対PF
command-a-reasoning111B~11 tok/s0.101.0
IQuest-Coder-40B nvfp440B26-28 tok/s0.65-0.70≈6.5-7.0
小型7B fp167B60-80 tok/s9-11別枠

この PF では IQuest-Coder-40B が111B系の6〜7倍でした。サイズあたりの速度比較であり、推論品質や nvfp4 の正しさを単独で証明する指標ではありません。

考察

なぜDenseはCPUで厳しいのか

MoEモデル(例: Kimi-K2.5の活性32B)はトークンごとに一部のエキスパートだけ計算します。Denseは40B全層を毎回計算するため、計算量の削減が効きません。同じ「40B級」でもCPU推論の負荷は根本的に異なります。

12チャネルの EPYC 9175F でも、全層を読む Dense の負荷は大きくなります。MoE の一部 expert を L3 cache に残す方式とはアクセスが異なります。

項目Dense 40BMoE 229B(活性10B)
毎トークンの計算量40B全層10B相当
L3キャッシュ活用効かない(全層アクセス)効く(エキスパート局所性)
CPU推論のTG測定困難10-37 tok/s
CPU推論の実用性非実用バッチ用途で実用

Aider whole-editの構造的問題

whole-edit形式が遅い原因:

  1. ファイル全体を出力するためトークン数が膨大
  2. repo-map + 添付ファイルでpromptも肥大
  3. Prefixキャッシュヒット率が6%(変動するコンテキストのため)
  4. KVキャッシュが急速に膨張(7→13%)

対策はwhole-editを避けてdiff/patch形式に変更することです。出力トークン数を大幅に削減でき、生成速度の問題を構造的に回避できます。

モデル品質と制御性

Go の構造化した長いテストコードを生成できました。111B Reasoning モデルより、論理の誤りや原文にない補完が少ない例もありました。EOS(End of Sequence)と stop・max_tokens が効き、生成の終端を制御できました。

深い推論、証明、長い思考では command-a-reasoning を候補にしています。日常の生成では、速度と終端制御も比較します。

安定運用できている理由

安定して動いた構成の特徴は次の4点です。

  1. nvfp4 × vLLM main/nightly の組み合わせが成立している
  2. stop / max_tokens が適切に効いている
  3. Instruct 型らしく EOS が素直で、出力の終端制御がしやすい
  4. agent-gateway の設計と噛み合っている。特に non-stream 時だけ retrieval を差し込むような実装方針とも整合している

LLM導入では、モデルだけでなく serving と agent-gateway の組み合わせも確認する必要があります。

改善策の優先順位

同じ待ち時間の問題を調べる場合の候補です。

  1. GPU 配置 --device nvidia.com/gpu=all と --n-gpu-layers 999 で GPU に載せます。今回の GPU は RTX PRO 6000 MAX-Q 96GBです。
  2. CPU 用の調整案
    • batch-size を512〜1024にします。
    • ubatch-size を128〜256にします。
    • 履歴と repo-map を減らします。
  3. モデル縮小案 CPU が必要なら7B〜14Bを候補にします。

再現用の設定

GPU nvfp4(推奨構成)

  vllm serve IQuestLab/IQuest-Coder-V1-40B-Instruct-nvfp4 \
  --max-num-seqs 1 \
  --max-model-len 32768
  

CPU Q5_K_M(参考: 非推奨)

  podman run --rm -it \
  -p 8081:8080 --shm-size 16g --cap-add=SYS_NICE \
  -v "$MO":/models:ro,Z $IMG \
  --host 0.0.0.0 --port 8080 -m "$MODEL" \
  --jinja -c 8192 \
  --threads 14 --threads-batch 14 \
  -b 2048 -ub 512 \
  --parallel 1 --flash-attn on
  

Aider設定の最適化

  • --edit-format diff: whole-editを避けて出力を削減
  • temperature=0: greedy固定で生成を高速化
  • repo-mapと/add対象を最小限に
  • max_model_lenを必要最小に設定

結論と今後の展望

今回の環境では、IQuest-Coder-V1-40B + nvfp4 + vLLM は日常の生成に使う候補になりました。次の分担を検討しています。

  • 日常(agent/aider/CI): IQuest-Coder-40B nvfp4を主候補にします
  • 深い推論・設計レビュー: command-a-reasoning(サブ)
  • バッチ処理(CPU常駐): MoEモデル(Kimi-K2.5等)

IQuest-Coder-40B を標準のルーティング先とし、難しい推論や設計レビューを command-a-reasoning に任せる案です。25–28 tok/sという速度だけで、全タスクの品質を判断したものではありません。

次は prompt を固定し、prefix cache hit rate を約40%から60%以上にすることを目標にします。p95 latency を基準とした SLO の調整も予定しています。