前言

大模型推理的成本问题一直困扰着工程团队。以DeepSeek-V4为例,其MoE架构包含大量专家网络,原始权重以FP8和MXFP4混合格式存储,在Atlas A2和A3系列昇腾NPU上无法直接运行低比特运算单元。CANN生态中的AMCT(Ascend Model Compression Toolkit)正是为解决这一矛盾而生——它作为昇腾NPU原生的模型压缩工具包,能将FP8/MXFP4权重转换为INT8等硬件友好格式,使模型在昇腾NPU上启用低比特运算,从而获得体积缩减和推理加速的双重收益。AMCT于2025年12月首次上线,2026年持续迭代更新,目前已支持INT8、INT4、MXFP8、MXFP4、HiFloat8五种量化精度,PTQ算法覆盖Min-Max、AWQ、GPTQ、SmoothQuant四种主流方案,并且原生支持DeepSeek-V4、Qwen3.6-MoE等前沿大模型的量化部署。量化后模型体积可缩减约50%(INT8)或约75%(INT4),这对动辄数百GB权重的大模型而言,意味着存储和内存带宽的巨大节省。本文将以DeepSeek-V4模型的INT8量化为线索,完整走通从环境配置到NPU部署的全流程,涵盖安装构建、算法选型决策、量化脚本执行、精度验证问题定位、以及amct_ops自定义算子的接入方法。

amct的安装与PyTorch环境适配

AMCT的构建依赖CANN Toolkit和torch_npu的紧密配合,环境准备阶段需要确认几个关键版本约束。Python版本不低于3.9,PyTorch选择2.7.1或2.1.0且必须配套对应版本的torch_npu,CANN Toolkit不低于8.5.0且需提前安装NPU驱动和固件,GCC不低于7.3,CMake不低于3.16(官方推荐3.20以避免某些构建警告),patch不低于2.7。这些版本约束并非随意设定,而是由AMCT内部编译流程决定的——构建过程会链接CANN的算子库和torch_npu的ATen扩展,任何版本错配都会在运行时暴露为符号找不到或段错误等难以定位的问题。尤其需要注意的是CANN Toolkit和CANN Ops必须同时安装且版本一致,仅安装Toolkit而缺少Ops会导致AMCT编译时找不到自定义算子的头文件,报出形如"fatal error: ascendc/ascendc_kernel.h: No such file or directory"的错误。NPU驱动和固件的版本也需要与CANN版本匹配,驱动版本过低会导致设备初始化失败,固件版本过低则可能缺少特定算子的硬件支持。

源码构建流程分为拉取代码、编译打包、安装验证三个阶段:

git clone https://atomgit.com/cann/amct.git
cd amct
bash build.sh --torch
pip3 install build_out/amct_pytorch-1.1.0-py3-none-linux_aarch64.tar.gz --user
python3 -c "import amct_pytorch as amct; print('AMCT installed')"

build.sh --torch triggers the PyTorch backend compilation, producing a tar.gz that must be installed via pip; the --user flag avoids system-wide permission issues, and the verification import confirms the native extension loaded correctly against the matched torch_npu version.

构建过程中有两个常见陷阱值得单独说明。其一是pip版本高于25.2时需要追加--no-build-isolation参数,否则pip的构建隔离环境找不到已安装的torch,触发ModuleNotFoundError: No module named 'torch'。这是因为AMCT的setup.py在构建阶段需要导入torch来获取头文件路径和库路径,隔离环境切断了这一依赖链。其二是CANN版本与torch_npu版本必须严格对齐——CANN 8.5.0对应torch_npu的特定发布版本,版本错配会在运行时抛出算子注册失败的异常。开发者应在CANN官方文档中查对版本兼容矩阵,切勿混装。

对于不具备物理NPU设备的开发者,AMCT提供了一站式平台快速体验路径。该平台内部已集成完整的CANN环境,可直接在Atlas A3上运行量化样例,省去本地环境搭建的繁琐步骤。DeepSeek-V4和Qwen3.6-MoE均有一站式平台的快速启动文档,开发者只需关注量化参数配置,无需操心底层驱动和工具链的安装。在一站式平台上,环境变量(ASCEND_HOME_PATH、LD_LIBRARY_PATH等)均已预设完毕,AMCT的安装也简化为pip install一行命令,极大降低了上手门槛。

PTQ量化算法选型:Min-Max/AWQ/GPTQ/SmoothQuant各自的适用场景

AMCT支持四种PTQ量化算法,各有其适用边界和精度-开销权衡。理解这些算法的核心原理和局限,才能在具体模型和硬件约束下做出合理选择。

Min-Max是最朴素的权重量化算法,直接取权重的最大值和最小值作为量化范围,将浮点值线性映射到目标比特的整数区间。它的计算开销最小,不需要校准数据,适合对精度不敏感的CNN类模型或作为基线对照实验。Min-Max支持INT8权重量化(W8)和INT8全量化(W8A8),但不支持INT4精度。当模型权重分布接近均匀时,Min-Max的精度损失可控;一旦权重中出现明显的离群值,量化范围被少数极端值拉大,正常值的量化粒度变粗,误差会急剧放大。因此Min-Max在大模型场景下通常只作为快速验证手段,而非最终部署方案。

AWQ(Activation-aware Weight Quantization)的核心洞察是:并非所有权重对量化误差的敏感度相同,仅保护约1%的显著权重即可大幅减少整体误差。它通过网格搜索在预设范围内寻找最优缩放因子,对显著权重进行放大后再执行量化,通过缩小量化间隔来降低这些关键权重的误差。AWQ同时支持INT8和INT4权重量化,且只需少量校准数据(通常几百条即可),是大模型仅权重量化的首选方案之一。AWQ的局限在于它只处理权重量化,不涉及激活值的量化,因此无法解决激活离群值导致的推理精度问题。

GPTQ(Generative Pre-trained Transformer Quantization)采用逐层贪心量化策略,根据激活值计算海森矩阵,分块对权重进行微调以最小化量化误差。与AWQ的网格搜索不同,GPTQ通过海森矩阵的逆来指导权重的逐个修正,理论上能够找到更优的量化配置。GPTQ的量化精度通常优于AWQ,但计算开销更大,因为它需要构建并求解海森矩阵。GPTQ支持INT8、INT4、MXFP4和HiFloat8权重量化,是AMCT中覆盖精度格式最广的算法。对于精度要求极高的部署场景,GPTQ值得投入额外的校准计算时间。

SmoothQuant专门解决激活值中离群值导致的量化困难。它的核心思路是数学等价变换——计算均衡因子,将激活除以该因子、同时将权重乘以该因子,使得激活值的分布更加均匀,从而降低激活量化的难度。变换前后算子的数学计算结果完全等价,但量化友好性大幅提升。SmoothQuant仅支持INT8全量化(W8A8),适用于激活值存在明显离群点的场景。在Transformer类模型中,注意力层的激活值往往分布极不均匀,SmoothQuant在此类场景下效果尤为突出。DMQ(Diagonal Matrix Quantization Balancer)均衡算法与SmoothQuant的原理类似,也是在计算量化因子之前对数据进行均衡处理,将数据的量化难度转移一部分至权重,两者在AMCT中的使用方式有所不同——SmoothQuant作为独立算法可选,DMQ作为量化流程中的预处理步骤集成。

AMCT还提供了ADA(Adaptive Rounding)算法用于权重量化后的舍入模式微调。ADA的核心思想是量化后权重的舍入方向并非总是"就近取整"最优,通过少量无标签数据训练可学习参数alpha,自适应决定每个权重向上还是向下舍入,从而最小化量化误差。ADA通常作为Min-Max或AWQ的后处理步骤使用,在精度要求严格的场景下可以进一步挽回量化损失。此外,AMCT还支持AutoRound算法,它把舍入偏移量做成可学习参数,并可联合调节min/max scale,让权重在低比特量化时选择更优的舍入方向,专门面向LLM的轻量级训练后量化。不过需注意AutoRound带自定义quantize() hook,目前PTQ fake quant可用,但部署导出中export_deploy()暂不支持该类hook。,其Attention层原始权重为FP8格式、MoE层原始为MXFP4格式,目标是转换为INT8在Atlas A2/A3上运行。由于需要同时处理权重量化和激活量化,且激活值存在离群点,W8A8整数量化(quant_type=w8a8-int)是最稳妥的选择。AMCT内部会综合运用SmoothQuant处理激活、Min-Max或AWQ处理权重,开发者无需手动切换算法,只需指定quant_type即可。值得补充的是,AMCT还支持FlatQuant算法用于INT4全量化(W4A8),以及MXQuant算法用于MXFP8/MXFP4精度格式,这些算法扩展了模型压缩的精度选择空间,使得开发者可以根据硬件能力(是否支持浮点低比特运算单元)和精度需求(是否可以容忍INT4的精度损失)灵活选择量化方案。

DeepSeek-V4量化实操:amct_pytorch接口调用

AMCT为DeepSeek-V4提供了专门的模型转换脚本convert_model.py,位于amct_pytorch/experimental/deepseek-v4/目录下。该脚本的核心工作流是:将FP8/MXFP4权重反量化到BF16中间格式,再重新量化为INT8格式,同时生成对应的缩放因子。

执行转换的命令行如下:

python convert_model.py \
  --input_fp8_hf_path /data/deepseek-v4-fp8 \
  --output_hf_path /data/deepseek-v4-int8 \
  --quant_type w8a8-int

w8a8-int specifies W8A8 integer quantization where both weights and activations are quantized to INT8 with integer scales; the input path points to the original FP8/MXFP4 model checkpoint directory in HuggingFace format, and the output path receives the converted safetensors with quantization parameters embedded in config.json.

转换过程中,脚本会遍历safetensor文件中的所有权重张量,按层类型分别处理。MoE专家网络的w1/w2/w3权重原始格式为MXFP4——两个4bit值打包存储于一个uint8中,元素数量看似为权重维度的一半。脚本需要先解包:提取低4位和高4位,将它们映射到E2M1浮点值,使元素数量翻倍恢复到真实维度。解包后读取对应的.scale张量,扩展至与权重相同的维度,逐元素相乘得到BF16精度的权重值。

Attention层的wq_a、wkv、wo_a、wq_b、wo_b权重原始格式为FP8,每个权重块大小为128乘128,共享一个scale因子。脚本直接读取FP8浮点值,乘以对应scale得到BF16。Indexer层的wq_b权重同样为FP8格式,处理方式与Attention层一致。MTP(Multi-Token Prediction)相关层涉及FP8和MXFP4两种格式,按上述规则分别处理。

得到BF16权重后,脚本对量化列表中的层重新量化为INT8并生成scale因子。非量化层(embed.weight、head、mtp.0.head、indexer.weights_proj、compressor相关权重等)仅执行FP8到BF16的反量化,不做重新量化。这一设计是有意为之的——词嵌入层和输出头的权重对量化极其敏感,强行量化往往导致精度不可逆的劣化。

输出目录的结构包含量化后的safetensors权重文件、权重索引文件model.safetensors.index.json、以及更新后的config.json。config.json中新增了quant_method(取值compressed-tensors或mxfp8)、format(int-quantized或float-quantized)、ignore(跳过量化的层名列表)、kv_cache_scheme(KV cache量化配置)、config_groups(各层量化参数)、weight_block_size(MX格式的权重块大小)等字段。推理框架会读取这些字段来正确加载和执行量化模型。

量化类型不限于w8a8-int,还支持bfloat16(仅反量化到BF16不执行重量化)、w8a8-mx(W8A8 MX浮点量化)和w4a8-mx(W4A8 MX浮点量化)。不同类型适用于不同的硬件和精度需求:w8a8-int兼容性最广,w4a8-mx压缩率最高但精度损失更大,bfloat16作为无损对照基准。

若需要更细粒度的量化控制,可以通过amct_pytorch的通用API手动编排量化流程:

import amct_pytorch as amct
import torch

model = torch.load("/data/deepseek-v4-fp8/model.pt", map_location="cpu")
cfg = amct.create_quant_config(
    model=model,
    record_file="./calibration_record.txt",
    config_defination="./quant_config.json"
)

create_quant_config scans the model graph and generates a quantization configuration file specifying which layers to quantize and which algorithm to use; the record_file path stores calibration statistics, and config_defination allows fine-grained override of default PTQ parameters like algorithm selection per layer and bit width settings.

通过config_defination参数可以指定每层使用的量化算法、比特宽度、是否启用channel_wise量化等细节。对于DeepSeek-V4的MoE专家层,推荐channel_wise=True以获得更精细的逐通道量化因子;对于数据量较少的层(如某些路由器权重),channel_wise=False更为稳健,避免因单个通道样本不足导致量化因子失准。

create_quant_config生成的配置文件可以作为后续量化流程的输入,配合amct_pytorch的其他API(如calibration和convert接口)实现完整的量化流水线。这种手动编排方式虽然比convert_model.py脚本更复杂,但提供了完全的控制灵活性,适用于非标准模型或需要混合量化策略的场景。

精度验证与问题定位

量化完成后,精度验证是不可跳过的环节。常用方案是在标准评测数据集上对比量化前后的指标差异。对于语言模型,perplexity是最直接的度量——在相同验证集上分别计算FP8原始模型和INT8量化模型的困惑度,差异在可接受范围内即视为通过。除了perplexity,还可以在下游任务评测集上对比生成质量,例如数学推理、代码生成、多轮对话等场景,确保量化没有引入特定任务的能力退化。

精度偏离的常见原因有几类,需要逐一排查。校准数据不足或分布偏移会导致量化因子不准确,此时应增加校准样本数量并确保其分布与真实推理数据一致。权重中存在极端离群值时,Min-Max的量化范围被拉大、正常值的量化粒度变粗,可换用AWQ保护显著权重以缩小有效量化范围。激活值离群值导致的误差应考虑SmoothQuant进行均衡处理,将激活的量化难度转移至权重。

AMCT提供了量化层的逐层误差分析能力,可以定位到具体哪个层引入了最大误差。如果MoE中某几个专家的权重分布异常(例如某个专家的w1权重方差远大于其他专家),可以将其加入ignore列表跳重量化,保持BF16精度。config.json中的ignore字段正是为此设计——将不适宜量化的层名列入该列表,转换脚本会跳过这些层,仅执行FP8到BF16的反量化。

另一个值得关注的细节是KV cache的量化配置。DeepSeek-V4的长上下文推理对KV cache显存占用极其敏感,上下文长度越长,KV cache占用的显存比例越高。config.json中的kv_cache_scheme字段控制KV cache的量化策略,合理配置KV cache量化可以在几乎不影响精度的前提下节省可观的显存开销,间接提升推理吞吐。开发者应根据实际推理场景的上下文长度,权衡KV cache量化的精度影响和显存收益。

当逐层误差分析指向特定MoE专家时,还需要区分是权重本身的问题还是校准数据在该专家上的激活模式异常。一个实用的诊断方法是比较该专家在校准集上的激活均值和方差——如果方差远大于其他专家,说明该专家在特定输入上被强烈激活,量化误差被放大。此时可以尝试增加包含该激活模式的校准样本,或对该专家单独使用GPTQ算法以获得更优的量化配置。如果多个专家的量化误差都很高,可能需要重新审视整体校准数据的质量和数量——AMCT官方建议校准数据至少覆盖512条样本,且数据分布应尽可能接近真实推理场景。对于MoE模型,还需确保校准数据能够均匀激活各个专家,避免某些专家因校准数据覆盖不足而量化失准。在实践中,可以通过路由器输出统计各专家在校准集上的激活频率,对激活频率过低的专家考虑加入ignore列表。

昇腾NPU部署:amct_ops自定义算子接入

量化后的模型要真正在昇腾NPU上运行,还需要amct_ops提供的自定义算子支持。amct_ops是AMCT的NPU自定义算子层,与amct_pytorch的算法编排职责不同,它更贴近底层硬件实现。amct_pytorch通过Python接口或torch.ops.amct调用算子,无需关注Ascend C kernel、C++ extension、CMake编译等底层细节,而amct_ops正是承载这些底层实现的模块。

amct_ops当前提供hifloat8_cast算子,支持FP16/BF16与HiFloat8的双向转换。虽然DeepSeek-V4的INT8量化部署主要依赖推理框架内置的INT8反量化逻辑,但amct_ops在HiFloat8量化场景下不可或缺。构建和安装流程如下:

cd amct/amct_ops
bash ops_build.sh --soc ascend910b
pip install dist/amct_ops-*.whl

ops_build.sh compiles Ascend C kernels targeting the specified SoC (ascend910b for Atlas A2, ascend910_93 for A3), producing a wheel with .so extensions that register custom NPU operators; the SoC flag determines the kernel binary format and must match the deployment hardware.

构建时需通过--soc参数指定目标平台:ascend910b对应A2系列(Ascend 910B1/B2/B3),ascend910_93对应A3系列(Ascend 910_93),ascend950对应A5系列(需CANN编译器支持dav-3510)。SoC参数决定了kernel的二进制格式,必须与部署硬件一致,否则算子在运行时会因指令集不兼容而报错。

构建产物位于dist/目录下,文件名格式为amct_ops-1.0.0-cp*-cp*-linux_arch.whl,其中arch随构建主机自动生成为x86_64或aarch64。wheel文件包含所有算子的Python包及编译好的.so扩展。安装后支持两种调用方式:

import amct_ops
from amct_ops.hifloat8_cast import encode_to_hifloat8, decode_from_hifloat8

x_bf16 = torch.randn(4, 128, dtype=torch.bfloat16, device="npu:0")
x_hf8 = encode_to_hifloat8(x_bf16)
x_rec = decode_from_hifloat8(x_hf8, torch.bfloat16)

方式一通过amct_ops模块直接导入,拥有IDE补全和文档字符串支持;方式二通过torch.ops.amct命名空间调用,与PyTorch的自定义算子注册机制一致。两种方式在功能上完全等价,开发者可按使用习惯选择。

对于DeepSeek-V4的INT8量化模型部署,推理框架(如vLLM或MindIE)会读取config.json中的量化参数,在运行时调用相应的反量化逻辑将INT8权重还原为高精度值参与计算。不同推理框架对量化模型的支持程度不同——MindIE作为华为官方推理引擎,对AMCT产出的量化模型支持最为完善,可直接读取config_groups中的量化参数自动构建反量化计算图;vLLM社区版则需要额外适配compressed-tensors格式的量化配置。开发者应根据所用的推理框架确认其对AMCT量化格式的支持情况,必要时需要自行编写权重加载和反量化的适配代码。amct_ops的独立安装设计使得它不必绑定AMCT主流程,可以单独作为PyTorch扩展包使用,降低了部署耦合度。amct_ops与amct_pytorch的分工可以这样理解:amct_pytorch负责量化算法的编排和执行,产出量化后的权重与参数文件;amct_ops负责推理阶段NPU上的底层算子实现,将量化参数转化为硬件可执行的操作。两者通过config.json和safetensors中的量化参数文件衔接,形成完整的训练后量化到部署的闭环。从代码组织上看,amct_pytorch目录下包含algorithms(量化算法实现)、cli(命令行工具)、experimental(实验性模型支持如DeepSeek-V4)等子目录,而amct_ops目录下包含hifloat8_cast(HiFloat8转换算子的Ascend C kernel源码、C++ binding和Python接口)、ops_build.sh(统一构建脚本)、setup.py(wheel打包配置)和ops_init.py(打包时复制为__init__.py,提供包接口和文档字符串)。这种目录结构使得两个模块可以独立迭代——新增量化算法只需修改amct_pytorch,新增NPU算子只需修改amct_ops,互不干扰。

效率对比

维度 量化前(FP8/MXFP4混合) 量化后(INT8 W8A8) 变化说明
模型体积 原始混合精度体积 体积缩减约50% INT8权重统一编码,存储密度提升
NPU兼容性 Atlas A2/A3不支持FP8/MXFP4低比特运算 完全支持INT8运算 解除硬件限制,可正常启用低比特计算单元
推理吞吐 无法在A2/A3上以低比特运行 吞吐提升 INT8运算单元利用率提高,内存带宽压力降低
部署门槛 需要支持FP8/MXFP4的高端硬件 Atlas A2/A3即可运行 硬件要求降低,可部署范围扩大

结尾

AMCT作为昇腾NPU原生的模型压缩工具包,在CANN生态中承担了从高精度权重到硬件友好格式的桥梁角色。DeepSeek-V4的INT8量化实战展示了完整的工作流:源码构建与环境适配、PTQ算法选型决策、convert_model.py脚本执行与参数配置、精度验证与逐层问题定位、amct_ops算子接入与NPU部署。AMCT的多精度支持(INT8/INT4/MXFP8/MXFP4/HiFloat8)和多算法覆盖(Min-Max/AWQ/GPTQ/SmoothQuant/FlatQuant/MXQuant)为不同场景下的精度-性能权衡留出了充分空间,而amct_pytorch与amct_ops的分层设计将量化算法编排与底层硬件算子实现解耦,使开发者可以根据实际需求灵活组合。对于需要在Atlas A2/A3上部署大模型的工程团队而言,这套工具链提供了一条从量化到部署的可复现路径。从长期工程实践的角度看,AMCT的价值不仅在于提供了现成的量化脚本,更在于它建立了一套可扩展的量化框架——新增模型适配只需编写convert脚本并注册到experimental目录,新增精度格式只需扩展amct_ops的Ascend C kernel,新增算法只需在algorithms目录下实现相应接口。这种架构设计使得AMCT能够持续跟进行业前沿,快速适配新一代大模型的量化需求。


仓库地址:https://atomgit.com/cann/amct

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐