【免费下载链接】turboquant_plus项目地址https://gitcode.com/gh_mirrors/tu/turboquant_plus点击查看免费下载本文复盘 turboquant_plus 项目中 TurboQuant4turbo4格式的起死回生过程2026 年 3 月底这个 4-bit KV cache 量化格式在 Metal 上的 PPL 高达 679、在 CUDA 上的 prefill 只有 q8_0 的 51.9%社区结论是别用。读完全文你将掌握完整的排障路径7 个 bug 的定位与修复、QJL 残差校正为何在 attention 场景下有害的消融证据以及最终16 个最优质心 4-bit PolarQuant格式的设计、打包方式与长上下文稳定性验证方法。1. 起点一个被判定不可用的格式turbo4 是 TurboQuant 的 4-bit 变体对 WHT 旋转后的 KV cache 向量做 3-bit PolarQuant 量化外加 1-bit QJLQuantized Johnson-Lindenstrauss残差校正共 4.25 bit/值压缩率 3.76x。从算法设计看它本应严格优于 3.5-bit 的 turbo3——多出的 1 个 bit 通过 QJL 投影校正 PolarQuant 的残差误差理论上可以在几乎不损失压缩率的前提下接近无损。仓库中的 Python 参考实现 TurboQuant 正是这一两阶段结构先(b-1)-bit PolarQuant 做 MSE 最优压缩再用 1-bit QJL 对残差做无偏内积校正PolarQuant 负责抽范数 → 归一化 → 随机旋转 → 最近质心的编码链QJL 则用正交投影矩阵S取符号位E[⟨x̂,y⟩] ⟨x,y⟩论文 Theorem 2 的无偏性。但在 2026 年 3 月 28 日的实测中Metal本仓库 forkPPL 679.27完全不可用。根因是kernel_set_rows_turbo把 turbo3 格式的数据写进了 turbo4 的块。CUDAbuun 的 forkPPL 从 2K 上下文的 -0.28% 退化到 64K 的 3.69%QJL 噪声随上下文长度累积prefill 只有 q8_0 的 51.9%慢得灾难性。社区结论turbo3 is better in every way. Do not bother using turbo4.当时的关键数字指标turbo4损坏态turbo3q8_0PPL (Metal)679.276.17566.1109Decode (Metal)44.43 tok/s78.2486.01PPL 64K (CUDA)3.69%0.49%baselinePrefill (CUDA)51.9% of q8_099.3%baseline2. 找到 7 个 Bug三个关键 Bug 解释了 PPL 679对 Metal 路径的代码分析共发现 7 个 bug其中 3 个是关键 bug直接解释了 PPL 679 这个荒谬数字。Bug 1SET_ROWS 用 turbo3 的打包方式写 turbo4 块kernel_set_rows_turbo是 turbo3 和 turbo4 共用的模板它按 turbo3 的 21 bit 打包方案2 个低位在qs[]、1 个高位在signs[]32 元素块写入。但 turbo4 使用 128 元素块、3-bit 索引跨字节边界的打包格式。共享模板把 turbo3 格式的数据写进 turbo4 块损坏了每一次 KV cache 写入。修复为 turbo4 提供专用的kernel_set_rows_turbo4正确处理 128 元素块。效果PPL 从 679 降到 6.19。仓库中的消融日志 turbo4_setrows_fix_results.txt 记录了修复前后的完整对照BEFORE FIX (shared SET_ROWS, turbo3 packing applied to turbo4): turbo4 PPL 679.27 (completely broken) AFTER FIX (dedicated SET_ROWS with correct 3-bit packing QJL): turbo4 PPL 6.1894 /- 0.331Bug 2dequant 中缺少 QJL 矩阵乘法Metal 的 dequant 把 QJL signs 当原始 ±1 值乘以 scale 因子。而 C 参考代码做的是完整的矩阵-向量乘法turbo_qjl_matrix_t × signs。没有矩阵乘法QJL校正就只是随机噪声。这一点与 Python 参考实现 QJL.dequantize 一致——它明确执行self.S.T signs.T再乘以√(π/2)/√d · ||x||的缩放。Bug 3SET_ROWS 完全缺失 QJL 步骤SET_ROWS 内核做了 PolarQuant 量化却从未计算 QJL 残差、投影或符号。KV cache 里的signs[]字段要么为零、要么是陈旧数据dequant 再用这些垃圾去校正。Bug 4–7辅助问题SET_ROWS 中 3-bit 打包格式不匹配把 turbo3 的 21 方案套到 turbo4 的 packed 3-bit 格式上C 参考量化器中rnorm未初始化QJL scale 由垃圾值算出Metal 用错误基下的残差计算rnorm残差在旋转空间而非归一化空间Metal 用 WHT 代替 QJL 随机矩阵也许是故意的近似但破坏了与 C 参考实现的对称性。3. QJL 消融实验论文自己的校正机制对 attention 有害修好 Bug 1 后 turbo4 PPL 降到 6.19但比 turbo36.18还略差。自然的疑问是QJL 到底有没有用把 dequant 中的符号校正去掉即可做消融// Original: cache[i] (recon[i] signs_f[i] * qjl_scale) * norm; cache[i] recon[i] * norm; // PolarQuant only结果详见 turbo4_qjl_ablation.txt配置PPLturbo4 with QJL6.1894turbo4 without QJL6.1756turbo3参考6.1756QJL 让质量变差去掉之后 turbo4 与 turbo3 完全相同。这个结论后来被三个独立团队交叉验证buunCUDAturbo4 PPL 从 2K 的 -0.28% 退化到 64K 的 3.69%QJL 噪声随上下文累积scos-lab独立实现GPT-2 上 b3 的 MSE 方案 PPL 7.6%带 QJL 的 Prod 方案 300%——QJL 的方差被 softmax 放大Arclabs001YATQ3-bit MSE-only top-1 71.0% vs QJL 61.2%-9.8%——QJL 消除了偏差但爆炸了方差。Softmax 能容忍均匀偏差容忍不了方差。TurboQuant 论文自己的消融OpenReview也确认MSE-only无 QJL、无双层通道已经能击败基线QJL 校正并非必需。从源码结构看这个现象有清晰的机制解释QJL.dequantize 的文档注明经典无偏估计E[||x̂||²] (π/2)·||x||²天然带 π/2 的能量膨胀MMSE 最优收缩系数为2/π ≈ 0.6366即便取收缩最优1-bit 符号向量重建出的残差仍是高方差的。attention 的 logit 是q·k/√d每个 key 的误差直接进入 softmax 的指数竞争方差爆炸会翻转 top-k 排名。仓库中 test_qjl_inner_product_bounded 也印证了这一点测试注释明确写到4-bit 时 PolarQuant 本身已经足够精确QJL 的近似噪声可能不会改善内积保持论文的 QJL 收益在更低位宽2–3 bit时最强。决定彻底弃用 QJL。4. 速度调查3-bit 跨字节解包吃掉了 58% 的 decode 时间弃用 QJL 后 turbo4 的质量追平 turbo36.1756但 decode 仍是 48 tok/s远低于 turbo3 的 78。逐层剥离的分层隔离实验turbo4_component_isolation.txt定位了瓶颈组件损失 tok/s占差距比例128 块 FA tiling 开销13.733%3-bit 跨字节解包24.358%QJL 符号解包 scale3.69%3-bit 解包问题turbo4 原始的 3-bit 索引提取int bit_offset j * 3; int byte_idx bit_offset / 8; int bit_pos bit_offset % 8; uint16_t raw (uint16_t)xb-qs[byte_idx]; if (byte_idx 1 QK_TURBO4 * 3 / 8) { raw | (uint16_t)xb-qs[byte_idx 1] 8; } uint8_t idx (uint8_t)((raw bit_pos) 0x7);每个元素除法、取模、条件性第二字节读取、移位、掩码共 128 次迭代——占整个 decode 成本的 58%。对比 turbo3 的字节对齐 21 方案idx (qs[j/4] ((j%4)*2)) 0x3; if (signs[j/8] (1(j%8))) idx | 4;只有简单的移位和掩码无跨字节访问。修复turbo4 改用 21 bit 打包与 turbo3 相同。由于 QJL 已弃用signs[]字段恰好空闲正好放第 3 个索引位。效果48.05 → 63.79 tok/s33%。整块缓存问题turbo4 的 dequant 在栈上分配float cache[128]把 128 个元素全部解量化后只返回 4 个。FA 的 vec 内核在每个块位置调用它 32 次——每次都重复做完整的 128 元素解包。turbo3 从 32 元素块中直接提取需要的元素规避了这个问题。修复为 turbo4 实现与 turbo3 相同的按元素直接提取模式见 turbo4_direct_extract_results.txt。效果63.79 → 78.30 tok/s23%追平 turbo3。5. 4-bit 突破16 个最优质心取代 31 拆分弃 QJL、修 dequant 之后turbo4 实质上只是128 元素块布局的 turbo3——同样的质量、同样的速度但 turbo4 最初的承诺质量优于 turbo3仍未兑现。修复方案不再把 4 bit 拆成 3PolarQuant 1QJL而是让全部 4 bit 都用于 PolarQuant——16 个最优质心替代 8 个。4-bit 质心的计算对旋转后坐标分布 N(0, 1/√d) 的 16 级最优标量量化器质心即每个分位数区间内的条件期望。文档给出的 d128 质心表[-0.1739, -0.1172, -0.0895, -0.0688, -0.0513, -0.0356, -0.0210, -0.0069, 0.0069, 0.0210, 0.0356, 0.0513, 0.0688, 0.0895, 0.1172, 0.1739]注意最外侧质心为 0.1739约为 1.97σσ 1/√128 ≈ 0.0884。仓库中的 Python 代码模块 optimal_centroids 用对高斯近似的 Lloyd 迭代计算质心1-bit、2-bit 有闭式解b ≥ 3 走 _lloyds_gaussian其文档说明也点明论文给出 1-bit 与 2-bit 闭式质心更高位宽用 Lloyd 算法在高斯近似上求解——即参考实现与 GPU 内核使用的具体质心表属于同一方法论下的两种落地高斯近似 vs 旋转后真实分布标定第 9 节的质心调查小节正是对这一差异的正面回应。打包方式简单的 nibble每字节 2 个索引、无跨字节访问解包只需(qs[j/2] ((j%2)*4)) 0xF——比 21 方案更简单。结果配置PPLvs q8_0Decode tok/svs q8_0q8_06.1109—85.711.00xturbo4 4-bit6.12500.23%79.870.93xq4_06.14240.52%83.360.97xturbo36.17561.06%76.840.90x完整日志见 turbo4_4bit_polarquant_results.txt。turbo4 4-bit 同时做到质量优于 turbo3与 q8_0 的 PPL 差距缩小 4.5 倍质量优于 q4_0压缩率优于 q4_03.76x vs 3.56xdecode 速度追平 turbo3prefill 接近 q8_096%。6. 完整旅程每一步的增量步骤PPLDecode tok/s变更损坏态共享 SET_ROWS679.2744.43— 专用 SET_ROWS6.189444.43修复块损坏 弃用 QJL6.175648.05QJL 在损害质量 21 bit 打包6.175663.79消除跨字节读取 直接提取 dequant6.175678.30消除冗余整块缓存 4-bit PolarQuant6.125079.8716 个最优质心总计PPL 679 → 6.13decode 44 → 80 tok/s。7. 验证代码审查、交叉验证与长上下文稳定性代码审查OpenAI Codexgpt-5.3-codex审查最终 diff 时发现一次越界内存访问block_turbo4_0结构体的qs[48]是按 3-bit 打包定尺寸的但 4-bit nibble 打包会写入qs[0..63]。结构体改为qs[64]保持 68 字节块大小不变。这类改了打包格式但结构体尺寸没跟着改的越界正是 GPU 量化格式开发中最隐蔽的一类 bug。交叉验证buun 的 CUDA turbo4旧 QJL 格式确认了 QJL 在长上下文下的退化见 turbo4_vs_buun_comparison.txt64K 时 3.69%scos-lab 的独立实现确认 MSE QJL for attentionArclabs001 的 YATQ 分析量化了 QJL 经 softmax 的方差爆炸TurboQuant 论文自身消融确认 MSE-only 已可击败基线。长上下文稳定性上下文turbo4 4-bitturbo3对比5126.12506.1756turbo4 胜8K5.55465.5700turbo4 胜16K5.08135.0630大致持平噪声范围内无退化趋势——与 buun 的 QJL 版 turbo42K -0.28% → 64K 3.69%形成鲜明对比见 turbo4_4bit_long_context.txt。8. 经验教训QJL 对 KV cache attention 有害。1-bit 校正消除偏差但爆炸方差softmax 放大方差。三个独立团队确认。跨字节位提取在 GPU 上代价极高。3-bit 打包格式占掉 58% 的 decode 时间nibble 打包或字节对齐 21 方案快得多。块大小为 128 时整块 dequant 缓存行不通。FA 内核每个位置调用 dequant 32 次每次都做完整的 128 元素解包却只取回 4 个元素直接提取消除了这 32 倍冗余。更多质心 误差校正。同样位宽下16 个最优 PolarQuant 质心比 8 质心 QJL 校正质量更好实现更简单、执行更快。原论文设计对该应用场景并非最优。TurboQuant 面向通用向量量化设计在 KV cache attentionsoftmax 放大方差这一具体场景下QJL 成分是负贡献。9. 当前状态与质心调查turbo4 4-bit PolarQuant 已合入feature/turboquant-kv-cachemain。TURBO4_USE_4BIT宏在 Metal 上默认启用 4-bit 路径CUDA 端在移植完成前仍走旧 3-bitQJL 路径。Prefill 上下文扩展上下文turbo4 tok/sturbo3 tok/sq8_0 tok/sturbo4/q8_02K2682270826651.01x4K2370228922551.05x8K2041205420021.02x16K1621169816051.01x32K1141120410981.04xturbo4 prefill 在所有上下文长度上追平甚至超过 q8_0——压缩后的 cache 在内存总线上搬运的数据更少见 turbo4_prefill_comparison.txt8K 下 2037 tok/s为 q8_0 的 96%。总体表现PPL0.23% vs q8_0本项目测试过的最佳量化 KV cache 质量Decode79.87 tok/sq8_0 的 93%快于 turbo3 的 76.84Prefill所有上下文长度均为 q8_0 的 101–105%NIAH31/3393.9%优于 q8_0 的 30/3390.9%KLD0.0096比 turbo3 的 0.0161 低 40%注意 q4_0 的 0.0081 略低但 PPL 更差——更多质心对 top-token 预测的帮助大于整体分布匹配Dense 模型decode 追平 q8_017.25 vs 17.17 tok/s真实 PDF24Kdecode 63.7 tok/s比 turbo3 的 53.3 快 20%Sparse V激活且兼容长上下文稳定无 QJL 退化。跨模型泛化结果Qwen、Llama、Gemma、Phi、Mistral 等 7 个模型 5 个家族的 quick-bench 数据见 cross-model-validation.md。质心调查已解决buun 在 CUDA 上测试我们的 4-bit 质心最初发现它们在 hd128 上效果更好、hd256 上略差他的 agent 怀疑质心非标准Ours (d128, σ0.0884): 外侧质心 0.1739 (1.97σ) buuns (N(0,1) scaled): 外侧质心 0.2416 (2.73σ)结论我们的质心是 N(0, 1/√128) 上的标准 Lloyd-Max 解正是 post-FWHT 分布下的正确选择buun 的实证验证显示它们与从真实 KV 数据计算的最优解相差在 0.2–0.3% 以内。2K 上下文的 -0.19%胜过 q8_0是短上下文假象——8K 时为 0.82%与高斯质心相同。为什么 turbo4 修复了 head_dim128 的质量差距hd128 的质量差距不是质心、FWHT 混合层数或 InnerQ 均衡的问题而是位宽与维度的本质问题。attention logit 为q·k/√d每个 logit 的量化误差方差Var(Δlogit) MSE_per_element / d固定 MSE 时hd128 的 logit 方差是 hd256 的2 倍参与平均的维度是 128 而非 256。方差越大 → softmax 排名错误越多 → PPL 越差。从 8 个质心升到 16 个turbo3→turbo4大约把每元素 MSE 减半因此 hd128 上的 turbo4 在 logit 噪声上约等于 hd256 上的 turbo3。buun 的 CUDA 数据印证配置hd128 vs q8_0解释turbo38 质心3.33%噪声高、质心少、维度少turbo4 高斯质心1.20%仅 16 质心一项就改善 3 倍turbo4 我们的质心2K-0.19%短上下文假象turbo4 我们的质心8K0.82%与高斯质心相同——质心已经最优结论质心是已解决问题。hd128 的修复靠更多 bitturbo4不是更好的质心不是 InnerQ不是 CAT 对齐。异常地简单。下一步方向按 head_dim 区分的质心码本d128 与 d256非对称 K/Vturbo3-K turbo4-V——受限于跨类型 FA 内核实例化跨模型验证见 cross-model-validation.md上游集成CUDA 移植。10. 附独立验证追加记录2026-03-31QJL 在 attention 负载下损害质量这一发现在本文档发布前后被多方独立确认Aaryan-Kapoor2026-03-25独立实现了仅含 Algorithm 1MSE、不带 QJL 的版本从另一实现收敛到 PolarQuant-only 路线scos-lab2026-03-28量化了 PPL 退化——GPT-2 上 Paper (Prod keys) 300% vs MSE (both) 7.6%。QJL 引入的方差被 softmax 放大。低方差MSE胜过无偏性ProdAmesianXBlackwell DGX Spark2026-03-30最初 QJL 实现损害质量根因是 MSE 的 WHT 与 QJL 的 SRHT 旋转相关改用独立符号模式后修复——首个可工作的 QJL 实现来自独立随机种子Arclabs001/YATQ2026-03-28量化了 QJL 经 softmax 的方差爆炸并发现 MSE 与 QJL 旋转使用独立随机种子时 QJL 有效WHT QJL MSE is the solution!确认根因是旋转相关而非 QJL 本身elusznik上游 PR #210892026-03-27首个上游 PR 实现了不带 QJL 的 CPU TurboQuant把 QJL 列为后续工作varjorantavLLM fork PR2026-04-02把 vLLM TurboQuant 默认从 4-bit 修回 FP8 值引用本文档作为value 精度是质量瓶颈的依据A100 上 Qwen3-8B 实测 FP8 值与 FP16 基线一致4-bit 产生垃圾输出——独立印证无旋转的低 bit V 量化必然失败的预测unamedkr / quantumaikrquant.cpp2026-04-07把 TurboQuant 论文RHT → Lloyd-Max 高斯码本 → 1-bit QJL逐字移植为单头文件 C 实现。QJL 阶段对 attention score 的贡献是逐字节为零的——禁用后 PPL 与完整管线逐位相等。理论解释无偏估计器中的常数 √(π/2)/m 是为高斯投影行推导的在 Rademacher±1行上每个 key 的贡献被残差范数缩放淹没。随后他们同样把释放出来的 bit 重新投入 4-bit 码本8 → 16 质心与本文档的复活路径完全一致Llama 3.2 3B 上 turbo_kv_4b PPL 14.285.3% vs FP32优于 llama.cpp q4_0 KV约 14.9910.6%。致谢spiritbuun 提供 CUDA turbo4 数据并下了别用的判词——最终被证明可以翻盘scos-lab 提供独立 MSE QJL 结论与 K/V 范数差异数据Arclabs001/YATQ 量化了 QJL 的 softmax 方差爆炸OpenAI Codex 抓住了结构体越界 bugSean Rasch 贡献 turbo4 Python 测试覆盖PR #41——对应仓库中的 tests/test_turbo4.py覆盖 d64/128/256 往返正确性、非 128 对齐 head dim96/160/192/320、零向量与极端范数等边界情况。赞分享【免费下载链接】turboquant_plus项目地址https://gitcode.com/gh_mirrors/tu/turboquant_plus点击查看免费下载相关推荐Strata 的 --kv q4_0Hadamard 旋转下的 4-bit KV 缓存原理、质量代价与实测数据Strata 的 kv q4_0 Hadamard 旋转下的 4 bit KV 缓存原理、质量代价与实测数据 本文基于仓库中的实测报告 bench/resul人工智能大模型本地部署推理引擎模型推理服务模型量化5分钟打开Unity游戏文件AssetRipper资源提取与脚本反编译简指南5分钟打开Unity游戏文件AssetRipper资源提取与脚本反编译简指南 打开游戏目录看到一堆 AssetBundle、.dll 和 Level 文件彻底解决Rufus持久化分区文件损坏问题从原理到修复全指南彻底解决Rufus持久化分区文件损坏问题从原理到修复全指南 你是否遇到过用Rufus创建持久化存储分区后文件莫名损坏、系统无法启动的情况本文将深入解析这一桌面应用开发工具上一篇MAA明日方舟助手智能游戏辅助工具完全指南下一篇明日方舟MAA自动化助手解放双手的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?