135M 权重实测:三值量化误差 60%,int8 只有 3.7%,差距在尺度
把一份现成的 fp16 权重直接压成三值-1 / 0 / 1重构误差是 60%而 int8 分组量化只有 0.8%。两个数字放在一起看容易得出三值不靠谱的结论但这个比较其实不公平官方那批 1.58 bit 模型是从预训练就在用三值权重后处理直接压和它不是一个场景。下面这份数据是给想在自己权重上试三值的人看的——误差打哪来、把尺度定细一点能挽回多少、存下来的体积差几倍。1.58 bit 这个数字的来历三值权重的取值只有三种均匀分布下的信息熵是 log2(3) ≈ 1.585 bit这就是1.58 bit的来源真正落盘时按 2 bit 打包所以宣传里的 1.58 是信息量下限不是文件大小。论文《The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits》给的量化式很朴素先把权重矩阵按平均绝对值缩放再四舍五入到 {-1, 0, 1}即 W̃ RoundClip(W / (γε), -1, 1)γ 取权重矩阵的平均绝对值。换句话说三值量化除了权重本身还要保存一个尺度。官方推理框架 microsoft/BitNet 在仓库里给了加速数字x86 CPU 上相比同尺寸 fp16 模型快 2.37 到 6.17 倍、能耗降 71.9% 到 82.2%ARM 上是 1.37 到 5.07 倍、能耗降 55.4% 到 70.0%100B 的三值模型能在单颗 CPU 上跑到 5 到 7 token/s。这些数字的前提都是模型本身就是三值训练的不是把 fp16 模型压出来的。先解决读权重这一步我测的对象是 HuggingFaceTB 的 SmolLM2-135M单文件 safetensors134.5M 参数BF16。safetensors 的格式简单到不需要装任何库开头 8 字节是 JSON 头长度接下来是头的 JSON里面每个张量带 dtype、shape 和一对 data_offsets数据区紧跟头之后。唯一要自己处理的是 BF16——numpy 没有这个 dtype把 uint16 左移 16 位再按 float32 解读即可。importjsonimportnumpyasnp pathmodel.safetensorswithopen(path,rb)asf:nint.from_bytes(f.read(8),little)# 头 8 字节 JSON 头长度hdrjson.loads(f.read(n))base8n# 数据区起点infohdr[model.layers.0.self_attn.q_proj.weight]f.seek(baseinfo[data_offsets][0])rawf.read(info[data_offsets][1]-info[data_offsets][0])unp.frombuffer(raw,dtypenp.uint16).astype(np.uint32)16# BF16 - FP32wu.view(np.float32).reshape(info[shape])print(w.shape,w.dtype,float(np.abs(w).max()))运行结果safetensors 头部条目: 272 | 张量 dtype: [BF16] | 元数据: [format] 张量数: 272 | 参数总量: 134515008 (134.5 M) 文件大小: 256.6 MiB 头部大小: 30528 字节六种量化方案的真实误差四个张量各跑一遍embed_tokens49152×576、第 0 层的 q_proj、第 15 层的 down_proj 和 gate_proj。误差口径是相对 Frobenius 范数 ‖W−Q‖/‖W‖越低越好。方案每权重位数embed_tokensq_projdown_projgate_proj平均三值·整张量尺度20.61500.66750.55780.57250.6032三值·按输出行尺度20.60250.60810.54100.53260.5710三值·分组 6420.59760.60300.53610.52810.5662三值·分组 1620.57770.58400.52070.51360.5490int8·整张量尺度80.03360.04210.03800.03600.0374int8·分组 12880.01040.00830.00740.00710.0083三值的误差在 55% 到 67% 之间int8 是 0.7% 到 4.2%差两个量级。尺度定得越细三值确实越好但收益不大从整张量换到按输出行平均误差只从 0.6032 降到 0.5710。顺手统计了量化后的码字分布这个能验证 1.58 bit 是不是虚的张量尺度方式归零比例饱和到 ±1 的比例embed_tokens整张量33.8%66.2%embed_tokens按输出行33.2%66.8%q_proj整张量42.5%57.5%q_proj按输出行39.9%60.1%归零比例在 33% 到 43%接近均匀三值分布的 1/3所以按 2 bit 打包没有浪费多少熵口径的 1.58 bit 是实的。换成输出误差看再算体积账重构误差只说明权重被改了真正影响结果的是矩阵乘。让 X 是随机激活Y XWᵀ再插一组离群激活随机挑千分之一通道放大 30 倍模拟大模型里常见的大通道张量方案普通激活带离群激活q_proj三值·整张量0.66910.6037q_proj三值·分组 160.58440.5408q_projint8·整张量0.04230.0474down_proj三值·整张量0.55700.5461down_proj三值·分组 160.52050.5133down_projint8·整张量0.03810.0371离群激活把 int8 整张量的输出误差从 0.0423 推到 0.0474涨了 12%三值几乎不动不是它抗离群是它本来就已经错了 60%离群那点扰动占不上比重。想抗离群方向是 int8 里把大通道单独拎出来算跟三值无关。体积这块容易被忽略尺度也要存而且是 fp16 存。按 134515008 个参数算存法权重位数尺度额外位数合计体积fp16160.00016.000257 MiBint8·整张量80.0008.000128 MiBint8·分组 12880.1258.125130 MiB三值·整张量20.0002.00032 MiB三值·按输出行20.0282.02833 MiB三值·分组 6420.2502.25036 MiB三值·分组 1621.0003.00048 MiB三值分组 16 把误差从 0.6032 压到 0.5490相对改善 9%代价是每组一个 fp16 尺度每权重从 2.0 bit 涨到 3.0 bit体积从 32 MiB 变 48 MiB。分组 64 是折中0.5662、2.25 bit、36 MiB。我怎么用它先摆结论三值不是后训练量化方案。现成 fp16 模型直接压三值误差 60%这不是无损官方的无损前提是训练时就用三值权重——想走这条路准备的是重训预算不是量化脚本。只想过省内存又不想重训我会直接上 int8 分组 128误差 0.83%、体积 130 MiB差不多是 fp16 的一半代价几乎可以忽略。真要压到三分之一以下才轮到三值出场。尺度粒度要先算账再动手。按输出行定尺度只多 0.028 bit/权重误差降 3.2 个百分点接近白拿分组 16 的重构误差比按行好 4%但要付 1 bit/权重体积多 45%。我自己的判断是分组 64 到头再细不划算。踩到的坑有两个。一是 embed_tokens 是这批张量里误差最高的0.6150分组 16 之后 0.5777而且它的量化噪声走的是整行查表的路子直接进残差真要用三值我会单独给它更细的分组或者干脆留着不量化。二是 BF16 的头里还有个__metadata__键它没有 dtype 字段我第一次遍历头部时直接 KeyError顺手把它跳过就行。至于量化耗时2 核机器上 embed_tokens 的 2831 万权重三值 0.90 秒、int8 0.94 秒——量化本身从来不是瓶颈。要落地的话就三件事从自己模型里抽 q_proj 和 down_proj 各一个张量跑一遍整张量 absmean 和按行 absmean误差降不到 5% 就别上分组只求省内存先上 int8 分组 128算体积时把尺度位数一起算进去分组 16 是三值权重的 3 bit不是 2 bit。

相关新闻

LeetCode 200:岛屿数量——从 Flood Fill 到二维网格 BFS

LeetCode 200:岛屿数量——从 Flood Fill 到二维网格 BFS

LeetCode 200:岛屿数量——从 Flood Fill 到二维网格 BFS 目录LeetCode 200:岛屿数量——从 Flood Fill 到二维网格 BFS一、从 733 图像渲染继续往下做二、一开始我对“岛屿”的理解有点绕三、那怎么知道自己发现了一座新岛?1、为什么“没访问…

2026/11/8 11:22:43 阅读更多 →
生产环境API Key怎么管?VModal密钥轮换、安全存储与防泄露最佳实践

生产环境API Key怎么管?VModal密钥轮换、安全存储与防泄露最佳实践

生产环境API Key怎么管?VModal密钥轮换、安全存储与防泄露最佳实践 【免费下载链接】vmodal_sdk_flutter V- Modal AI: Visual Video / Image Search - SDK Flutter 项目地址: https://gitcode.com/gh_mirrors/vm/vmodal_sdk_flutter 把 VModal 的 API Key 硬…

2026/10/20 3:53:15 阅读更多 →
mcp-for-beginners 实战:使用 TypeScript 与官方 SDK 构建可扩展的 MCP Server 示例

mcp-for-beginners 实战:使用 TypeScript 与官方 SDK 构建可扩展的 MCP Server 示例

教程文档人工智能 【免费下载链接】mcp-for-beginners This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for deve…

2026/10/26 9:06:53 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/8 1:19:03 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/7 12:08:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/8 1:35:05 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/8 1:38:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/7 12:08:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/8 1:23:14 阅读更多 →

日新闻

周新闻

月新闻