- 人工智能
- 大模型
- 模型推理服务
- 推理引擎
- 本地部署
- 模型量化
【免费下载链接】lmdeploy
LMDeploy is a toolkit for compressing, deploying, and serving LLMs.
本文是一份围绕 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 架构 | 代表型号 |
|---|---|---|
| INT8 | Volta(sm70) | V100 |
| INT8 | Turing(sm75) | 20 系列、T4 |
| INT8 | Ampere(sm80、sm86) | 30 系列、A10、A16、A30、A100 |
| INT8 | Ada Lovelace(sm89) | 40 系列 |
| INT8 | Hopper(sm90) | H100 |
| FP8 | Ada Lovelace(sm89) | 40 系列 |
| FP8 | Hopper(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思想,整体流程可以拆解为三步:
- 权重平滑(Weight Smoothing):对语言模型的权重进行平滑处理,把激活值中的离群点(outliers)迁移到权重侧,使激活分布更"规整",从而让后续 8-bit 量化更加稳定、精度损失更小。
- 模块替换(Module Replacement):将原模型
DecoderLayer中的RMSNorm模块替换为QRMSNorm,将nn.Linear模块替换为QLinear。这两个量化模块定义在 lmdeploy/pytorch/models/q_modules.py 中,负责在推理时完成"归一化+动态量化"与"8-bit 矩阵乘+反量化"。 - 保存量化模型(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 int8FP8 量化:
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-dtype | int8 | 量化数据类型:int8/float8_e4m3fn/float8_e5m2/fp8 |
--calib-dataset | wikitext2 | 校准数据集,支持wikitext2、c4、pileval、gsm8k、neuralmagic_calibration、open-platypus、openwebtext |
--calib-samples | 128 | 校准样本数量 |
--calib-seqlen | 2048 | 校准样本的序列长度 |
--calib-batchsize | 1 | 校准推理的 batch size,显存紧张时调小,追求速度时可调大 |
--calib-search-scale | 关闭 | 是否搜索平滑比例(scale ratio),开启后使用 AWQ 式比例搜索而非固定 0.5 |
--dtype | auto | 加载权重与校准推理的精度:float16/bfloat16/auto |
--device | cuda | 量化计算设备,支持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 量化,本文覆盖了从原理、量化、推理到服务的完整链路。实际使用时有几点值得注意:
- 硬件先行:FP8 量化仅适用于 Ada Lovelace(40 系列)与 Hopper(H100)及更新架构;老卡请选择
--quant-dtype int8。 - 校准数据与样本量:默认
wikitext2与 128 个样本即可获得较好效果;分布与目标场景差异大时可换用c4、gsm8k等数据集(完整支持列表见 calibrate.py)。 - 精度选项:
--calib-search-scale会额外搜索每层最优平滑比例(AWQ 式),通常能进一步降低精度损失,但校准耗时更长。 - 显存控制:校准阶段大模型请保持默认
--calib-batchsize 1,必要时结合_prepare_for_calibrate的 CPU/GPU 分层放置机制控制峰值显存。 - 模型架构支持:量化前请确认模型架构已注册在
LAYER_TYPE_MAP/NORM_TYPE_MAP(calibrate.py),Mixtral 等 MoE 模型会自动展开专家层映射(update_moe_mapping,calibrate.py)。 - 推理/服务统一走 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.
相关推荐
LMDeploy W8A8 权重量化实战指南:SmoothQuant 实现 INT8/FP8 模型量化与部署
LMDeploy W8A8 权重量化实战指南:SmoothQuant 实现 INT8/FP8 模型量化与部署 W8A8(Weight 8 bit, Activa
人工智能大模型模型推理服务推理引擎本地部署模型量化vLLM-Omni Int8 W8A8 量化指南:Diffusion Transformer 在线量化与序列化权重加载实战
vLLM Omni Int8 W8A8 量化指南:Diffusion Transformer 在线量化与序列化权重加载实战 本篇技术指南聚焦 vLLM Omni
人工智能大模型模型推理服务多模态语音音频媒体生成本地部署vLLM FP8 W8A8 量化实战:用 llm-compressor 离量化与在线动态量化的完整指南
vLLM FP8 W8A8 量化实战:用 llm compressor 离量化与在线动态量化的完整指南 FP8(8 位浮点)量化是让 LLM 推理同时获得显存缩
人工智能大模型模型推理服务推理引擎本地部署
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考