news 2026/9/27 21:16:01

LMDeploy W8A8 量化部署实战:SmoothQuant INT8/FP8 权重量化、离线推理与在线服务全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LMDeploy W8A8 量化部署实战:SmoothQuant INT8/FP8 权重量化、离线推理与在线服务全指南
  • 人工智能
  • 大模型
  • 模型推理服务
  • 推理引擎
  • 本地部署
  • 模型量化

【免费下载链接】lmdeploy

LMDeploy is a toolkit for compressing, deploying, and serving LLMs.

项目地址:https://gitcode.com/gh_mirrors/lm/lmdeploy
点击查看免费下载

本文是一份围绕 LMDeploy 开源仓库中 W8A8(权重 8-bit + 激活 8-bit)量化能力编写的完整实战指南。文章以 docs/zh_cn/quantization/w8a8.md 为核心骨架,系统讲解如何基于 SmoothQuant 算法对 LLM 进行 INT8 / FP8 量化,并结合仓库源码(lmdeploy/lite/apis/smooth_quant.py、lmdeploy/pytorch/models/q_modules.py、lmdeploy/pytorch/kernels/cuda/w8a8_triton_kernels.py)深入剖析平滑(smoothing)、模块替换(module replacement)与动态量化推理的底层原理。读完本文,你将掌握:W8A8 量化的适用硬件与基本概念、lmdeploy lite smooth_quant命令行工具的完整参数与用法、量化模型的离线推理(pipeline)与在线服务(api_server)部署方法,以及量化流程每一步在源码中的真实实现。

W8A8 量化概述:INT8 与 FP8

W8A8 表示模型权重(Weight)以 8-bit 存储、激活值(Activation)以 8-bit 表示的量化方案。相比常见的 4-bit 权重量化(如 AWQ、GPTQ),W8A8 保留了更高的精度,同时通过 8-bit 整数(INT8)或 8-bit 浮点数(FP8)计算显著降低显存占用与访存带宽,是"压缩、部署、服务 LLM"(LMDeploy 项目定位)的重要环节。

LMDeploy 同时支持 INT8 与 FP8 两种 8-bit 量化数据类型。由于 FP8(float8_e4m3fn)依赖于新一代 GPU 的原生支持,两种数据类型的可用硬件范围不同,官方文档给出如下 NVIDIA GPU 支持矩阵:

量化类型支持的 GPU 架构代表型号
INT8Volta(sm70)V100
INT8Turing(sm75)20 系列、T4
INT8Ampere(sm80、sm86)30 系列、A10、A16、A30、A100
INT8Ada Lovelace(sm89)40 系列
INT8Hopper(sm90)H100
FP8Ada Lovelace(sm89)40 系列
FP8Hopper(sm90)H100

从表中可以看出:INT8 覆盖从 V100 到 H100 的绝大多数 NVIDIA 数据中心 GPU,而 FP8 仅支持 40 系列(Ada Lovelace)与 H100(Hopper)及更新架构。在lmdeploy/pytorch/kernels/cuda/w8a8_triton_kernels.py的__main__测试代码中也可以看到is_fp8_supported = device_map[0] >= 9的判断逻辑——FP8 测试仅在计算能力 9.x(即 Hopper)及以上的设备上执行,与文档描述一致。

安装 LMDeploy

量化、推理与服务全流程依赖完整的 LMDeploy 工具链,执行以下命令安装全部依赖:

pip install lmdeploy[all]

[all]扩展包含推理所需的 Triton 内核编译环境、服务端等组件。量化过程中会通过 Hugging Face Hub 下载模型权重与校准数据集,因此请确保网络可访问或提前准备好本地模型目录。

8-bit 权重量化三步流程

LMDeploy 的 W8A8 量化基于SmoothQuant思想,整体流程可以拆解为三步:

  1. 权重平滑(Weight Smoothing):对语言模型的权重进行平滑处理,把激活值中的离群点(outliers)迁移到权重侧,使激活分布更"规整",从而让后续 8-bit 量化更加稳定、精度损失更小。
  2. 模块替换(Module Replacement):将原模型DecoderLayer中的RMSNorm模块替换为QRMSNorm,将nn.Linear模块替换为QLinear。这两个量化模块定义在 lmdeploy/pytorch/models/q_modules.py 中,负责在推理时完成"归一化+动态量化"与"8-bit 矩阵乘+反量化"。
  3. 保存量化模型(Save Quantized Model):完成上述替换后,将新模型、tokenizer 与量化配置保存到工作目录,得到可直接被 LMDeploy 加载推理的量化 checkpoint。

这三步在源码中被封装为一个整体。打开 lmdeploy/lite/apis/smooth_quant.py 可以看到smooth_quant函数入口的完整签名:

def smooth_quant(model: str, work_dir: str = './work_dir', calib_dataset: str = 'wikitext2', calib_samples: int = 128, calib_seqlen: int = 2048, search_scale: bool = False, batch_size: int = 1, w_bits: int = 8, dtype: Literal['float16', 'bfloat16', 'auto'] = 'auto', device: str = 'cuda', quant_dtype: Literal['int8', 'fp8', 'float8_e4m3fn', 'float8_e5m2'] = 'int8', revision: str = None, download_dir: str = None, trust_remote_code: bool = False):

其中--quant-dtype参数用于控制量化结果是 8-bit 整数还是浮点数类型:int8对应torch.int8,fp8是float8_e4m3fn的简写。源码第 33-36 行明确实现了这一映射:

if quant_dtype == 'fp8': quant_dtype = 'float8_e4m3fn' quant_dtype = getattr(torch, quant_dtype, torch.int8)

同时,函数第 42 行通过assert q_dtype_info.bits == w_bits校验量化数据类型的位宽必须与w_bits(默认 8)一致,防止误用。

命令行入口

lmdeploy lite smooth_quant是上述三步的 CLI 封装,命令解析逻辑定义在 lmdeploy/cli/lite.py,其子命令smooth_quant最终调用 lmdeploy/lite/apis/smooth_quant.py 中的同名函数。更多参数细节可执行lmdeploy lite smooth_quant --help查看。

以下示例分别演示了 int8 与 fp8 两种量化方式(以 InternLM2.5-7B-Chat 为例):

INT8 量化:

lmdeploy lite smooth_quant internlm/internlm2_5-7b-chat --work-dir ./internlm2_5-7b-chat-int8 --quant-dtype int8

FP8 量化:

lmdeploy lite smooth_quant internlm/internlm2_5-7b-chat --work-dir ./internlm2_5-7b-chat-fp8 --quant-dtype fp8

--quant-dtype的合法取值在 lmdeploy/cli/utils.py 中定义为['int8', 'float8_e4m3fn', 'float8_e5m2', 'fp8'],其中fp8等价于float8_e4m3fn;float8_e5m2是另一种 FP8 格式,精度范围不同,通常用于对范围要求更高的场景。

命令行参数速查表

结合 lmdeploy/cli/lite.py 与smooth_quant函数签名,smooth_quant子命令支持以下主要参数:

参数默认值说明
model必填模型名(Hugging Face Hub 上的仓库名)或本地 HF 格式模型路径
--work-dir./work_dir量化模型的输出目录
--quant-dtypeint8量化数据类型:int8/float8_e4m3fn/float8_e5m2/fp8
--calib-datasetwikitext2校准数据集,支持wikitext2、c4、pileval、gsm8k、neuralmagic_calibration、open-platypus、openwebtext
--calib-samples128校准样本数量
--calib-seqlen2048校准样本的序列长度
--calib-batchsize1校准推理的 batch size,显存紧张时调小,追求速度时可调大
--calib-search-scale关闭是否搜索平滑比例(scale ratio),开启后使用 AWQ 式比例搜索而非固定 0.5
--dtypeauto加载权重与校准推理的精度:float16/bfloat16/auto
--devicecuda量化计算设备,支持cuda或npu
--revision无模型版本(分支名、tag 或 commit id)
--download-dir无模型权重下载目录,默认使用 Hugging Face 缓存目录
--trust-remote-code关闭加载需要远端代码的模型时开启

量化流程源码级解析

下面结合源码逐环节说明lmdeploy lite smooth_quant内部做了什么:

第一步:加载模型并校准。函数先调用 lmdeploy/lite/apis/calibrate.py 中的calibrate,加载 HF 模型与 tokenizer,在wikitext2等校准数据集上以少量样本(默认 128 条、seqlen 2048)前向推理,统计各层激活值的分布,并把统计结果导出为work_dir/inputs_stats.pth。校准时的关键设计是_prepare_for_calibrate(calibrate.py)——将目标DecoderLayer与lm_head留在 CPU 上,其余模块搬到 GPU,从而显著降低校准阶段的显存占用。

需要说明的是,校准与量化仅支持特定模型架构。LAYER_TYPE_MAP/NORM_TYPE_MAP(calibrate.py)中注册了 InternLM2/3、Qwen2/3、Qwen3Moe、Qwen3_5、Llama、Phi3、ChatGLM、Mixtral、Qwen2VL、Qwen2_5_VL、Mistral 等架构;若模型类型不在映射表中,会直接抛出RuntimeError提示不支持。

第二步:权重平滑。从inputs_stats.pth读取激活统计act_scales = inp_stats['absmax'](smooth_quant.py)。随后根据search_scale分支:

  • 默认(search_scale=False):调用smooth_layers(lmdeploy/lite/quantization/awq.py),按NORM_FCS_MAP/FC_FCS_MAP描述的层间关系,对每个RMSNorm及其下游线性层、每个线性层及其下游层执行平滑。
  • 开启search_scale:调用awq_layers(awq.py),使用校准阶段搜索出的逐层平滑比例ratios替代固定比例。

平滑的核心数学实现在smooth_ln_fcs(awq.py):默认平滑比例alpha=0.5,平滑系数由act_scales.pow(alpha) / w_scales.pow(1 - alpha)计算得到,然后对 RMSNorm 权重执行ln.weight.div_(scales)、对下游线性层执行fc.weight.mul_(scales.view(1, -1)),从而把激活离群点"搬"进权重。代码中还处理了多种边界情况:ln.weight为零的位置跳过平滑、GQA(如 LLaMA2 的 v_proj 与 o_proj)维度不匹配时直接返回、Qwen/Phi3 融合型 QKV/GateUp 只缩放 V 与 Up 部分等,并在每层结束后打印 GPU 峰值显存。

第三步:模块替换与保存。平滑完成后,通过collect_target_modules收集所有nn.Linear与 RMSNorm 模块,逐一执行(smooth_quant.py):

for modules, q_cls in ((fcs, QLinear), (rmsnorms, QRMSNorm)): for name, module in modules.items(): ... q_module = q_cls.from_float(module, quant_dtype=quant_dtype) parent_name, _, child_name = name.rpartition('.') parent = model.get_submodule(parent_name) setattr(parent, child_name, q_module)

其中from_float负责把浮点权重真正量化成 8-bit 并保存 scale(见下文"推理内核"一节)。名中包含lora或模型架构注册的跳过模式(MODELS.get(arch).skipped_modules())的模块不会被量化,而是记录进quantization_config['modules_to_not_convert']。最后,量化配置以quant_method='smooth_quant'、quant_dtype字段写入model.config,并通过model.save_pretrained(work_dir, safe_serialization=True)与tokenizer.save_pretrained(work_dir)保存(smooth_quant.py)。对于视觉语言模型(VL),则走save_vl_model分支,一并保存视觉塔与语言模型。

量化模型的离线推理

量化完成后,得到的就是一个标准 HF 格式的 checkpoint(外加quantization_config标记)。LMDeploy 的 pipeline 接口可以直接加载它,仅需几行代码即可完成离线推理:

from lmdeploy import pipeline, PytorchEngineConfig engine_config = PytorchEngineConfig(tp=1) pipe = pipeline("internlm2_5-7b-chat-int8", backend_config=engine_config) response = pipe(["Hi, pls intro yourself", "Shanghai is"]) print(response)

要点说明:

  • backend_config指定 PyTorch 推理后端(W8A8 量化模型走 PyTorch 引擎),tp=1表示单卡张量并行;显存或性能需要时可按2^n增大tp。
  • 模型路径既可以是上文--work-dir输出的本地目录,也可以是已经上传到 Hub 的量化模型仓库名。
  • 关于 pipeline 的完整用法(batch 推理、流式输出、多模态输入等),参见 pipeline 指南。

推理服务部署:api_server 一键服务化

除离线推理外,LMDeploy 的api_server支持把量化模型一键封装为服务,对外提供兼容 OpenAI 规范的 RESTful API。启动命令如下:

lmdeploy serve api_server ./internlm2_5-7b-chat-int8 --backend pytorch
  • 服务默认端口为23333。
  • --backend pytorch与离线推理保持一致,指定 PyTorch 后端以加载 W8A8 量化模型。

服务启动后,可在终端通过内置的api_client与 server 对话:

lmdeploy serve api_client http://0.0.0.0:23333

此外,访问http://0.0.0.0:23333可以直接在浏览器中打开Swagger UI,在线阅读并试用各接口;各接口(如/v1/chat/completions、/v1/completions)的定义与使用方法可查阅 api_server 文档。

推理内核原理:QRMSNorm 与 QLinear 的动态量化

W8A8 量化模型在推理时不再走原版RMSNorm+nn.Linear,而是由量化模块在前向过程中动态量化激活值,这是 SmoothQuant 方案与静态量化(如 WeightOnly、静态 FP8)的核心区别。量化模块定义在 lmdeploy/pytorch/models/q_modules.py:

  • QTensor(q_modules.py):封装"量化后的张量 + scale(+ zero_point)"的数据类,并把不存在的属性转发给内部原始 tensor,便于无缝接入后续算子。
  • QRMSNorm(q_modules.py):forward中先完成传统 RMS 归一化,再调用rms_norm_dynamic_quant对归一化输出做逐 token 动态量化,返回QTensor。
  • QLinear(q_modules.py):权重在from_float时经per_channel_quant量化为 8-bit 并保存逐通道 scale(buffer,float32);forward中,若输入是普通 tensor 则先做逐 token 量化(per_token_quant_int8),若输入已是QTensor(来自上一层QRMSNorm)则直接复用其量化结果,然后调用matmul_kernel_dynamic_quant完成 8-bit 矩阵乘,最后按rms_scale * linear_scale反量化回 float16 输出。

这些算子的 Triton 实现集中在 lmdeploy/pytorch/kernels/cuda/w8a8_triton_kernels.py:

  • rms_norm_dynamic_quant(第 463-513 行):RMS 归一化 + 逐 token 动态量化 kernel,支持带残差融合(add_rms_norm_quant_kernel)。
  • per_token_quant_int8(第 258-290 行):激活值按absmax / Q_MAX求 scale 并量化,Q_MAX由torch.iinfo/torch.finfo依据量化类型动态确定;INT8 会 round 到整数,FP8 则直接按浮点截断。
  • matmul_kernel_dynamic_quant(第 157-216 行):8-bit GEMM Triton kernel,_linear/_linear_add通过@triton.autotune在BLOCK_M×BLOCK_N×BLOCK_K多组配置间自动择优,累加器根据输入是否为浮点类型选择fp32或int32,最终c = c * rms_scale * linear_scale完成反量化,可选残差与 bias 融合。
  • per_channel_quant为逐通道权重量化(权重量化在from_float阶段一次性完成,属于静态量化侧)。

值得一提的还有 lmdeploy/pytorch/kernels/default/w8a8_kernels.py 提供的默认(非 Triton)实现,以及lmdeploy/pytorch/kernels/w8a8_triton_kernels.py中通过FunctionDispatcher按后端分发算子的机制——同一个接口在 CUDA、默认等不同后端下会自动路由到对应实现。lmdeploy/pytorch/kernels/cuda/w8a8_triton_kernels.py的__main__中还内置了test_rms_and_linear/test_per_token_quant数值一致性校验与bench_rms_and_linear基准测试,可直接作为内核正确性与性能的参考验证工具。

总结与注意事项

围绕 W8A8 量化,本文覆盖了从原理、量化、推理到服务的完整链路。实际使用时有几点值得注意:

  1. 硬件先行:FP8 量化仅适用于 Ada Lovelace(40 系列)与 Hopper(H100)及更新架构;老卡请选择--quant-dtype int8。
  2. 校准数据与样本量:默认wikitext2与 128 个样本即可获得较好效果;分布与目标场景差异大时可换用c4、gsm8k等数据集(完整支持列表见 calibrate.py)。
  3. 精度选项:--calib-search-scale会额外搜索每层最优平滑比例(AWQ 式),通常能进一步降低精度损失,但校准耗时更长。
  4. 显存控制:校准阶段大模型请保持默认--calib-batchsize 1,必要时结合_prepare_for_calibrate的 CPU/GPU 分层放置机制控制峰值显存。
  5. 模型架构支持:量化前请确认模型架构已注册在LAYER_TYPE_MAP/NORM_TYPE_MAP(calibrate.py),Mixtral 等 MoE 模型会自动展开专家层映射(update_moe_mapping,calibrate.py)。
  6. 推理/服务统一走 PyTorch 后端:离线推理与服务部署均需显式指定PytorchEngineConfig或--backend pytorch。

如需进一步了解 SmoothQuant 之外的其他量化路径(如 AWQ 4-bit 权重量化、GPTQ、KV Cache 量化),可继续阅读 W4A16 量化指南 与 KV Cache 量化指南。

  • 人工智能
  • 大模型
  • 模型推理服务
  • 推理引擎
  • 本地部署
  • 模型量化

【免费下载链接】lmdeploy

LMDeploy is a toolkit for compressing, deploying, and serving LLMs.

项目地址:https://gitcode.com/gh_mirrors/lm/lmdeploy
点击查看免费下载

相关推荐

上一篇:MSYS2高级用法:CI/CD集成、多环境管理和自动化构建技巧
下一篇:深度解析OpenCore Legacy Patcher:为旧Mac设备解锁现代macOS的完整技术方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 21:07:38

mybatis中的sql映射文件(1)—resultType

目录0.前言1.resultType解析1.1.基本类型举例:1.2JavaBean类型1.3List类型1.4Map类型0.前言 mybaits中sql映射文件是一个xml文件,里面记录的和数据库交互的各种信息,相当于sql语句,在写这些语句的时候,遇到很多不同的参数&#x…

作者头像 李华