私は llama.cpp における KV キャッシュ圧縮のための、オープンソース TurboQuant 実装に取り組んでいて、そこで致命的なボトルネックにぶつかりました。dequant(デクォント)です。
長いコンテキスト(M5 Max で 32K)では、dequant だけでデコード時間の約 40 パーセントを占めていました。
いつものやり方で直そうとしました: - LUT(ルックアップテーブル)の登録
- SIMD の小技
- フューズドカーネル
- 分岐なしの数式
約 14 種類のアプローチをテストしました。どれもベースラインを上回りませんでした。ハードウェア側はすでに限界でした。
最終的にうまくいったのは、ずっとシンプルな方法でした。
フラッシュアテンションは、V に触れる前に softmax の重みを計算します。
長いコンテキストでは、それらの重みのほとんどが基本的にゼロです。
そこで、dequant を速くするのではなく、注意(attention)が無視できる位置では V のデクォントを丸ごとスキップすることにしました。
カーネル内ではだいたい 3 行です。
Qwen3.5-35B-A3B(M5 Max)での結果:
TurboQuant KV(turbo3): - +22.8% デコード(32K)
- PPL 不変
- NIAH: 7/9 → 9/9
標準の q8_0 KV キャッシュ: - +5% デコード
- PPL 同一
- NIAH 同一
つまり、これは TurboQuant 固有の話ではありません。アテンションのスパース性をそのまま使っています。
また M2 Pro でもテストしました: - K 側で 4-mag LUT + スパース V スタックはきれいに動作
- turbo3 は ~0.45x → ~0.73x(q8_0 と比べて)
リポジトリとベンチマーク:
https://github.com/TheTom/turboquant_plus
解説:
https://github.com/TheTom/turboquant_plus/blob/main/docs/papers/sparse-v-dequant.md
CUDA や他のセットアップで試してみたい人がいれば、結果を見られると嬉しいです。
注:CUDA ポートは現在、独立してテスト中です。利用可能になり次第、結果を共有します。
[link] [comments]
![[Boost]](/_next/image?url=https%3A%2F%2Fmedia2.dev.to%2Fdynamic%2Fimage%2Fwidth%3D800%252Cheight%3D%252Cfit%3Dscale-down%252Cgravity%3Dauto%252Cformat%3Dauto%2Fhttps%253A%252F%252Fdev-to-uploads.s3.amazonaws.com%252Fuploads%252Fuser%252Fprofile_image%252F3618325%252F470cf6d0-e54c-4ddf-8d83-e3db9f829f2b.jpg&w=3840&q=75)



