llm_edge_inference

第7章:量化友好的模型设计

在前面的章节中,我们探讨了各种后训练量化技术。然而,模型的架构设计本身对量化效果有着决定性影响。本章将深入探讨如何从模型设计阶段就考虑量化友好性,使得模型在部署时能够以更低的精度运行而不显著损失性能。这种设计理念对于边缘部署尤为重要,因为它能够从根本上提升模型的可压缩性。

章节大纲

7.1 激活函数选择与量化

7.2 归一化层的量化考虑

7.3 注意力机制的量化优化设计

7.4 量化感知的架构搜索

7.1 激活函数选择与量化

激活函数是神经网络的核心组件,其选择直接影响模型的量化性能。不同的激活函数具有不同的输出分布特性,这决定了量化时的难易程度。

7.1.1 激活函数的量化特性分析

对于激活函数 f(x),其量化友好性主要取决于以下特性:

  1. 输出范围的有界性:有界激活函数更容易量化,因为其动态范围是固定的。

  2. 梯度的连续性:量化会引入离散化误差,连续梯度有助于反向传播时的误差补偿。

  3. 输出分布的均匀性:输出值在量化区间内分布越均匀,量化损失越小。

数学上,对于激活值 a = f(x),其量化误差可以表示为:

ε_q = Q(a) - a ≤ Δ/2

其中 Δ 是量化步长。对于 n 比特量化:

Δ = (a_max - a_min) / (2^n - 1)

显然,(a_max - a_min) 越小,量化误差越小。

量化函数的数学表示

均匀量化函数 Q 可以表示为:

Q(x) = Δ · round((x - a_min) / Δ) + a_min

对于对称量化(常用于权重): Q(x) = Δ · round(x / Δ)

其中 Δ = 2·max( x ) / (2^n - 1)

非对称量化(常用于激活): Q(x) = s · (clamp(round(x/s + z), 0, 2^n-1) - z)

其中:

激活函数的李普希茨常数

激活函数的李普希茨常数 L 定义为:

f(x₁) - f(x₂) ≤ L x₁ - x₂ , ∀x₁, x₂

这个常数直接影响量化误差的传播。对于常见激活函数:

李普希茨常数越小,量化误差的传播越慢。

量化误差的传播分析

考虑一个简单的两层网络: y = f₂(W₂ · f₁(W₁ · x))

当对激活函数 f₁ 的输出进行量化时,误差传播可以表示为:

∂L/∂f₁ = (∂L/∂y) · (∂y/∂f₁) = (∂L/∂y) · f₂’(W₂f₁) · W₂

量化误差 ε_q 对最终损失的影响: ΔL ≈ (∂L/∂f₁)ᵀ · ε_q

这表明激活函数的导数特性直接影响量化误差的传播。导数变化剧烈的激活函数(如在某些区域接近0或无穷大)会放大量化误差。

误差累积的上界估计

对于 L 层网络,假设每层使用相同的激活函数 f,权重矩阵的谱范数为 ‖W_i‖₂ ≤ ρ,激活函数的李普希茨常数为 L_f,则总误差上界:

ε_total ≤ Σᵢ₌₁ᴸ (ρ·L_f)^(L-i) · ε_q,i

当 ρ·L_f < 1 时,误差不会指数增长。这解释了为什么 ReLU(L_f = 1)配合适当的权重初始化(控制 ρ)能够实现深层网络的稳定量化。

量化误差的概率分布

假设输入 x 服从正态分布 N(0, σ²),均匀量化误差可以近似为均匀分布 U(-Δ/2, Δ/2)。通过中心极限定理,多层累积的量化误差趋向正态分布:

ε_accumulated ~ N(0, σ²_ε)

其中 σ²_ε = (L·Δ²)/12,L 是网络层数。

这个结果表明:

信息论视角的量化分析

从信息论角度,量化可以看作是一个有损压缩过程。对于激活值分布 p(a),使用 n 比特均匀量化的信息损失可以用率失真理论分析:

D = E[(a - Q(a))²] = ∫ p(a)(a - Q(a))² da

对于均匀分布 p(a) = 1/(a_max - a_min),在高码率假设下:

D ≈ (a_max - a_min)² / (12 · 2^(2n))

这个公式揭示了几个重要见解:

最优量化器设计:Lloyd-Max算法

对于非均匀分布,Lloyd-Max算法给出最优量化器:

量化区间边界:bᵢ = (rᵢ + rᵢ₊₁)/2 重构值:rᵢ = ∫{bᵢ₋₁}^{bᵢ} x·p(x)dx / ∫{bᵢ₋₁}^{bᵢ} p(x)dx

对于高斯分布 N(0, σ²),最优量化器的重构值近似为: rᵢ ≈ σ · λᵢ

其中 λᵢ 是预计算的常数,例如对于3比特量化: λ = [-2.15, -1.34, -0.76, -0.25, 0.25, 0.76, 1.34, 2.15]

熵约束的量化设计

考虑量化后的熵 H(Q(a)),我们需要在失真和熵之间权衡:

L = D + λ·H(Q(a))

其中 λ 控制率失真权衡。这导出了熵约束的量化器设计准则:

∂L/∂rᵢ = 0 ⟹ rᵢ = E[a a ∈ Rᵢ] + λ/(2ln2) · (1/P(Rᵢ))

这表明稀疏区域(P(Rᵢ)小)应该有更大的量化间隔。

激活函数的量化敏感度度量

为了系统地评估激活函数的量化友好性,我们定义量化敏感度指标:

S_q = E[ f’(x) ] · Var[f(x)] / E[ f(x)

其中:

量化敏感度越低,激活函数越适合量化。例如:

详细推导:ReLU的量化敏感度

对于输入 x ~ N(0, 1),ReLU(x) = max(0, x) 的统计特性:

E[ReLU(x)] = ∫₀^∞ x·φ(x)dx = 1/√(2π) E[ReLU(x)²] = ∫₀^∞ x²·φ(x)dx = 1/2 Var[ReLU(x)] = E[ReLU(x)²] - E[ReLU(x)]² = 1/2 - 1/(2π) ≈ 0.341

E[ ReLU’(x) ] = P(x > 0) = 1/2

因此:S_q(ReLU) = (1/2 × 0.341) / (1/(2π))² ≈ 0.534

基于Fisher信息的量化分析

Fisher信息矩阵可以衡量参数变化对输出分布的影响:

I(θ) = E[(∂log p(y x,θ)/∂θ)²]

对于量化参数 θ_q,相对Fisher信息:

F_rel = tr(I(θ)⁻¹·I(θ_q)) / dim(θ)

这个指标接近1表示量化保持了大部分信息。实验表明:

激活函数的局部线性度

量化本质上是分段常数近似,因此激活函数的局部线性度很重要。我们可以通过泰勒展开分析:

f(x + δ) = f(x) + f’(x)δ + f’‘(x)δ²/2 + O(δ³)

在量化区间 [x_i, x_{i+1}] 内,如果二阶导数 f’‘(x) 较小,则函数接近线性,量化误差主要来自常数偏移。定义局部非线性度:

NL(x) = f’‘(x) · Δ² / f’(x)

其中 Δ 是量化步长。NL(x) 越小,该区域的量化误差越小。

7.1.2 ReLU家族与量化友好性

ReLU家族激活函数因其简单性和量化友好性而广受欢迎:

标准ReLU: f(x) = max(0, x)

优点:

缺点:

ReLU的稀疏性与压缩

ReLU引入的稀疏性对量化和压缩都有益处。定义稀疏率:

ρ = P(ReLU(x) = 0) = P(x ≤ 0)

对于标准正态输入,ρ = 0.5。稀疏性带来的压缩增益可以用信息论分析:

H_sparse = -ρlog₂(ρ) - (1-ρ)log₂(1-ρ) + (1-ρ)·H_nonzero

其中 H_nonzero 是非零值的熵。对于50%稀疏性,理论上可以节省约1比特/值的存储。

ReLU的量化感知训练

在QAT中,ReLU的梯度需要考虑量化:

∂L/∂x = ∂L/∂y · ∂y/∂x_q · ∂x_q/∂x

其中:

这导致了”量化感知的死神经元”问题:当量化使x_q ≤ 0时,梯度完全消失。

ReLU的量化分析

对于标准ReLU,当输入x服从N(0, σ²)分布时:

在INT8量化中,典型的处理策略是:

  1. 收集激活统计,找到99.9%分位数作为a_max
  2. 使用非对称量化:[0, a_max] → [0, 127]
  3. 量化公式:x_q = min(127, round(127 · x / a_max))

ReLU6: f(x) = min(max(0, x), 6)

这是专门为量化设计的激活函数:

ReLU6的设计原理

选择6作为上界的原因:

  1. 实验观察:在ImageNet预训练的网络中,ReLU激活值的99%分位数通常在5-8之间
  2. 量化效率:6 = 48/8,便于定点运算
  3. 动态范围:[0, 6]映射到[0, 127]时,量化步长Δ = 6/127 ≈ 0.047,提供足够的精度

数学分析表明,当使用ReLU6替代ReLU时,梯度裁剪效应为: ∂ReLU6/∂x = { 0, x < 0 1, 0 ≤ x < 6 0, x ≥ 6 }

这种硬裁剪在x > 6时会导致梯度消失,但实践中很少出现,因为BatchNorm通常将激活值控制在合理范围内。

ReLU6的统计特性

对于输入 x ~ N(0, σ²),ReLU6的输出分布:

E[ReLU6(x)] = σ/√(2π) · [1 - exp(-18/σ²)] + 6·[1 - Φ(6/σ)]

其中 Φ 是标准正态CDF。当 σ = 1 时:

ReLU6的量化误差分析

使用 INT8 量化 [0, 6] → [0, 127]:

量化误差:ε = x - Q(x) ≤ 3/127 ≈ 0.024

相对误差上界:ε_rel = ε/x ≤ 0.024/x

对于 x ≥ 0.5,相对误差 < 5%,这解释了为什么 ReLU6 在低比特量化下表现优异。

Leaky ReLU: f(x) = max(αx, x), α < 1

量化考虑:

Leaky ReLU的量化优化

对于Leaky ReLU,需要处理正负两个区域的不同缩放:

定点实现方案:

if x >= 0:
    y = x
else:
    y = (α_numerator * x) >> α_shift

其中α = α_numerator / 2^α_shift。例如:

这种表示避免了浮点乘法,使用整数乘法和位移实现。

PReLU (Parametric ReLU)

PReLU将负斜率α作为可学习参数: f(x) = max(αx, x)

量化策略:

  1. 训练时约束α的取值范围,如α ∈ [0, 0.25]
  2. 量化α到固定的候选值集合:{0, 1/16, 1/8, 1/4}
  3. 使用查找表存储不同通道的α值

Hard Swish与量化

Hard Swish是Swish的量化友好版本: f(x) = x · clip(x + 3, 0, 6) / 6

设计特点:

与ReLU6的对比实验显示,Hard Swish在保持量化友好性的同时,提供了更好的梯度流动,特别是在网络较深时。

ReLU变体的统一框架

我们可以将ReLU家族统一表示为: f(x) = min(max(α_l · x, x), α_u · x)

其中:

这个框架有助于设计新的量化友好激活函数,通过调整α_l和α_u来控制动态范围和梯度流动。

7.1.3 平滑激活函数的量化挑战

平滑激活函数如 GELU、Swish 在大型语言模型中越来越常见,但它们给量化带来了挑战:

GELU (Gaussian Error Linear Unit): f(x) = x · Φ(x)

其中 Φ(x) 是标准正态分布的累积分布函数。

GELU 的近似形式: f(x) ≈ 0.5x(1 + tanh(√(2/π)(x + 0.044715x³)))

量化挑战:

  1. 非线性程度高,需要更高精度的查找表
  2. 导数变化剧烈,量化误差传播快
  3. 计算复杂,难以在低精度下准确实现

GELU的泰勒展开分析

在 x = 0 附近的泰勒展开:

GELU(x) = 0.5x + (1/√(2π))x² - (1/(2√(2π)))x³ + O(x⁴)

这揭示了 GELU 的关键特性:

对比 ReLU 的分段线性,GELU 的高阶项使其更难量化。

GELU的动态范围分析

对于输入 x ~ N(0, σ²):

GELU(x) x 对所有 x 成立

更精确地:

这种渐近行为类似于带软阈值的 ReLU。

GELU的数值特性分析

GELU的导数: f’(x) = Φ(x) + x·φ(x)

其中φ(x) = (1/√(2π))exp(-x²/2)是标准正态密度函数。

关键观察:

GELU的高效量化实现

  1. 查找表方法
    • 区间:[-4, 4](覆盖99.99%的输入)
    • 表大小:256项(8比特索引)
    • 插值:线性插值减少表项需求
  2. 分段多项式近似
    区间[-∞, -1.5]: f(x) ≈ 0
    区间[-1.5, -0.5]: f(x) ≈ -0.0535x³ - 0.1606x² - 0.1606x - 0.0535
    区间[-0.5, 0.5]: f(x) ≈ 0.5x + 0.3989x² + 0.0785x³
    区间[0.5, 1.5]: f(x) ≈ 0.0535x³ - 0.1606x² + 0.8394x + 0.0535
    区间[1.5, ∞]: f(x) ≈ x
    
  3. 硬件友好的近似: QuickGELU(OpenAI提出): f(x) = x · σ(1.702x)

    这种近似的优势:

    • 只需要sigmoid查找表
    • 保持了GELU的主要特性
    • 量化误差比原始GELU小30%

分段多项式近似的误差分析

对于上述5段近似,最大绝对误差:

ε_max = max GELU(x) - GELU_approx(x) < 0.002

相对误差在 |x| > 0.1 时: ε_rel < 0.5%

这个精度对于 INT8 量化(误差约 0.4%)是足够的。

基于Remez算法的最优近似

使用Remez交换算法可以找到最优的分段多项式近似:

对于区间 [-2, 2],3次多项式最优近似: GELU(x) ≈ 0.5x + 0.398942x² - 0.0293x³ + ε(x)

其中 ε(x) < 0.0035,这比泰勒展开的误差小一个数量级。

Swish/SiLU: f(x) = x · σ(x)

其中 σ(x) 是 sigmoid 函数。

Swish的量化分析

Swish的导数: f’(x) = σ(x) + x·σ(x)·(1-σ(x)) = σ(x)·(1 + x - x·σ(x))

特性:

为了量化友好,可以考虑分段线性近似:

f(x) ≈ { 0, x < -3 x/6 + 0.5, -3 ≤ x < 3 x, x ≥ 3 }

Hard Sigmoid与Hard Swish

Hard Sigmoid是Sigmoid的线性近似: σ_hard(x) = clip(x/6 + 0.5, 0, 1)

基于此,Hard Swish定义为: f(x) = x · σ_hard(x + 3) = x · clip(x/6 + 0.5, 0, 1)

量化优势:

Mish激活函数的量化

Mish定义: f(x) = x · tanh(ln(1 + e^x))

Mish比Swish更平滑,但量化更困难:

量化策略:

  1. 使用统一的查找表存储整个Mish函数
  2. 利用对称性:注意到Mish(-x) ≈ 0时可以简化

平滑激活函数的通用量化框架

对于形如f(x) = x · g(x)的激活函数,我们可以:

  1. 分解量化
    • 分别量化x和g(x)
    • 使用高精度乘法器
    • 结果再量化
  2. 联合量化
    • 直接量化f(x)的输出
    • 需要更大的查找表
    • 避免中间量化误差
  3. 自适应精度
    • 在梯度大的区域使用高精度
    • 在近线性区域使用低精度
    • 基于局部非线性度NL(x)动态分配

实验对比:量化误差分析

在BERT-base模型上的实验结果(INT8量化):

这表明选择合适的近似方法对保持模型性能至关重要。

7.1.4 可学习激活函数设计

为了同时获得表达能力和量化友好性,可以设计可学习的激活函数:

分段线性激活函数: 将激活函数参数化为多个线性段:

f(x) = { a₁x + b₁, x < t₁ a₂x + b₂, t₁ ≤ x < t₂ … aₙx + bₙ, x ≥ tₙ₋₁ }

其中 {aᵢ, bᵢ, tᵢ} 是可学习参数。

连续性约束

为确保函数连续,需要满足: aᵢtᵢ + bᵢ = aᵢ₊₁tᵢ + bᵢ₊₁

这可以通过参数化实现: bᵢ₊₁ = bᵢ + (aᵢ - aᵢ₊₁)tᵢ

可学习激活的初始化策略

  1. 线性初始化
    • 初始化为恒等函数:aᵢ = 1, bᵢ = 0
    • 逐渐学习非线性
  2. ReLU初始化
    • 左半部分:aᵢ = 0
    • 右半部分:aᵢ = 1
    • 从ReLU开始优化
  3. 统计初始化
    • 基于激活值分布的分位数设置断点
    • tᵢ = F⁻¹(i/n),其中F是累积分布函数

自适应分段数选择

使用稀疏正则化自动选择分段数:

L_sparse = λ₁Σᵢ aᵢ - aᵢ₊₁ + λ₂Σᵢ bᵢ - bᵢ₊₁

这鼓励相邻段合并,减少参数数量。

量化感知的激活函数学习: 在训练时引入量化约束:

L_total = L_task + λ · L_quant

其中 L_quant 惩罚激活值的动态范围:

L_quant = E[max(0, f(x) - r_max)²]

这鼓励激活函数学习有界的输出。

基于神经架构搜索的激活函数设计

搜索空间定义:

示例发现的激活函数: f(x) = x · min(1, max(0, 1 + 0.5sign(x)))

这本质上是一个可学习的不对称ReLU。

激活函数的硬件成本模型

定义成本函数: C(f) = α·N_mul + β·N_add + γ·N_lut + δ·N_branch

其中:

优化目标变为: min L_task + λ₁L_quant + λ₂C(f)

7.2 归一化层的量化考虑

归一化层(BatchNorm、LayerNorm等)在现代深度网络中无处不在,它们对量化的影响往往被低估。正确处理归一化层是实现高效量化的关键。

7.2.1 BatchNorm与量化的相互作用

BatchNorm 的前向计算:

y = γ · (x - μ)/√(σ² + ε) + β

在推理时,这可以融合为线性变换:

y = ax + b

其中: a = γ / √(σ² + ε) b = β - γμ / √(σ² + ε)

BatchNorm的统计特性

训练时的运行统计更新: μ_running = (1 - α)μ_running + α·μ_batch σ²_running = (1 - α)σ²_running + α·σ²_batch

其中 α 是动量参数(通常为 0.1)。

推理时使用固定的运行统计,这对量化有重要影响:

量化引起的统计偏移

设量化误差为 ε_q,则量化后的均值和方差:

μ_q = μ + E[ε_q] σ²_q = σ² + Var[ε_q] + 2Cov(x, ε_q)

对于均匀量化,E[ε_q] ≈ 0,但 Var[ε_q] = Δ²/12 不为零,导致方差估计偏大。

量化策略

  1. 预融合方案:将 BN 参数融合到前一层的权重中 W_fused = W · diag(a) b_fused = Wa_bias + b

  2. 后量化方案:保持 BN 独立,对归一化后的值量化

    • 优点:激活值分布稳定
    • 缺点:需要额外的量化/反量化操作

融合的数学推导

考虑 Conv-BN 序列: z = BN(Conv(x)) = γ·(Wx + b_conv - μ)/σ + β

展开后: z = (γ/σ)·W·x + (γ/σ)·(b_conv - μ) + β

因此融合参数为: W_fused = (γ/σ) ⊙ W (按输出通道缩放) b_fused = (γ/σ) ⊙ (b_conv - μ) + β

数值稳定性考虑: 当 σ² 很小时,除法操作会放大量化误差。解决方案:

量化感知的BatchNorm训练

在QAT中,BatchNorm的梯度需要考虑量化:

∂L/∂γ = Σᵢ (∂L/∂yᵢ) · (xᵢ - μ)/σ ∂L/∂β = Σᵢ (∂L/∂yᵢ)

但量化会影响这些梯度的准确性。解决方案:

  1. 渐进量化:训练初期使用高精度,逐渐降低
  2. 梯度缩放:根据量化噪声水平调整学习率
  3. 统计量平滑:使用更大的batch size或更高的动量

7.2.2 LayerNorm的量化特性

LayerNorm 在 Transformer 架构中广泛使用:

y = γ · (x - μ) / σ + β

其中 μ 和 σ 是按特征维度计算的。

LayerNorm的数学细节

对于输入 x ∈ ℝᵈ: μ = (1/d)Σᵢ xᵢ σ² = (1/d)Σᵢ (xᵢ - μ)²

与BatchNorm不同,LayerNorm的统计量是实例相关的,这带来独特挑战。

量化挑战

  1. 动态统计量:每个样本的 μ 和 σ 都不同
  2. 无法预先融合:不像 BN 可以离线融合
  3. 除法运算:需要高精度或查表实现

LayerNorm的数值稳定性分析

考虑量化对统计量计算的影响:

μ_q = (1/d)Σᵢ Q(xᵢ) = μ + (1/d)Σᵢ εᵢ

由于量化误差 εᵢ 通常是零均值的,μ_q ≈ μ。

但对于方差: σ²_q = (1/d)Σᵢ (Q(xᵢ) - μ_q)² = σ² + (1/d)Σᵢ εᵢ² + 交叉项

量化增加了约 Δ²/12 的方差偏差。

优化技术

  1. RMSNorm 替代: y = x / RMS(x) · γ

    其中 RMS(x) = √(mean(x²))

    • 减少了减法运算
    • 计算更稳定

    RMSNorm的量化优势:

    • 避免了均值计算,减少累积误差
    • RMS总是正数,简化了除法实现
    • 实验表明性能损失小于0.1%
  2. 固定点近似: 使用泰勒展开近似 1/√x: 1/√x ≈ a - bx + cx²

    系数可以预计算并量化存储。

    Newton-Raphson迭代优化

    对于计算 1/√x,使用迭代: y₀ = 初始猜测(查表) yₙ₊₁ = yₙ(3 - x·yₙ²)/2

    两次迭代即可达到INT8精度要求。

  3. 量化友好的 LayerNorm: 设计输出范围受限的归一化: y = clip(γ · (x - μ) / σ + β, -r, r)

LayerNorm的混合精度实现

建议的精度分配:

这种方案在精度和效率间取得平衡。

Pre-LayerNorm vs Post-LayerNorm

Pre-LayerNorm架构: y = x + Attention(LN(x))

Post-LayerNorm架构: y = LN(x + Attention(x))

量化角度的比较:

7.2.3 归一化参数的融合技术

参数融合是减少量化开销的重要技术:

Conv-BN 融合: 对于卷积层后接 BN:

  1. 原始计算:y = BN(Conv(x))
  2. 融合后:y = Conv’(x),其中权重和偏置已包含 BN 效果

融合公式: W’ = γ/σ · W b’ = γ/σ · (b - μ) + β

量化时机

  1. 训练时量化:在融合前进行 QAT
  2. 部署时量化:融合后进行 PTQ

实验表明,训练时量化通常效果更好,因为网络可以适应量化误差。

7.2.4 量化感知的归一化设计

可学习的裁剪范围: y = LayerNorm(x) y_clipped = clip(y, -α, α)

其中 α 是可学习参数,通过梯度下降优化。

统计量量化: 对于 LayerNorm 的均值和方差计算,可以使用低精度:

混合精度策略

这种策略在精度和效率之间取得良好平衡。

7.3 注意力机制的量化优化设计

注意力机制是 Transformer 的核心,也是量化的难点。其涉及的 Softmax 操作和矩阵乘法对数值精度要求较高。

7.3.1 Softmax的数值稳定性与量化

标准 Softmax 计算: softmax(x)ᵢ = exp(xᵢ) / Σⱼ exp(xⱼ)

数值稳定版本: softmax(x)ᵢ = exp(xᵢ - max(x)) / Σⱼ exp(xⱼ - max(x))

量化挑战

  1. 指数函数的动态范围极大
  2. 除法运算需要高精度
  3. 小概率值的精确表示

量化优化方案

  1. 对数域计算: log_softmax(x)ᵢ = xᵢ - log(Σⱼ exp(xⱼ))

    优点:避免指数爆炸,数值更稳定

  2. 温度缩放: softmax(x/T)ᵢ = exp(xᵢ/T) / Σⱼ exp(xⱼ/T)

    较大的 T 使分布更平滑,更适合量化

  3. 分段线性近似: 对于输入范围 [-c, c],可以用分段函数近似 exp(x)

7.3.2 注意力分数的动态范围控制

注意力计算: Attention(Q,K,V) = softmax(QK^T/√d)V

缩放因子的作用: 1/√d 防止点积结果过大,这对量化至关重要。

动态范围分析

量化友好的设计

  1. 学习缩放因子: Attention(Q,K,V) = softmax(QK^T/τ)V

    其中 τ 是可学习参数

  2. 注意力裁剪: scores = clip(QK^T/√d, -c, c) attention = softmax(scores)

  3. 相对位置编码: 使用有界的相对位置偏置,而非无界的绝对位置编码

7.3.3 多头注意力的量化策略

多头注意力涉及多个并行的注意力计算:

MultiHead(Q,K,V) = Concat(head₁, …, headₕ)W^O

按头量化: 不同的注意力头可能有不同的激活分布,可以采用不同的量化参数:

  1. 独立量化:每个头使用独立的 scale 和 zero-point
  2. 分组量化:相似的头共享量化参数
  3. 混合精度:重要的头使用高精度,其他使用低精度

头的重要性评估: 可以通过以下指标评估头的重要性:

7.3.4 线性注意力与量化兼容性

线性注意力通过核技巧避免显式计算 N×N 的注意力矩阵:

LinearAttention(Q,K,V) = φ(Q)(φ(K)^T V)

其中 φ 是特征映射。

量化优势

  1. 避免 Softmax,减少非线性运算
  2. 计算复杂度从 O(N²) 降到 O(N)
  3. 中间结果的动态范围更可控

常见的特征映射

  1. ELU + 1: φ(x) = ELU(x) + 1

    保证非负输出,适合量化

  2. ReLU: φ(x) = ReLU(x)

    最简单的选择,但可能损失表达能力

  3. Performer 的随机特征: φ(x) = exp(x^T R - ||x||²/2) / √m

    其中 R 是随机矩阵

量化实现要点

7.4 量化感知的架构搜索

自动化架构搜索(NAS)可以找到最适合量化的网络结构。量化感知的 NAS 在搜索过程中就考虑量化约束。

7.4.1 混合精度架构搜索空间

搜索空间定义:

  1. 层级选择
    • 层类型:Conv, DWConv, Linear, etc.
    • 层参数:通道数、核大小、步长等
  2. 精度选择
    • 权重精度:{2, 4, 8, 16} bits
    • 激活精度:{4, 8, 16} bits
  3. 量化方案
    • 对称/非对称量化
    • 按通道/按张量量化

超网络表示: 构建包含所有候选操作的超网络:

output = Σᵢ αᵢ · opᵢ(input)

其中 αᵢ 是架构参数,opᵢ 是候选操作。

7.4.2 硬件感知的搜索目标

多目标优化:

min L = L_task + λ₁·L_latency + λ₂·L_energy + λ₃·L_size

各项定义:

  1. 任务损失 L_task: 模型在目标任务上的性能(如分类准确率)

  2. 延迟损失 L_latency: L_latency = max(0, T_model - T_target)

    其中 T_model 是模型推理时间

  3. 能耗损失 L_energy: L_energy = Σᵢ (ops_i · energy_per_op_i)

  4. 模型大小损失 L_size: L_size = Σᵢ (params_i · bits_i) / 8

硬件建模: 对不同硬件平台建立性能模型:

7.4.3 渐进式量化搜索策略

避免直接搜索离散空间,采用渐进式策略:

第一阶段:连续松弛 使用 Gumbel Softmax 松弛离散选择:

α_soft = softmax((log α + g)/τ)

其中 g 是 Gumbel 噪声,τ 是温度参数。

第二阶段:渐进离散化 逐渐降低温度 τ,使选择趋向 one-hot:

τ_t = τ_0 · decay^t

第三阶段:精细调整 固定架构,只优化量化参数:

7.4.4 自动化量化配置生成

基于搜索结果自动生成量化配置:

配置模板

{
  "layer_1": {
    "weight_bits": 4,
    "activation_bits": 8,
    "quantization_scheme": "symmetric",
    "granularity": "per_channel"
  },
  ...
}

启发式规则

  1. 首层和末层使用较高精度
  2. 下采样层使用较高精度
  3. 残差连接的层精度需匹配
  4. 瓶颈层可以使用较低精度

自动校准流程

  1. 收集激活统计信息
  2. 基于敏感度分析分配比特
  3. 迭代优化量化参数
  4. 验证精度满足要求

本章小结

量化友好的模型设计是实现高效边缘部署的基础。本章的关键要点:

  1. 激活函数设计
    • 有界激活函数(如 ReLU6)天然适合量化
    • 平滑激活函数需要特殊处理或近似
    • 可学习激活函数能够自适应量化约束
  2. 归一化层优化
    • BatchNorm 可以通过参数融合优化
    • LayerNorm 需要考虑动态统计量的量化
    • 混合精度策略在归一化层特别有效
  3. 注意力机制改进
    • Softmax 是量化的主要瓶颈
    • 动态范围控制至关重要
    • 线性注意力提供了量化友好的替代方案
  4. 自动化搜索
    • NAS 可以找到最优的量化配置
    • 硬件感知搜索考虑实际部署约束
    • 渐进式策略避免搜索空间爆炸

设计量化友好的模型需要在训练阶段就考虑部署需求,这种”设计即优化”的理念是未来边缘 AI 的发展方向。

练习题

基础题

  1. 激活函数分析 给定激活函数 f(x) = x·sigmoid(x) (Swish),分析其在 [-3, 3] 区间内的动态范围,并设计一个 4 段的分段线性近似。

    Hint: 计算 f(x) 在关键点的值和导数,确保近似函数连续。

  2. BatchNorm 融合计算 给定卷积层参数 W ∈ R^(64×32×3×3),偏置 b ∈ R^64,BatchNorm 参数 γ ∈ R^64, β ∈ R^64, μ ∈ R^64, σ ∈ R^64,写出融合后的等效卷积参数计算公式。

    Hint: 注意 BatchNorm 是按输出通道进行归一化的。

  3. Softmax 量化误差 对于输入 x = [2.1, 1.8, -0.3, 0.5],分别计算使用 FP32 和 INT8 量化(范围 [-4, 4])后的 Softmax 输出,并分析误差。

    Hint: INT8 量化公式:x_q = round(127 * x / 4)

  4. 多头注意力量化分配 一个 8 头注意力层,总计算预算为 32 bits(所有头的精度之和),如何分配每个头的量化精度?假设头的重要性分数为 [0.3, 0.2, 0.15, 0.1, 0.1, 0.08, 0.05, 0.02]。

    Hint: 考虑最小精度为 2 bits,使用贪心算法。

挑战题

  1. 自定义激活函数设计 设计一个满足以下条件的激活函数:
    • 输出范围 [-2, 2]
    • 在 x=0 处可导且导数为 1
    • 具有非线性特性
    • 可以用不超过 8 个参数的查找表精确表示

    Hint: 考虑使用双曲正切函数的变形或分段多项式。

  2. 量化感知的 LayerNorm 推导 LayerNorm 中除法运算 1/σ 的定点数实现方案,要求使用不超过 3 次乘法和 2 次加法,误差小于 1%。

    Hint: 使用牛顿-拉夫逊迭代或查表加插值。

  3. 线性注意力的量化分析 比较标准注意力和线性注意力(使用 ReLU 作为特征映射)在 INT8 量化下的误差累积。考虑序列长度 N=512,维度 d=64 的情况。

    Hint: 分析矩阵乘法次数和中间结果的动态范围。

  4. NAS 搜索空间设计 为移动端图像分类任务设计一个量化感知的 NAS 搜索空间,要求:
    • 模型大小 < 5MB
    • INT8 推理延迟 < 10ms (on Snapdragon 888)
    • Top-1 准确率 > 70% (ImageNet)

    描述搜索空间的关键维度和约束。

    Hint: 考虑 MobileNet 和 EfficientNet 的设计原则。

答案

点击查看答案 1. Swish 函数在 [-3, 3] 区间的分段线性近似: - 区间 [-3, -1.5]: f(x) ≈ 0 - 区间 [-1.5, 0]: f(x) ≈ 0.2x + 0.3 - 区间 [0, 1.5]: f(x) ≈ 0.7x - 区间 [1.5, 3]: f(x) ≈ x - 0.15 2. 融合公式: - W'[i] = γ[i]/σ[i] · W[i,:,:,:] - b'[i] = γ[i]/σ[i] · (b[i] - μ[i]) + β[i] 3. FP32: [0.517, 0.388, 0.034, 0.061] INT8 量化后: [0.515, 0.390, 0.035, 0.060] 最大绝对误差: 0.002 4. 精度分配:[8, 6, 5, 4, 4, 3, 2, 2] bits 使用贪心算法,优先给重要性高的头分配更多比特 5. 建议函数:f(x) = 2 * tanh(x/2) 满足所有条件,可用 8 点查找表 + 线性插值实现 6. 使用迭代:x₀ = 0.5, x₁ = x₀(3 - σ²x₀²)/2 两次迭代可达到 <1% 误差 7. 标准注意力:O(N) 次 INT8 累加误差 线性注意力:O(d) 次 INT8 累加误差 当 d << N 时,线性注意力的量化误差更小 8. 搜索空间关键维度: - 深度:12-20 层 - 宽度倍数:[0.5, 0.75, 1.0] - 块类型:MBConv, Fused-MBConv - 量化配置:每层 2-8 bits 约束通过查找表预测延迟