[{"data":1,"prerenderedAt":397},["ShallowReactive",2],{"article:column:/column/llm-to-agent-learning/18":3},{"id":4,"title":5,"body":6,"description":389,"extension":390,"meta":391,"navigation":392,"path":393,"seo":394,"stem":395,"__hash__":396},"column/column/llm-to-agent-learning/18.md","18｜量化与压缩：少用几位，保住什么、损失什么",{"type":7,"value":8,"toc":369},"minimark",[9,13,16,21,24,27,37,41,44,47,55,58,61,64,67,70,73,80,83,87,90,93,96,99,102,108,111,114,118,121,124,127,130,138,141,147,150,154,157,160,167,174,178,181,189,192,195,199,207,214,221,224,228,231,239,247,255,258,262,265,268,271,274,277,280,284,290,293,298,301,306,309,312,317,320,325,328,333,336,339,344,347,352,355,360,363,366],[10,11,12],"p",{},"一份模型用16位保存权重，换成4位后小了很多，介绍页却仍写着同样的参数数量。它删掉了知识吗？既然还原后仍能计算，为什么不把所有模型都压到更低？",[10,14,15],{},"上一章的蒸馏让学生重新学习教师行为。本章讨论另一条路线：保留原有计算结构，把其中的数换成占用更少空间的近似表示。关键不只是“省多少”，还包括误差在哪里产生、怎样影响输出，以及硬件能否真正利用这种表示。",[17,18,20],"h2",{"id":19},"_1位数减少意味着可分辨的档位变少","1．位数减少，意味着可分辨的档位变少",[10,22,23],{},"一位二进制只能记录两种状态，4位最多区分16种编码，8位最多区分256种。编码怎样对应数值，由格式决定。4位并不意味着只能记录整数0到15：我们可以用这些编号去指向一组正数、负数和零。",[10,25,26],{},"量化就是把更多可能的数映射到有限档位。好比把连续测得的长度记到尺子的刻线上，几个不同原值可能落在同一格。一旦只留下格子编号，就无法判断原来究竟是哪一个数。反量化把编号换回对应的近似数值，并不能找回已经丢失的小数。",[10,28,29,30],{},"浮点数原本也只有有限精度；量化通常进一步降低表示所需位数。整数式量化、低位浮点和后面介绍的NF4，档位安排并不相同。看到“都是4-bit”，不能据此认定它们的误差、计算方式和兼容性相同。",[31,32,36],"a",{"href":33,"rel":34},"https://huggingface.co/docs/transformers/v4.57.1/en/quantization/concept_guide",[35],"nofollow","Transformers：量化概念",[17,38,40],{"id":39},"_2亲手把五个权重量化再还原","2．亲手把五个权重量化，再还原",[10,42,43],{},"取一组人工权重：［－1.26，－0.73，0.08，0.91，1.40］。为方便手算，选择对称的整数档位－7到7，共15档，用4位编码存放，剩余一种编码不用。这是教学约定，不是所有4位格式的标准。",[10,45,46],{},"最大绝对值为1.4，让它对应整数7，每一档的间距就是1.4÷7＝0.2。这个间距叫缩放尺度scale，记为s。它说明整数编号增加1，对应原数值增加多少。",[10,48,49,50],{},"量化分三步：原值除以s，就近舍入为整数，再把超出范围的结果限制在－7到7。最后一步叫截断或裁剪；本组数没有超界。反量化则把整数乘回s。",[31,51,54],{"href":52,"rel":53},"https://pytorch.org/blog/quantization-in-practice/",[35],"PyTorch：量化映射、scale与zero-point",[10,56,57],{},"例如，－0.73÷0.2＝－3.65，舍入为－4，反量化得到－0.8。再如，0.08÷0.2＝0.4，舍入为0，还原也是0。小数没有被完整地藏在整数里，它与同一档内的其他数无法区分了。",[10,59,60],{},"逐项计算，整数为［－6，－4，0，5，7］，还原值为［－1.2，－0.8，0，1.0，1.4］。约定“误差＝还原值减原值”，五项误差是［0.06，－0.07，－0.08，0.09，0］。",[10,62,63],{},"把绝对值相加再除以5，平均绝对误差为0.30÷5＝0.06。最大的绝对误差是0.09。这里没有舍入到一半的平局；若遇到，具体实现还需约定向哪里舍入。",[10,65,66],{},"在没有裁剪、使用最近档位舍入的这把均匀尺子上，一个数距离最近刻线最多是半格，即0.1。这解释了本例误差为何都不超过0.1。若原值超出范围，例如仍用这把尺子记录2.6，只能截到1.4，误差就达到－1.2，半格界限不再适用。",[10,68,69],{},"这种以零为中心的方法，零点就是0。更一般的仿射量化允许另设zero-point，记为z：先把原值除以s，再加上z并舍入；还原时先减z，再乘s。z表示“真实的零对应哪个整数编码”。范围偏向正数时，移动零点可能让有限档位利用得更充分。",[10,71,72],{},"例如用0到15的整数记录－1到2，取s＝0.2、z＝5。真实的0先变成0÷0.2＋5＝5，还原时（5－5）×0.2＝0；真实的1编码为10，还原为1。这里整数5代表零，整数10代表一。把编码当成原值直接计算，就会弄错数值含义。",[10,74,75],{},[76,77],"img",{"alt":78,"src":79},"18｜量化与压缩：少用几位，保住什么、损失什么：图1","/collections-assets/llm-to-agent-learning/94723502fa9b6ce61281f1008eeb3f63c7055e36434192d94665c562becbc694.png",[10,81,82],{},"图1｜上方在同一数轴标出原值、最近刻线和误差：－0.73映到－0.8，0.08映到0。中间放大一格说明无裁剪时的半格界；下方2.6裁剪到1.4的误差远超过半格。15档是本章教学约定。",[17,84,86],{"id":85},"_3很小的权重误差也要经过后续计算","3．很小的权重误差，也要经过后续计算",[10,88,89],{},"把刚才的权重与输入［2，－1，－3，0，1］逐项相乘再相加，忽略偏置。原输出为－2.52＋0.73－0.24＋0＋1.4＝－0.63。使用还原后的权重，输出变成－2.4＋0.8＋0＋0＋1.4＝－0.20，相差0.43。",[10,91,92],{},"这个差不是凭空产生的：0.06×2＋（－0.07）×（－1）＋（－0.08）×（－3）＝0.43。输入会给权重误差重新加权。本例三项影响同向叠加；换一组输入，也可能部分抵消。",[10,94,95],{},"因此，“每个权重误差不到0.1”不能推出“每层输出误差也不到0.1”。后面还有注意力、非线性和多层计算。最后两个候选token的分数原本接近时，微小变化就可能改变排名；它们相差很大时，同样扰动也可能不改变选择。",[10,97,98],{},"把最后一句也变成能手算的例子。若候选A、B的logits原本为1.00和0.98，分别受到－0.02和＋0.02的扰动，就变成0.98和1.00，第一名交换。若原本为1.00和0.00，同样扰动后为0.98和0.02，第一名保持。",[10,100,101],{},"更一般地，若每个候选的扰动绝对值都不超过ε，两项分差最多缩小2ε。原领先差大于2ε时，这两项的顺序就保持；这只是给定误差界的条件推论，并未证明真实模型每层都有这样的误差界。",[10,103,104],{},[76,105],{"alt":106,"src":107},"18｜量化与压缩：少用几位，保住什么、损失什么：图2","/collections-assets/llm-to-agent-learning/11c55504163664e4e14b9bc3cffce5d3b1f62f5e1031c625a0feff393a45296e.png",[10,109,110],{},"图2｜同一组权重误差经过输入加权，输出差为0.43。下方比较同样±0.02扰动：领先0.02时可以换序，领先1.00时仍保持。图中logits是另一组独立教学数值，不是由上方0.43直接推得。",[10,112,113],{},"数值误差与任务错误之间没有固定换算率。平均误差小是有用线索，仍需检查完整回答。反过来，某个权重变化明显，也不代表每道题都会出错。",[17,115,117],{"id":116},"_4一个异常值为什么会影响一整组小数","4．一个异常值，为什么会影响一整组小数",[10,119,120],{},"现在把14加入刚才的量化组，仍保留－7到7的档位，并按最大绝对值定尺度。s变为14÷7＝2，刻度一下粗了十倍。原有五个数分别还原成［－2，0，0，0，2］，新增的14则能精确还原。",[10,122,123],{},"只计算原有五个数，平均绝对误差变成（0.74＋0.73＋0.08＋0.91＋0.60）÷5＝0.612。照顾大数的范围，让附近小数失去了分辨率。这里的“异常值”是相对这组数的尺度而言，并不说明它是错误数据或无用参数。",[10,125,126],{},"可以缩小范围并裁剪14，但那会给大数带来误差；可以把数据分成小组，各自保存scale，让异常值只影响所在组；也可以对敏感部分保留较高精度。这些做法都在重新分配有限精度，没有免费的完美选项。",[10,128,129],{},"这里存在三个相关但不同的目标：扩大范围可减少裁剪，缩小格距可减少舍入误差，实际任务关心的却是输出和决定。第3节的输出差等于Σeᵢxᵢ，所以相同的权重平均误差，遇到不同输入也可能造成不同影响。选择scale时应说明优先控制什么，再用实际任务验收。",[10,131,132,133],{},"分组还需要附加信息。假设每64个4位权重共用一个32位scale，权重占64×4＝256位，加上scale共288位，平均每权重4.5位，还未计其他信息。组越小，尺度越贴近局部数据，但记录尺度的相对成本往往越大。QLoRA论文明确讨论了分块量化与这类尺度开销。",[31,134,137],{"href":135,"rel":136},"https://arxiv.org/pdf/2305.14314",[35],"QLoRA论文：第2、3节",[10,139,140],{},"把14单独分一组、其余五数留一组，能恢复本例的小数精度，但这里只用于说明机制，不是实际模型推荐的分组方式。真实分组还要适配矩阵布局和计算内核。",[10,142,143],{},[76,144],{"alt":145,"src":146},"18｜量化与压缩：少用几位，保住什么、损失什么：图3","/collections-assets/llm-to-agent-learning/472f38793a4aa4a79eb25757da0015661b0cd7272ca53922bdac56138073c020.png",[10,148,149],{},"图3｜同样15个档位，范围由［－1.4，1.4］扩大到［－14，14］时，步长从0.2增至2。上、下两把尺各自标明范围，不能按画面距离比较数值。分组为小数与14保留独立scale，可以缩小异常值影响，但要额外保存尺度。",[17,151,153],{"id":152},"_5权重和激活面对的是两类变化","5．权重和激活，面对的是两类变化",[10,155,156],{},"权重是在普通推理时反复使用的参数；激活是当前输入经过各层产生的中间数值。量化权重主要减少这部分参数的存储和搬运，量化激活则还会影响运行中的中间表示。写着W4A16的方案，通常表达权重4位、激活16位；各模块、缓存和累加精度仍要另查。",[10,158,159],{},"权重可以在部署前检查，而激活会随输入变化。静态量化常用代表性输入做校准，观察数值范围，再确定尺度。若只用短中文问答校准，实际却大量处理长代码，观察到的范围未必适用。校准是在为近似计算估计合适范围，不等同于对任务正确率做验证。",[10,161,162,163],{},"动态方法可以在运行时为相关数据重新确定量化参数，适应变化，但也增加统计和转换开销。还有只量化权重、保留较高精度激活的方案。具体量化哪些对象，应读实现，不能只看文件名里的位数。",[31,164,166],{"href":52,"rel":165},[35],"PyTorch：动态、静态与量化感知训练",[10,168,169,170],{},"训练后量化通常从已经训练好的模型出发；量化感知训练则在训练中模拟舍入等影响，让可训练参数有机会适应。后者需要额外训练条件，也不能保证任意低位下都保持质量。",[31,171,173],{"href":33,"rel":172},[35],"Transformers：PTQ与QAT",[17,175,177],{"id":176},"_6存储用几位计算就一定用几位吗","6．存储用几位，计算就一定用几位吗",[10,179,180],{},"不一定。低位权重可以紧凑存放，到计算时按需转换为较高精度，再与激活相乘。有些硬件和内核也支持直接利用低位表示运算。应分别询问存储dtype、计算dtype和累加方式；dtype就是数据类型，不能用一个标签概括全部过程。",[10,182,183,184],{},"例如Transformers v4.57.1的bitsandbytes文档分别设置load_in_4bit与bnb_4bit_compute_dtype。前者指定4位加载，后者可以指定BF16计算。这说明存储与计算是两个开关，不意味着整份模型必须同时展开成永久保留的高精度副本。",[31,185,188],{"href":186,"rel":187},"https://huggingface.co/docs/transformers/v4.57.1/en/quantization/bitsandbytes",[35],"Transformers：4位加载与计算类型",[10,190,191],{},"做一笔只含权重载荷的账：80亿个数，每数16位是160亿字节，即16 GB；4位是40亿字节，即4 GB，均按十亿字节为1 GB。这是理想载荷减少到四分之一，尚未计尺度、未量化模块、激活、缓存与临时空间。",[10,193,194],{},"速度也不会自动变成四倍。减少权重搬运可能有利，但解包、反量化、内核支持、批次与输入长度都会改变收益。一个更小的模型文件，不能替代同一设备、同一任务下的延迟与吞吐测量。",[17,196,198],{"id":197},"_7nf4与qlora怎样落到实际工具","7．NF4与QLoRA怎样落到实际工具",[10,200,201,202],{},"刚才用的是等间距刻度。NF4使用不同的思路：参照正态分布安排非均匀档位，让数值较集中的区域得到更密的表示。4位编码指向对应的码表值，再结合分块尺度恢复近似权重。它不是“整数乘0.2”的另一种名字，也不能对任意分布都承诺最佳。",[31,203,206],{"href":204,"rel":205},"https://huggingface.co/docs/bitsandbytes/v0.48.2/reference/nn/linear4bit",[35],"bitsandbytes v0.48.2：LinearNF4",[10,208,209,210],{},"第14章已解释QLoRA的冻结基座和可训练适配器。现在可以补上其中的数值层：原论文用NF4存放基座，以较高精度参与计算，并进一步量化尺度常数来降低元数据开销。适配器更新并不让原来被舍入的小数神奇恢复。",[31,211,213],{"href":135,"rel":212},[35],"QLoRA论文：存储类型与计算类型",[10,215,216,217],{},"作为现代模型的具体落点，Transformers v4.57.1量化概念指南给出Llama-3.1-8B-Instruct的4位加载示例，同时明确指定BF16计算。这份示例证明这些选项能在同一配置里分开表达；它没有把量化类型显式设为NF4，因此不能把它直接称为NF4训练实验。",[31,218,220],{"href":33,"rel":219},[35],"官方示例：Llama-3.1-8B-Instruct",[10,222,223],{},"这也是读配置的重要习惯：只推断实际写出或由文档明确规定的内容，不因为示例出现在“量化”页面，就替它补上训练方法、速度或准确率结论。",[17,225,227],{"id":226},"_8四种方法改动的位置并不相同","8．四种方法，改动的位置并不相同",[10,229,230],{},"量化改变数值表示，同一张矩阵通常仍有同样数量的位置。它与把原文件打包成可完整解压的压缩包也不同：量化把－0.73与附近一些数合并到同一档，只靠量化结果无法唯一恢复原文件；无损压缩则要求解压后逐项恢复原始内容。",[10,232,233,234],{},"剪枝则让部分连接或整个通道失效、置零或移除。仅把许多数变为零，未必让普通稠密计算少做工作，还需要合适的表示和执行支持。",[31,235,238],{"href":236,"rel":237},"https://docs.pytorch.org/tutorials/intermediate/pruning_tutorial.html",[35],"PyTorch：结构化与非结构化剪枝",[10,240,241,242],{},"LoRA给更新增加低秩约束，主要减少需要训练的参数，不等于删除基座。",[31,243,246],{"href":244,"rel":245},"https://arxiv.org/abs/2106.09685",[35],"LoRA原论文",[10,248,249,250],{},"蒸馏让学生学习教师的输出或分布，学生可以使用不同规模和结构。",[31,251,254],{"href":252,"rel":253},"https://arxiv.org/pdf/1503.02531",[35],"知识蒸馏原论文",[10,256,257],{},"这些方法可组合，但作用层次不同：看到“小文件”，先问它少了参数、少了每参数位数，还是只保存了一份适配器。",[17,259,261],{"id":260},"_9怎样判断省下的空间值得","9．怎样判断省下的空间值得",[10,263,264],{},"先固定原模型版本、任务题集、提示和生成规则，再比较量化版本。既看整体成绩，也检查任务中的关键错误，例如日期提取错误、代码运行失败或无依据补全。几条看起来顺畅的回答，无法排除少数重要场景退步。",[10,266,267],{},"同时记录权重文件、峰值运行内存、首段输出等待时间和持续生成速度。这些指标可能朝不同方向变化。还要区分平均速度与峰值资源：平均每秒输出更多token，不代表第一次出字更快；短问题能运行，也不代表最长输入仍不会超出内存。测试输入的长度、并发请求数和输出上限，应接近实际使用。",[10,269,270],{},"如果两版输出不同，先确定是同一解码条件，再追踪是否由数值变化引起。改变位数的同时又换了提示、采样参数和软件版本，会混入多个原因。量化通常以尽量保持原有任务行为为目标，也不应被当成主动修复知识错误的办法。",[10,272,273],{},"这里可以借用数值软件的两层验收。先固定同一输入，把原精度与量化后的中间输出作差，检查偏差从哪里出现；再检查日期、计算结果等任务要求有没有退步。第一层帮助定位误差，第二层判断代价是否可接受。原精度输出在这里是数值参照，并不自动成为事实标准。量化本来就允许近似，容差应事先约定；但容差内的数值差，也不能代替关键任务的回归检查。图2中接近的两个候选就可能因小扰动换序。",[10,275,276],{},"若部署目标是“原来装不下，现在装得下”，即使速度没有提高，也可能有实际价值；若目标是低延迟，就必须直接测延迟。",[17,278,279],{"id":279},"本章练习",[281,282,283],"h3",{"id":283},"题目",[10,285,286],{},[287,288,289],"strong",{},"问题1｜近似值能恢复多少",[10,291,292],{},"s＝0.2、整数编码－4时，反量化是多少？它能证明原值恰好相同吗？若仍用本章［－1.4，1.4］范围记录2.6，误差是多少，为什么半格界不适用？",[10,294,295],{},[287,296,297],{},"问题2｜范围与附加开销",[10,299,300],{},"加入14且共用scale后，0.91为什么还原为0？每64个4-bit权重共享一个32-bit scale，平均每权重多少bit？分组为什么仍要测任务效果？",[10,302,303],{},[287,304,305],{},"问题3｜从数值到选择",[10,307,308],{},"A、B的logits为1.00与0.98，每项扰动绝对值不超过0.02，能保证A仍领先吗？若改为1.00与0.00呢？",[281,310,311],{"id":311},"思考提示",[10,313,314],{},[287,315,316],{},"提示1｜对应问题1",[10,318,319],{},"先乘scale；区分最近刻线舍入与越界裁剪。",[10,321,322],{},[287,323,324],{},"提示2｜对应问题2",[10,326,327],{},"scale由组内最大绝对值决定；把尺度开销也分摊到64个权重。",[10,329,330],{},[287,331,332],{},"提示3｜对应问题3",[10,334,335],{},"两项可以向相反方向移动，分差最多缩小2ε。",[281,337,338],{"id":338},"参考答案与解析",[10,340,341],{},[287,342,343],{},"答案1｜对应问题1",[10,345,346],{},"还原为－0.8，但不能反推唯一原值，－0.73也映到此档。2.6被裁剪到1.4，按还原值减原值，误差为－1.2。半格0.1只约束未裁剪的最近档位舍入，越界值不满足条件。",[10,348,349],{},[287,350,351],{},"答案2｜对应问题2",[10,353,354],{},"scale＝14/7＝2，0.91/2＝0.455，舍入为0。平均为(64×4＋32)/64＝4.5 bit，尚未计其他元数据。分组改变舍入与裁剪分布，输入又会加权放大或抵消误差，较小权重误差不能直接替代完整任务检查。",[10,356,357],{},[287,358,359],{},"答案3｜对应问题3",[10,361,362],{},"第一组不能保证：A减0.02变0.98，B加0.02变1.00，顺序交换。第二组能保持这两项的顺序，因为原领先差1.00大于2ε＝0.04；最不利情形仍是0.98对0.02。结论依赖给定扰动界，只讨论这两个候选。",[17,364,365],{"id":365},"下一章",[10,367,368],{},"我们已经得到一份可使用的模型，权重也可能经过近似表示。模型给出下一token的分数后，程序究竟选哪一个，怎样继续，什么时候停？下一章沿着自回归生成，把概率、采样与完整文本连起来。",{"title":370,"searchDepth":371,"depth":371,"links":372},"",3,[373,375,376,377,378,379,380,381,382,383,388],{"id":19,"depth":374,"text":20},2,{"id":39,"depth":374,"text":40},{"id":85,"depth":374,"text":86},{"id":116,"depth":374,"text":117},{"id":152,"depth":374,"text":153},{"id":176,"depth":374,"text":177},{"id":197,"depth":374,"text":198},{"id":226,"depth":374,"text":227},{"id":260,"depth":374,"text":261},{"id":279,"depth":374,"text":279,"children":384},[385,386,387],{"id":283,"depth":371,"text":283},{"id":311,"depth":371,"text":311},{"id":338,"depth":371,"text":338},{"id":365,"depth":374,"text":365},"从信息表示和学习出发，用可核算的例子与白板图逐步理解大模型、后训练、推理和Agent系统。","md",{},true,"/column/llm-to-agent-learning/18",{"title":5,"description":389},"column/llm-to-agent-learning/18","LMl-pPM6BsUxKVvm4n-yFHCNcJ3wv8dlNlFGTORn1C0",1791935828763]