尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

你瘦不下来但大模型可以:量化原理了解一下

你瘦不下来但大模型可以:量化原理了解一下 温馨提示另有配套视频版附带图解演示观感不同欢迎到各大视频平台搜索同名标题或【蛋先生说识】什么是量化丹尼尔蛋兄最近在折腾大模型本地部署经常遇到 “量化” 这个词一直没搞懂到底是什么蛋先生就是用大模型量化交易啊搞钱丹尼尔真的蛋先生(ಡωಡ) 假嘟哈哈。此量化非彼量化啦丹尼尔额那到底什么是量化蛋先生打个比方吧——量化就像把 4K 高清视频压成 720P文件小了硬盘省了内存也省了。虽然画质有点损失但大部分时候你看剧根本感觉不到差别量化的基本原理丹尼尔哦原来是给大模型瘦身啊那具体是怎么压缩的呢蛋先生核心思路就是把位数多的浮点数比如 FP16映射成位数更少的整数比如 INT8、INT4来存储不了解 FP16 的同学可以先去各大平台搜索 《大模型参数存储格式揭秘BF不是男朋友》补个基础丹尼尔哦那如何映射蛋先生假设有一组浮点数[-0.20, -0.14, -0.09, -0.05, -0.02, 0.00, 0.03, 0.07, 0.11, 0.15, 0.18, 0.20]值范围是[-0.2, 0.2]。现在要把它们映射到 5 个整数编码-2、-1、0、1、2你会怎么分丹尼尔(.) 容我思考片刻…算了你还是直接说答案吧蛋先生先把[-0.2, 0.2]这个区间五等分每份交界处打个刻度再给每个刻度贴上整数标签刻度位置−0.2−0.100.10.2整数标签-2-1012量化的规则很简单每个浮点数看自己离哪个刻度最近就贴上那个刻度的整数标签原始浮点最近的刻度贴上标签-0.20−0.2-2-0.14−0.1-1-0.09−0.1-1-0.05−0.1-1-0.02000.00000.03000.070.110.110.110.150.220.180.220.200.22丹尼尔哇, amazing这样存储确实省了不少空间。但怎么把整数还原成浮点数呢蛋先生大模型推理时大部分情况下的确是需要把整数权重反量化回浮点数来计算少数情况下是可以直接用整数计算的这个等讲到公式时再细聊对称 INT4 / INT8 量化丹尼尔原理大概听懂了可以再深入一点蛋先生量化方案有很多GPTQ / AWQ / llama.cpp 等但它们共享同一个底层基石对称 INT4 / INT8 量化。下面我通过一个完整的演算示例带你走一遍丹尼尔真贴心赶紧开讲蛋先生假设我们有一组 FP16 格式的权重参数范围是w ∈ [−0.2, 0.2]。准备用 INT4 量化。4 bit 有符号整数用二进制补码表示编码范围是q ∈ [−8, −7, ... 0 ... 6, 7]丹尼尔等等为什么是[−8, −7, ... 0 ... 6, 7]而不是[−7, ... 0 ... 6, 7, 8]蛋先生这是二进制补码硬件标准自行问 AI 去吧这里不展开讲了丹尼尔好好您继续蛋先生零偏移zₚ 0这正是「对称」的含义0 轴两侧的编码范围相对零点完全对称映射。我们的目标只有一个算出scale通过它才能让 INT4 跟 FP16 之间互转丹尼尔目前为止云里雾里的蛋先生别急一步步来步骤 1统计原始权重极值蛋先生第一步简单先找出权重参数的最大值和最小值丹尼尔这个例子是wₘᵢₙ −0.2wₘₐₓ 0.2步骤 2计算最大绝对值 A蛋先生好助手。第二步求两个原始权重极值的最大绝对值 A丹尼尔这我也会A max(|wₘₐₓ|, |wₘᵢₙ|) max(0.2, 0.2) 0.2步骤 3计算 scale蛋先生第三步采用行业标准公式s A / 7丹尼尔等等为啥是 7INT4 编码不是 −8 到 7 吗蛋先生关键就在这——7 是最大的正编码我们想让最大的浮点数权重 A 完美对应到 q 7这样正方向不浪费任何编码空间丹尼尔没听懂蛋先生套公式看看s 0.2 / 7验证一下q 7⇒ŵ 7 × s 7 × 0.2 / 7 0.2刚好对上。这就是反量化后面再聊丹尼尔那为什么不能拿 ‑8 来算 scale比如s A / 8蛋先生问得好。我们来试一把s 0.2 / 8 0.025。正向最大编码还是 77 × 0.025 0.175。但我们真实权重最大值是 0.20.2 0.175正向直接溢出权重直接失真丹尼尔明白了蛋先生scale 拿到了我们算下最关键的最小值 q −8 对应多少−8 × 0.0285714 ≈ −0.22857丹尼尔下限 −0.22857 比 −0.2 还多出来一截蛋先生没错−8 这个编码档位其实是闲置的因为没有权重参数会落到这个区间。这就是对称量化的一个小代价正数侧最大可用编码只有 7scale 分母只能用 7导致必然有一个编码用不上步骤 4量化 — 浮点转整数丹尼尔好像有点理解 scale 了它有点像一把尺子上的刻度之间的距离相邻刻度之间的距离就是 scale蛋先生恩理解得很到位。有了 scale就可以来计算浮点数到整数编码的转换了。公式如下w_int clip( round(w_float / scale), Qmin, Qmax )丹尼尔一看公式就头疼蛋先生其实很简单就三步除 scale → 四舍五入 → 截断。除 scale把浮点值按 scale 切分算出它落在哪一档 四舍五入可以算出它离这一段的两个头尾的整数编码哪个更近 截断防御性编程确定结果落到合法的范围比如 INT4 的合法区间就是 [−8, 7]小于最小值就取最小值大于最大值就取最大值。对称量化的场景下截断基本不会触发丹尼尔你还是举一些例子吧蛋先生正负两个浮点数各一个示例吧例 1w 0.1 ① 除 scalew / s 0.1 ÷ 0.0285714 ≈ 3.5 ② 四舍五入q round(3.5) 4 ③ 截断至 [−8, 7]4 在区间内无需截断 例 2w −0.18 ① 除 scalew / s −0.18 ÷ 0.0285714 ≈ −6.3 ② 四舍五入q round(−6.3) −6 ③ 截断至 [−8, 7]−6 在区间内无需截断步骤 5反量化 — 整数转回浮点丹尼尔看明白了。那量化完后推理时怎么把整数变回浮点数呢蛋先生直接用重建公式ŵ q × s一步搞定例 1 反量化ŵ 4 × 0.0285714 ≈ 0.11428 例 2 反量化ŵ −6 × 0.0285714 ≈ −0.17143丹尼尔咦0.1 回去变成 0.11428−0.18 变成 −0.17143误差还不小蛋先生这就是量化的代价嘛 (─.─||)。INT4 总共就 16 个取值档位精度有限。比如 0.1 恰好落在 q3 和 q4 的正中间往 4 靠就有了这个误差存在什么问题丹尼尔这种量化方式会有哪些问题呢蛋先生有一些比如权重分布如果不相对 0 轴对称——像[0, 0.2]这种全是正数的对称量化会让 −8 到 −1 这 8 个编码直接荒废掉。这时就得用非对称量化了再比如权重里混进了极端离群值比如[0.10, 0.12, 0.08, 0.11, 0.09, 0.80]全局 scale 会被 0.8 撑大0.1 附近的参数全挤到同一档。解决方案是分组量化各组独立算自己的 scale把极端值的影响控制在一个小组内丹尼尔感觉脑袋快要装不下了……蛋先生我觉得不止你正在看这篇文章的朋友们应该也快打盹了 (─.─||)。今天就到这有缘再聊丹尼尔拜拜写在最后亲们都到这了要不点赞 / 收藏 / 关注支持下我呗 o(▽)
返回列表