一、TurboQuant 速览
| 项目 | 内容 |
|---|---|
| 发布方 | Google Research(Amir Zandieh & Vahab Mirrokni) |
| 论文 | TurboQuant / PolarQuant(AISTATS 2026) / QJL(AAAI 2025),ICLR 2026 报告 |
| 定位 | KV 缓存量化算法(不是权重量化) |
| 核心 | PolarQuant(笛卡尔→极坐标映射消常量)+ QJL(1-bit 残差纠错) |
| 压缩比 | KV 缓存 ≥6×(输出 3-bit) |
| 精度 | LongBench / RULER / Needle-In-A-Haystack 等零损 |
| 训练 | 无需训练、无需校准(data-oblivious,即插即用) |
| 现状 | 算法已公开;llama.cpp 对应 PR #21089(tbq3_0/tbq4_0) 待合入,目前 CPU-only |
| 一句话 | 压的是"占显存大户"的 KV 缓存,长上下文本地推理的显存账要重算 |
二、核心亮点
1. 它压的是 KV 缓存,不是权重——这是多数指南跳过的区别。权重量化(Q4_K_M 等)压缩的是模型" permanent 知识",让模型塞进显存;KV 缓存量化压缩的是推理时每个 token 的"临时工作记忆"。当上下文从 4K 拉到 128K,权重一分没涨,涨的全是 KV 缓存。一个 70B 模型在 128K 上下文下的 KV 缓存本身就能吃掉 40GB+ 显存——比很多量化后的权重(Q4 约 35–40GB)还大,甚至比权重更先顶爆单卡。TurboQuant 瞄准的正是这个被忽视的瓶颈:很多人以为把权重压到 Q4 就能本地跑长上下文,结果卡在 KV 缓存上。
2. PolarQuant + QJL 两步,做到"零额外开销"。传统向量量化要为每个小块存全精度量化常数,额外吃掉 1–2 bit,部分抵消收益。TurboQuant 先随机旋转向量、转成极坐标(半径+角度),映射到固定的"圆形网格",省掉昂贵的归一化与常量存储;再用 QJL(基于 Johnson-Lindenstrauss 变换)把残差压成单个符号位(+1/-1)做误差纠错。两步叠加,3-bit 输出、6× 压缩,且不需要任何校准数据。
3. 6× 压缩、零损、即插即用。Google 在 Gemma / Mistral 上跨 LongBench、RULER、NIAH、ZeroSCROLLS、L-Eval 五套长上下文基准验证:下游任务结果"完美"(非可接受区间,是零损);4-bit TurboQuant 在 H100 上注意力计算较 32-bit 基线最高8× 加速。最关键的是不需要重训、不需要微调——这点让它在生产侧一旦集成就能直接 drop-in。它还是># 方案 A:llama.cpp 最新版(需 Flash Attention 才能用非 f16 缓存) git clone https://github.com/ggml-org/llama.cpp cd llama.cpp && make -j && pip install -r requirements.txt # 方案 B:Ollama(0.3.7+ 起在配置面板提供 KV cache 量化开关) # macOS / Linux 手动启动 export OLLAMA_FLASH_ATTENTION=1 export OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve
启动推理服务(以任意一个长上下文 GGUF 为例,把缓存压到 8-bit):
bash
llama-server \ -m ./Qwen3-VL-30B-A3B-Q4_K_M.gguf \ -c 131072 \ -fa \ --cache-type-k q8_0 \ --cache-type-v q8_0 \ -ngl 99说明:
-fa开启 Flash Attention 是前置条件,否则-ctk/-ctv低于 f16 会失败;K 和 V 可独立设,显存极紧时可用-ctk q8_0 -ctv q4_0(V 比 K 更耐压)。TurboQuant 的tbq3_0待 PR 合入后再替换格式名即可。验证是否生效:启动时加--verbose,日志会打印每层的 cache 类型与大小;部分构建会悄悄回退到 F16,看不到确认就是没生效。
下面这段脚本按架构估算 KV 缓存显存,帮你判断该压到哪一档(来源:标准 KV 公式,非本机实测):
python
def kv_cache_gb(n_layers, n_kv_heads, head_dim, ctx_len, bits): # K、V 两套缓存;每元素字节数 = bits / 8 per_token = 2 * n_layers * n_kv_heads * head_dim * (bits / 8) return per_token * ctx_len / 1e9 # 以 80 层 / 8 KV 头 / head_dim 128 的 70B 类模型、128K 上下文为例 spec = dict(n_layers=80, n_kv_heads=8, head_dim=128, ctx_len=128_000) for name, bits in [("FP16", 16), ("Q8_0", 8), ("Q4_0", 4), ("TurboQuant(3bit)", 3)]: print(f"{name:14s} KV 缓存 ≈ {kv_cache_gb(**spec, bits=bits):6.2f} GB")效果验证(连本地服务做长文档问答,顺带计时):
python
from openai import OpenAI import time client = OpenAI(base_url="http://localhost:8080/v1", api_key="sk-noauth") long_doc = ("【项目周报】..." * 300) # 模拟一份长文档 t0 = time.time() stream = client.chat.completions.create( model="local", messages=[{"role": "user", "content": f"基于下文回答问题:\n{long_doc}\n\n问题:本周完成的核心任务有哪些?"}], max_tokens=512, stream=True, ) n, ttft = 0, None for chunk in stream: delta = chunk.choices[0].delta.content if delta: if ttft is None: ttft = time.time() - t0 n += len(delta) print(f"生成 {n} 字,首字延迟 {ttft:.2f}s(KV 缓存已量化,长上下文不爆显存)")四、性能测评
| 方案 | KV 压缩比 | 质量影响 | 注意力加速 | 本地可用性 |
|---|---|---|---|---|
| FP16(默认) | 1×(基准) | 无损 | 1× | llama.cpp / Ollama 默认 |
| Q8_0 | ≈2× | 几乎无感(社区盲测难分) | 略增 | 立即可用 |
| Q4_0 | ≈4× | 聊天/RAG 可接受,代码生成掉 2–4% PPL | 略增 | 立即可用 |
| TurboQuant(3bit) | ≥6× | 长上下文基准零损 | H100 上最高 8× | llama.cpp PR #21089 待合入(目前 CPU-only) |
显存实例(70B 类 / 128K 上下文,按第三节脚本估算):FP16 ≈ 41GB → Q8_0 ≈ 20GB → Q4_0 ≈ 10GB → TurboQuant(3bit) ≈ 7.7GB。对比社区实测参考(craftrigs,同档 70B@128K):FP16 42.9GB / Q8_0 21.4GB / Q4_0 10.7GB,量级一致。
数据来源:Google Research 官方博客(ICLR 2026,6× 压缩 / 零损 / 8× H100 加速 / 无训练校准)、s5labs 与 themenonlab 对论文的拆解、llama.cpp / Ollama 官方 KV 缓存量化文档、craftrigs 社区实测。本文所有 tok/s 与显存均为官方 / 社区口径或公式估算,本机无 GPU 未实测,TurboQuant 的 6×/8× 数字来自 Google 研究侧 H100 基线,非消费级卡复测。
选型一句话:聊天 / 通用问答无脑q8_0(质量几乎无损、缓存减半);RAG 检索嵌入用q4_0(只匹配不生成,掉点可接受);代码生成等精度敏感任务保留 FP16 或只压到q8_0;等 TurboQuant 的tbq3_0合入后,长上下文场景可优先切 3-bit 档拿满 6× 收益。
五、使用建议
- 适用场景:长上下文问答、RAG 检索增强、多轮 Agent 对话、32K+ 上下文且显存紧张的消费级 / 单卡部署。先把 KV 缓存开到
q8_0(质量几乎无损,缓存直接减半),再视余量考虑q4_0。 - 不适用场景:超长、精度敏感的代码生成——
q4_0KV 缓存曾在 Python 函数签名上出现可感知的错误(F16/Q8_0 正确),这类任务保留 FP16 或只压到 Q8_0。 - 调优提示:① KV 缓存与权重量化是正交的两件事,可叠加(权重 Q4 + KV Q8 同时省);② 显存极紧用
-ctk q8_0 -ctv q4_0的非对称组合;③ 压完缓存记得把num_ctx调大,否则省下的显存没转化成可用上下文;④ 关注 llama.cpp PR #21089,合入后把格式换成tbq3_0/tbq4_0即可上 TurboQuant 的 3-bit 档。
显存档位参考(以 70B 类 / 128K 上下文估算,已与社区实测交叉验证):
| 显卡 | 不开 KV 量化可用上下文 | 开 Q8_0 后 | 开 Q4_0 后 |
|---|---|---|---|
| RTX 4060 8GB | 不现实(权重都放不下) | 仅作参考 | 仅作参考 |
| RTX 4070 12GB | ~8K | ~16K | ~24K+ |
| RTX 4080S 16GB | ~16K | ~32K+ | ~48K+ |
| RTX 4090 24GB | ~32K | ~64K+ | ~96K+ |
说明:上表为"缓存主导显存预算"时的经验翻倍关系,实际取决于模型权重占用;小模型(7B/14B)权重本就宽松,压缓存主要换来更长上下文而非救命。
你本地跑长上下文时,是被权重还是被 KV 缓存先顶爆显存的?开q8_0后上下文拉长了多少?
数据口径提醒:TurboQuant 为 Google Research 研究算法(ICLR 2026),其 6× 压缩 / 零损 / 8× H100 加速均来自研究侧报告,尚未在消费级硬件广泛复测;llama.cpp 主线当前仅提供q8_0/q4_0KV 缓存量化(已稳定可用),TurboQuant 格式待 PR 合入。本文显存数字为按标准 KV 公式的架构估算,已与社区实测量级交叉验证,但不替代你的本机测量。
往后回顾:
- 单卡 24GB / 手机能跑的端侧 Agent 基座,把 MiMo 的 1T 集群故事压到桌面
- 金融增强开源模型:Ling-3.0-flash-Fin,私有化投研Agent新选择
- 开源计算机/浏览器操作智能体:Nex-N2.5-mini 部署实测,