先週、Gemma 4 を CUDA 上で動かすのに取り組みました。フル精度(BF16)と GGUF の量子化推論の両方で動作させています。以下、その様子の動画です。ほかに見落とされがちな癖があるモデルなので、いくつかの発見を共有します。
性能(Gemma4 E2B、RTX 3090):
| 設定 | BF16 Float | Q4_K_M GGUF | |-------------------------|------------|-------------| | 短い生成(p=1, g=32) | 110 tok/s | 170 tok/s | | 長い生成(p=512, g=128) | 72 tok/s | 93 tok/s | 誰も警告してくれない精度の罠
正直、動かすのは私が思っていたよりずっと大変でした。
Gemma 4 は attention_scale=1.0 を使います(通常の 1/sqrt(d_k) ではなく QK-norm)。これにより、標準的なトランスフォーマーよりも 精度エラーへの感度が約22倍高くなります。LLaMA や Qwen でうまくいくことが、Gemma 4 では静かにゴミの出力になります:
- F16 KV キャッシュ? 精度の損失がデコード手順を通して増幅され、約50トークン後に出力が崩壊する
- 融合(fused)アテンションカーネル? 約4ステップ後にトークンが発散する
- head_dim=512 の Flash Attention v1? ロジットが全ゼロになる(カーネルのバグ)
私が到達したルールはこれです:KVキャッシュの境界で dtype 変換をしないこと。BF16 モデル = BF16 の KV キャッシュで、内部のアテンション計算は F32。F32 GGUF = F32 の KV キャッシュ。モデル重みとキャッシュの間で dtype を混ぜると、そこで破綻します。
精度を正しく合わせられた後は、出力が Python の transformers とトークン単位で一致しました(最初の30トークンを HF のフィクスチャで検証済み)。
ほかにも知っておくと良いこと:
- ハイブリッドアテンション(スライディングウィンドウのローカル+head_dim=512 のフルグローバル)なので、標準の SDPA をそのまま差し込むことはできません。Metal の SDPA は head_dim=256 で上限があり、また Flash Attention v1 には 512 のところでカーネルバグがあります
- 最後の N 層での KV キャッシュ共有により、KV メモリが約57%節約でき、コンシューマ向けカードへの収まりが良くなる
- アーキテクチャは本当に新しい(デュアル RoPE 設定、層ごとの埋め込み、サンドイッチノーム)で、単なる別の LLaMA 亜種ではありません。そこがクールです。とはいえ、アテンションのスケーリングがあれば精度問題がここまで大きくならずに済んだのに、とは思います
Gemma 4 をローカルで動かしている人、ほかにもいますか? 同じ精度の問題に当たったか、私が見逃した回避策を見つけたかが気になります。
[リンク] [コメント]




