背景

Llama-4-MaverickはMetaのMoEモデルで、128個のエキスパートから少数を選択する構成。総パラメータは大きいが活性パラメータは17B級に収まるため、CPU推論でも現実的な速度が出る。

768GB DDR5メモリのEPYC 9175F環境では、Q4_K_M(約290GB)もQ8_0(約426GB)も物理メモリに収まる。問題は「どちらを選ぶか」。速度重視のQ4_K_Mと品質重視のQ8_0を同一環境・同一タスクで比較し、用途別の選択基準を出した。

目的

  1. Q4_K_MとQ8_0のPrefill/Decode速度を同一環境で比較
  2. TTFT(Time To First Token)の差を定量化
  3. 出力品質の差を実務タスクで評価
  4. バッチ処理とaider利用での使い分け基準を確立

実験環境

項目仕様
CPUAMD EPYC 9175F(Zen 5, 16C, L3 512MB)
メモリDDR5-6400 768GB(12ch)
GPU使用せず(CPU推論)
OSUbuntu 24.04 LTS
Runtimellama.cpp server(Podman rootless)
スレッド14
コンテキスト16,384

モデル仕様

項目Q4_K_MQ8_0
アーキテクチャLlama-4-Maverick(MoE, 128E)同左
モデルサイズ約290GB約426GB
量子化精度4bit混合8bit

結果

速度比較

指標Q4_K_MQ8_0差分
PP速度(tok/s)65-6850-52Q4が約30%高速
TG速度(tok/s)21-2415-16Q4が約40%高速
TTFT(800-1000tok)12-17秒16-20秒Q4が3-5秒速い

Q4_K_M実測ログ

Prompt(tok)PP時間(s)PP速度(tok/s)Gen(tok)TG速度(tok/s)
81912.068.416523.7
1,10116.865.481421.3

Q8_0実測ログ

Prompt(tok)PP時間(s)PP速度(tok/s)Gen(tok)TG速度(tok/s)
81915.652.410416.6
1,00019.750.891615.2

メモリ挙動

  • Q4_K_M: mmap + page cacheで必要部分のみ常駐。prompt cache 1エントリあたり180-380MiB
  • Q8_0: buff/cacheに数百GBが載る。RSSは小さく見えるが正常(mmapの特性)
  • MoE(128E)のため、アクティブなエキスパートのみ頻繁に参照され、未使用ページは温まりにくい

考察

速度差の原因

Q4_K_MはQ8_0の約68%のモデルサイズ(290GB vs 426GB)。MoE推論ではトークンごとに選択されたエキスパートの重みをメモリから読む。読み出すデータ量がそのままメモリ帯域消費になるため、小さい量子化ほどメモリ帯域の制約を受けにくい。

TG速度の差(40%)がモデルサイズの差(32%)より大きいのは、Decode時のランダムアクセスパターンでキャッシュミスが増え、メモリレイテンシの影響が増幅されるため。

品質差の実感

Q8_0の方が:

  • 文脈保持が安定(長い会話で話が逸れにくい)
  • 破壊的編集が減る(aiderでのコード修正で特に顕著)
  • 推論の「安心感」がある

ただし差は劇的ではない。コード雛形生成や要約タスクではQ4_K_Mで十分。差が出るのは複雑なリポジトリ操作や長文生成。

768GB RAM環境だからこそQ8_0が選択肢になる

Q8_0の426GBは一般的なサーバーでは非現実的だが、768GB DDR5環境ではモデル + KVキャッシュ + page cacheが全てメモリに収まる。「メモリが余っているならQ8_0」という判断は、この環境固有の合理性。

感想

Q4_K_MとQ8_0の使い分けは「速度 vs 品質」ではなく「用途の性質」で決まる。

  • 高回転のワンショット生成、Dagster/dbtのバッチ処理: Q4_K_Mが有力。速度40%差は処理量に直結
  • aider運用、複雑なrepo操作、長文生成: Q8_0。破壊的編集のリスク軽減が速度差より重い
  • 日次ON/OFF運用: Q4_K_M。起動が速い
  • 常時稼働・常駐: Q8_0。品質安定性が長時間運用で効いてくる

MoEモデルのCPU推論では、Denseモデルと違って量子化レベルの選択肢が実用的な範囲に収まる。128エキスパートの局所的なアクセスパターンがメモリ帯域の効率的な利用に寄与しているため、Q8_0でも15-16 tok/sが出る。

再現方法

Q4_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 /models/Llama-4-Maverick-17B-128E-Instruct-Q4_K_M.gguf \
  --jinja -c 16384 \
  --threads 14 --threads-batch 14 \
  -b 1024 -ub 256 \
  --parallel 1 --flash-attn on
  

Q8_0

同一コマンドでモデルファイルをQ8_0版に変更。

補足ノウハウ

MoEのmmap挙動

128エキスパートのうち少数しか使わないため、mmap page cacheの「温まり方」が偏る。連続して同じトピックを処理すると同じエキスパートが繰り返し参照され、キャッシュヒット率が上がる。逆にトピックが頻繁に変わるワークロードではpage faultが増える。

prompt cacheの効果

Q4_K_MでもQ8_0でも、prompt cacheのLCP similarity hitは有効。固定System Promptを使う運用では2回目以降のTTFTが大幅に短縮される。