news 2026/9/10 14:28:20

SGLang ModelSlim 量化支持解析:基于 quant_model_description.json 的 NPU 自动量化加载方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SGLang ModelSlim 量化支持解析:基于 quant_model_description.json 的 NPU 自动量化加载方案

SGLang ModelSlim 量化支持解析:基于 quant_model_description.json 的 NPU 自动量化加载方案

【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang

ModelSlim 是昇腾 NPU 生态中面向大模型的压缩量化工具,其产物以 compressed_tensors 风格组织。SGLang 在 python/sglang/srt/layers/quantization/modelslim/ 目录中实现了对 ModelSlim 量化模型的开箱即用支持:启动引擎时无需显式指定--quantization modelslim,推理框架会从权重目录中的quant_model_description.json自动解析量化方式并按层装配对应算子。读完本文,你将掌握 ModelSlim 量化格式的识别方式、SGLang 支持的量化方案清单、自动检测的实现原理,以及在不同模型与算子形态下的加载行为。

ModelSlim 与 SGLang 的对接方式

ModelSlim(msmodelslim)是昇腾(Ascend)上用于大模型量化的压缩模块,其产物遵循 compressed_tensors 的格式约定:权重目录中携带一份描述每个张量量化方式的quant_model_description.json,各层的weightweight_scale等参数以量化后的形态直接落盘。SGLang 不需要预先知道某个 checkpoint 用了哪种量化算法,只要识别到这份描述文件,就可以据此完成加载。

因此 SGLang 中 ModelSlim 支持的核心设计是"免参数自动检测":对于 ModelSlim 量化的模型,直接加载权重即可,不需要在启动命令中添加--quantization modelslim,量化方法会从权重中下载的quant_model_description.json自动解析。这一点在 README 中被明确强调。

从源码看,这一机制由ModelSlimConfig实现,它在 python/sglang/srt/layers/quantization/modelslim/modelslim.py 中定义,并通过 量化模块注册表 以"modelslim"名称注册。同时,命令行参数选项 中也将modelslim列为可选量化方式(标注为 "for NPU"),因此它既支持自动检测,也保留了显式指定的兼容入口。

支持的量化方案全景

ModelSlim 以 compressed_tensors 格式开发,覆盖线性层与 MoE 层两大类算子,其核心量化方案如下:

类别方案对应实现类(schemes/ 目录)
线性层W4A4 动态线性(W4A4_DYNAMIC)modelslim_w4a4_int4.py 中的ModelSlimW4A4Int4
线性层W8A8 静态线性(W8A8)modelslim_w8a8_int8.py 中的ModelSlimW8A8Int8
线性层W8A8 动态线性(W8A8_DYNAMIC)同上,ModelSlimW8A8Int8的动态分支
线性层W4A4_MXFP4modelslim_mxfp4.py 中的ModelSlimMXFP4Scheme
线性层W4A8_MXFPmodelslim_mxfp4_w4a8.py 中的ModelSlimMXFP4W4A8Scheme
线性层W8A8_MXFP8modelslim_mxfp8.py 中的ModelSlimMXFP8Scheme
MoEW4A4 动态 MoE(W4A4_DYNAMIC)modelslim_w4a4_int4_moe.py 中的ModelSlimW4A4Int4MoE
MoEW4A8 动态 MoE(W4A8_DYNAMIC)modelslim_w4a8_int8_moe.py 中的ModelSlimW4A8Int8MoE
MoEW8A8 动态 MoE(W8A8_DYNAMIC)modelslim_w8a8_int8_moe.py 中的ModelSlimW8A8Int8MoE
MoEW4A4_MXFP4 / W4A8_MXFP / W8A8_MXFP8modelslim_w4a4_mxfp4_moe.py、modelslim_w4a8_mxfp4_moe.py、modelslim_mxfp8_moe.py

schemes 子目录中的 12 个实现文件与 schemes/init.py 的导出一一对应,覆盖了 int8/int4 整数方案与 MXFP4/MXFP8 浮点块缩放方案两大路线。

从方案到算子的映射集中在ModelSlimConfig.get_linear_scheme()get_moe_scheme()中(modelslim.py):

  • 线性层quant_model_description.json{prefix}.weight的取值匹配:W4A4_DYNAMICModelSlimW4A4Int4W8A8/W8A8_DYNAMICModelSlimW8A8Int8W8A8_MXFP8ModelSlimMXFP8SchemeW4A8_MXFPModelSlimMXFP4W4A8SchemeW4A4_MXFP4ModelSlimMXFP4Scheme;未匹配到时打日志告警并返回None,此时该层回退为不量化(UnquantizedLinearMethod)。
  • MoE 层同时读取w13(gate_proj + up_proj)与w2(down_proj)两组投影的描述,且要求 w13 两个投影的量化方式必须一致,否则抛出Mismatched ModelSlim quantization for W13错误。

自动检测:quant_model_description.json 的读取链路

ModelSlimConfig通过get_config_filenames()声明其配置文件名仅为quant_model_description.json(modelslim.py)。模型加载时,框架在权重目录中查找该文件;一旦存在,from_config()即构建ModelSlimConfig并接管后续所有层的量化装配,无需用户传参。这正是"直接加载模型权重即可"的底层实现。

quant_model_description.json的本质是一个键值描述:键是形如layers.0.self_attn.qkv_proj.weight的层路径,值是量化方式名(如W8A8_DYNAMICW4A4_DYNAMICFLOAT等)。ModelSlimConfig.__init__会将其解析为self.quant_description,并额外维护:

  • ignore列表:描述中被标记为不量化的层;
  • packed_modules_mapping:融合模块(如qkv_projq_proj/k_proj/v_proj融合)与子投影之间的映射,用于把融合层前缀正确解析到量化描述上。

由于不同模型的 checkpoint 命名存在差异,__init___quant_prefix_candidates()/_resolve_quant_prefix()(modelslim.py)做了大量别名归一化,可推断其设计目标是尽可能无感兼容各类 ModelSlim 产物:

  • 为每个block_sparse_moe.*键同时生成mlp.*别名(Kimi-K3 等模型内部用mlp,checkpoint 却保留 HF 的block_sparse_moe层级);
  • 为带/不带language_model.前缀的键互建别名(兼容多模态 checkpoint 的外层前缀);
  • 处理 MTP 结构:将 DSpark checkpoint 中的mtp.<stage>.*权重名映射为运行时草稿模型使用的stages.<stage>.*命名,并同步替换attn→self_attnffn→mlpw1/w2/w3→gate_proj/down_proj/up_proj等投影名(modelslim.py)。

此外,当quant_config中出现hc_head_前缀的键时,会识别为 DeepSeek-V4 权重,并通过DeepseekV4ForCausalLM.remap_weight_name_to_dpsk_hf_format重映射为 HF 命名。

线性层实现:以 W4A4 与 W8A8 为例

所有线性层 scheme 都继承自抽象基类ModelSlimLinearScheme(modelslim_scheme.py),它约定三个抽象方法:create_weights(按方案创建量化参数)、process_weights_after_loading(权重加载后的后处理)、apply_weights(量化前向计算)。

W4A4 动态线性(ModelSlimW4A4Int4:权重以 int8 张量承载 4-bit 打包数据(启用SGLANG_NPU_W4A4_NEW_PACKING环境变量时输出维度减半,即每字节打包 2 个 4-bit 值),并注册weight_scaleweight_offset两个逐通道参数(形状[out, 1])。前向计算委托给硬件后端 NPU 的NPU_W4A4DynamicLinearMethod内核。

W8A8 线性(ModelSlimW8A8Int8:权重为 int8,weight_scale/weight_offset为逐通道参数。静态(W8A8)与动态(W8A8_DYNAMIC)的差异在于:静态分支额外注册input_scaleinput_offset(逐张量)与quant_bias(int32 逐通道)以及反量化缩放deq_scale,动态分支则无需这些输入量化参数。静态分支在 bf16 下使用 float32 的deq_scale,fp16 下使用 int64,其他 dtype 会直接报错——这体现了 NPU 内核对反量化精度的硬性要求。

MXFP4 / MXFP8 路线ModelSlimMXFP4Scheme处理 packed-FP4 权重(uint8,形状[out, in//2],每字节两个 FP4 值),块缩放为 UE8M0 格式 uint8(形状[out, in//32],group_size=32);ModelSlimMXFP8Scheme处理 float8_e4m3fn 权重与 uint8 块缩放(形状[out, in//32])。两者均将后处理与前向委托给 NPU 内核(NPUSingleLevelMXFP4OfflineLinearMethodNPUMXFP8LinearMethod),离线权重在加载后仅做转置/重排,前向使用npu_quant_matmulgroup_sizes=[1,1,32]执行 MX 格式矩阵乘。

MoE 层实现:w13 与 w2 双组装配

ModelSlim 的 MoE 支持通过ModelSlimFusedMoEMethod与一对ModelSlimMoEScheme实例完成。每个 MoE 层创建两个 scheme 实例:weight_prefix="w13"负责 gate + up 融合投影,weight_prefix="w2"负责 down 投影。

以 modelslim_w4a8_int8_moe.py 的ModelSlimW4A8Int8MoE为例:

  • 权重视图:w13[num_experts, intermediate, hidden]w2[num_experts, hidden//2, intermediate](int8);w13的 scale/offset 为[num_experts, 2*intermediate, 1]w2[num_experts, hidden, 1](float32)。
  • group_size=0表示逐通道量化(is_per_channel_weight=True);非逐通道时额外注册_weight_scale_second/_weight_offset_second(形状含in_features // group_size维)。
  • activation_use_clip控制激活裁剪路径,此时_scale_bias参数生效(w2 组的 bias 尾维为16 // tp_size,与张量并行切分相关)。
  • 权重加载后统一调用NPUW4A8Int8MoEMethod.process_weights_after_loading(layer, weight_prefix)完成分组处理。

ModelSlimW4A4Int4MoE(modelslim_w4a4_int4_moe.py)的维度同样受SGLANG_NPU_W4A4_NEW_PACKING影响:启用时w13权重形状为[num_experts, intermediate, hidden],未启用时按[num_experts, 2*intermediate, hidden]展开,scale/offset 形状随权重对齐。

get_moe_scheme中,方案名到类的映射表(moe_quant_schemes)覆盖W4A4_MXFP4W4A8_MXFPW4A4_DYNAMICW4A8_DYNAMICW8A8_DYNAMICW8A8_MXFP8六种组合;若某层在描述文件中找不到匹配键,会抛出包含全部尝试过的键模式的详细报错,便于定位 checkpoint 命名问题。

前向执行上,ModelSlimFusedMoEMethod.applyw13/w2的 weight、scale、offset(以及可选的 scale_bias、weight_bias 等)封装为AscendQuantInfo,交由MoeRunner统一调度路由、激活与归约(modelslim.py)。此外,若 MoE 层的路由 gate 需要量化,模型侧也会按ModelSlimConfig判定:例如 qwen3_moe.py 中,当量化方式为modelslim时路由 gate 遵循描述文件驱动(仅离线路径)。

与其他模块的联动与约束

  • RMSNorm bias 补丁:W8A8 静态量化要求 RMSNorm 输出带 bias 用于后续量化。ModelSlimConfig在检测到描述文件中存在norm.bias键时,通过apply_module_patchsglang.srt.layers.layernorm.RMSNorm注入__init__(增加零初始化 bias 参数)与forward_npu(调用sgl_kernel_npu.norm.add_rmsnorm_bias完成带 bias 的归一化)两个包装函数(modelslim.py)。
  • 跳过层判断is_layer_skipped依据描述中FLOAT标记决定某层是否走UnquantizedLinearMethod;对融合层,要求其所有子投影量化状态一致,否则报错。
  • 模型集成ModelSlimConfig已被 deepseek_v4_nextn.py、kimi_k25.py、kimi_vl_moonvit.py 等多模态与 MoE 模型引用;supports_kimi_k3_quantized_latent_projections = True表明其支持 Kimi-K3 的量化潜在投影。
  • 平台约束:ModelSlim 是 NPU 专属量化类型,线性层方法继承自_NPULinearMethodBase,内核均来自sglang.srt.hardware_backend.npu硬件后端,因此该模块面向昇腾 NPU 推理场景。README 同时声明该模块包含 w4a4/w8a8 的单元测试覆盖。

使用建议

  • 对于 ModelSlim 产出的 checkpoint,直接使用常规加载流程即可,无需额外传参;自动检测依赖权重目录中的quant_model_description.json存在且命名正确。
  • 若在非 NPU 环境或描述文件缺失/命名异常时遇到问题,可先确认该模型确为 ModelSlim 量化产物,再检查quant_model_description.json{层前缀}.weight的取值是否属于上表所列方案名。
  • 需要排查某层装配情况时,可关注引擎日志中的Using ModelSlimXXXScheme/Using ModelSlimXXXMoE ... for W13/W2提示(logger.info_once输出,modelslim.py),它们直接反映该层最终选中的量化算子。
  • 相关源码集中在 modelslim/ 目录,schemes 子目录为各方案实现,入口与装配逻辑见 modelslim.py,NPU 内核实现可进一步查阅 hardware_backend/npu/quantization 目录下的linear_method_npu.pymoe_methods.py等文件。

【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang

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

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

Filament 表格布局完全指南:从移动端堆叠到自定义行布局

Filament 表格布局完全指南&#xff1a;从移动端堆叠到自定义行布局 【免费下载链接】filament A powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire 项目地址: https://gitcode.com/GitHub_Trending/fi/filamen…

作者头像 李华