简介

本文全面介绍大模型量化技术,详细解释量化基本原理、核心价值(省空间、省时、省钱)及不同量化策略(仅权重量化、全量化等)。深入探讨LLM量化面临的异常值挑战,分析其来源、分类及对模型性能的影响,为开发者提供从基础概念到前沿技术的全面指南,帮助解决大模型部署中的资源瓶颈问题。

引言:当万亿参数成为“新常态”,我们为何需要模型量化?

我们正处在一个由人工智能主导的变革时代,而这个时代的“主角”——大型语言模型(LLM)正以惊人的速度膨胀。得益于Transformer、MoE等强大架构的提出,深度学习模型的参数规模从数十亿轻松跨越至上万亿,能力边界被一次次刷新。然而,这股强大的AI浪潮之下,汹涌的“资源暗流”也随之而来。当我们为模型的智慧惊叹时,一个极其现实的问题摆在了所有开发者和企业面前:我们那昂贵的、顶配的GPU,似乎越来越不够用了。

这种“不够用”并非错觉,而是大模型指数级增长带来的必然结果,主要体现在两大核心痛点上:

显存之困:每一寸空间都弥足珍贵

大模型强大的能力根植于其海量的参数。但“大”也意味着沉重的负担。将一个模型跑起来,首先要面对的就是堪称“吞金巨兽”的显存压力。

  • 模型参数本身:一个看似“中等”规模的模型,如LLaMA-13B,若以半精度(FP16)格式加载,就需要大约26GB的显存。这意味着,仅仅是让模型“站起来”,就足以榨干一张顶级消费级显卡的全部显存。对于动辄数百、上千亿参数的更大模型,所需的硬件成本更是天文数字。
  • 动态的KV Cache:这或许是比模型参数更隐蔽的“显存杀手”。在处理长文本时,为了维持上下文记忆,模型会生成一个KV Cache。它的可怕之处在于,其大小会随着输入序列长度的增加而线性增长。例如,在处理一个32K长度的文本序列时,光是KV Cache本身就可能吞噬掉几十GB的宝贵显存。这使得模型处理超长文本的能力被显存容量死死卡住,极大地限制了其应用场景的拓展。

效率与成本之痛

显存的捉襟见肘,会直接引发一系列连锁反应,最终体现为计算效率的下降和部署成本的飙升。

计算效率下降:
  • 批处理能力受限:由于显存不足,服务器难以同时处理多个请求,吞吐量(Throughput)大打折扣。
  • 响应延迟增加:特别是在处理长序列时,模型的推理时间显著延长,无法满足实时交互等场景的严苛要求。

部署成本高昂:最终,所有的性能问题都会传导至成本端。推理成本可以粗略地估算为:

推理成本 ≈ 模型Token的平均推理时间 × 功耗 × 电费

模型越大,推理越慢,需要的GPU越多,功耗和电费就越高昂。无论是希望在云端提供服务的企业,还是想在边缘设备、移动终端上运行AI应用(这些场景对内存和功耗的限制更为苛刻)的开发者,都面临着巨大的挑战。

综上所述,如何让这些“庞然大物”变得更小、更快、更省钱,同时尽可能不损失其强大的智能,已经成为整个AI领域亟待解决的核心议题。

为了打破这一困境,研究者们提出了包括模型剪枝(Pruning)、知识蒸馏(Knowledge Distillation)、紧凑架构设计在内的多种模型压缩技术。而在众多技术中,模型量化(Model Quantization),以其普适性和显著的效果,成为了我们为大模型“瘦身续命”的首选利器。

本系列文章,就将带您深入探索模型量化的世界。而今天,作为开篇,我们将从最基本的问题开始:什么是模型量化?它又是如何解决上述难题的?

第一章:什么是模型量化?—— 为模型来一次“有损”但高效的“瘦身”

如果说引言部分我们探讨了为什么要给大模型“瘦身”,那么这一章,我们就来揭晓“瘦身”的具体动作和其带来的惊人效果。这个动作,就是模型量化(Model Quantization)。

1.1 核心思想:从高精度到低精度的转变

模型量化的核心思想朴素而又强大:将模型内部那些用于计算和存储的数字,从“高精度”格式,转换为“低精度”格式。

下面这张图精准地概括了量化的定义:

简单来说,当前大模型最常见的量化操作,就是将标准的32位单精度浮点数(FP32),转换为8位定点整数(INT8)。这个过程,本质上是将一个范围更广、表达更精确的连续数值,映射到一个范围较小、表达相对粗略的离散整数上,如下图所示:

要理解这个转变的威力,我们首先需要了解这些数字在计算机中究竟长什么样。一个32位的浮点数(FP32)之所以精确,是因为它用了足足32个比特位来编码一个数字,其中包含了符号、指数(决定数值范围)和尾数(决定数值精度)三部分。而像FP16、BF16等半精度格式,则是在范围和精度之间做了不同的取舍。

从上图我们可以清晰地看到几个常用的浮点数,假设我们从FP32转变到INT8,意味着表示一个数字所用的比特数从32个急剧减少到了8个。根据内存计算公式:

一个FP32参数占用4个字节,而一个INT8参数仅占用1个字节。这是一个实实在在的4倍压缩!

当我们将一个模型中数以十亿计的参数全部进行这样的转换,就完成了一次彻底的“瘦身”。
一直在更新,更多的大模型学习和面试资料已经上传带到CSDN的官方了,有需要的朋友可以扫描下方二维码免费领取【保证100%免费】👇👇

1.1.1 量化带来的核心价值

这次手术究竟能带来哪些实实在在的好处呢?总的来说,这些好处可以概括为三个核心价值:省空间(更低的存储和内存需求)、省时(更快的推理速度)和省钱(更低的部署与运营成本)。

1. 省空间:更小的模型,更低的硬件门槛

这是量化最直观的收益。将数据类型从32位的FP32转换为8位的INT8,意味着表示每一个参数所用的比特数减少了4倍。

  • 更小的磁盘占用:一个庞大的预训练模型,其文件体积会成倍缩小。例如,一个70亿参数(7B)的模型,其FP32权重约为28GB,而INT8量化后仅需约7GB。这极大地便利了模型的存储、分发和加载。
  • 更低的内存(显存)消耗:在推理时,模型需要被完整加载到GPU显存中。内存消耗的降低意味着我们可以用更亲民的硬件来运行更强大的模型。

2. 省时:更快的推理,更高的系统效率

除了节省空间,量化还能显著提升模型的推理速度。这种加速主要来源于两个方面:

  • 减少访存瓶颈:对于大模型推理,特别是在逐个生成token的解码(decoding)阶段,系统的瓶颈往往不在于计算本身,而在于从GPU显存(HBM)中读取那数以十亿计的庞大权重参数所花费的时间。这个过程是访存密集型(IO bound)的。因为量化后的权重体积变得更小,从显存读取到计算核心所需的时间也相应缩短,从而极大地降低了推理延迟。
  • 释放硬件潜力(向量化运算):现代CPU和GPU都为低精度整数运算设计了专门的、高效的计算单元和指令集,即向量化运算(SIMD)。这允许处理器在单个指令周期内并行处理更多的数据。我们可以做一个形象的类比:想象一个处理器有一条512位宽的数据通道。如果用它来处理32位的FP32浮点数,一次最多能处理 512 / 32 = 16 个。但如果换成处理8位的INT8整数,同样的时间内,它能处理 512 / 8 = 64 个!这直接带来了理论上高达4倍的计算吞吐量提升,极大地加速了矩阵乘法等核心运算。

3. 省钱:更低的综合部署与运营成本

“省空间”和“省时”最终都将转化为最直接的商业价值——“省钱”。模型的部署和运营成本可以用下面这个公式来粗略衡量:

推理成本 ≈ 模型 token 的平均推理时间 × 功耗 × 电费

模型量化通过以下方式全面降低了这一成本:

减少硬件需求:更低的显存占用意味着可以用更少、更便宜的GPU来部署同一个模型。

降低推理时间:更快的推理速度意味着在单位时间内可以服务更多的用户请求,提升了服务器的吞吐量。

降低功耗:整数运算比浮点运算能效更高,能显著降低运行时的功耗,从而节省大量的电费开销。

总而言之,模型量化的核心思想就是一次权衡(Trade-off):我们牺牲了理论上的一部分数值精度(这种精度损失在很多场景下对模型最终性能影响甚微),来换取在存储、内存、速度和成本上实实在在的巨大收益。这笔交易,对于当前被大模型“压得喘不过气”的硬件资源来说,无疑是极具价值的。

1.2 量化的三大对象:我们到底在量化什么?

在了解了量化的核心思想之后,我们可能会有一个疑问:量化这个“瘦身”手术,具体是作用在模型的哪个部位上呢?实际上,量化并非一个笼统的操作,而是可以精确地作用于模型内部不同的数据流上。根据量化对象的不同,我们主要可以将其分为三类:权重量化、激活值量化和KV Cache量化

1.2.1 权重量化 (Weight Quantization)

这是最基础、最常见的量化操作。

  • 对象:模型的所有权重参数(Weights)。权重是模型在训练过程中学习到的知识的载体,可以看作是模型的“DNA”或“知识库”。在模型训练完成后,权重的值是固定不变的,因此它们是静态(Static)的。
  • 目标:主要目标是压缩模型的体积,降低其在硬盘上的存储占用和在推理时加载到内存(显存)中的空间。
  • 特点:由于权重是静态的,对它们进行量化相对简单。我们可以在模型部署前,离线地、充分地分析权重的数值分布,找到最佳的量化方案,而无需任何额外的校准数据。
1.2.2 激活值量化 (Activation Quantization)

这是实现模型端到端加速的关键,但同时也更具挑战性。

  • • 对象:模型在计算过程中产生的中间激活值(Activations)。如果说权重是模型的“DNA”,那么激活值就像是模型在思考时,神经网络中流动的“实时电信号”。
  • • 目标:激活值量化的核心目标是为了实现极致的推理加速。只有当权重和激活值被量化为低精度整数(如INT8)后,我们才能让整个矩阵乘法运算完全在高效的整数计算单元上执行,从而最大限度地发挥硬件的加速潜力。
  • • 特点与挑战:与静态的权重不同,激活值是动态(Dynamic)的,它的数值分布会随着每一个不同的输入而剧烈变化。我们无法预知下一次输入会产生什么样的激活值,这使得量化变得非常困难。更糟糕的是,正如我们将在后面章节深入探讨的,LLM的激活值中常常藏着一些数值极大的“异常值”(Outliers),它们是量化过程中最主要的精度杀手。

下图清晰地对比了**仅权重量化和权重-激活值联合量化(全量化)**的计算流程差异。

1.2.3 KV Cache量化

这是一种针对Transformer架构,特别是长文本推理场景下的核心优化技术。

  • • 对象:自注意力机制中用于存储上下文历史信息的键(Key)和值(Value)缓存,即KV Cache。KV Cache可以被看作是模型的“记忆”,模型每生成一个新词,都要回顾一遍完整的KV Cache。
  • • 目标:主要目标是节省推理时的显存占用。正如引言中提到的,KV Cache的体积会随着序列长度线性增长,是长文本应用中最主要的显存瓶颈。通过将其从FP16量化到INT8甚至更低,可以成倍地降低这部分“短期记忆”的占用空间。
  • • 特点:对KV Cache进行量化,能让模型在有限的显存下处理更长的文本序列,或者在同样序列长度下支持更大的批量(Batch Size),从而显著提升系统的吞吐量和效率。

综上所述,这三大对象——权重、激活值、KV Cache共同构成了大模型量化的主要战场。不同的量化算法会根据其目标,对这三者采取不同的量化策略和组合,以期在模型精度、推理速度和内存占用之间找到最佳的平衡点。

第二章:量化的基石:解密数字世界的“魔法”

在上一章,我们理解了模型量化的核心思想及其带来的巨大收益。现在,让我们潜入更深的层次,探索这一切得以实现的基石——计算机是如何表示数字的。因为神经网络的推理和训练都是计算密集型的,所以,数值的有效表示就显得尤为重要。

2.1 浮点数家族(FP):精度与范围的艺术

要真正理解量化,我们必须先成为“数字世界的解剖学家”,解剖构成现代AI模型的“细胞”——浮点数(Floating-Point, FP)。为什么有FP32,又有FP16、BF16,甚至更新的FP8?因为在有限的比特空间内,对一个数字的表示永远是一场关于“范围”(Range)和“精度”(Precision)的艺术性权衡。

2.1.1 王者FP32:衡量一切的黄金标准

FP32(32位单精度浮点数) 是我们最熟悉,也是计算领域长期以来的“黄金标准”。它用32个比特位来表示一个数字,其内部结构像一个精密的仪器,由三部分构成:

  • 符号位 (Sign Bit): 1位。这是最简单的一部分,只占1个比特位,用来决定数字的正负(0代表正数,1代表负数)。它就像数字前面的正负号+ / -。,0代表正数,1代表负数。
  • 指数位 (Exponent): 8位。这是决定数值范围或“数量级”的核心。它不直接存储指数大小,而是通过一个偏移量(Bias)来间接表示。例如,在FP32中,指数位有8个比特,偏移量为127。如果指数位存储的二进制值是130,那么实际的指数就是130 - 127 = 3。这意味着它将把尾数代表的基础值放大 倍。我们可以把它类比为测量长度时选择的单位:指数位决定了我们是用“毫米”、“米”还是“千米”来度量,它决定了数值的“宏观尺度”。
  • 尾数位 (Mantissa): 23位。这是决定数值精度或“有效数字”的核心。它存储了数字的小数部分。为了最大化利用空间,标准浮点数(规范数)采用了一个巧妙的设计:它默认小数点前有一个隐含的前导1。例如,如果尾数位存储的是二进制101…,那么实际代表的尾数值是1.101…(二进制)。继续用测量长度的类比,尾数位就像是我们在选定单位(如“米”)后,尺子上记录的具体刻度,比如“1.8125米”。它的位数越多,刻度就越密,测量就越精确。
总结一下:

浮点数符号位尾数位指数位偏移量

通过这三个部分的组合,浮点数可以用有限的比特(如32位)表示一个巨大范围内的、具有很高精度的数值。但也正是这种复杂性,使得它的计算开销远高于简单的整数。

让我们再以一个例子来手动“解剖”一个FP32数字,看看它是如何工作的: 假设有一个FP32数的二进制表示为:

0 10000010 11010000000000000000000

1.解析符号位: 第一位是0,代表这是一个正数。

2.解析指数位: 接下来8位是10000010。

  • • 转换为十进制,它是130。
  • • 但这不是最终的指数!为了能表示正负指数,FP32引入了偏移量(Bias),其值为127。实际指数需要用存储值减去偏移量。
  • • 所以,实际指数 = 130 - 127 = 3。

3. 解析尾数位: 最后23位是11010000000000000000000。

  • • 浮点数有一个巧妙的“隐含前导1”设计,即默认尾数所代表的小数前还有一个1.。
  • • 所以,实际的尾数二进制为 1.1101。
  • • 转换为十进制:

4. 计算最终值:

最终值符号位尾数指数

FP32以其巨大的动态范围和高精度(约7位十进制有效数字)成为了无可争议的王者,但它的“王冠”之重——32比特的庞大身躯,也正是我们在大模型时代试图优化的对象。

2.1.2 “双子星”FP16与BF16:效率与稳定的抉择

为了给FP32“减负”,人们设计出了两种16位的半精度(Half-Precision)格式,它们是AI领域最常见的效率担当,但各自的“性格”却截然不同。

FP16 (半精度浮点数):追求极致效率的“急先锋”。

  • • 构成: 1位符号,5位指数,10位尾数
  • • 特点: 它的内存占用直接减半,能显著提升访存和计算效率。但它的致命短板在于指数位太少,只有5位,导致其动态范围非常小。在训练大模型时,梯度值很容易超出其表示范围而变成无穷大(上溢),或因太小而变成0(下溢),导致训练过程非常不稳定。它更适合数值范围相对可控的推理场景。

BF16 (Bfloat16):追求训练稳定性的“战略家”。

  • • 构成: 1位符号,8位指数,7位尾数
  • • 特点: BF16的设计堪称绝妙,它保留了和FP32完全相同的8位指数,这意味着它的动态范围和FP32一样巨大,从根本上解决了FP16的溢出问题。但作为代价,它的尾数位只有7位,精度是三者中最低的。它用“牺牲小我(精度)”的策略,换来了“完成大我(训练稳定)”的成功。
2.1.3 新锐FP8:极限压缩的探索

在追求极致性能的道路上,研究者们将目光投向了更激进的FP8格式。它旨在结合浮点数的宽动态范围和8位整数的极高效率。主要有两种变体:

  • FP8-E5M2: 拥有5位指数和2位尾数。它的动态范围与FP16相当,但精度极低,适用于那些对数值范围敏感但对精度要求不高的场景。
  • FP8-E4M3: 拥有4位指数和3位尾数。它的动态范围较小,但精度比E5M2略高,适用于数值分布更集中的场景。

FP8的出现,标志着浮点数量化进入了一个新阶段,它试图在低比特下继续维持浮点数动态范围的优势。

综上所述,整个浮点数家族展现了一幅生动的“权衡”画卷:指数位的比特数决定了“能看多远”(范围),而尾数位的比特数决定了“能看多清”(精度)。在有限的总比特数下,两者永远是此消彼长的关系。

2.2 整数家族(INT):量化的终点

在上一节剖析了结构复杂、表示精准的浮点数家族后,我们现在将目光转向它们更“接地气”的亲戚——整数(Integer, INT)家族。如果说浮点数是AI世界的“贵族”,那么整数就是高效勤恳的“工兵”。模型量化的核心目的,正是要将信息从“贵族”能够理解的复杂语言,翻译成“工兵”能够高效执行的简洁指令。

整数的本质是定点数(Fixed-Point),即小数点的位置被固定(通常在末尾)。这种表示法牺牲了浮点数那样的宽动态范围和高精度,换来的是两个无与伦比的优势:极简的结构和极高的运算效率。这正是硬件所钟爱的特性。

在模型量化的世界里,我们主要关注两位核心成员:INT8和INT4。

2.2.1 高效的INT8:当前的主流选择

INT8(8位定点整数)是当前模型量化领域当之无愧的“主流王者”,是平衡性能与精度的“甜点区(sweet spot)”。

  • • 基本定义: INT8使用8个比特位来表示一个数字。这意味着它总共只能表示 2^8 = 256 个不同的离散值。对于有符号整数,这个范围通常是 -128 到 127。
  • • 为何成为主流?

1. 足够高的表达能力: 对于深度学习模型,尤其是那些被证明存在大量冗余的过参数化大模型,用256个等级来近似描述权重或激活值的分布,在许多情况下已经足够。实践表明,从FP32量化到INT8,模型的精度损失通常可以控制在非常小的范围内。
2. 极致的硬件亲和性: 这才是INT8成功的关键。现代GPU(如NVIDIA的Tensor Core)和CPU(如支持AVX指令集的Intel处理器)内部都集成了专门为8位整数矩阵乘法设计的、高度优化的计算单元。这些硬件可以直接执行INT8 x INT8的运算,速度远超浮点计算。

一个重要的细节:累加精度

  • • 值得注意的是,虽然乘法本身可以在INT8下高效执行,但为了防止中间结果溢出,其累加过程通常会在一个更高精度的累加器(Accumulator)中完成,比如INT32。举个例子,两个INT8的最大值相乘:127 * 127 = 16129。这个结果远远超出了INT8的表示范围(-128到127),如果用INT8来存储,就会发生严重的溢出。因此,硬件会智能地使用32位的INT32累加器来存储这个中间结果,确保计算的正确性,最后再将最终结果转换回所需的格式。
2.2.2 极限的INT4:挑战性能极限

如果说INT8是稳健的优化,那么INT4(4位定点整数)就是对性能极限发起的冲锋。

基本定义: INT4只用4个比特位来表示一个数字,这意味着它只能表示 2^4 = 16 个不同的离散值。

优势与挑战并存

  • 极致的压缩率: 从FP32到INT4,比特数从32位降到了4位,带来了惊人的8倍压缩率!这意味着模型体积更小,内存占用更低,理论上的访存和计算加速潜力也更大。
  • 巨大的精度挑战: 用区区16个等级去描述原本复杂的浮点数分布,无疑会引入巨大的量化误差。简单地将模型量化到INT4,往往会导致模型性能出现不可接受的雪崩式下滑。

因此,INT4量化不能使用简单的方法,它必须依赖更复杂、更精巧的量化算法(例如我们将在后续文章中深入探讨的GPTQ、AWQ等)来精心处理,通过各种补偿和优化手段,才能在享受其极致压缩比的同时,将精度损失控制在可接受的范围内。

总而言之,整数家族是量化的高效终点。INT8是当下可靠的“工作主力”,而INT4则是探索未来更高效率可能性的“前沿先锋”。

2.3 量化与反量化:核心公式全解析

在认识了浮点数和整数这两个“物种”之后,我们现在要来学习连接它们之间桥梁的“语法书”——量化与反量化公式。正是这套简洁而精妙的数学法则,构成了所有量化技术的基础。

我们主要讨论的是线性量化(Linear Quantization),这也是当前应用最广泛的方案。它的目标是在浮点数和整数之间建立一个简单的、一一对应的线性映射关系。

要搭建这座转换的桥梁,我们需要两个核心的“建筑构件”:缩放因子(Scale)和零点(Zero-Point)。

2.3.1 核心构件一:缩放因子 (Scale, s 或 Δ) - 定义“汇率”

缩放因子是量化中最关键的概念,我们可以把它理解为浮点数世界和整数世界之间的“汇率”或“地图比例尺”。它定义了一个整数单位(比如1)等价于多少浮点数值。

  • • 物理意义: 如果s = 0.1,就意味着整数1代表浮点数0.1,整数2代表浮点数0.2,以此类推。s的值越小,量化的精度就越高。

  • • 计算方法: s是通过原始浮点数的范围和目标整数的范围来计算的。

  • • 和 :你想要量化的那批浮点数中的最大值和最小值。

  • • 和 :目标整数格式所能表示的最大值和最小值(例如,对于无符号INT8,就是255和0)。

2.3.2 核心构件二:零点 (Zero-Point, z) - 校准“原点”

如果说缩放因子定义了“步长”,那么零点就是用来校准“起点”的。

物理意义: 它的核心使命是确保浮点数世界中的0.0能够被整数世界中的某个值精确表示,从而避免引入系统性的偏差(bias)。

为何需要: 想象一下,我们要量化的浮点数范围是[-10.5, +30.2],这是一个非对称的范围。如果我们想把它映射到[0, 255]这个整数区间,浮点0.0应该对应哪个整数呢?零点z就是这个负责对齐的整数偏移量。

与对称/非对称的关系:

  • • 在非对称量化(Asymmetric Quantization)中,z通常是一个非零整数,以完美适配非对称的数据分布(如ReLU激活函数后的值)。
  • • 在对称量化(Symmetric Quantization)中,我们会强制让浮点范围关于0对称(如[-30.2, +30.2]),这样浮点0.0就能自然地映射到整数0(对于有符号整数)或者127/128附近(对于无符号整数),此时z就可以固定为0或接近中间值,简化计算。
2.3.3 完整流程:量化与反量化公式

有了缩放因子s和零点z,我们就可以进行完整的“翻译”工作了。

1. 量化 (Quantization) - 从浮点到整数

这个过程可以分解为四步:

  • • 缩放: 将原始浮点数r除以缩放因子s,将其“压缩”到单位尺度。
  • • 平移: 加上零点z,将原点对齐。
  • • 取整: 使用round函数将结果四舍五入到最近的整数。这是量化误差(Quantization Error)最主要的来源,因为小数部分的信息在这里被丢弃了。
  • • 截断: 使用clip函数确保最终的整数值q不会超出目标范围(例如[0, 255]),防止溢出。

2. 反量化 (Dequantization) - 从整数到浮点

这个过程是量化的逆运算,用于将量化后的整数q近似地恢复回浮点数 。在很多场景下,比如当硬件不支持整数运算时,或者在计算的最后一步需要浮点输出时,就需要执行反量化。

虽然这些公式看起来很简单,但整个模型量化技术的博大精深之处,正在于如何为不同的权重和激活值,找到最优的和,从而计算出能最大程度保留模型信息的s和z。这正是我们将在后续章节探讨的各种高级量化策略(如裁剪、校准)和算法(如GPTQ、AWQ)所要解决的核心问题。

第三章:主流路径之争:仅权重量化 vs. 全量化

在我们理解了量化的基础构件之后,便来到了实践中的第一个关键抉择点:究竟是对模型的哪个部分进行量化?是只压缩占据大量存储空间的权重,还是连同在计算中不断流动的激活值也一并处理?这催生了两条主流的技术路径:仅权重量化(Weight-only Quantization)和全量化(Full Quantization)。

3.1 仅权重量化:专注核心,简单高效

仅权重量化是一种“抓大放小”的策略,也是目前社区中最流行、最容易上手的量化方案。它将优化的焦点完全集中在模型参数这个“最大的目标”上。

3.1.1 核心定义与工作流程

顾名思义,仅权重量化就是只对模型中静态的、预先训练好的权重(Weights)参数进行低精度转换(例如从FP16转换为INT8或INT4),而计算过程中动态产生的激活值(Activations)则保持原有的高精度格式(如FP16)。

我们可以做一个形象的比喻:这就像是我们将一本厚重的精装版百科全书(FP16权重)换成了一部轻便的、经过压缩排版的平装版(INT8权重)。书中的知识(模型能力)没有变,但书本本身变得更容易携带和翻阅了。而我们在阅读时所做的笔记(激活值)仍然是用原来的精细笔迹书写的。

它的工作流程非常清晰,如下图(a)部分所示:

  • • 加载(Load): 在推理时,首先从GPU显存中快速加载经过压缩的、低精度的权重。这是节省时间的第一步。
  • • 反量化(De-quantize): 在权重进入计算单元之前,一个关键的步骤是将其“解压”,即通过反量化操作,迅速恢复成高精度的FP16格式。
  • • 计算(Compute): 最终,核心的矩阵乘法是在高精度下完成的,即 。
3.1.2 优点:为何它如此受欢迎?

实现简单: 由于只处理静态的权重,整个过程相对简单。我们可以在模型部署前离线完成所有转换,不需要像处理动态激活值那样复杂。

通常无需校准数据: 因为我们不量化依赖于输入的激活值,所以通常不需要准备一个“校准数据集”来分析其动态范围,这大大降低了实施门槛。

精度损失风险较低: 因为核心的计算仍然在高精度下进行,所以相比于全量化,它对模型最终精度的影响通常更小,方案更为“安全”。

3.1.3 性能提升的真相:并非算得更快,而是等得更短

一个非常重要且容易被误解的问题是:既然计算最终还是FP16 \times FP16,那速度到底是怎么提升的呢?

答案是:性能提升的核心来源并非计算加速,而是内存带宽的节省

对于大语言模型,尤其是在逐个生成token的解码(decoding)阶段,系统的瓶颈往往不是GPU的计算速度不够快,而是访存速度太慢。GPU需要花费大量时间等待那庞大的权重矩阵从显存(HBM)中被读取到计算核心。这个过程是典型的访存密集型(IO bound)。

仅权重量化通过将权重压缩4倍(INT8)甚至8倍(INT4),极大地减少了需要传输的数据量。数据传输时间缩短了,GPU等待的时间就变短了,因此端到端的推理延迟就降低了。我们是“等”得更短了,而不是“算”得更快了。

3.1.4 适用场景与局限

最适用场景: 需要显著减小模型体积、降低内存占用,并对推理延迟有一定优化需求的场景。它是资源有限环境下部署大模型的绝佳“入门级”方案。

局限性:

  • • 加速效果有上限: 因为没有利用到硬件的整数计算单元,其加速效果不如全量化来得彻底。
  • • Prefill阶段可能变慢: 在处理初始长文本(Prefill)这种计算密集型阶段,由于多了一个反量化的操作,仅权重量化甚至可能会带来微小的性能下降。

总而言之,仅权重量化是一种非常务实且高效的量化策略,它用相对较小的代价,解决了模型“太大太重”的核心痛点,并带来了可观的性能收益,是理解和应用大模型量化技术一个完美的起点。

3.2 全量化:端到端加速,释放硬件全部潜力

如果说“仅权重量化”是一次精准、低风险的局部优化,那么全量化(Full Quantization),又称为权重-激活值联合量化(Weight-Activation Quantization),则是一场更彻底、更全面的性能“革命”。它追求的不是简单的“瘦身”,而是对模型整个计算流程的“基因改造”,以压榨出硬件的最后一滴性能。

3.2.1 核心定义与工作流程

全量化的核心定义非常清晰:它将模型中的权重(Weights)和激活值(Activations)这两个参与核心计算的关键单元,同时量化到低精度格式(通常是INT8)。

我们可以使用赛车的比喻:如果说仅权重量化是只更换了赛车的“轻量化轮胎”(权重),那么全量化就是连赛车在赛道上行驶时流经引擎的“空气和燃油”(激活值)也一并进行了优化处理,让整个动力系统都在最高效的状态下协同工作。

其工作流程,如下图(b)部分所示,与仅权重量化有着本质的区别:

  • • 激活值量化(Activation Quantization): 当高精度的激活值(如FP16)从上一层流过来时,它首先会经过一个量化(Quantization)步骤,被动态地(或基于静态校准参数)转换为低精度的INT8格式。
  • • 低精度整数计算(Integer Compute): 接下来,核心的矩阵乘法变成了一次极高效的 整数运算。这个步骤可以直接在GPU的Tensor Core等专用硬件上执行,速度极快。
  • • 反量化(De-quantize): 计算得到的累加结果(通常是INT32精度,以防溢出)在需要时(例如,需要与一个高精度的残差连接相加,或作为最终输出时),再通过反量化步骤恢复为高精度格式。
3.2.2 优点:为何要追求全量化?

极致的性能释放: 这是全量化最核心的价值。通过实现端到端的低精度计算,它能够完全避免耗时的浮点运算,最大限度地利用现代硬件中为整数运算设计的“高速公路”。在支持的硬件上,其推理速度可以达到FP32的数倍之多,是追求极致低延迟和高吞吐量场景的终极方案。

全面的带宽优化: 不仅是权重的加载,计算过程中在各层之间流动的激活值也变成了低精度格式。这意味着在整个模型的“血液循环”中,数据传输的压力都得到了缓解,进一步降低了访存瓶颈。

3.2.3 挑战:力量的代价

获得极致性能的背后,是全量化需要面对的严峻挑战,而这些挑战几乎全部集中在如何处理“激活值”上。

激活值的量化难题: 我们在后续章节会深入探讨,激活值的数值分布是动态的、不稳定的,并且常常包含一些数值极其巨大的“异常值”(Outliers)。这些异常值会严重干扰量化过程,导致巨大的精度损失。

更高的精度风险: 直接对这些棘手的激活值进行量化,就像是用一把刻度很粗的尺子去测量一个形状极其不规则的物体,很容易产生巨大的测量误差。因此,全量化方案,特别是对于低至4比特的量化,其模型精度的下降风险远高于仅权重量化。

对校准的强依赖: 为了解决上述难题,并保证量化后的模型精度,全量化(尤其是追求高性能的静态全量化)强依赖于一个关键步骤——校准(Calibration)。我们需要一个“引路人”来提前告诉我们激活值的“大致样貌”,而这个引路人,就是我们将要介绍的校准数据集。

总而言之,全量化代表了通过量化技术所能达到的性能优化的顶峰。但这份力量并非唾手可得,它要求我们必须更深入地理解和处理模型内部动态数据的复杂性,尤其是那些棘手又关键的激活值。

3.3 为何需要校准数据集?—— 激活值量化的“引路人”

在上一节,我们明确了“全量化”是追求极致性能的理想路径,但也指出了它最大的挑战在于处理动态的、不稳定的激活值。权重是静态的,其数值分布在模型训练后便已尘埃落定,我们可以从容地离线分析它。但激活值不同,它的分布随着每一个不同的输入而剧烈变化。

这就带来了一个核心矛盾:如果我们想实现最高效的静态量化(即为每一层预先计算好一套固定不变的量化参数s和z),我们应该以哪个输入下的激活值分布为准呢?如果选的范围太窄,新来的数据可能会溢出;如果选的范围太宽,又会损失精度。

为了解决这个难题,一个关键的角色应运而生——校准数据集(Calibration Dataset)。

3.3.1 校准集的角色:激活值分布的“星探”

首先要明确,校准数据集不是训练集。它通常是一小部分(例如几百到一千个)能够代表模型未来真实输入数据分布的样本集合。你可以从你的训练集中抽取一小部分,或者使用一些有代表性的真实世界数据。

它的唯一使命,就是充当一个“引路人”,帮助我们在模型正式部署前,“窥探”并“统计”出激活值通常会呈现出什么样的数值分布。

3.3.2 校准流程:“量化”前的彩排

校准的过程,就像是为模型量化进行的一次“彩排”。整个流程大致如下:

前向传播: 将校准数据集中的样本,逐一输入到原始的、未经量化的FP32模型中。

观察与记录: 在模型进行前向传播时,我们在需要量化激活值的每一层后面都安插一个“观察者”。这个观察者会忠实地记录下流经该层的所有激活值的数值,并通常会将它们统计成一个直方图(Histogram),以描绘其完整的分布轮廓。

分析与决策: 当所有校准数据都“过”一遍模型后,我们就为每一层的激活值都收集到了一个“典型”的分布图。接下来,就是最关键的一步——根据这个分布,用特定的校准算法来计算出该层最优的、固定不变的量化参数s和z。

3.3.2 校准算法:从“简单粗暴”到“智能裁剪”

如何根据收集到的分布信息来确定最佳的量化范围(即 和),是不同校准算法的核心区别。

1. 简单粗暴的max-min法

这是最直观的方法:直接使用在校准过程中观测到的激活值的最大值作为 ,最小值作为。这种方法虽然简单,但有一个致命的缺陷:对异常值(Outliers)极其敏感

举个极端的例子:假设某一层激活值,99.9%的数值都稳定在[-100, 100]之间,但校准数据中恰好有一个样本,使激活值出现了一个10000的异常值。如果使用max-min法,量化范围就会被这个异常值“绑架”,变成[-100, 10000]。这会导致那99.9%的正常值被挤压到极小的整数范围内,从而损失大量有效信息。

2. 更智能的裁剪策略(Clipping)

为了解决异常值问题,更高级的校准算法会采用“裁剪”的策略,即主动忽略一小部分极端值,为占绝大多数的正常值寻求一个更优的量化范围。

常见的智能裁剪策略包括:

  • 百分位法(Percentile): 一种简单有效的启发式方法。例如,不取100%的最大/最小值,而是取99.9%分位点的值作为量化范围,直接忽略掉最极端的0.1%的异常值。
  • KL散度法(KL Divergence): 一种更精妙的、基于信息论的方法。它会尝试不同的裁剪阈值T,并计算每个阈值下,量化后的数据分布与原始数据分布之间的信息损失(用KL散度衡量)。最终,它会选择那个能使信息损失最小的阈值 T 作为量化范围。这是NVIDIA TensorRT等工具中采用的先进方法。
  • 均方误差法(MSE): 寻找一个能量化范围,使得量化再反量化后的值与原始值之间的均方误差最小。

这个部分我们后面几篇文章进行详细的讲解,总而言之,校准数据集是激活值静态量化的基石。它的代表性和所采用的校准算法的先进性,共同决定了全量化模型的最终精度。可以说,一次成功的校准,是全量化模型能够兼顾高性能与高精度的前提保证。

第四章:量化的精细化策略:从宏观到微观的选择

经过前几章的学习,我们已经掌握了量化的基本原理和决策要素。然而,在实际操作中,量化并非只有一种固定的模式,它更像一个“乐高”积木盒,提供了多种组件和策略,我们可以根据不同的需求(模型、硬件、性能目标)来自由组合,搭建出最适合的量化方案。本章,我们就将全面解析这些关键的策略选择。

4.1 宏观工作流程:训练后“急救”还是训练中“免疫”?(PTQ vs QAT)

这是我们在量化之旅中遇到的第一个,也是最重要的战略分岔路。它决定了我们是在模型“成型之后”对其进行改造,还是在“成长过程”中就为其注入抗体。

4.1.1 训练后量化 (Post-Training Quantization, PTQ) - “便捷的急救手术”

PTQ是目前大语言模型领域应用最广泛的方案,正如其名,它的所有操作都在模型训练完成之后进行。

核心理念: 将一个已经完全训练好的、高精度的FP32模型视为一个“成品”。我们不对其内部的训练过程做任何干涉,而是像一个外科医生一样,在外部对这个成品进行一次低风险的“微创手术”,将其转换为低精度格式。

工作流程:

  • • 拿到一个训练好的FP32模型。
  • • 准备一个校准数据集(我们已在3.3节中详述)。
  • • 通过校准过程,为模型的权重和激活值计算出最佳的量化参数(s和z)。
  • • 使用这些参数,将模型转换为最终的量化模型(如INT8)。

优点:

  • 简单高效,成本极低: 这是PTQ最大的优势。它避免了重新训练大模型那天文数字般的计算开销,整个过程只需要少量数据和有限的计算资源,几小时内就能完成。
  • 数据无关性强: 它不依赖于庞大的原始训练数据集,只需要一小部分有代表性的校准数据即可,大大降低了实施门槛。

缺点:

  • 精度损失风险: 由于模型在原始训练时,并不知道自己未来会被量化,这种“后知后觉”的转换可能会带来一定的精度损失。尤其是在进行4比特等超低比特量化时,精度下降的风险会更大。
4.1.2 量化感知训练 (Quantization-Aware Training, QAT) - “昂贵的基因免疫”

与PTQ的“术后改造”不同,QAT选择在模型的“成长发育期”就介入。

核心理念: 在模型的训练或微调过程中,就让它“感知”到量化的存在。它通过在网络中插入“伪量化算子”(Fake Quantization Operators)来模拟量化操作在训练时可能带来的误差(如取整、裁剪等)。

工作流程:

  • • 在训练的前向传播中,伪量化算子会实时地将FP32的权重和激活值“伪装”成量化后的样子再参与运算。
  • • 在反向传播计算梯度时,由于常规的量化操作(如round)是不可导的,QAT会使用一种名为直通估计器(Straight-Through Estimator, STE)的技巧,近似地将梯度“穿透”伪量化算子,传递给原始的FP32权重,从而让模型在训练中学会如何调整自己,以主动适应和规避量化带来的误差。

优点: 精度更高: 因为模型是“带着镣铐跳舞”,主动学习如何最小化量化误差,所以QAT最终得到的模型精度通常显著高于PTQ,是追求极致模型性能的“王牌方案”。

缺点: 成本极其高昂: 它需要进行完整的模型训练或微调,对计算资源(大量高端GPU、长时间训练)和数据的要求与训练一个大模型无异,成本高到几乎让所有大型LLM望而却步。

4.1.3 总结与选择建议

我们可以用下面这张图和表格,来清晰地对比二者的差异。

特性 训练后量化 (PTQ) 量化感知训练 (QAT)
执行时机 模型训练完成之后 模型训练或微调之中
成本开销 低,快速便捷 极高,需要大量算力和时间
数据需求 少量校准数据 大量训练数据
模型精度 相对较低(尤其在超低比特下) 相对更高
主流应用 大语言模型(LLM)、快速部署场景 对精度有极致要求的模型(如CV领域)

结论非常明确:对于动辄千亿参数的大语言模型,PTQ以其无与伦比的低成本和便捷性,成为了当下绝对的主流和唯一切实可行的选择。而QAT则作为一种“高精度武器”,保留在那些资源允许、且对模型精度要求严苛的特定场景中使用。

4.2 激活值量化策略:静态 vs. 动态

在PTQ(训练后量化)的路径上,处理权重通常是直接了当的,因为它们是静态的。真正的挑战和决策点在于如何处理激活值——这些在网络中流动、随输入而变的动态数据。针对激活值的量化,主要有两种截然不同的策略:静态量化和动态量化

4.2.1 静态量化 (Static Quantization) - “未卜先知”,追求极致速度

静态量化是一种“预先准备,快速通过”的策略。它的核心思想是在模型正式部署之前,就“预测”并固定下激活值的量化参数。

工作流程: 正如我们在 3.3 节所详述的,静态量化强依赖于校准数据集。它通过让一小部分有代表性的数据“预先”流过模型,来窥探并统计出每一层激活值的“典型”数值范围。基于这个统计结果,它会为每一层的激活值计算出一套固定不变的缩放因子s和零点z。这套参数随后会被永久地保存在量化模型中。

优点: 极致的推理性能: 这是静态量化最大的优势。因为所有的量化参数都是预先计算好的,所以在真正推理时,硬件无需进行任何额外的计算,可以直接执行量化和矩阵乘法。这使得静态量化方案的延迟最低、资源效率最高,特别适合于对响应速度有严苛要求的服务器部署和边缘计算场景。

缺点: 精度依赖于校准: 它的成败完全系于校准数据集的“质量”。如果未来真实的输入数据分布与校准集大相径庭,那么预先算好的那套固定的s和z就会变得不合时宜,从而可能导致较为明显的精度下降。

4.2.2 动态量化 (Dynamic Quantization) - “相机行事”,追求更高精度

动态量化则采取了一种完全相反的、更加灵活的“实时决策”策略。

工作流程: 动态量化完全不需要校准数据集。它选择在每一次前向传播(即每次推理)的过程中,“实时地”分析当前输入所产生的激活值。具体来说,对于每一层的激活值张量,它都会在运行时动态地计算出其当前的最大值max和最小值min,并基于这个实时的范围,即时地计算出本次推理所用的s和z。

优点:

  • • 通常精度更高: 由于量化参数是为每一次输入“量身定制”的,它能完美地适配当前激活值的动态范围,因此通常能达到比静态量化更高的精度。这在输入数据分布变化非常剧烈的场景中尤其有优势。
  • • 部署简单: 省去了准备和管理校准数据集的步骤。

缺点:

  • • 引入运行时开销: 这是动态量化最主要的代价。每一次推理都需要额外执行一次(或多次)在激活值上计算最大/最小值的操作,这个额外的计算开销会直接增加推理的延迟。因此,它的运行速度通常慢于静态量化。
  • • 硬件支持受限: 并非所有的AI加速硬件都对这种运行时的动态计算提供了良好的优化支持。
4.2.3 总结与选择建议

我们可以用一个简单的表格来总结二者的核心区别:

特性 静态量化 (Static) 动态量化 (Dynamic)
参数计算时机 推理前(Offline),一次性计算并固定 推理时(Online),每次都实时计算
校准数据 需要 不需要
推理速度 快,无额外开销 相对较慢,有运行时计算开销
模型精度 依赖校准,可能较低 通常更高,适应性强
适用场景 延迟敏感、服务器部署、边缘计算 输入分布变化大、对精度要求极高的场景

选择建议: 在绝大多数追求高吞吐、低延迟的生产环境中,静态量化因其卓越的性能而成为首选方案。动态量化则作为一种有力的补充,在那些可以容忍一定延迟来换取更高精度的特定任务中发挥其价值。

4.3 数值映射方法:对称与非对称的权衡

在我们确定了要量化的对象(权重/激活值)和时机(静态/动态)之后,还需要深入到量化公式的核心,做一个关键的技术选择:我们应该如何将浮点数的范围映射到整数的范围上?这里存在两种主流的映射方法:对称量化(Symmetric Quantization)和非对称量化(Asymmetric Quantization)。

它们之间的核心区别,就在于如何处理零点(Zero-Point, z)。

4.3.1 对称量化 (Symmetric Quantization) - 简洁高效,中心对齐

对称量化,顾名思义,它要求量化的范围必须是关于原点0对称的。

图解: 观察浮点数轴(黄色): 这里的浮点数范围被设定为 [-α, α] (图中是[-4, 4]),这是一个严格关于原点0对称的区间。

  • • 观察映射关系: 由于范围是对称的,它可以非常自然地进行映射。浮点数0被精确地映射到了整数0。在这种情况下,我们不需要一个额外的零点偏移量,或者说,它的零点z永远固定为0。您可以看到,浮点数1此时被映射到了整数32。

核心机制: 它的第一原则是,浮点数世界的0.0必须精确地映射到整数世界的0。为了实现这一点,它强制规定零点z恒等于0。这也意味着,它只能处理形如[-R, R]这样上下限绝对值相等的浮点数范围,并将其映射到有符号的整数区间,例如[-127, 127]。其中,R通常取为原始浮点数张量的绝对值的最大值(即 )。

优点: 计算高效: 由于零点z为0,在进行矩阵乘法等运算时,可以省去大量和零点相关的加减法操作,使得计算过程更简洁,硬件执行效率更高。

最佳拍档:权重(Weights) 在深度学习模型中,权重的数值分布通常非常接近一个均值为0的正态分布(高斯分布),天然就是对称的。因此,使用对称量化来处理权重,既高效又不会损失太多精度,是天作之合。

缺点: 灵活性差,可能浪费量化空间: 如果数据的分布本身不是对称的,强行使用对称量化就会造成浪费。一个典型的例子是经过ReLU激活函数后的激活值,其数值全部为非负数。如果用对称量化,那么[-127, 0)这个负数区间就完全被浪费了,相当于凭空损失了一半的表示能力,导致量化误差增大。

4.3.2 非对称量化 (Asymmetric Quantization) - 灵活百搭,物尽其用

非对称量化提供了一种更灵活、适应性更强的映射方案。

图解:

  • 观察浮点数轴(黄色): 您可以看到,我们想要量化的原始浮点数范围是从 β = -3 到 α = 4。这是一个典型的非对称区间,其中心并不在0点。
  • 观察整数轴(蓝色): 我们的目标是将其映射到[-128, 127]这个整数区间。
  • 观察映射关系: 为了充分利用整个整数区间,非对称量化引入了一个可变的整数零点z。您可以看到,浮点数0并没有映射到整数0,而是映射到了一个值为z的整数点。同理,浮点数1被映射到了整数17。这个z就像一个灵活的“锚点”,确保了无论原始数据如何分布,我们都能物尽其用,不浪费任何一点整数的表示空间。

核心机制: 它不再要求浮点0.0必须映射到整数0,而是引入了一个可变的整数零点z作为偏移量。这使得它可以将任意区间 ,完美地映射到整个整数范围(例如无符号INT8的[0, 255]),而不会浪费任何一个整数“卡槽”。

优点: 精度利用率高: 对于非对称的、有偏置的数据分布,非对称量化能够更充分地利用整数的表示范围,从而获得比对称量化更高的精度。正如上面提到的ReLU激活值的例子,非对称量化可以将[0, R]的范围映射到完整的[0, 255]区间,精度是对等情况下对称量化的两倍。

最佳拍档:激活值(Activations) 由于激活值的分布常常因为激活函数(如ReLU)或模型的某些内在偏置而是非对称的,使用非对称量化来处理它们,可以最大程度地保留其信息,是更理想的选择。

缺点: 计算相对复杂: 因为引入了非零的零点z,在进行矩阵乘法等运算时,需要额外的计算步骤来处理这个偏移量,计算复杂度略高于对称量化。

4.3.3总结与选择建议
特性 对称量化 (Symmetric) 非对称量化 (Asymmetric)
零点 (Zero-point) 固定为 0 可变整数
量化范围 关于0对称 [-R, R] 任意范围
计算复杂度 低,更高效 相对较高
精度利用率 对称分布时高,非对称时低(浪费一半) 高,能充分利用整个整数范围
最佳应用对象 权重 (Weights) 激活值 (Activations)

实践中的黄金法则: 在对大语言模型进行量化时,最常见的做法是采取混合策略——对数值分布相对规整、对称的权重采用对称量化,以追求极致的计算效率;而对数值分布更复杂、常常非对称的激活值采用非对称量化,以保证模型的精度。这种组合拳可以在性能和精度之间取得绝佳的平衡。

4.4 裁剪策略:如何面对“异常值”的第一道防线

在我们之前的讨论中,反复提到了计算缩放因子s需要一个关键前提:确定待量化浮点数的范围 。那么,这个范围应该如何确定呢?面对大语言模型中普遍存在的“异常值”(Outliers),选择不同的范围策略,将直接决定量化的成败。

方案一:MinMax量化 - “老实”但“天真”

最直观、最“老实”的方法就是MinMax量化。

核心机制: 它会扫描校准数据中某一激活值或权重的所有数值,找到其中绝对的最小值作为r_{min},绝对的最大值作为r_{max}。它的想法很朴素:我希望能完整地表示所有出现过的数值,一个都不能少。

致命缺陷:被异常值“绑架” 这种“老实”的想法在面对大语言模型的激活值时,会显得非常“天真”。LLM的激活值中常常包含一些数值极大的异常值。如果使用MinMax法,整个量化范围就会被这些极端个例严重“污染”和“拉伸”

举个例子,假设某层激活值,99.9%的数值都稳定在[-10, 10]之间,但校准时恰好出现了一个100的异常值。MinMax法会将量化范围定为[-10, 100]。这会导致计算出的缩放因子s变得很大,使得[-10, 10]内的所有丰富细节,可能最终都被映射到区区几个整数上,大部分信息就此丢失。

方案二:截断量化 (Clipping) - “牺牲小我”,成就“大我”

为了解决MinMax的困境,更智能、更务实的截断量化(Clipping-based Quantization)应运而生。

核心机制: 它不再试图容纳所有数值,而是采取“牺牲小我,成就大我”的策略。它会主动设定一个比绝对最大/最小值更窄的自定义裁剪范围 。任何超出这个范围的数值,都会被“裁剪”到边界上。

利弊权衡:

  • • 优点: 通过选择一个更紧凑的范围,计算出的缩放因子s会小得多,这意味着整数世界的每一个“步长”都对应了浮点世界一个更小的距离。这使得占绝大多数的、在裁剪范围内的“正常值”能够被更精细地量化,从而显著降低整体的量化误差。
  • • 缺点: 代价是,我们主动放弃了对被裁剪掉的异常值的精确表示,这些异常值的量化误差会变得很大。

幸运的是,对于神经网络而言,这种权衡通常是值得的。模型对绝大多数正常值的细微变化更敏感,而对少数极端异常值的巨大误差则相对不敏感。

如何智能地“下刀”?- 先进的校准算法

既然要“裁剪”,那么在哪里“下刀”(即如何确定最佳的裁剪阈值)就成了一门艺术。业界发展出了多种先进的校准算法来寻找这个最佳点:

  • • 百分位法 (Percentile): 一种简单有效的启发式方法。例如,不取100%的最大/最小值,而是取99.99%分位点的值作为量化范围,直接忽略掉最极端的0.01%的异常值。
  • • KL散度法 (KL Divergence): 一种更精妙的、基于信息论的方法。它会尝试不同的裁剪阈值,并计算每个阈值下,量化后的数据分布与原始数据分布之间的信息损失(用KL散度衡量)。最终,它会选择那个能使信息损失最小的阈值作为最佳量化范围。这是NVIDIA TensorRT等工具中采用的先进方法。
  • • 均方误差法 (MSE): 寻找一个能量化范围,使得量化再反量化后的值与原始值之间的均方误差(Mean Squared Error)最小。

总而言之,选择一个合适的裁剪策略,是进行有效校准、应对异常值挑战的第一道,也是至关重要的一道防线。

4.5 “庖丁解牛”:解剖大模型中的张量维度

在深入探讨各种精细的量化粒度之前,我们有必要先暂停一下,像庖丁解牛一样,解剖一下大模型中最核心的计算单元——线性层(Linear Layer)中的张量,搞清楚其中每一个维度的具体含义。只有对这些“骨骼脉络”了然于胸,我们才能真正理解“逐通道”、“逐Token”这些策略的精妙之处。

在线性层中,最核心的运算是一次矩阵乘法:。其中,X是激活值张量,W是权重张量。

4.5.1 激活值张量 (Activation Tensor, X) - “流动的文本信息”

想象一下,当一句话,比如“The cat sat on the mat.”被送入模型时,它在某一层的输入就是激活值张量X。

  • • 形状: [序列长度, 隐藏层维度] (英文: [sequence_length, hidden_dimension])
  • • 举例: [6, 4096]

让我们来解剖这两个维度:

第一维 [序列长度]:代表“Token”,即矩阵的【行】

含义: 这一维表示输入文本中Token的数量。Token是模型处理文本的最小单元,可以是一个完整的单词、一个子词或者一个标点符号。

比方: 我们可以把这个矩阵想象成一个“班级花名册”。每一行就代表一个“学生”,也就是一个Token。

  • • 第0行:代表Token “The”
  • • 第1行:代表Token “cat”
  • • … 以此类推,共6行。
第二维 [隐藏层维度]:代表“特征”,即矩阵的【列】

含义: 这一维是模型的隐藏层大小,代表了用来描述每一个Token的特征数量。这4096个数字共同构成了一个高维向量,是模型对这个Token在当前上下文中的全方位、深层次的“理解”。

比方: 继续用“班级花名册”的比喻,每一列就代表一门“科目”(比如数学、物理、艺术…)。每一行(学生/Token)在每一列(科目/特征)上都有一个具体的分数(数值)。这4096个“科目分数”合在一起,就构成了这个“学生”的完整档案。

结论 -> Per-Token量化: 因此,逐Token(Per-Token)量化,就是以【行】为单位进行量化。它为每一个Token(每一位学生)的完整特征向量(所有科目的成绩单)都计算一套独立的量化参数s和z。

4.5.2 权重张量 (Weight Tensor, W) - “固化的模型知识”

权重张量W是线性层的核心,它包含了模型学到的所有知识,可以被看作是固化下来的“神经网络”本身。

  • • 形状: [输入维度, 输出维度] (英文: [input_dimension, output_dimension])
  • • 举例: [4096, 4096] (这里的输入维度必须与激活值的隐藏层维度匹配)
第二维 [输出维度]:对应“通道/神经元”,即矩阵的【列】

含义: 这是理解“逐通道”的关键。我们可以把每一列看作一个“输出通道(Output Channel)”或者一个“神经元(Neuron)。这一整列包含了从所有4096个输入特征连接到这一个输出神经元的全部权重。

比方: 我们可以把权重矩阵想象成一个“专家委员会”。每一列就是一个“专家”。

  • • 第0列:“经济学专家”
  • • 第1列:“历史学专家”
  • • …

当激活值(学生的各科成绩单)输入时,每一位“专家”(每一列)都会根据自己的知识体系(列中的权重值),对所有输入信息进行加权求和,最终给出一个自己的输出值。

结论 -> Per-Channel量化: 因此,逐通道(Per-Channel)量化,就是以【列】为单位进行量化。它为每一个输出通道/神经元(每一位专家)都计算一套独立的量化参数s和z。

下面这张图完美地将上述两个概念结合在了一起:

  • • 左侧的激活矩阵X: 它的量化是以【行】为单位的,即Per-Token。
  • • 右侧的权重矩阵W: 它的量化是以【列】为单位的,即Per-Channel。

好了,现在我们已经完成了“解剖”工作,知道了在LLM的线性层中,激活值的“行”代表Token,权重的“列”代表通道。带着这个清晰的坐标系,我们再来审视各种量化粒度,一切就豁然开朗了。

4.5.3 逐张量与逐组量化

我们已经知道了激活值的行代表Token,权重的列代表通道。现在,我们用这个坐标系来审视剩下的两种粒度。

逐张量/逐层量化 (Per-Tensor / Per-Layer) - “一视同仁”

这是最粗糙的粒度,现在我们可以更精确地理解它的含义了。

对应到维度:

  • • 对于激活值张量 X (形状 [6, 4096]): 它完全忽略了“行”(Token)和“列”(特征)的区别。它会把这 6 * 4096 = 24576 个数字全部看作一个整体,从这所有数字中找到一个全局的最大值和最小值,然后计算出唯一一套s和z,应用到每一个数字上。
  • • 对于权重张量 W (形状 [4096, 4096]): 同理,它会把所有 4096 * 4096 个权重值视为一体,用唯一一套量化参数来处理。

比方: 这就像我们之前说的“全班统一标准”,但现在我们知道,这个标准不仅统一了所有学生(Tokens),甚至还统一了所有科目(Channels),是真正意义上的“一刀切”。

逐组量化 (Per-Group) - “灵活分组,折中方案”

这是介于“逐通道”和“逐张量”之间的一种非常流行和实用的方案。

对应到维度: 它通常应用于权重张量W。它不对每一列(通道)都进行独立量化,而是将若干个相邻的列(通道)打包成一个“组”(Group)。

举例: 我们的权重矩阵W有4096列(即4096个“专家”)。如果我们设定组大小(group size)为128,那么:

  • • 第0列到第127列,这128位“专家”被划分为“第一组”。我们只在这一组内部寻找最大/最小值,并计算出一套专属的 。
  • • 第128列到第255列,这128位“专家”被划分为“第二组”,再为它们计算另一套独立的 。
  • • 以此类推,最终我们将得到 4096 / 128 = 32 组量化参数。

结论: 逐组量化通过这种折中的方式,在精度(远高于逐张量)和开销(远低于逐通道)之间取得了绝佳的平衡。它既能较好地适应权重的局部自分布,又避免了过多的参数和计算复杂性,因此在GPTQ、AWQ等现代先进量化算法中得到了广泛应用。

4.6 量化粒度:从“一刀切”到“精准打击”

在确定了宏观的量化策略后,我们还需要深入到更微观的层面,决定我们的量化“手术刀”要切多细。这个“精细度”就是量化粒度(Granularity)。

它的核心定义是:一组量化参数(即缩放因子s和零点z)所作用的范围有多大? 换句话说,是整个矩阵共用一套参数,还是每一行/每一列都有自己专属的参数?这个选择,是平衡模型精度和计算开销的又一重要权衡。

4.6.1 逐张量/逐层量化 (Per-Tensor / Per-Layer) - “一视同仁”的粗放策略

这是所有粒度中最粗糙、最简单的一种。

核心机制: 顾名思义,逐张量(Per-Tensor)量化就是对一整个张量(Tensor),例如一个完整的权重矩阵或一个完整的激活值矩阵,只计算和使用唯一一套量化参数s和z。无论这个张量有多大,内部数值分布多么复杂,它都“一视同仁”,用同一把“尺子”去度量所有的元素。由于在神经网络中,一个权重矩阵通常对应一个网络层(Layer),因此这种方法也常被称为逐层(Per-Layer)量化。

优点:

  • • 实现最简单: 算法逻辑非常直白,易于工程实现。
  • • 开销最小: 对于一个巨大的张量(例如包含数百万个参数的权重矩阵),我们只需要额外存储两个浮点数(s和z),这个开销几乎可以忽略不计。

缺点:致命的精度瓶颈 它的优点也正是其缺点所在。“一视同仁”的策略完全忽略了张量内部数值分布的巨大差异,这在面对大语言模型时,往往会导致灾难性的精度损失。我们可以通过下面这张图和其中的卷积滤波器例子来理解:

在大多数计算机视觉任务中,层的激活输入与许多不同的卷积过滤器进行卷积。每个卷积滤波器都可以有不同的取值范围。而逐层量化会对对属于同一层的所有卷积滤波器使用相同的裁剪范围。虽然这种方法很容易实现,但由于每个卷积滤波器的范围可能变化很大,它通常会导致次优精度。

想象一下,一个网络层(Layer 1)里有多个不同的通道(可以理解为图中的Filter 1, 2, 3…)。

  • • Filter 1的数值范围可能非常大,比如[-100, 100]。
  • • 而Filter 3的数值范围可能非常小,比如[-1, 1]。

如果采用逐层量化,我们就必须找到一个能容纳所有通道的范围,那这个范围就必须是[-100, 100](如上图中“Layerwise Quantization”部分的红色虚线所示)。

接下来,灾难发生了:我们用这个为[-100, 100]设计的“大刻度尺”(即一个很大的缩放因子s)去度量Filter 3中[-1, 1]的精细数值。结果很可能是,[-1, 1]范围内的所有不同数值,在量化后都被映射到了同一个整数上(例如0),其内部的所有信息都因此被完全抹除。

在这个例子中,范围大的Filter 1就像一个“坏邻居”,它自身的“异常值”严重“污染”了邻居Filter 3的量化过程,导致其精度严重下降。

结论: 由于存在这个致命的精度瓶颈,纯粹的逐张量/逐层量化在现代大语言模型的实践中已经很少被直接使用,尤其是在对精度要求较高的场景。它更多地是作为理解量化粒度概念的起点,并促使我们去探索更精细、更智能的量化方案。

4.6.2 逐通道量化 (Per-Channel) - “因材施教”的精准策略

上一节我们看到,粗放的“逐张量”量化会因为“一视同仁”而导致严重的精度损失。为了解决这个问题,一个更精细、更合理的策略应运而生:逐通道量化(Per-Channel Quantization)。

如果说“逐张量”量化像是给全校学生用同一张试卷,那么“逐通道”量化就像是为不同年级的学生提供难度各异的试卷,真正做到了“因材施教”。

核心机制: 它的核心思想非常直接:不再为整个权重张量计算唯一的量化参数,而是为张量的每一个通道(Channel)都计算一套独立的、专属的缩放因子s和零点z。

在LLM的线性层(Linear Layer)中,一个权重矩阵的形状通常是[output_features,input_features]。在这种情况下,“逐通道”通常指的就是逐输出通道(Per-Output-Channel)。也就是说,矩阵的每一行(代表一个输出神经元/特征的全部输入权重)都会拥有自己的一套量化参数。

这种“分而治之”的策略完美地解决了逐张量量化中的“坏邻居”问题。让我们再次回到上一节的例子:

现在,请看上图右侧的 “Channelwise Quantization” 部分。 Filter 1(数值范围为[-100, 100])会根据自身的范围,计算出自己的一套s_1和z_1。 Filter 3(数值范围为[-1, 1])则会根据它自己的、更窄的范围,计算出完全不同的、更精细的一套s_3和z_3。

两者之间互不干扰。Filter 1的巨大范围不再“污染”Filter 3的量化过程。Filter 3内部的精细数值变化,可以在它自己的“高精度刻度尺”下得到充分的保留。

优点: 精度显著提升: 这是逐通道量化最核心的优势。通过将不同通道的数值分布隔离开,它能够极大地降低量化误差,更好地保留模型的原始信息,这对于维持大模型的复杂能力至关重要。

缺点:

  • • 实现更复杂: 相比于逐张量量化,它的算法逻辑需要处理向量化的量化参数,稍微复杂一些。
  • • 额外的存储开销: 我们不再是为每个张量存储两个浮点数,而是需要存储两个向量(一个s向量和一个z向量),向量的长度等于通道数。虽然这个开销相比于庞大的权重本身来说依然很小,但也是一个不可忽略的因素。

逐通道量化是量化技术从“能用”到“好用”的关键一步。它通过更精细的粒度,在计算开销和模型精度之间找到了一个出色的平衡点,是现代高性能量化算法(如GPTQ、AWQ等)中处理权重的标准实践。

4.6.3 逐Token量化 (Per-Token) - 为每个“词语”量身定制

上一节我们介绍了“逐通道”这种为权重“因材施教”的精准策略。现在,我们将目光转向模型中另一大主角——激活值(Activations)。如果说“逐通道”是为每一位“教师”(输出神经元)制定了不同的教学大纲,那么“逐Token”量化就是为每一位来上课的“学生”(输入的Token)提供了专属的、量身定制的“听课设备”。

核心机制: 它是一种专门应用于激活值张量的精细化粒度。对于一个形状为 [序列长度, 隐藏层维度] 的激活值张量,我们不再为整个张量或每一列(通道)计算量化参数,而是为序列中的每一个Token(即矩阵的每一行)都计算一套独立的、专属的缩放因子s和零点z。

为何需要针对Token进行定制?

在处理自然语言时,不同词语(Token)在特定上下文中产生的激活值,其数值分布和范围可能存在天壤之别。例如,在一个句子中,像“的”这样的停用词,其激活值向量的整体幅值可能很小;而像“爱因斯坦”这样的关键词,其激活值向量的幅值可能就非常大。

如果使用“逐张量”甚至“逐通道”的策略,就很难同时照顾到这两种差异巨大的情况。“爱因斯坦”这个Token产生的巨大激活值范围,会“绑架”整个量化过程,导致“的”这个Token的激活值精度严重受损。而逐Token量化则完美地解决了这个问题,它为“的”和“爱因斯坦”分别计算最适合它们自己的量化参数,实现了真正的“私人定制”。

图解: 下面这张图的(a)部分,清晰地展示了逐Token量化的过程:

可以看到,左侧的FP16激活值矩阵被量化时,它的每一行(代表一个Token)都配备了一套独立的量化参数(图中用S表示缩放因子),从而保证了每个Token都能在其最合适的范围内被精确量化。

黄金组合:逐Token激活 + 逐通道权重

在现代大语言模型的量化实践中,我们通常不会只使用一种粒度,而是将它们组合起来,以达到最佳效果。其中,最经典、最强大的“黄金组合”之一就是:

  • • 对激活值采用逐Token量化,以应对其随输入变化的动态性和Token间的巨大差异。
  • • 对权重采用逐通道量化,以适应其不同通道间固有的分布差异。

结论: 逐Token量化是高精度激活值量化的关键技术。它通过极细的粒度,精准地捕捉了不同Token的动态数值范围,为维持大语言模型在量化后的性能表现立下了汗马功劳。当它与逐通道权重量化相结合时,便构成了许多先进量化算法的基石。

4.6.4 逐组量化 (Per-Group) - “灵活分组,折中方案”

在我们了解了“逐张量”的粗放和“逐通道/逐Token”的精细之后,自然会思考:有没有一种介于两者之间的、既能保证较高精度又不会带来太大开销的折中方案呢?答案是肯定的,这就是在现代量化算法中被广泛采用的逐组量化(Per-Group Quantization)。

核心机制: 逐组量化的思想非常直观:它既不为整个张量,也不为每一个单独的通道计算量化参数,而是将若干个相邻的通道打包成一个“组”(Group),然后为每一个组计算一套独立的缩放因子s和零点z。

举个具体的例子:假设一个权重矩阵有4096个输出通道。在逐通道量化中,我们需要计算和存储4096组(s, z)参数。 在逐组量化中,如果我们设定组大小(group size)为128,那么我们就将这4096个通道划分为 4096 / 128 = 32 个组。现在,我们只需要计算和存储32组(s, z)参数。这种方法在著名的GPTQ、AWQ等算法中都扮演了核心角色。

图解: 下面这张图可以帮助我们直观地理解“分组”的概念。

另一张图则更写实地展示了对权重矩阵进行逐组量化的过程:

优点:完美的平衡艺术

逐组量化之所以如此流行,在于它在精度和开销之间取得了绝佳的平衡。

  • 精度远高于“逐张量”: 相比于“一刀切”的逐张量量化,逐组量化显然能更好地适应张量内部不同区域的数值分布,因为它将量化范围缩小到了更局部的“组”内,精度得到了显著提升。
  • 开销远低于“逐通道”: 相比于为每个通道都配备一套参数,逐组量化大大减少了需要存储和管理的量化参数数量,降低了实现的复杂度和硬件开销。

结论: 逐组量化并非一个固定的概念,而是一种灵活的“框架”。通过调整组大小(group size),我们可以在“逐张量”(group size = 全部通道)和“逐通道”(group size = 1)之间自由滑动,找到最适合当前模型和硬件的“甜点区”。正是这种灵活性和出色的平衡能力,使其成为当前最高效、最先进的LLM量化算法中不可或缺的一环。

4.7 术语小贴士:W8A8是什么意思?

在深入研究模型量化的世界时,您会不可避免地遇到像 W8A8、W4A16 这样如同“摩斯密码”般的术语。它们是量化工程师和研究人员之间快速交流的“黑话”。理解了它,您就拿到了进入量化技术核心圈的“通行证”。

这个术语的结构非常简单,我们可以将其拆解为三部分:

数字数字

  • • W: 代表 权重 (Weights),即模型中固化的、通过训练学到的参数。
  • • A: 代表 激活值 (Activations),即模型在推理时,层与层之间流动的动态数据。
  • • 数字: 代表 量化的比特数 (Bit-width),即用来表示该部分数据的二进制位数。

因此,WXAY 的含义就是:权重被量化为X比特,激活值被量化为Y比特。

4.7.1 常见“黑话”解析

让我们来看几个最常见的组合和它们所代表的量化策略:

1. W16A16:

  • • 解读: 权重为16比特,激活值为16比特。
  • • 含义: 这通常是未量化的基准状态,代表模型正在标准的半精度(FP16/BF16)下运行。

2.W8A8:

  • • 解读: 权重为8比特,激活值为8比特。
  • • 含义: 这是最经典的全量化(Full Quantization)方案。权重和激活值都被转换成了INT8。这种方案的目标是最大限度地利用硬件的INT8计算单元,以追求极致的推理速度。

3.W8A16 或 W4A16:

  • • 解读: 权重为8比特(或4比特),激活值为16比特。
  • • 含义: 这是一种典型的仅权重量化(Weight-only Quantization)方案。我们只对权重进行了压缩,而激活值为了保证精度,依然保持在FP16。W4A16是目前在社区中非常流行的一种部署大模型到消费级显卡的方案,因为它在大幅压缩模型体积的同时,较好地保持了模型精度。

4.W4A8:

  • • 解读: 权重为4比特,激活值为8比特。
  • • 含义: 这是一种激进的混合精度全量化方案。它对权重进行了极致的4比特压缩,同时对激活值也进行了相对成熟的8比特量化。

5.W4A4:

  • • 解读: 权重为4比特,激活值为4比特。
  • • 含义: 这是超低比特全量化,代表了对压缩和性能的极限探索。将所有数据都量化到4比特,通常会带来较大的精度损失,必须依赖非常先进的量化算法(如QAT或带有复杂补偿策略的PTQ)才能实现。
4.7.2 与量化范式结合

我们可以将这些术语与之前讨论的量化范式结合起来,形成一个更清晰的认知。

  • • W8A16 这样的方案,激活值不动,通常用简单的PTQ方法就能实现,属于“Low effort”的范畴。
  • • 而像 W4A8 或 W4A4 这样激进的方案,为了保证精度,往往需要QAT的介入,属于“Fine-tuning”的范畴。

总结: WXAY这个简单的术语,就像一个“配方标签”,它高度概括了一套量化方案的核心策略。通过解读它,我们可以迅速判断出该方案是侧重于压缩体积(如W4A16),还是侧重于计算加速(如W8A8),以及它可能的技术复杂度和精度风险。

第五章:LLM量化最大的挑战:神秘的“异常值”(Outliers)

经过前面几章的铺垫,我们似乎已经掌握了一套完整的量化“兵法”:从数据类型到量化公式,从宏观策略到微观粒度。看起来,只要按部就班,就能成功地为任何大模型“瘦身”。然而,如果事情这么简单,量化就不会至今仍是学术界和工业界的研究热点。

实践中,当我们把这些经典理论直接应用于现代的大语言模型(LLM)时,往往会发现模型性能出现了灾难性的下降。这一切的背后,都指向了同一个“幕后黑手”——异常值(Outliers)。可以说,与异常值的斗争,构成了整个高级量化技术的主旋律。

5.1 什么是异常值?为何它会“绑架”量化过程?

异常值的“庐山真面目”

首先,我们来给异常值画个像。在LLM的权重或激活值张量中,异常值指的是那些其数值的绝对值,远大于绝大多数其他数值的“极端分子”。

上面是一个outlier示例(一共有4个黄色的outliear feature),横轴是hidden_dim维度,纵轴是sequence维度。上图中seq_len = 3,所以一个outlier feature是一个3×1的向量。这些异常值并非随机的噪声,而是在大模型中系统性出现的一种现象。它们虽然数量占比极少,但其巨大的数值,却足以“绑架”整个量化过程。

异常值究竟是如何破坏我们精心设计的量化流程的呢?问题就出在计算缩放因子s的环节上。

回忆一下,我们的缩放因子s(或Δ)是由待量化范围的最大值 和最小值 决定的。当一个张量中存在异常值时,这个 (或 )就不再由占99.9%的“正常值”决定,而是被那0.1%的“极端分子”完全掌控了。

下面这张图生动地说明了这个问题:

左侧,代表激活值分布的红色曲线中,那个高耸的尖峰就是一个异常值。为了容纳这个尖峰,整个量化范围被极大地拉伸,导致下方那些平缓的“正常值”几乎分不到任何有效的量化级别(low effective bits),因此变得“难以量化”。而右侧平滑的权重分布则没有这个问题上图。

让我们通过一个具体的数值例子来感受一下这种“绑架”的威力:

假设我们有一个激活值向量 A = [-0.10, -0.23, 0.08, -0.38, -0.28, -0.29, -2.11, 0.34, -0.53, -67.0]。

情况一:带着异常值进行量化
  • • 由于存在-67.0 这个巨大的异常值,MinMax量化会将范围定为[-67.0, 0.34]。
  • • 计算出的缩放因子s会非常大。
  • • 量化再反量化后,向量A可能会变成:[-0.00, -0.00, 0.00, -0.53, -0.53, -0.53, -2.11, 0.53, -0.53, -67.00]。
  • • 结果是灾难性的:除了最大的几个值,其他大部分数值的精度信息几乎被完全抹除,全都变成了0.00或-0.53。
情况二:如果移除异常值
  • • 假设我们神奇地移除了-67.0,现在只对剩下的值进行量化,范围是[-2.11, 0.34]。
  • • 量化再反量化后,向量可能会变成:[-0.10, -0.23, 0.08, -0.38, -0.28, -0.28, -2.11, 0.33, -0.53]。
  • • 结果非常理想:几乎所有的原始信息都得到了完美的保留。

这个例子有力地证明了,异常值就像一颗“老鼠屎”,它以一己之力,就能“坏了一锅汤”,让整个量化过程失去意义。

总结:异常值是LLM量化中的核心挑战。它通过极大地拉伸量化范围,严重“稀释”了正常值的量化精度,是导致量化后模型性能下降的罪魁祸首。那么,这些神秘的异常值从何而来?我们又能否简单地将它们剔除呢?下一小节,我们将深入探讨这些问题。

5.2 异常值的“涌现”:大模型的“成年礼”

在上一节,我们认识了异常值这个量化过程中的“头号公敌”。一个自然的问题是:这些“极端分子”是从哪里来的?它们是模型训练中的偶然错误,还是另有玄机?

答案可能出乎意料:异常值的出现,并非偶然,而是在大模型规模增长到一定程度后,一种系统性的、必然的“涌现”(Emergence)现象。它就像是LLM从一个“少年”成长为“青年”时,必然经历的一场“成年礼”——伴随着能力的觉醒,也带来了新的、更复杂的特征。

“LLM.int8()”的作者将这种现象称为“涌现特征”(Emergent Features)。它描述了异常值并非一蹴而就,而是随着模型规模的扩大,其数值、数量以及受影响的层和Token比例都在逐渐增长,最终在某个临界点发生“相变”(Phase Shift),全面爆发。

5.2.1 “涌现”的轨迹:从零星出现到全面爆发

研究人员通过对不同规模Transformer模型的细致观察,描绘出了异常值“涌现”的清晰轨迹:

  • • 小型模型(如125M): 在这个阶段,异常值如同“星星之火”,它们是概率性的,只在少数情况下、零星地出现在模型的某些特定部分,例如自注意力机制的投影层输出中。
  • • 中型模型(如350M ~ 1.3B): “火势”开始蔓延。异常值开始更稳定地出现在注意力和前馈网络(FFN)的输出中,并且开始呈现出某种规律性,例如在不同层级的同一特征维度上出现,暗示着模型内部可能正在形成某种跨层协作。
  • • 大型模型(如2.7B ~ 6B): 异常值变得系统性。在超过60%的模型层中,它们都会稳定地出现在相同的特征维度上,仿佛已经成为了模型处理信息的一种固有模式。

在了解了异常值对量化过程的“绑架”之后,我们自然会问:这种现象有多普遍?它是如何产生的?研究人员通过对不同规模Transformer模型的细致观察,发现了一个惊人的规律:异常值的出现并非线性递增,而是在某个关键节点上,会发生一次剧烈的“相变”(Phase Shift)。

整个“涌现”过程中,最激动人心的时刻发生在大模型跨越60亿到67亿参数这个门槛时。

  • • 横轴代表模型的参数量(单位:十亿)。
  • • 纵轴代表模型中有多少百分比的层(layers)或Token受到了异常值的影响。

观察曲线: 在模型规模小于60亿参数时,您可以看到两条曲线(蓝色代表层,黄色代表Token)虽然在增长,但趋势相对平缓。然而,当模型规模跨越图中虚线标记的60亿到67亿参数这个狭窄的区间时,一场剧变发生了。两条曲线的斜率突然变得异常陡峭,呈现出非线性的、爆炸性的增长。

这次“相变”带来了两个直接且严重后果:

  • 全局化现象: 正如上图所示,在跨越这个临界点后,受异常值影响的模型层比例从约65%猛增至100%,而受影响的Token比例也从约35%跃升至75%。这意味着,异常值不再是模型的局部特征,而是瞬间演变成了一个遍布模型每一个角落的全局现象。
  • 朴素量化的失效: 也正是在这个“相变点”之后,所有我们之前讨论的、没有特殊处理机制的简单量化方法开始彻底失效。因为异常值的全面爆发导致量化的动态范围被极度拉伸,使得占绝对多数的“正常”数值在量化后其精度信息被完全“清零”,最终导致量化后的模型几乎丢失了所有有效信息,性能雪崩。
5.2.2不仅关乎大小,更关乎“智慧”

更有趣的发现是,异常值的涌现并不仅仅和模型的参数“大小”挂钩,它还和模型的“智慧”程度——即性能密切相关。

横轴这次变为了模型的C4困惑度(Perplexity),这是一个衡量语言模型性能的核心指标,其数值越低,代表模型性能越好,模型越“聪明”。

观察曲线: 从图中我们可以清晰地看到,随着模型性能的提升(困惑度从左到右逐渐降低),受异常值影响的层和Token的比例也呈现出平滑的指数级增长。

这揭示了一个深刻的结论:异常值并非模型的“缺陷”或“bug”,而是模型在学习和成长的过程中,为了获得更强能力而自发演化出的一种内在属性。模型越强大、越“聪明”,其内部的数值分布就越“极端”,异常值现象就越显著。

5.2.3 “成年”的烦恼与机遇

异常值的“涌现”是大语言模型发展过程中的一种基础性、规律性的现象。它是一把双刃剑:

一方面,它是模型能力不断增强、智能水平不断提升、走向“成熟”的标志。

另一方面,它也为我们进行模型量化设置了巨大的障碍,是所有量化误差的根源。

那么,这些对模型能力至关重要的异常值,我们到底该如何看待?是该不顾一切地保留,还是想方设法地抑制?

5.3 异常值的双面性:既是“麻烦制造者”,也是“性能守护神”

通过前面的分析,我们知道异常值是量化过程中的“天灾”。一个自然而然的想法便是:既然这些“极端分子”如此碍事,我们能不能在量化前直接将它们“干掉”(例如,通过裁剪或设为0)呢?

答案是:绝对不能

这正是LLM量化中最具戏剧性的核心矛盾:异常值一方面是破坏量化精度的“麻烦制造者”,另一方面,它又是支撑模型强大能力的“性能守护神”。它是一把锋利无比的双刃剑。

5.3.1 一面:“麻烦制造者” - 量化精度的“毁灭者”

这一点我们已在 5.1 节中详细讨论过。我们再简单回顾一下它的“罪状”:

  • “绑架”量化范围: 异常值的巨大数值会极大地拉伸量化范围([r_{min}, r_{max}]),导致计算出的缩放因子s过大。
  • “稀释”有效精度: 过大的缩放因子s会使得绝大多数“正常”数值在量化后被映射到极少数的几个整数上,甚至直接被“清零”,从而丢失了大量宝贵的细节信息。
  • 拖慢特定算法速度: 对于一些需要对异常值进行特殊处理的高级量化算法(如SpQR),保留这些稀疏的异常值需要走一个特殊的、更慢的计算通路,反而可能会导致整体推理速度下降。
5.3.2 另一面:“性能守护神” - 模型能力的关键支柱

尽管异常值给量化带来了天大的麻烦,但大量的研究和实验都指向了一个惊人但明确的结论:保留这些异常值,对于维持大语言模型的性能至关重要。它们不是可以随意丢弃的噪声,而是模型能力的关键组成部分。

对模型预测能力的致命影响 实验证明,如果粗暴地移除异常值,哪怕只是移除极少数几个特征维度,也会导致模型性能的“雪崩”。

一项研究发现,对于一个大型Transformer模型,如果将包含异常值的7个特征维度移除,模型的Top-1预测概率会直接从约40%腰斩至约20%,而衡量模型性能的困惑度(Perplexity)指标会暴增600-1000%!相比之下,如果随机移除7个不包含异常值的特征维度,模型的性能几乎不受任何影响。
下面这张图生动地展示了移除一个“超级权重”(一种关键的权重异常值)后的灾难性后果:

模型理解“上下文”的关键 更深入的研究揭示了异常值在模型认知功能中所扮演的核心角色。我们需要区分模型的两种知识:

  • • 参数化知识 (Parametric Knowledge): 指模型在训练中背下来的、固化在权重里的“死记硬背”的知识。例如,“法国的首都是巴黎”。
  • • 上下文知识 (Contextual Knowledge): 指模型根据当前输入(Prompt)进行推理、理解和生成新信息的能力。例如,阅读一篇长文后进行总结。

研究表明,异常值正是模型处理和理解“上下文知识”的关键机制。

实验发现,如果破坏掉模型中的异常值,模型回答“中国首都是哪里”这类参数化知识问题的能力不受影响,但其在需要依赖上下文进行数学推理(如GSM8K测试)或逻辑分析的任务上,表现会断崖式下滑。

更有趣的是,当给模型一个与事实冲突的上下文(例如,“请注意,知识已更新,纽约现在是英国的城市”),正常模型会陷入困惑。但破坏掉异常值后,模型反而能更坚定地忽略这个错误的上下文,并回答出“纽约是美国的城市”。这恰恰证明了,异常值是引导模型关注和信任当前输入上下文的“开关”。关闭了这个开关,模型就只会依赖自己背过的“死知识”了。

5.3.3 核心矛盾与量化算法的使命

至此,LLM量化的核心矛盾已经完全暴露在我们面前:

我们面对的是一些对于量化过程极其有害,但对于模型性能又极其重要的数值。我们既不能容忍它们破坏量化精度,又不能粗暴地将它们移除。

如何解决这个两难的困境?这正是所有高级量化算法的终极使命。所有后续我们将要讨论的算法,如LLM.int8()、SmoothQuant、AWQ等,它们所有的精妙设计,归根结底都是为了回答同一个问题:

5.4 异常值的分类:普通异常值与“核弹级”的巨大异常值

在我们深入探讨了异常值的“双面性”之后,研究者们进一步发现,并非所有的异常值都是“生而平等”的。为了更精确地设计量化策略,我们需要学会区分它们。根据其分布模式和极端程度,我们可以将激活值中的异常值大致分为两类:分布更广的“普通异常值”和极其稀疏但数值更夸张的“巨大异常值”。

5.4.1 普通异常值 (Normal Outliers) - “通道”的“常客”

这是我们早期认知中对异常值的主要印象,它的核心特点是与“通道”(Channel)强相关。

核心特征:

  • • 通道相关性: 普通异常值往往稳定地出现在特定的几个特征维度(通道)中。如果把一个激活值张量看作一张表格,那么这些异常值总是集中在固定的那几列。
  • • Token普遍性: 在这些特定的“异常通道”里,几乎每一个Token(每一行)都会呈现出较大的数值。
  • • 挑战与对策: 这种“通道级”的异常值,正是我们之前讨论的,导致“逐张量”量化失效的元凶。因为它的存在,使得不同通道间的数值范围差异巨大。应对它的主要武器,就是我们已经介绍过的逐通道(Per-Channel)或逐组(Per-Group)量化。通过为每个通道或每个组计算独立的量化参数,就可以有效地将这些“常客”异常值的影响隔离在它们自己的通道内。
5.4.2 巨大异常值 (Massive Outliers) - “Token”的“天选之子”

随着研究的深入,人们发现了一种更极端、更神秘的异常值,它的特点是与“Token”强相关。

核心特征:

  • • Token相关性: 与普通异常值不同,巨大异常值仅仅出现在极其稀疏、数量极少的特定Token上。
  • • 极端数值: 它们的数值大到夸张,论文中给出的一个定量定义是:幅值超过100,并且至少是其所在隐藏状态中值幅度的1000倍。
  • • 出现位置: 它们常常出现在一些结构性的、有特殊功能的Token上,例如句首的起始Token [BOS]、标点符号(如.、\n)或某些高频功能词(如“and”、“of”)。

上图展示了巨大异常值的出现模式。无论输入什么句子,在LLaMA2和Mixtral模型中,巨大的激活尖峰总是稳定地出现在固定的几个特征维度,并且只与序列开头的第一个Token相关

更深层的作用:充当“偏置项”

研究表明,这些巨大异常值在模型中扮演着一个非常特殊的角色——一个固定的、但至关重要的偏置项(Bias)。它们就像模型内置的“全局参数”,通过在注意力机制中吸引大量关注,来为所有其他Token的计算提供一个恒定的基准或偏移。

上图的文字结论一针见血地指出了巨大激活值的本质作用

挑战与对策: 这种“Token级”的巨大异常值,是连“逐通道”量化都难以处理的“硬骨头”。因为它是在某个特定Token上“平地起高楼”,使得该Token的数值范围与其他所有Token完全不同。常规的量化策略很难在不产生巨大误差的情况下处理它,因此催生了更具创新性的解决方案,例如我们将在后续系列文章中探讨的旋转矩阵法或基于Attention Sink的前缀量化法等。

5.4.3 图解对比:一目了然的区别

下面这张图堪称总结这两种异常值区别的“神图”:

  • • 左图 (a) Normal Outliers: 可以看到,红色的“山脉”(异常值)虽然高耸,但它横跨了整个Token维度,即在每个Token上都存在,但集中在某些特定的Channel维度。
  • • 右图 (b) Massive Outliers: 您可以看到,整个平面上只有一个“定海神针”般的红色尖峰,它只存在于极少数的Token维度上,但在数值(Y轴)上远超左图的异常值。

总结: 对异常值进行分类,是高级量化算法设计的基石。普通异常值是一个“通道级”的校准问题,可以通过更精细的量化粒度(如Per-Channel)来解决。而巨大异常值则是一个更深层次的“Token级”结构性问题,它的存在,直接推动了量化技术从“优化”走向“重构”,催生了众多前沿的、更具创造性的量化思想。

5.5 追根溯源:异常值在Transformer中的“诞生之旅”

为了真正地“降服”异常值,我们必须成为一名“侦探”,追溯它的源头,理解它在Transformer这个复杂精密的“城市”中,是如何从一个无害的“市民”一步步演变成一个“极端分子”的。研究表明,异常值的诞生并非源于单一环节的“bug”,而是Transformer架构中多个核心模块环环相扣、协同作用下的系统性产物。

本节,我们将开启这次“溯源之旅”,首先来到它的第一个“诞生地”。

5.5.1 起点:Softmax的“赢家通吃”困境

异常值的第一个“火花”,往往源于自注意力机制(Self-Attention)中那个我们再熟悉不过的Softmax函数。

源起:“什么都不做”的特殊需求 在复杂的语言任务中,一个注意力头(Attention Head)有时需要学会一项特殊的技能——“什么都不做” (no-op)。这意味着,对于当前正在处理的这个Token,它认为没有任何其他Token值得去关注,也不想用任何其他Token的信息来更新自己。

但注意力机制的设计,要求它必须“关注”点什么(因为Softmax的输出概率之和必须为1)。模型为了实现这种“什么都不做”的效果,便演化出一种聪明的策略:将几乎全部的注意力权重(例如99.99%),都集中到一些没有实际语义、安全无害的Token上,比如句号.、逗号,或者特殊的分隔符[SEP]。通过“假装”高度关注这些无意义的符号,注意力头就巧妙地实现了对所有有意义信息的“无视”。

上图的热力图就清晰地展示了这种现象:在(a), (b), ©三种不同情况下,注意力权重(左侧灰度图)都高度集中在了[SEP]这个Token上,而几乎忽略了句子中其他所有真实的词语

困境:Softmax的数学天性

这种“赢家通吃”的注意力分布,给Softmax函数带来了一个巨大的数学难题。Softmax的计算公式是

上面这个数学性质告诉我们一个残酷的事实:

要想让一个Token的注意力权重 趋近于0,它的输入Logit值 就必须比另一个Token的Logit值 小得不成比例——理论上需要小无穷多。反之,要想让某个Token(比如[SEP])的注意力权重趋近于1,它的Logit值 就必须比其他所有Token的Logit值大得不成比例——理论上需要大无穷多。

这种数学上的要求,迫使模型必须在送入Softmax之前,生成具有巨大动态范围的Logit值。这,就是异常值最初的“火花”。

根源:前一层的FFN 那么,这个巨大的Logit值又是从哪来的呢?它来自于计算Query和Key向量的线性层。而这些线性层的输入,又恰恰来自于前一个Transformer模块的输出,特别是其中的前馈网络(FFN)部分。

上图清晰地指出了这个“作案链条”:前一层(previous layer)的FFN部分是产生“最大异常值”(biggest outliers)的源头,这些异常值随后通过残差连接,被送入下一层(next layer)的注意力机制中,成为了制造巨大Logit差异的“原材料”

更有甚者,由于注意力计算前通常还有一个LayerNorm层,它会试图将数值归一化。为了“抵抗”这种归一化效应,并依然能在Softmax中制造出足够的差异,前一层FFN就必须输出一个更加巨大的异常值,才能保证在被LayerNorm“削弱”之后,依然“火力”充足。

至此,异常值的“诞生之旅”第一站已经清晰:注意力机制的功能需求与Softmax函数的数学天性一拍即合,共同催生了对极端数值的强烈需求,这个需求信号被传递给了前一层的FFN,点燃了异常值诞生的星星之火。

5.5.2 “催化剂”之一:RoPE的位置编码

如果说Softmax的需求点燃了异常值的“火花”,那么旋转位置编码(Rotary Position Embedding, RoPE)则像是一个关键的“催化剂”,它为异常值的形成提供了“结构蓝图”,尤其是在自注意力机制的查询(Query, Q)和键(Key, K)矩阵中。

核心现象:RoPE模型的“特有病” 研究人员发现了一个非常有趣的现象:

  • • 在使用RoPE作为位置编码方案的模型(如Llama、Gemma、Qwen系列)中,其Q和K矩阵内普遍存在着显著的、大规模的结构化异常值。
  • • 而在那些不使用RoPE,采用其他位置编码方案的模型(如GPT-2、OPT)中,则观察不到这种现象。

这个强烈的相关性暗示,RoPE机制本身与这些结构化异常值的出现有着密不可分的关系。

深层机制:被“征用”的低频维度 RoPE的本职工作是通过“旋转”向量的不同部分来注入相对位置信息。它会对嵌入向量中的不同维度应用不同频率的旋转:

  • • 高频维度: 旋转快,对短距离位置敏感。
  • • 低频维度: 旋转慢,对长距离位置关系敏感。

关键在于,研究表明,模型似乎“征用”了这些旋转缓慢的低频维度,让它们不仅仅编码位置信息,更编码了丰富的语义内容。正是为了承载这些重要的语义信息,模型倾向于在这些特定的低频维度上,系统性地生成数值巨大的异常值。

对量化算法的影响:

RoPE催生的这些结构化异常值,其重要性在不同量化算法的表现上得到了验证。实验表明,那些能够“尊重”并特意保留这些大规模数值的量化技术(例如AWQ),在需要理解上下文的任务上能够维持模型的原有性能。反之,若采用未能很好保留这些数值的方法(例如GPTQ的某些早期版本),模型的上下文推理能力则会遭受重创。

结论: 因此,RoPE在异常值的“诞生之旅”中扮演了一个独特的“催化剂”和“结构设计师”角色。它并非像FFN那样直接“放大”数值,而是通过其内在的频率机制,为模型在Q和K矩阵中“指定”了适合生成结构化异常值的位置,使得这些异常值的出现不再是随机的,而是有章可循、有据可依的。

5.5.3 “放大器”之一:FFN的门控协同效应

如果说Softmax的需求点燃了异常值的“火花”,那么前馈网络(Feed-Forward Network, FFN),特别是现代LLM中普遍采用的SwiGLU等门控结构,则扮演了“鼓风机”和“超级放大器”的角色。它接收来自注意力层的输出,并将其内部可能存在的微小异常趋势,急剧放大成棘手的“参天大树”。

核心机制:SwiGLU的“双路并进” 我们首先来看一下SwiGLU的计算公式:

这里的关键在于括号内的部分:输入x被同时送入两个不同的线性层( 和 ),形成两条并行的路径:

  • • 门控路径 (Gate Path): 的结果经过一个Swish激活函数,其输出可以看作一个“门控信号”,决定了哪些信息可以往下传递。
  • • 数值路径 (Value Path): 的结果(也称作up-projection)承载了主要的数值信息。

最后,这两条路径的结果会进行逐元素相乘(odot)。正是这个乘法操作,为异常值的“疯长”提供了绝佳的土壤。

异常值的“协同放大”效应 现在,想象一下当一个包含中等大小异常值的激活值x输入到FFN中时,会发生什么:

  • • 这个异常值在通过门控路径()后,可能依然是一个较大的值。
  • • 同时,它在通过数值路径()后,也可能是一个较大的值。
  • • 当这两个较大的值在对应的维度上进行逐元素相乘时,一个“大数乘以大数”的效应就发生了!其结果是一个被平方级放大的、更加巨大的异常值。

这就是FFN中异常值的“协同放大”效应。一个原本并不算极端的值,在经过FFN的双路并行再相乘的结构后,其幅度被急剧放大。

分布的“尖峰化” 除了放大异常值,FFN的门控机制还导致了另一个现象:零值聚集。当门控路径的输入是一个较大的负数时,Swish函数的输出会非常趋近于0。这个0在与数值路径相乘后,会强制将最终的输出也变为0,无论数值路径上的值有多大。

这导致FFN的输出呈现出一种非常“不健康”的分布:存在少数极其巨大的“尖峰”(由协同放大效应产生)。 存在大量非常靠近零的“谷底”(由门控的“关闭”效应产生)。

这种两极分化、动态范围极大的“尖峰”分布,对于需要找到一个统一量化范围的量化算法来说,无疑是一场噩梦。

上图展示了真实模型中FFN层的输出统计,可以看到,像[SEP]和,这样的Token,其输出值远超其他词语,形成了明显的尖峰

这张图片展示了BERT模型中,两个不同层(Layer #10 和 Layer #11)的前馈网络(FFN)输出值的统计情况。我们可以将它分为左右两部分来解读:

左侧图表(蓝色柱状图):揭示异常值的“Token相关性”

  • • 横坐标: 代表文本中具体的Token,例如特殊的分隔符[SEP]、逗号,、括号)以及常见的英文单词the, it, to, and, so。
  • • 纵坐标: 代表该Token在经过FFN层计算后,其输出向量中某个维度的数值大小。
  • • 核心观察: 我们可以清晰地看到,无论是第10层还是第11层,[SEP]这个Token的输出值都呈现出“鹤立鸡群”的姿态,其数值大小(在第10层接近90000)远远超过了其他所有Token,形成了极其陡峭的尖峰。像逗号,这样的标点符号,其输出值也显著高于普通单词。

这个现象告诉我们:FFN产生的巨大异常值,并非随机出现在任何词语上,而是与少数特定的、功能性的Token(如分隔符和标点符号)强相关。

右侧图表(绿色柱状图):揭示异常值的“通道集中性”

  • • 横坐标: 代表特征维度/通道(Channel ID)的编号,例如#180, #720, #381等。
  • • 纵坐标: 代表在这些特定的通道上,FFN的输出值有多大。
  • • 核心观察: 图中展示的这些被选出的通道,其输出值都非常高,普遍在20000到40000之间。

这个现象告诉我们:FFN输出的巨大数值,也并非随机地分布在所有4096个(或其他数量)特征维度上,而是“集中火力”出现在了少数特定的“异常通道”中。

综合结论:FFN输出的“尖峰”分布

将这四张图结合起来,我们就得到了FFN输出的全貌:

在FFN的输出激活值张量中,巨大的数值(异常值)只会在少数特定的Token(行)和少数特定的通道(列)的交叉点上出现。这就形成了一种极其“不健康”的、两极分化的“尖峰”分布:大部分数值都非常小,接近于零,但极少数位置上却存在着“核弹级”的巨大数值。

正是这种巨大的动态范围和尖峰式的分布,使得为FFN的输出找到一个既能容纳“尖峰”又不“压扁”“谷底”的统一量化范围变得异常困难,从而对量化算法构成了巨大的挑战。

结论: FFN在异常值的“诞生之旅”中,扮演了一个至关重要的“放大器”角色。它接收来自上游的、可能还不太起眼的数值波动,通过其独特的门控和乘法结构,将其“催化”并“放大”成真正棘手的、具有巨大动态范围的异常值,为后续的量化过程制造了巨大的麻烦。

5.5.4 “放大器”之二:LayerNorm的推波助澜

在异常值的“诞生之旅”中,还有一个角色出人意料,但又至关重要,它就是层归一化(Layer Normalization, LayerNorm)。

从名字上看,LayerNorm的使命是“归一化”,即稳定数据分布,防止梯度消失或爆炸,它理应是异常值的“抑制者”。然而,在实际中,由于其内部一个关键的可学习参数,它有时反而会成为异常值的“放大器”。

核心机制:先“抑制”,后“放大”

我们来看一下LayerNorm的计算公式:

这个过程可以分为两步:

  • • 归一化步骤: 这一部分是真正的“归一化”,它会将输入x调整为均值为0,方差为1的标准分布。在这一步,输入x中存在的异常值,其幅度实际上是被抑制和缩小了。
  • • 仿射变换步骤: 这一部分,模型会用两个可学习的参数——缩放参数γ(gamma)和偏置参数β(beta),对归一化后的数据进行线性变换,以恢复其表达能力。问题就出在可学习的缩放参数γ上。

γ的“放大器”效应 :在模型训练的过程中,它可能会发现,某个特定的特征通道(Channel)对于最终的预测结果至关重要。为了给这个重要的通道赋予更大的“话语权”,模型会学着为这个通道分配一个非常大的γ值。

现在,想象一下当一个携带了由FFN层产生的巨大异常值的激活值,进入LayerNorm时会发生什么:

    1. 归一化步骤先将这个异常值“压”了下去。
    1. 但随后,模型用它为这个异常值所在通道学到的那个巨大的γ值,重新乘了回去。
    1. 结果是,被“压”下去的异常值又被重新“抬”了起来,甚至可能被放得更大,最终导致LayerNorm的输出中,异常值依然显著存在。

图解:有无γ的天壤之别 :下面这张图通过一个对比实验,无可辩驳地证明了γ的放大器作用:

  • • 看图(a) 这是标准LayerNorm的输出。我们可以清晰地看到,在第308个通道(高亮行)上,存在着一个非常尖锐的异常值。
  • • 看图(b) : 这展示了模型学到的缩放参数γ。我们发现,恰好在第308个通道上,γ的值也异常地大。
  • • 看图© : 这是移除了γ缩放步骤后的输出(即Non-scaling LayerNorm)。奇迹发生了,第308通道上的异常值完全消失了,整个输出的数值分布变得非常平缓。

这个实验有力地证明了,正是可学习的缩放参数γ扮演了“放大器”的角色,将上游传来的异常值“推波助澜”,使其更加显著。

  • • 关于RMSNorm的补充说明 值得一提的是,当前像Llama等主流大模型中使用的RMSNorm,虽然简化了计算(只计算方差,不计算均值),但其核心结构依然是“归一化 + 可学习的γ缩放”。因此,它也存在着与LayerNorm完全相同的、放大重要通道异常值的潜在问题。

结论: LayerNorm(及其变体RMSNorm)在异常值的诞生之旅中,扮演了一个充满矛盾的“帮凶”角色。它本意是稳定数据,但其内在的可学习缩放机制,却使其成为了异常值信号在模型中传递和放大的最后一环,为最终的量化工作带来了额外的复杂性。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一直在更新,更多的大模型学习和面试资料已经上传带到CSDN的官方了,有需要的朋友可以扫描下方二维码免费领取【保证100%免费】👇👇

01.大模型风口已至:月薪30K+的AI岗正在批量诞生

在这里插入图片描述

2025年大模型应用呈现爆发式增长,根据工信部最新数据:

国内大模型相关岗位缺口达47万

初级工程师平均薪资28K(数据来源:BOSS直聘报告)

70%企业存在"能用模型不会调优"的痛点

真实案例:某二本机械专业学员,通过4个月系统学习,成功拿到某AI医疗公司大模型优化岗offer,薪资直接翻3倍!

02.如何学习大模型 AI ?

🔥AI取代的不是人类,而是不会用AI的人!麦肯锡最新报告显示:掌握AI工具的从业者生产效率提升47%,薪资溢价达34%!🚀

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

1️⃣ 提示词工程:把ChatGPT从玩具变成生产工具
2️⃣ RAG系统:让大模型精准输出行业知识
3️⃣ 智能体开发:用AutoGPT打造24小时数字员工

📦熬了三个大夜整理的《AI进化工具包》送你:
✔️ 大厂内部LLM落地手册(含58个真实案例)
✔️ 提示词设计模板库(覆盖12大应用场景)
✔️ 私藏学习路径图(0基础到项目实战仅需90天)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

更多推荐