大模型优化方式包含以下内容
量化
目的是对模型压缩与加速。量化过程包含缩放(Scale) 和有时需要的零点(Zero Point),以将浮点数范围映射到整数范围。
Details
包含w8a8,w4a16,w8a16,w8a8c8(perchannel以及pertoken) 一般像w8a8都是激活层pertoken,权重层perchannel量化;一般使用对称量化,非对称对硬件都有要求,计算会变慢,但是精度提升。量化同时降低首token时延和增量推理时延。
量化中会出现的一类问题是幻觉问题,可以通过量化回退解决
量化回退思想:扫描指定目录下的所有safetensors模型文件,对每个权重张量进行统计分析,评估其数值分布特性和量化误差。
-
统计分析
四分位比例计算:通过计算 (最大值-最小值)/(上四分位-下四分位) 来评估权重分布的离散程度
这个比例越大,说明数据分布越分散,可能存在异常值或极端值 -
量化误差评估
INT8对称量化模拟:对权重进行模拟量化再反量化
NRMSE计算:使用归一化均方根误差来评估量化前后的精度损失
NRMSE越小,说明量化对模型精度影响越小 -
文件处理
递归扫描目录下的所有 .safetensors 文件
使用 safe_open 安全地加载模型权重
对每个张量分别进行分析
优势:
模型体积减少:4bit量化可使模型大小减少75%(例如,70B模型从140GB降至35GB)。
降低内存带宽压力:读取4bit权重所需带宽是读取16bit权重的1/4。
加速计算:许多硬件(如GPU的Tensor Cores)对低精度计算有专门优化,计算速度更快。
量化中计算参考文章:https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-quantization
Tip
量化与dropout有什么区别
# 量化(确定性数值映射)
scale = max_value / 127
quantized_value = round(original_value / scale) # 确定性转换
# Dropout(随机性掩码)
mask = random_binary_matrix(keep_probability) # 随机生成
output = input * mask # 随机置零
量化是部署优化技术,用于模型压缩和加速; Dropout是训练正则化技术,用于提高泛化能力。
框架测优化
推理系统设计:比如将LLM推理解耦为Prefill(预填充)、Decode(解码)和Caching(缓存)三个可独立扩展的资源池;
Details
P是计算密集型,D是内存带宽密集型;caching存储密集型,是一个分布式共享KV缓存。它从Prefill和Decode中分离出来,集中管理所有请求的KV Cache;由大容量、低延迟的内存或SSD组成,可能通过高速RDMA网络互联(如华为的UB);
解耦与调度:
- 一个新请求到达后,调度器将其Prefill任务发送给 Prefill池。
- Prefill池计算完Attention后,将产生的KV Cache 直接写入远端的 Caching池,然后立即释放Prefill池的资源去处理下一个请求的Prefill。
- 对于该请求的Decode任务,调度器将其发送给 Decode池。
- Decode池在生成每个Token时,通过高速网络从 Caching池 按需获取它需要的KV Cache片段。
这种架构代表了LLM推理服务的未来发展方向,从“一个设备处理所有”的集成架构,转向“专业硬件处理专业任务”的离散化、池化架构。
比如model和后处理异步化,来提升吞吐;
针对embedding模型只进行全量推理的特点,跳过kv cache相关tensor等的计算;
针对离线大批量处理场景,优化非必要cpu操作耗时,如array转list、list转tuple等;
算子测下发优化(硬件处理角度)
- 通信-通信-计算 三流并发
现有的多机多卡分布式moe推理场景下,激活集合通信,门控权重与路由专家、共享专家计算等步骤是顺序下发,导致集群利用率低,推理时延大。
Details
-
优化思路:
- 将共享专家与门控权重计算从全激活改为DP(动态规划)计算。
- 把原先有依赖关系的计算通信转换为可以并行执行的过程。
- 利用两种形态的通信(AIV, SDMA),实现“通信-通信-计算”的并发。
-
收益点:
- 提升带宽:通过两种形态通信并行,提高有效带宽。
- 减少数据量:先量化再进行通信,使通信的数据量减半。
- 节省时间:通信与计算并行,缩短总耗时。
- 降低计算量:共享专家与门控权重计算量并行后,整体计算量降至原来的1/DP倍数。
- 微批处理流水线:重叠计算与通信
Details
1. 分解阶段:将一个Micro-batch的前向传播(计算)和所需的梯度同步(通信,如All-Reduce)识别为两个独立的阶段。 2. 流水线执行: - 时间步 t:NPU正在为Micro-batch A 执行计算。 - 同时:DMA(直接内存访问)引擎正在将上一个Micro-batch B 计算好的梯度从NPU内存搬移到网络接口,准备进行通信。 3. 重叠:计算单元(Cube)和通信单元(DMA/Network)是独立的硬件部件。通过精心调度,可以让它们同时满负荷工作。
- MLA优化:算子融合、原生NZ格式KV缓存、MTP感知平铺等
- nz格式:一种专为注意力机制优化的稀疏块状存储格式,用于存储Key和Value缓存。NZ格式将KV缓存组织为更小的、对齐的数据块(Blocks)。这种格式与NPU计算单元(如3D Cube)处理数据的模式高度匹配。
计算注意力时,NPU可以直接从这种格式的缓存中高效地加载数据块进行计算,无需额外的格式转换(Transpose/Reshape)开销。 - MTP感知平铺:MTP(Multi-Thread Parallelism)指昇腾NPU内部的多线程并行架构。具体分以下三步:算法会动态分析MatMul操作的维度(M, N, K);此优化指根据NPU硬件线程的特性来智能地切分(Tiling)计算任务;确保切分后的子任务大小均匀。
- nz格式:一种专为注意力机制优化的稀疏块状存储格式,用于存储Key和Value缓存。NZ格式将KV缓存组织为更小的、对齐的数据块(Blocks)。这种格式与NPU计算单元(如3D Cube)处理数据的模式高度匹配。
- bert类模型参数量非常小,当计算量较小时,算子存在下发瓶颈,因此针对gelu算子、add_layer_norm算子做下发优化,针对add_layer_norm做二维输入的支持;
- 算子编译优化prune hidden states提前至attention算子之前,减少最后一层计算量;
Details
当前最后一层流程: norm -> qkv_proj -> rope -> attention -> o_proj -> norm -> gate_up_proj -> gelu -> down_proj -> _prune_hidden_states 将prune前移到attention之前: norm -> qkv_proj -> rope -> _prune_hidden_states -> attention -> o_proj -> norm -> gate_up_proj -> gelu -> down_proj
算子融合
-融合算子fusedDispatch和fusedCombine (新的AI矢量绕过延迟敏感的SDMA路径,替换All-to-All,改善延迟)
Details
- 传统NPU之间的All-to-All通信:
- 依赖于系统直接内存访问(SDMA)来传输数据。
- SDMA引入了较大的启动开销,在超低延迟场景中成为性能瓶颈,尤其是在解码过程中。
- AIV-Direct设计目的:
- 克服由SDMA引起的高延迟问题。
- AIV-Direct的功能:
- AI矢量核心能够通过UB互联网络直接写入远程NPU的内存,绕过延时敏感的SDMA路径。
- 消除了SDMA的启动开销,提供快速且轻量化点对点通信途径。
- 显著减少传输启动延迟,并加速NPU间的数据交换,改善了解码等延迟敏感操作的性能。
显存优化
压缩kvcache
- kvcache低精度方式
对 KV—Cache 进行 Int8量化,从而将 KV-Cache 的大小缩小30%-40%。 - 缓存优化- lru缓存
已有的样本字符不需要再计算,直接返回,比如vllm/entrypoints/chat_utils.py中 _detect_content_format中增加@lru_cache(maxsize=128) - - page attention
原理:通过逻辑 block 与物理 block 的映射,实现内存上的非连续存储(映射关系由 block table 维护)。
与传统的注意力算法不同,PagedAttention 允许在不连续的内存空间中存储连续的键和值。具体来说,PagedAttention 将每个序列的 KV 缓存划分为多个块,每个块包含固定数量的令牌的键和值。在注意力计算过程中,PagedAttention 内核会有效地识别和获取这些块。由于块不需要在内存中是连续的,因此我们可以像在操作系统的虚拟内存中一样以更灵活的方式管理键和值:可以将块视为页面,将 token 视为字节,将序列视为进程。序列的连续逻辑块通过块表映射到非连续的物理块。随着新 token 的生成,物理区块会按需分配。
创新点:
KV Cache 被切分为固定大小的 block;通过逻辑 block 与物理 block 的映射,实现非连续存储(映射关系由 block table 维护);PagedAttention 支持按需分配和回收 block,并允许多个序列共享 block。PagedAttention 使用了 copy-on-write(CoW)机制,允许多个生成样本共享大部分输入 prompt 的 KV Cache
(Reference Counting)引用计数: 跟踪内存块的共享状态,实现安全回收。
(Block-level Copy-on-Write)优化块复制操作:只有在真正要写入(修改)的时候,才会进行复制操作,这样不会污染数据
4. KV-Cache 共用
比如MQA、GQA
flash attention
原理:针对全局内存和共享存储的 I/O 速 度的不同,尽可能的避免 HBM 中读取或写入注意力矩阵。FlashAttention 目标是尽可能高效地使 用 SRAM 来加快计算速度,避免从全局内存中读取和写入注意力矩阵。
同一层级falshattention 实现的方式有哪些?
Details
Flash Attention 的核心思想是 “分块计算” 和 “核融合”。 *分块(Tiling)*:将大的 Q, K, V 矩阵分割成小的块(Tiles),这些块的大小足以被加载到 GPU 的高速 SRAM 中。 循环计算:通过双重循环,将这些小块从 HBM 加载到 SRAM,然后在 SRAM 内部进行所有的计算步骤(矩阵乘法、Softmax、矩阵乘法)。 *核融合(Kernel Fusion)*:将整个注意力计算(MatMul -> Softmax -> MatMul)融合打包成一个单独的Kernel来方便快速计算
[!CAUTION]
重计算(Recomputation):
Softmax 操作本身是全局的,因为它需要知道所有元素的值来计算归一化分母。在反向传播时,Flash Attention 不需要存储巨大的中间矩阵 S 和 P。它只存储了最终的输出 O 和统计量 l, m。当需要计算梯度时,它会利用存储的 Q, K, V, O, l, m 以及反向传播算法,重新计算出注意力矩阵 S 和 P 的块。这是一种用计算换空间的典型策略。
优势:显存占用从O(N²)降至O(N),允许处理极长序列。
flashattenton2:
从GPU硬件特性(并行度、内存层次、Warp调度)出发,重构了算法实现。
最重要的是并行化策略,增加了序列来增加并行
Details
FlashAttention-1:它的并行化主要集中在非序列维度上,即批量大小(Batch Size)和注意力头数(Heads)。对于序列本身,它采用的是串行循环的方式。flashattenton2新增在序列长度维度并行。将不同块的计算分配给不同的GPU线程块(Thread Block)。 循环顺序(外循环 vs 内循环):减少了HBM访问,q变成只要读一遍 Warpanize 设计:每个Warp独立负责计算一个子块的注意力输出,最后再通过共享内存(Shared Memory)进行归约合并。
算子融合
原理:减少内核启动开销和内存读写,提升计算效率。
Details
神经网络由许多层(算子)组成,如:Linear -> GeLU -> Linear。 在未优化的情况下,每个算子都会启动一个独立的GPU内核(Kernel),并将中间结果写回HBM,然后再由下一个算子读入。这个过程会产生大量的内核启动开销和内存读写延迟。 算子融合将多个连续的操作合并成一个单一的、定制化的内核。 例如:将 MatMul + Add(偏置) + GeLU 三个算子融合成一个 FusedMatMulBiasGeLU 内核。
Continuous Batching (连续批处理)
核心思想是:以每次前向传播(iteration)为调度单位,而不是以整个请求(sequence)为单位。
也就是已完成请求立即离开批次,新请求立即加入,批处理持续进行。
- 静态批处理 (Static Batching):在推理前,将多个请求合并为一个大的请求,然后一次性推理。这种方式可以提高吞吐量,但是需要所有请求都完成后才能返回结果,所以一般不会应用
- 动态批处理 (Dynamic Batching)
收集一批_同时到达_的请求,一起处理,完成后下一批。
其它方式
比如NZ优化,tensor.cpu同步消除
投机推理(MTP)
MTP实现的算法有哪些?
本质是大模型一次稍贵但便宜得多的并行计算,再加上K次小模型的廉价计算
Details
小模型选择: 优先是
- 同架构缩小版(最常用、最有效):
- 量化后模型
- 使用网络前几层(缺点:实现复杂,需要修改模型结构,浅层表示可能无法很好地模拟完整模型的输出。)
- 专用知识蒸馏小模型(缺点:需要额外的训练成本和数据。)
降低延迟的核心原因在于:用一次昂贵的并行计算,换取了多次昂贵的串行计算。因为大模型在这个过程中并没有自己生成任何新token!它只是在计算一组已知候选token的概率。
为什么一次并行验证比三次串行生成快得多?
硬件利用效率:GPU是一种大规模并行处理器,它最擅长做的事情就是一次性处理一大块数据。一次处理长为 L+K 的序列,其计算效率远高于串行处理3个长度分别为 L, L+1, L+2 的序列。
内核启动开销:每次启动GPU内核(Kernel)进行前向传播都有固定的开销。合并成一次内核启动,就消除了两次额外的开销。
内存读写优化:一次处理长序列的数据可以更好地利用缓存,减少与慢速显存(HBM)的通信次数。
LLM中一些优化特性
prefix-caching
PageAttention 主要管理同一个请求内部的 KV Cache,prefix caching能够共享相同提示词的多个请求
PD分离
p与d分开在不同的实例并行进行推理,收益点:
p不会阻塞d,在SLO要求下有收益;
p与d按其计算特点使用不用的并行方式
图模式
将模型的计算过程预先编译成一个静态的计算图,减少host耗时,减少device空闲
- 降低内核启动开销:减少 GPU 内核启动次数。
- 内存优化:图编译器可以更好地规划内存分配和复用。
- 算子融合:将多个小算子融合成一个大算子,减少数据搬运,提升计算效率。
chunked-prefill
将长输入切分为多个chunk处理,降低显存开销,支持更长序列;
decode不会被prefill完全阻塞,降低decode时延;平衡硬件的资源利用率,提升总体吞吐
其他重要特性
- Guided-decoding:
- 通过logit-process, 格式化控制模型输出
- Reasoning content:
- 解析返回体中的reasoning
- Function call:
- 解析返回体中的tool;通常和guided-decoding一起使用
- Multi-lora:
- 基模型和多个挂载的lora权重一起推理服务