2. LLM推理优化

参考综述 A Survey on Efficient Inference for Large Language Models

img

  • LLMs typically demand higher computational cost, memory access cost and memory usage in their inference process (we will analyse the root causes in the Sec. 2.3), which deteriorates the efficiency indicators (e.g., latency, throughput, power consumption and storage) in the resource-constrained scenarios
  • 效率指标:存储延迟吞吐量,能量和电源消耗 <—将大大影响---- 计算消耗,访存消耗,存储使用
  • 推理低效的根本原因:
    • 模型大小: 极大影响计算消耗, 访存消耗和存储使用
    • 注意力操作: 当输入增长时, 注意力计算成二次方增长 (矩阵计算)
    • 解码过程: 在解码阶段, 模型权重将从chip HBM 加载到 GPU chip, 此外还有KV cache随着输入的增长也会导致内存碎片

2.1. 分类

img

  • 加速推理方法的三个层次:数据层次优化,模型层次优化,系统层次优化
    • 数据层次优化:通过输入的prompt或者更好的组织输出内容
      • 不需要改变原始模型(可能需要添加辅助模型,但是开销相对于训练的损耗不值一提)
    • 模型层面的优化:设计模型框架或者压缩预训练模型
      • 前者需要costly预训练或者少量微调成成本来获得模型能力,而后者通常会损失模型性能
    • 系统层面的优化:优化推理引擎和服务系统。
      • 前者并不涉及高消耗的模型训练,而后者在模型性能上是无损的

2.2 系统层面的优化

2.2.1. 推理引擎

img

2.2.1.1 🧐图和算子优化

  • 运行时分析: 图15中的分析结果表明,注意力算子和线性算子共同主导运行时间,它们的总时长通常超过推理时长的75%,并且多种算子占用很小的运行时,碎片化了算子执行的时间线并且增加了CPU侧内核启动的损耗,因此现今优化的推理引擎实行了高度融合的算子
    img

  • 注意力算子优化:

    • FlashAttention : 将整个注意力操作融合成单个的并且存储高效的算子。将输入矩阵进行分块,消除完整数据加载的需求。
    • FlashDecodeing : 目标是最大化计算并行化对于解码。在解码过程中,Q矩阵退化为一批向量,这使得在并行度仅限于批大小维度的情况下,填充计算单元变得具有挑战性。FlashDecoding通过沿序列维度引入并行计算来解决这个问题,但是会引起softmax计算的损耗
    • FlashDecoding++:oftmax中的最大值仅作为防止数据溢出的缩放因子。然而,动态最大值会带来显著的同步开销。此外,大量实验表明,在典型的LLM(如Llama2 [239]、ChatGLM [240])中,超过99.99%的softmax输入都处于特定范围内。因此,FlashDecoding++提出基于预先统计信息来确定缩放因子。这消除了 softmax计算中的同步开销,使得后续操作能够与 softmax计算并行执行
  • 线性算子优化:

    • General Matrix-Vector Multiplication (GEMV)(tensorRT-LLM)
    • FlashDecoding++:当工作负载变化时,存在两个挑战:并行度低和内存访问瓶颈
      • 采用精密的分块测率提高并行性以及利用双倍缓冲区技术来隐藏访存延迟
      • 线性操作在传统llm中通常有固定的大小,建立启发式筛选机制:基于不同的输入大小动态的选择不同的线性算子
        • 动态算子选择包括:FastGEMV [244]、FlatGEMM以及 cuBLAS [242]、[243]库提供的 GEMM
    • MegaBlocks:解决MoE FFN层优化。把MoE FFN计算形式化成块稀疏算子并且提出定制GPU核来加速
  • 图优化:

    • 内核融合
      • 减少内存访问
      • 减轻内核启动损失
      • 提高并行化
    • FlashAttention:融合注意力计算,减少访问注意力结果的损失
    • BytyTransformer and deepspeed:融合轻量算子(如残差连接层,层归一化,激活函数)到先前的线性算子。
    • 内核融合技术也被用于提高大语言模型(LLM)推理的利用率。查询(Query)、键(Key)和值(Value)矩阵的投影原本是三个独立的线性运算,现被融合为一个线性算子以部署在现代 GPU上。目前,内核融合技术已在 LLM推理实践中得到应用,高度优化的推理引擎在运行时仅使用少数融合内核。例如,在FlashDecoding++ [231] 的实现中,一个 transformer块仅集成了七个融合内核。借助上述算子和内核融合优化,FlashDecoding++相较于 HuggingFace实现实现了高达4.86倍的加速。

2.2.1.2. 🧐推测解码(投机解码)

这种方法的核心思想包括使用一个较小的模型(称为草稿模型)来有效地预测几个后续令牌,然后使用目标大型语言模型并行验证这些预测。
该方法旨在使LLM能够在通常单次推理所需的时间内生成多个标记。
img

  • 两个步骤
    • Draft Construction:部署草稿模型生成子序列tokens,并行地或者自回归的方式
      • 传统解码技术采用两种基础的采样策略:
        • 贪心采样:在每个解码步骤中选择概率最高的标记以生成特定的输出序列
          • BLockwise Parallel Decoding:保证draft tokens 准确地匹配贪心采样生成的序列来保证输出token的等价性
        • 核采样:从概率分布中采样标记,每次运行都会生成不同的标记序列
          • Speculative Sampling(投机采样):保留输出分布的等价性
            img
    • Draft Verification: 部署目标模型计算单个LLM推理步中所有草稿tokens的条件概率,随后依次决定是否接受每个token是否接受。接受度代表每个推理步平均被接受的draft tokens的个数,被视作衡量推测解码算法的性能的重要指标
      • Token tree verifier:用树结构来表示draft token集,使用树注意力机制来执行验证过程
        • 被证明是有效的提高推测解码的性能的方法
  • 主要研究方向
    • 设计更好的draft model
      • DistillSpec [220]直接从目标LLM中蒸馏出一个更小的草稿模型。
      • SSD [221]涉及从目标LLM中自动识别一个子模型(模型层的子集)作为草稿模型,从而无需单独训练草稿模型。
      • OSD [222] 在在线LLM服务中动态调整草稿模型的输出分布,以匹配用户查询分布。它通过监控LLM拒绝的草稿令牌,并利用这些数据通过蒸馏来优化草稿模型,从而实现这一目标。
      • PaSS [223]提出将目标LLM本身用作草稿模型,将可训练令牌(前瞻令牌)融入输入序列,以实现后续令牌的同时生成。
      • REST [224]引入了一种基于检索的推测解码方法,采用非参数检索数据存储作为草稿模型
      • SpecInfer [225]提出了一种集体增强调优技术,使一组草稿模型的输出分布与目标LLM的输出分布对齐。
      • Lookahead decoding[228]涉及并行生成目标LLM的n元语法,以辅助生成草稿令牌。
      • Medusa [48]专门微调LLM的多个头,用于生成后续草稿令牌。
      • Eagle [229]采用一种名为自回归头的轻量级Transformer层,以自回归方式生成草稿令牌,并将来自目标LLM的丰富上下文特征整合到草稿模型的输入中。
    • 设计更高效的draft construction 方式
      • 传统方法通常会生成单一的草稿 token序列,这给验证带来了挑战。对此,Spectr[230]主张生成多个草稿 token序列,并采用 k顺序草稿选择技术对 k个序列同时进行验证。该方法利用推测采样,确保输出分布的等价性。
      • 类似地,SpecInfer[225]也采用了类似的方法。然而,与 Spectr不同的是,SpecInfer 将草稿 token序列合并成一棵“token树”,并引入树注意力机制进行验证。这种策略被称为“token树验证器”。由于其有效性,token树验证器已被众多推测解码算法广泛采用[48], [224], [226], [229]。
      • 除了这些研究外,阶段推测解码[226]和级联推测草稿生成(CS Drafting)[227]提出通过将推测解码直接集成到 token生成过程中来加速草稿构建。
  • 效率分析
    img
    • Eagle
      • 采用自回归方法,直接利用先前生成tokens
      • 从原始llm的token和draft model中的token集成了丰富的特征,从而提高了推测解码的准确性
  • 端到端加速通过这些方法通常会低于接受率。因为draft model的生成成本通常不能忽略

2.2.2. 服务系统

img

2.2.2.1 存储管理

  • S3S^3 : 预先为每个请求估计一个最大生成长度上界, 防止浪费预分配的空间
    • 但是如果不能得到连续的空间分配, 那么这个方法将会失效 (页面碎片)
  • vllm : 通过分页的方式存储 KV cache
    • 先分配一个尽可能大的存储空间, 分成相等大小的多个物理块, 当请求到来, vllm动态的非连续地映射生成的KV cache 到预先分配的物理块中
  • LightLLM : 使用更细粒度的方式存储KV cache
    • LightLLM不再以块为单位,而是将单个token的KV缓存作为一个单元,从而使生成的KV缓存始终能填满预分配的空间。
分页与访存的平衡

通过分页的方式虽然能减轻存储空间的浪费, 但是注意力算子在使用KV cache的时候需要繁琐的寻址 (而非连续的方式寻址)

  1. PageAttention by vLLM : 存储的头部维度有16字节为K cache的连续向量
  2. FlashInfer : 为KV缓存协调多样化的数据布局,并辅以适当设计的内存访问方案。注意力算子的优化与分页KV缓存存储相结合,仍是服务系统发展中的前沿挑战。

2.2.2.2 连续批处理

The request lengths in a batch can be different, leading to low utilization when shorter requests are finished and longer requests are still running

  • ORCA : 计算过程包含多个迭代过程, 每个迭代要么处在与填充阶段要么处于解码阶段.
    • 不同的请求可以在迭代层次被批处理
    • 这个工作在迭代层次下批处理线性算子, 在序列的维度拼接不同的请求
  • vLLM : 使得不同KV cache长度被批处理
  • SarathiDeepSpeed-FastGen and AsrathiServe 引入了划分-融合(split-and-fuse)方法,来把预填充请求和解码请求批处理
    • 在序列维度划分长预填充请求,并且和多个短解码请求批处理
    • 平衡不同迭代次数的工作负载,并且显著减少了尾延迟
    • Split-and-fuse 技术前提是在与填充阶段,请求可以被划分成离散的块。块填充方法论涉及在序列维度划分预填充请求

2.2.2.3 🧐调度策略

  • Head-of-line blocking(队头阻塞) 在长请求被赋予优先时发生
    • 具体而言,内存使用量会随着长请求的增加而迅速增长,当系统耗尽内存容量时,会阻碍后续请求的处理
  • vLLMLightLLM使用的是简单的first come first serve的原则
  • DeepSpeed-FastGen 优先处理解码请求
  • FastServe 提出一个优先调度策略优化对头阻塞问题,实现low job completion time
    • 采用多级反馈队列
    • 对于解码阶段,由于位置的请求长度,先预测长度以及使用skip-join 的方式找到合适的优先级
  • VTC 讨论公平性。
    • 引入一个基于token数量的成本函数,来衡量公平性,并且采用公平调度的方式来保证公平性

2.2.2.4. 分布式系统

由于预填充阶段是计算密集的,解码阶段是存储密集的。

  • Split-wiseTetriInferDistServe 证明了将请求的预填充和解码步骤分离的高效性
  • SpotServe :抢占式GPU实例。解决了动态并行控制和示例迁移
  • Infinite-LLM 将分页KV cache 方法拓展到分布式云环境

2.2.3. LLM 框架对比

img

  • 结果显示:FlashDecoding++TensorRT-LLM 推理速度表现得比其他的方法更出色

2.2.4. 未来的方向以及一些建议

系统级优化在提高效率的同时不会降低准确性,因此在LLM推理实践中变得普遍。推理优化也适用于服务。最近,算子优化与实际服务场景紧密结合,例如,RadixAttention[50]是专为前缀缓存设计的,tree attention[225]用于加速推测解码验证。应用和场景的迭代将继续对算子开发提出新的要求。鉴于实际服务系统中固有的多方面目标,如作业完成时间、系统吞吐量和公平性,调度策略的设计相应地变得复杂。在LLM服务领域,请求长度不确定,现有文献通常依靠预测机制来辅助调度策略的设计。然而,当前预测器[248]的效果未达到理想标准,表明服务调度策略的开发仍有改进和优化的潜力

2.3. 模型层次的优化

2.3.1. 🧐高效结构设计

img

2.3.1.1. 高效FFN设计

  • 专注于优化专家权重的获取过程以及使得这些专家更加轻量化
    • MoEfication :将一个非MoE LLM通过预训练权重转换为一个MoE版本
      • 消除昂贵的对于MoE模型的预训练
      • 将预训练大模型的FFN神经元划分为多个组,每个组的神经元同步的被激活函数激活
      • 然后,重构每组神经元为一个专家
    • Sparse Upcycling : 从密集模型的检查点直接初始化MoE-base LLM权重
      • MoE-based LLM 中的专家是密集模型中的FFN的复制体
    • MPOE: 通过Matrix Product Operators decomposition (矩阵乘积算子分解)减少MoE-based LLMs的参数量
      • 分解每个FFN的权重矩阵为一个全局共享张量(包含全局信息以及一个捕获特殊特征的局部辅助张量的集合)
  • 设计路由模型
    • Switch Transformer:引入一个额外的损失,称为负载平衡损失,用于惩罚路由模型的不均衡分配
      • 这个损失被形式化成token分配向量和一个均匀分布向量的点乘
    • BASE: 端到端地为每一个专家学习一个嵌入,将专家分配给和它的嵌入相似度高的token
      • 形式化了一个线性分配问题,并且使用拍卖算法高效解决这个问题
    • Expert Choice
      • 每个专家通过嵌入相似性独立的选择top-K的tokens
  • 提升训练方法
    • SE-MoE: 引入辅助损失,路由z-loss
      • 发现:由softmax 算子引入的指数函数会加剧舍入误差,并导致训练不稳定。
      • Z-loss惩罚输入到指数函数中的大logits,最小化每轮的舍入误差
    • StableMoE: 指出路由波动问题,导致专家分配在训练和推理阶段的不一致性
      • 对于相同的输入token,在训练时被分配给不同的专家,但是在推理时只分配一个专家
      • 首先,学习一个路由策略,并且使得它在骨干网络和推理阶段固定
    • SMoE-Dropout:在训练过程中,逐渐在增加激活的专家个数
    • GLaM: 预训练并发布了一些系列带有不同参数量的模型,并且对比了他们和密集型LLM在few-shot 任务上的性能
    • Mixtral 8 $\times$ 7B: 是一个开源的模型. 在推理阶段, 它使用13b激活参数, 并且对比LLaMA-2-70B模型实现了更好的性能
      • 每一层由8个FFN专家, 并且在推理时每个token被分配给2个专家

2.3.1.2. 高效注意力设计.

  • Multi-Query Attention:
    • (MQA)共享KV cache 在多个注意力头之间,同时保留不同的Q矩阵
    • Grouped-query attention(GQA): 把多个注意力头分组,对于每个组存储一个简单的KV cache。
  • Low-Complexity Attention
    • Kernel-based Attention: kernel ϕ\phi , 用一个核transformer特征映射 ϕ(Q)ϕ(K)T\phi(Q)\phi(K)^T 线性点乘, 近似非线性的softmax算子Softmax(QKT)\operatorname{Softmax(QK^T)}
      • 它通过先计算 ϕ(K)TV\phi(K)^TV 再与 ϕ(Q)\phi(Q) 相乘从而避免了 QKTQK^T 的传统二次计算量
      • Linear Transformer: 它采用了 ϕ(x)=elu(x)+1\phi(x)= \operatorname{elu}(x)+1 作为核函数
      • Performers 以及 RFA 提出了使用随机特征投影来更好地近似softmax函数
      • PolySketchFormer 使用了多项式函数以及草图技术来近似softmax函数
    • Low-Rank Attention : 使用了,将KV矩阵的token维度压缩为一个固定的, 更小的长度
      • 主流的研究 XRn×dXRk×d,XKVX\in\mathbb{R}^{n\times d }\to X'\in\mathbb{R}^{k\times d},其中X是K或者V
      • 其他研究: 采用线性投影压缩token维度, 对于KV矩阵分别乘以投影矩阵 PkP_kPvP_v
      • Linformer: 首先提出并分析attention 映射的低秩特性.
      • LRT: 提出同时使用低秩transformer于注意力块, FFN
      • FLuRKA: 结合低秩transformer以及核化的注意力矩阵
        • 首先减少KV矩阵的token维度, 然后采用核方法于Q和低秩的K
    • Luna 以及Set Transformer 使用更小的queries 来压缩K和V矩阵
      • Luna涉及额外的query矩阵有固定的长度k.
        • 更小的query于原始的上下文矩阵做注意力操作称为 pack attention, 将上下文矩阵压缩到 Rk×d\mathbb{R}^{k\times d}
        • 相似的, 采用原始的Q矩阵和压缩的KV矩阵做注意力, 称为unpack attentioin
        • 额外的quey矩阵可以是科学系的参数或者从前面的层中获得
      • Set Transformers: 引入长度固定的 inducing points 向量
      • Funnel Tansformer 使用pooling算子来逐渐压缩Q矩阵的序列长度

2.3.1.3. 🧐替代Transformer

在该研究领域内,两个突出的研究方向受到了广泛关注。

  • 其中一个研究方向专注于状态空间模型(State Space Model, SSM),该模型基于HiPPO理论[62]将序列建模表述为一种递归变换
    • 与基于注意力的Transformer相比,SSM在输入序列长度方面表现出线性计算和内存复杂度,这增强了其在处理长上下文序列时的效率。在本综述中,SSM指的是满足以下两个特性的一系列模型架构:
      1. 它们基于HiPPO[62]和LSSL[63]提出的以下公式对序列进行建模:
        img其中,A、B和C表示转移矩阵,x表示中间状态,u表示输入序列。
      2. 他们基于HiPPO理论[62]设计了转移矩阵A。具体来说,HiPPO提出通过将输入序列投影到一组多项式基上,将其压缩为一系列系数(即状态)。
    • 多项研究致力于改进转移矩阵A的参数化或初始化。这涉及到在状态空间模型(SSM)中优化矩阵的构建或初始化方式,以增强其在序列建模任务中的有效性和性能。
      • LSSL [63]首先提出使用HiPPO设计的最优转移矩阵HiPPO-LegS对A进行初始化。
        img
      • 然而,计算该卷积核的成本很高,因为它需要多次与A相乘。为此,S4 [64]、DSS [65] 和 S4D [66]提出对矩阵A进行对角化处理,从而加快计算速度。这可视为对转移矩阵A的一种参数化技术。
      • 早期的SSM对每个输入维度独立处理,导致可训练参数数量庞大。为提高效率,S5 [70]提出使用单组参数同时处理所有输入维度。基于此结构,S5引入了一种基于标准HiPPO矩阵的A参数化和初始化方法。
      • Liquid S4 [69] 和Mamba [73]则以输入依赖的方式对转移矩阵进行参数化,进一步增强了SSM的建模能力。此外,S5 [70] 和Mamba [73]均采用并行扫描技术,无需卷积操作即可实现高效的模型训练。该技术在现代GPU硬件上的实现和部署具有优势。
    • 另一类研究旨在基于状态空间模型(SSMs)设计更好的模型架构
      • GSS [67] 和 BiGS [72] 将门控注意力单元(GAU)[102]与状态空间模型相结合。具体来说,它们将门控注意力单元中的注意力操作替换为状态空间模型操作。
      • BST [71] 将状态空间模型与所提出的块Transformer相结合,后者引入了强大的局部归纳偏置。
      • H3 [68]观察到状态空间模型在回忆早期标记和比较序列中的标记方面存在不足。为此,它建议在标准状态空间模型操作之前添加一个移位状态空间模型操作,用于将输入标记直接移位到状态中。
      • MambaFormer [74] 通过将Transformer中的前馈网络(FFN)层替换为状态空间模型层,将标准Transformer与状态空间模型相结合。
      • Jamba [103]引入了另一种结合Transformer和状态空间模型的方法,即在状态空间模型中添加四个Transformer层。
      • DenseMamba[104]探讨了传统状态空间模型中隐藏状态退化的问题,并在状态空间模型架构中引入密集连接,以在模型更深层保留细粒度信息。
      • BlackMamba [105] 和 MoE-Mamba [106]提出使用混合专家(MoE)技术增强状态空间模型,以在保持模型性能的同时优化训练和推理效率。
  • 此外,其他研究主要侧重于采用长卷积或设计类注意力公式来对序列进行建模状态空间模型。
    img

2.3.2. 模型压缩

img

2.3.2.1 量化

将模型权重和激活从高位宽变为低位宽
img

  • 效率分析:
    • 再预填充阶段的延迟被高精度的CUDA核心的计算性能限制,未来解决这个挑战,现有的方法使用低精度的张量核心来计算量化的权重和激活值

      • Weight-Activation Quantization : Activations 在线量化再每个GEMM操作前进行
        img
    • 相反,在解码阶段,延迟主要是受到权重张量加载影响。现有技术通过只量化权重来加速内存读取

      • Weight-only Quantization: 涉及离线量化权重,然后将低精度权重反量化为FP16的格式进行计算
        img
2.3.2.1.1. 后训练量化

对于训练模型进行量化,无需重新训练,可能是一个开销大的过程

  • Weight-only 量化:
    • GPTQ
      • 在传统的OBQ算法上进行构建
        • OBQ利用权重矩阵每行的最优量化顺序,该顺序由相对于未量化权重的 Hessian矩阵的重建误差指导。
        • 在每个量化步后,OBQ迭代的调整未量化的权重来减少重构误差
        • 然而频繁的更新海森矩阵增加了计算复杂度
      • GPTQ通过采用统一的从左到右顺序对每一行进行量化,从而简化了这一过程,避免了大量Hessian矩阵更新的需求。该策略通过仅在量化一行时计算海森矩阵,然后将计算结果用于后续行,从而显著降低了计算需求,加快了整体量化过程。
    • LUT-GEMM:提出一个新的反量化方法
      • 使用查找表来减少反量化的损失
      • 非均匀的量化方法,称为Binary-Codeing Quantization(BCQ
    • AWQ: 权重通道对于性能的影响不同,特别强调那些与激活中表现出异常值的输入通道对齐的权重通道
      • 采用重参数化方法:通过网格搜索选择重参数化系数,最小化重构误差
    • OWQ:观察到量化的困难度与激活值的离群点有关。
      • 采用混合精度量化策略:找到权重矩阵中的弱列,分配高精度给这些特殊的权重并且为剩下的权重分配较低的精度水平
    • SpQR:引入了一个方法论:识别权重离群值,并且分配高精度,剩下的被量化到3bit
    • SqueezeLLM: 在全精度稀疏矩阵中存储离群值,并且采用非均匀的量化方式量化剩下的权重
    • QuIP:引入LDLQ
      • 一个最优自适应方法解决二次代理目标
      • 研究表明保证权重和海森矩阵之间的不相关性能提高LDLQ的效率
        • 采用随机正交矩阵乘法来实现不相关性
    • FineQuant:使用启发式的方法来决定每列的量化粒度,结合实验中获得的经验来设计量化方案
    • QuantEase:在GPTQ上构建
      • 当量化每一层使用坐标下降更精确地补偿未量化的权重
      • 可以使用GPTQ做初始化以及进一步优化补偿过程
    • LLM-MQ:用FP16的格式保护权重离群值,并且把他们存储在压缩稀疏列格式(CSR)
      • 将每层的位宽分配建模为整数规划问题,并采用高效求解器在几秒内完成求解
      • 设计高效CUDA核心来集成反量化算子
  • Weight-activation 量化
    • Zeroquant:采用核融合来最小化访存消耗,并进行逐层知识蒸馏来恢复其性能
    • FlexGen:直接量化权重核KV cache 到INT4 来减少大批量推理过程中的内存占用
    • LLM.Int8: LLM.int8() [194]发现激活值中的异常值集中在一小部分通道内。利用这一见解,LLM.int8() 根据输入通道内的离群值分布将激活和权重分为两个不同的部分,以最小化激活中的量化误差
      • 带有离群值的部分使用FP16的格式进行存储,其他的则以INT8进行存储
    • SmoothQuant 采用重参数化的方法解决量化激活值的挑战
      • 该方法引入了一个缩放因子,它在扩大权重通道数据范围的同时,缩小了相应激活通道的数据范围。
    • ZeroQuant:权重每组量化以及激活token量化。
      • ZeroQuantV2: 采用LoRC(Low-Rank Compensation),使用低秩矩阵来减少量化的不准确性
    • RPTQ:发现不同激活通道的分布存在显著差异,这给量化带来了挑战。为缓解此问题,RPTQ将具有相似激活分布的通道重组为簇,并在每个簇内独立应用量化。
    • OliVe:观察到离群值附近的正常值不太重要。因此,它将每个离群值与一个正常值配对,牺牲后者以实现离群值更广泛的表示范围。
    • OS+ : 每通道偏移和放缩
    • ZeroQuant-FP:研究表明,将激活值量化为浮点类型(FP4和FP8)比整数类型产生更好的结果
    • Omniquant:它优化权重裁剪的边界和等效变换的缩放因子,以最小化量化误差。
    • QLLM: 通过实施通道重组解决了异常值对量化的影响,引入了可学习的低秩参数来最小化量化误差
    • Atom:涉及激活的混合精度以及动态量化
      • 拓展了KV cache 的量化方法到INT4
    • LLM-FP4: 将整个模型量化到FP4的格式并且引入预偏移指数偏置技术。该方法将激活值的缩放因子与权重相结合,以解决离群值带来的量化挑战。
    • BiLLM: BiLLM[203]是迄今为止最低比特PTQ研究之一。BiLLM发现权重呈钟形分布,且权重的海森矩阵具有异常长的尾部分布。基于此,它提出根据海森矩阵将权重从结构上分为显著值和非显著值,并对它们分别进行二值化。因此,BiLLM可以将大型语言模型广泛量化至1.08比特,且不会导致困惑度显著下降。
    • KVQuant:提出了一个非均匀的量化方法for KV cache。
      • 通过在校正集上离线获得最优的数据形式
    • KIVI: 提出了一种不需要调整的2bit KV cache 量化算法
      • 对key cache进行每个通道的量化,以及对于value cache进行每个token的量化,通过group-wise的方式
    • Li et al.
2.3.2.1.2. 量化感知训练

将量化的影响融入模型训练的过程中,通过集成模拟量化效果的层,这种方法有助于权重适应量化引起的误差,从而提升任务性能

  • 为了减少数据的需求

    • LLM-QAT
      • 引入了一种不需要数据的方法:通过使用原始的FP16 LLMs来生成训练数据
      • 具体而言,LLM-QAT将分词词汇表中的每个标记作为起始标记来生成句子。
      • 基于生成的训练数据,LLM-QAT采用基于蒸馏的工作流程来训练量化的 LLM,使其匹配原始 FP16 LLM 的输出分布
    • Norm Tweaking
      • 将起始标记的选择限制为仅在比例最高的顶级语言类别中列出的那些语言类别。这种策略可以有效提高量化模型在不同任务上的泛化能力
  • 为了减少计算成本,很多方法采用参数效率调整策略(PEFT)来加速QAT

    • QLoRA:将权重量化到4bit,然后针对每个4位权重矩阵采用BF16精度的LoRA来微调量化模型
      • 允许在只是用30GB的GPU存储来完成65B的参数高效微调
    • QALoRA: 将分组量化和QLoRA结合
      • 由于QLoRA的量化参数量小于LoRA的参数,导致量化与低秩自适应的不平衡,于是采用分组来解决这个问题
      • 可以把LoRA项融入量化权重矩阵
    • LoftQ:使用原始FP16权重矩阵和量化后权重矩阵的差异的奇异值分解,初始化LoRA矩阵
      • 实现更精确对于原始权重的估计
    • Norm Tweaking: 提出在量化后训练LayerNorm层,并使用知识蒸馏使量化模型的输出分布与FP16模型匹配,实现类似于LLM-QAT的效果,同时避免高昂的训练成本。
2.3.2.1.3. 对比试验和分析

试验设置:采用了 weight-only 的量化方法(AWQ),使用LLaMA-2-7B 和 LLaMA-2-13B以及TensorRT-LLM以及LMDeploy推理框架

  1. Weight-only 量化能大大加速解码阶段,这种增强主要源于更快速地从HBM加载低精度的权重
  2. 对于预填充阶段,weight-only量化可能会增加延迟,这是因为与填充阶段的瓶颈是计算消耗而不是存储消耗
  3. 随着batch size和输入长度的增长,weight-only量化的加速程度将逐渐消失
    • 因为batch size和输入长度变大的时候,计算开销会增加,此时计算开销将会占主导,而访存开销将会降低
  4. Weight-only 量化由于能显著降低访存开销而对于LLM大有脾益

2.3.2.2. 稀疏化

这个方法只在通过高效忽略零元素,降低计算的复杂度和内存使用
通常被使用在权重参数和注意力激活

2.3.2.2.1. 权重剪枝

img
去除不那么重要的结构和权重,在不损失太多模型性能地在预填充和解码阶段降低计算和存储开销、

  • Unstructred pruning
    • 以细粒度剪枝单个权重值,对比结构化剪枝,他能实现更好的稀疏化,然而获得的稀疏模式缺乏高阶的规律性
    • 可能会导致不规则的访问内存以及计算模式,可能会导致硬件加速受阻
      • 重构误差
        • SparseGPT: 它集成OBS的思想:考虑移除每一个权重的网络重构误差
          • OBS迭代地决定剪枝mask剪枝,并且重构未剪枝的权重来补偿剪枝的损失
          • 通过Optimal Partial Update 技术来改进OBS
        • Prune and Tune:在SparseGPT上微调LLM
        • ISC:结合OBS和OBD的标准
        • BESA:通过重构误差的梯度下降来学习一个可微的二元掩码
          • 剪枝率有最小化重构误差决定
      • 基于幅度
        • Wanda:提出将权重大小与输入激活范数之间的逐元素乘积用作剪枝准则
        • RIA:通过使用相对重要性和激活度指标共同考虑权重和激活值,该指标基于每个权重元素的所有连接权重来评估其重要性。
        • OWL:专注于决定每一层的剪枝率
  • Structured pruning
    • 剪枝一整个通道或者层,操作的粒度更粗
    • 这些方法在传统硬件平台上能促进推理的加速
    • 然而粗粒度通常会较大影响模型的性能
    • LLM-pruner:提出一种任务无关的剪枝方法
      • 具体来说,它首先基于神经元之间的连接依赖关系识别大型语言模型中的耦合结构。
      • 然后,它基于精心设计的组级剪枝指标决定移除哪些结构组。
      • 剪枝后,它进一步提出通过一种参数高效的训练技术,即LoRA等,来恢复模型性能
    • Shared LLaMA:提出将原始大语言模型剪枝为现有预训练大语言模型的特定目标架构
      • 此外,它提出动态批加载技术
    • ZipLM
    • LoRAPrune:剪枝带有LoRA模块的预训练LLM。
    • LoRAShear
    • SliceGPT:基于RMSNorm运算的计算不变性理念
    • PLATON:提出剪枝时同时考虑他们的重要性和不确定性,它使用重要性分数的指数移动平均(EMA)来估计重要性,并采用上置信界(UCB)来表示不确定性
    • SIMPLE:通过学习对应的稀疏掩码来进行注意力头,FFN神经元和隐藏维度的剪枝
      • 剪枝后使用知识蒸馏来进行模型性能恢复
  • Sparse Attention:
    img
    • Static sparse attention:独立于输入移除激活值。这些方法预先定义稀疏注意力掩码。
      • 最常见的是局部注意力以及全局注意力模式
        • 局部注意力模式:使用固定大小的窗口注意力捕捉局部上下文
        • 全局注意力模式:模式通过计算并关注序列中的所有标记,捕获特定标记与所有其他标记的相关性。
      • Sparse Transformer:结合这些模式,用局部模式捕捉局部上下文,然后每隔几个词用全局模式聚合信息
      • StreamingLLM
      • BigBird:使用随机模式,局部模式、全局模式和随机模式的组合被证明能够封装所有连续的序列到序列函数,这证实了其图灵完备性。
      • Longformer:膨胀滑动窗口模式,它类似于膨胀卷积神经网络,使滑动窗口“膨胀”以增加感受野。
      • Structured Sparse Attention :提出了一种熵感知训练方法,该方法将高概率注意力值聚集到更密集的区域。
      • SemSA:采用基于梯度的剖析方法识别重要的注意力模式,并自动优化注意力密度分布,以进一步提升模型效率。
    • Dynamic sparse attention:对不同的输入会自适应地去除激活值,通过实时监测神经元激活值来绕过影响可忽略的神经元的计算,从而实现剪枝。
      • Token-pruning:Spatten等[153]、SeqBoat等[154]和Adaptively Sparse Attention等[155]利用语言结构中固有的冗余性,提出了动态令牌级剪枝策略。
        • Spatten等[153]通过聚合注意力矩阵列来评估每个词的累积重要性,随后在后续层中从输入中剪枝累积重要性最小的令牌。
        • SeqBoat等[154]使用稀疏sigmoid函数训练线性状态空间模型(SSM),以确定每个注意力头要剪枝的令牌。Spatten和SeqBoat都会对整个输入中无信息的令牌进行剪枝。
        • Adaptively Sparse Attention等[155]在生成过程中逐步剪枝令牌,它会丢弃未来生成不再需要的部分上下文。
      • Attention-pruning:
        • 如图11(d)所示,这些方法并非剪枝特定标记的所有注意力值,而是基于输入动态剪枝注意力的选择性部分。
        • 该领域内一种重要的方法是将输入标记动态分割成组(称为桶),并策略性地省略位于不同桶中的标记的注意力计算。这些方法的挑战和重点在于如何将相关标记聚类在一起,从而仅在它们之间进行注意力计算以提高效率。
        • Reformer[156]利用局部敏感哈希将具有相同哈希码的键和查询聚类到同一个桶中。
        • 在此基础上,Sparse Flash Attention[157]引入了专门针对这种基于哈希的稀疏注意力机制优化的GPU内核,进一步提高了计算效率。
        • 同时,Routing Transformer[158]采用球形k均值聚类算法将标记聚合到桶中,优化了注意力计算的选择过程。
        • Sparse Sinkhorn Attention[159]采用学习排序网络将键与相关的查询桶对齐,确保仅在相应的查询-键对之间计算注意力。
        • 与桶级操作不同,H2O[160]引入了标记级动态注意力剪枝机制。它将静态局部注意力与当前查询和一组动态识别的关键标记(称为重击者(H2))之间的动态计算相结合。这些重击者通过逐出策略动态调整,旨在在每个生成步骤中移除最不重要的键,有效管理重击者集合的大小和相关性。
      • 此外,将每个标记视为图节点并将标记之间的注意力视为边,为静态稀疏注意力提供了扩展视角[150],[161]。原始的全注意力机制相当于具有均匀最短路径距离1的完全图。稀疏注意力通过其随机掩码引入随机边,有效地将任意两个节点之间的最短路径距离减少到O(logn),从而保持类似于全注意力的高效信息流。Diffuser[161]利用图论视角,通过多跳标记相关性扩展稀疏注意力的感受野。它还从扩展器图特性中汲取灵感,设计出更优的稀疏模式,以近似全注意力的信息流。
      • Spatten[153]还将剪枝从令牌粒度扩展到注意力头粒度,消除非必要注意力头的计算,以进一步降低计算和内存需求

2.3.2.3 结构优化

2.3.2.3.1. 神经架构搜索 (NAS)

旨在自动搜索最优的神经架构来平衡性能和效率

  • AutoTinyBERT [135]利用一次性神经架构搜索(NAS)来发现Transformer架构的超参数。值得注意的是,它引入了一种引人注目的批次训练方法来训练超级预训练语言模型(SuperPLM),随后采用进化算法来识别最优子模型。
  • NAS-BERT [136] 使用多种创新技术,如块级搜索、搜索空间剪枝和性能近似,在传统的自监督预训练任务上训练大型超级网络。这种方法使NAS-BERT能够高效应用于各种下游任务,而无需大量重新训练。通过NAS进行结构剪枝 [137] 将结构剪枝视为多目标NAS问题,并通过一次性NAS方法解决。
  • LiteTransformerSearch [138]提出使用无需训练的指标,即参数数量,作为代理指标来指导搜索。该方法能够高效探索和选择最优架构,且在搜索阶段无需实际训练。
  • AutoDistil [139]提出了一种完全与任务无关的少样本NAS算法,其特点是三种主要技术:搜索空间划分、与任务无关的SuperLM训练和与任务无关的搜索。这种方法旨在通过最少的任务特定适应,促进跨各种任务的高效架构发现。通常,NAS算法需要评估每个采样架构的性能,这可能会产生显著的训练成本。因此,这些技术难以应用于大型语言模型。
2.3.2.3.2. 低秩分解 (LRF)

img

  • LoRD表明,通过低秩分解(LRF)压缩大型语言模型(LLMs)具有潜力,且不会大幅降低性能。具体而言,它采用奇异值分解(SVD)对权重矩阵进行因式分解,并成功将一个拥有160亿参数的大型语言模型压缩至123亿,性能下降极小。
  • TensorGPT提出了一种使用张量列车分解来压缩嵌入层的方法。每个标记嵌入都被视为矩阵乘积态(MPS),并以分布式方式高效计算。
  • LoSparse结合了低秩分解和权重剪枝在大型语言模型压缩方面的优势。通过利用低秩近似,LoSparse降低了直接模型剪枝中通常会出现的丢失过多表达性神经元的风险。
  • LPLR 和 ZeroQuant-V2均提出通过同时对权重矩阵应用低秩分解和量化来对其进行压缩。
  • DSFormer提出将权重矩阵分解为半结构化稀疏矩阵和小型密集矩阵的乘积。
  • ASVD设计了一种激活感知的 SVD方法。该方法包括在应用 SVD进行矩阵分解之前,基于激活分布对权重矩阵进行缩放。ASVD还包括通过搜索过程为每个层确定合适的截断秩

2.3.2.4. 知识蒸馏

img

2.3.2.4.1. 白盒知识蒸馏

利用教师模型结构和参数访问权限的蒸馏方法。该方法使知识蒸馏能够有效利用教师模型的中间特征和输出logits,从而提升学生模型的性能。

  • MiniLLM [129]提出采用标准的白盒知识蒸馏方法,但将正向KL散度(KLD)替换为反向KL散度。
  • GKD[130]引入了策略内数据的使用,其中包括学生模型自身生成的输出序列,以进一步蒸馏学生模型。该方法侧重于使用这些策略内数据对齐教师和学生模型之间的输出logits。
  • TED [131]提出了一种任务感知的分层知识蒸馏方法。该方法包括在教师和学生模型的每一层之后添加过滤器,训练这些特定于任务的过滤器,随后冻结教师模型的过滤器,同时训练学生过滤器以使其输出特征与相应的教师过滤器对齐。
  • MiniMoE [133] 通过将混合专家(Mixture-of-Experts,MoE)模型用作学生模型来缓解容量差距。
  • 对于新出现的实体,预训练语言模型(LLMs)可能缺乏最新信息。为了解决这个问题,一种解决方案是在提示中加入额外的检索文本,尽管这会增加推理成本。或者,KPTD [134]建议通过知识蒸馏将实体定义中的知识转移到LLM参数中。该方法基于实体定义生成转移集,并蒸馏学生模型,使其基于这些定义与教师模型的输出分布相匹配。
2.3.2.4.2. 黑盒知识蒸馏

黑箱知识蒸馏是指教师模型的结构和参数不可用的知识蒸馏方法.通常,黑盒知识蒸馏仅使用教师模型获得的最终结果。

  • 关于ICL能力,
    • Multitask-ICT[116]引入了上下文学习蒸馏,以迁移大型语言模型(LLMs)的多任务少样本能力,同时利用了上下文学习和语言建模的优势。
    • MCKD[117]观察到,从经过上下文学习的教师模型中蒸馏出的学生模型在未见过的输入提示上通常表现出更优的性能。基于这一观察,MCKD设计了一种多阶段蒸馏范式,其中前一阶段的学生模型被用于为后续阶段生成蒸馏数据,从而提高蒸馏方法的有效性。
  • 为了提炼思维链(CoT)推理能力,一些技术如Distilling Step-by-Step [118]、SCoTD [119]、CoT Prompting [120]、MCC-KD [121]和Fine-tune-CoT [122]提出了蒸馏方法,这些方法结合了从大型语言模型中提取的响应和推理过程来训练学生模型。
    • Socratic CoT [123]也致力于将推理能力迁移到更小的模型中。具体而言,它对一对学生模型进行微调,即问题生成(QG)模型和问答(QA)模型。QG模型经过训练,能够基于输入问题生成中间问题,从而引导QA模型生成最终响应。
    • PaD [124]观察到错误推理(即最终答案正确但推理步骤错误)可能对学生模型有害。为了解决这个问题,PaD提出为推理问题生成合成程序,然后可以通过额外的解释器对这些程序进行自动检查。这种方法有助于去除具有错误推理的蒸馏数据,提高学生模型训练数据的质量。
  • 针对指令跟随能力,已有多种方法被提出以将这种能力迁移到更小的模型中。
    • DISCO [126]引入了一种技术,即使用大型语言模型生成短语扰动。然后,由特定任务的教师模型对这些扰动进行筛选,以提炼高质量的反事实数据。
    • LaMini-LM [127]旨在通过设计多样化的指令集来迁移指令跟随能力,从而对学生模型进行蒸馏。Lion [128]利用教师模型识别困难指令,并生成新的复杂指令来对小型模型进行蒸馏。

2.3.2.5. 动态推理

本节重点介绍早期退出技术,该技术使大型语言模型能够根据特定样本或标记在不同的模型层停止推理。值得注意的是,虽然混合专家技术(在5.1.1节讨论)在推理过程中也会调整模型结构,但它们通常需要高昂的预训练成本。相比之下,早期退出技术只需训练一个小型模块来决定何时结束推理。我们将早期退出技术的研究分为两种主要类型:样本级早期退出和标记级早期退出(如图13所示)。
img

2.3.2.5.1. 采样级

对于每一个输入采样,决定最优尺寸和大语言模型结构

  • 一种常见的方法是在每一层之后为大型语言模型增加额外的模块,利用这些模块来决定是否在特定层终止推理。
    • FastBERTDeeBERTMPMPEE直接训练这些模块,使其基于当前层的特征做出决策(例如,输出0继续或1停止)。
    • Global Past-Future Early Exit提出了一种方法,通过来自前序层和后续层的语言信息丰富这些模块的输入。由于推理过程中无法直接获取后续层特征,因此训练了一个简单的前馈层来估计这些未来特征。
    • PABEE 将模块训练为直接预测的输出头,当预测结果保持一致时建议终止推理。
    • HASHEE采用了一种非参数决策方法,其基于的假设是相似样本应在同一层退出推理。
2.3.2.5.2. Token级

在大语言模型推理的解码阶段, tokens是按顺序生成的,token级早退技术旨在为每个输出 token优化大语言模型的大小和结构。

  • CALM [108] 在每个 Transformer层后引入早退分类器,训练它们输出置信度分数,以决定是否在特定层停止推理。值得注意的是,在自注意力块中,计算每一层当前 token 的特征依赖于同一层中所有先前 token 的特征(即 KV缓存)。为解决因先前 token早退而导致的 KV缓存缺失问题,CALM提出将特征从退出层直接复制到后续层,实验结果表明性能仅略有下降。
  • SkipDecode [109]解决了先前早退方法的局限性,这些局限性阻碍了它们在批量推理和 KV缓存中的适用性,从而限制了实际的加速增益。对于批量推理,SkipDecode为批次内的所有 token提出了统一的退出点。关于 KV缓存,SkipDecode确保退出点单调递减,以防止 KV缓存的重新计算,从而提高推理效率

2.3.3. 建议和未来展望

  • 在高效结构设计领域,寻找Transformer的替代架构是一个新兴的研究方向。诸如Mamba [73]、RWKV [60]及其各自变体[101]、[104]等模型已在各类任务中展现出具有竞争力的性能,近年来备受关注。尽管如此,研究这些非Transformer模型是否可能比Transformer模型存在某些缺点仍然具有现实意义。同时,探索非Transformer架构与注意力操作的融合[74]、[103]、[216]是未来研究的另一个有前景的方向。
  • 在模型压缩领域,量化是大语言模型(LLM)部署中主要采用的方法,这主要归因于两个关键因素。首先,量化为压缩LLM提供了一种便捷的方式。例如,采用训练后量化(PTQ)方法可在几分钟内将拥有70亿参数的LLM压缩为更小的形式。其次,量化有望大幅降低内存消耗并提高推理速度,同时仅带来微小的性能损失。这种权衡对于许多实际应用而言通常是可接受的。然而,值得注意的是,量化仍可能损害LLM的某些涌现能力,如自校准或多步推理能力。此外,在处理长上下文等特定场景中,量化可能导致显著的性能下降[204]。因此,需要谨慎选择合适的量化方法,以减轻这些特定情况下的性能下降风险
  • 大量文献致力于研究稀疏注意力技术,以实现高效的长上下文处理。例如,最近的代表性工作StreamingLLM [148]仅通过恢复几个注意力汇聚标记就能处理400万个标记。尽管如此,这些方法往往会牺牲关键信息,导致性能下降。因此,在高效管理长上下文的同时保留必要信息,仍是未来探索的重要领域。关于权重剪枝技术,LLM-KICK [217]指出,当前最先进的方法即使在相对较低的稀疏率下也会经历显著的性能下降。因此,开发有效的权重剪枝方法以维持LLM性能,仍是一个新兴且关键的研究方向
  • 模型结构的优化通常涉及神经架构搜索(NAS)的使用,这通常需要大量的计算资源,对其在大型语言模型(LLMs)压缩中的实际应用构成了潜在障碍。因此,研究采用自动结构优化进行大型语言模型压缩的可行性值得进一步探索。此外,低秩分解(LRF)等技术在压缩率和任务性能之间实现最佳平衡仍然面临挑战。例如,ASVD [146]在不损害大型语言模型推理能力的情况下,仅能实现10%至20%的适度压缩率。
  • 除了采用单独的模型压缩技术外,多项研究还探索了不同方法的组合以压缩大型语言模型,利用它们各自的优势来提高效率。例如,MPOE [88]专门对基于混合专家(MoE)的大型语言模型中的专家前馈网络(FFNs)应用权重矩阵分解,旨在进一步降低内存需求。LLM-MQ [191]利用权重稀疏性技术在模型量化过程中保护权重离群值,从而最大限度地减少量化误差。LPLR [143]专注于对低秩分解的权重矩阵进行量化,以进一步降低大型语言模型推理过程中的内存占用和内存访问成本。此外,LoSparse [142] 将低秩分解与权重剪枝相结合,利用剪枝来增强低秩近似的多样性,同时通过低秩分解保留重要权重并防止关键信息丢失。这些方法凸显了集成多种压缩技术以实现大型语言模型更好优化的潜力。