AMCT 量化感知训练简易配置文件(retrain_config_pytorch.proto)参数详解与实战指南
【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct
导读
本文档面向使用 CANN AMCT(昇腾 AI 处理器亲和的模型压缩工具仓)进行**量化感知训练(QAT)**的开发者,系统讲解基于retrain_config_pytorch.proto构造的简易配置文件:从 proto 消息结构、每个字段的取值与优先级,到量化、通道稀疏、4选2结构化稀疏及组合压缩四类典型.cfg配置样例,并穿插源码级解析,说明参数在工具内部的解析与生效方式。读完本文,你将能够独立编写一份"可运行、可调参"的简易配置文件,并通过create_quant_retrain_config接口的config_defination参数驱动模型完成量化感知训练或压缩配置生成。
retrain_config_pytorch.proto文件位于_AMCT安装目录_/amct_pytorch/proto/retrain_config_pytorch.proto(对应本仓库源码 retrain_config_pytorch.proto),基于该文件可以配置出量化感知训练简易配置文件、稀疏简易配置文件、组合压缩简易配置文件三类配置,用户按实际场景选择使用。
适用前提说明:本文参数与样例均以当前开源仓库(CANN AMCT)实际实现为准。proto 定义采用 proto2 语法,
required字段必填、optional字段可选、repeated字段可重复出现;配置文件中层名/层类型需与模型图中的实际名称一致(如conv1、fc、Linear、Conv2d等)。
一、配置文件定位:简易配置文件与 JSON 配置文件的关系
在 AMCT 的量化感知训练流程中,存在两种形态的配置文件:
- JSON 格式配置:由 create_quant_retrain_config 接口根据图结构自动生成(参数说明见量化感知训练配置参数),当推理精度不满足要求时需手动调整该 JSON 文件。
- 简易配置文件(.cfg):本文主题。它基于
retrain_config_pytorch.proto编写,通过create_quant_retrain_config(config_file, model, input_data, config_defination)接口的config_defination参数传入(默认值为 None),工具会将其解析为具体的量化/稀疏配置后再生成 JSON 配置。从源码看,该流程由 retrain_config_base.py 中的create_config_from_proto完成:先调用RetrainProtoConfig读取 proto 文本(见 retrain_proto.py),再结合图结构生成逐层的 JSON 配置。
简易配置文件的价值在于:以文本格式集中表达"全局量化参数 + 全局稀疏参数 + 按层/按类型差异化覆盖 + 跳过层",比直接手改 JSON 更清晰、更适合批量复用。
二、AMCTRetrainConfig:简易配置文件的顶层消息
AMCTRetrainConfig是简易配置文件的根消息,其字段如下:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| skip_layers | repeated | string | 全局参数:按层名跳过不做压缩的层。用于同时覆盖量化、稀疏等多特性场景下需要跳过的层;若与quant_skip_layers或regular_prune_skip_layers同时配置,取两者并集 |
| skip_layer_types | repeated | string | 全局参数:按层类型跳过不做压缩的层;若与quant_skip_types或regular_prune_skip_types同时配置,取两者并集 |
| override_layer_configs | repeated | RetrainOverrideLayer | 按层名重写部分层,实现差异化压缩(如 INT8 全局下对个别层差异化配置) |
| override_layer_types | repeated | RetrainOverrideLayerType | 按层类型重写部分层,实现差异化压缩 |
| fakequant_precision_mode | optional | FakequantPrecisionMode | fakequant 模型中 quant 自定义算子的scale_d数值精度模式:FORCE_FP16_QUANT将scale_d数值转换为 float16 精度(数值类型仍为 float32);不配置(默认)则保持 float32 精度 |
| batch_num | optional | uint32 | 量化使用的 batch 数量,默认值 1(proto 中[default = 1]) |
| retrain_data_quant_config | required | RetrainDataQuantConfig | 全局数据量化配置(量化感知训练数据量化配置) |
| retrain_weight_quant_config | required | RetrainWeightQuantConfig | 全局权重量化配置(量化感知训练权重量化配置) |
| quant_skip_layers | repeated | string | 量化场景专用:按层名跳过不需要量化的层;与skip_layers同时配置时取并集 |
| quant_skip_types | repeated | string | 量化场景专用:按层类型跳过不需要量化的层;与skip_layer_types同时配置时取并集 |
| prune_config | optional | PruneConfig | 全局稀疏配置 |
| regular_prune_skip_layers | repeated | string | 稀疏场景专用:按层名跳过不需要结构化稀疏的层;与skip_layers同时配置时取并集 |
| regular_prune_skip_types | repeated | string | 稀疏场景专用:按层类型跳过不需要结构化稀疏的层;与skip_layer_types同时配置时取并集 |
实现细节佐证:源码中 retrain_proto.py 的
get_quant_skip_layers()会先收集quant_skip_layers,再extend(self.get_skip_layers())后去重,即以"并集"方式合并全局与量化各自的跳过层;get_regular_prune_skip_layers()对稀疏场景同理。batch_num若未显式配置,proto 默认取 1。
参数优先级规则
override_layer_configs、override_layer_types与全局配置之间按如下优先级生效(文档明确给出):
- 量化场景:
override_layer_configs>override_layer_types>retrain_data_quant_config/retrain_weight_quant_config - 稀疏场景:
override_layer_configs>override_layer_types>prune_config
从源码可以印证:在 retrain_config_base.py 的_generate_retrain_config中,遍历可量化层时依次判断"层名是否命中 override_layers"→"层类型是否命中 override_types"→"否则使用全局 data/weight 配置",命中覆盖配置的层还会强制retrain_enable = True。优先级最高的override_layer_configs可以只重写数据量化(retrain_data_quant_config)或只重写权重量化(retrain_weight_quant_config),未重写的部分仍取自全局配置。
三、数据量化配置:RetrainDataQuantConfig 与 ActULQquantize
数据(激活)量化配置消息为RetrainDataQuantConfig,通过ulq_quantize字段选择ULQ(Universal Linear Quantization)数据量化算法(算法介绍见ULQ 数据量化算法,AMCT 在训练过程中不断训练量化因子以减少量化损失,初始化时会对数值做量化,因此对初始化敏感)。当前数据量化算法仅支持 ULQ。
ActULQquantize的字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| dst_type | optional | DataType | 数据量化位宽,支持 INT4 / INT8 / INT16,默认 INT8;当前版本仅支持 INT8 量化 |
| clip_max_min | optional | ClipMaxMin | 初始化的上下限值,不配置时默认用 IFMR 算法进行初始化 |
| fixed_min | optional | bool | 是否固定下限且下限为 0。默认:ReLU 之后为 true,其他场景为 false |
ClipMaxMin子消息包含两个必填字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| clip_max | required | float | 初始上限值 |
| clip_min | required | float | 初始下限值 |
使用注意(源码佐证):在 retrain_proto.py 的
_get_retrain_data_config中,一旦配置了clip_max_min,则clip_max与clip_min必须同时出现,否则直接报错 "clip_max and clip_min are both required."。clip_max_min会参与计算缩放因子,后续训练在其初始值基础上做调优——因此建议初始值与实际推理数据的上下限保持一致,否则可能导致量化后精度较差。
四、权重量化配置:RetrainWeightQuantConfig、ARQRetrain 与 WtsULQRetrain
权重量化配置消息为RetrainWeightQuantConfig,支持两种算法(oneof 二选一):
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| arq_retrain | - | ARQRetrain | ARQ 权重量化算法(Adaptive Range Quantization,对权重直接量化) |
| ulq_retrain | - | WtsULQRetrain | ULQ 权重量化算法 |
ARQRetrain字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| dst_type | optional | DataType | 选择 INT8 或 INT4 量化位宽,默认 INT8;当前版本仅支持 INT8 |
| channel_wise | optional | bool | 是否做 channel-wise 的 ARQ |
WtsULQRetrain字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| dst_type | optional | DataType | 选择 INT8 或 INT4 量化位宽,默认 INT8;当前版本仅支持 INT8 |
| channel_wise | optional | bool | 是否做 channel-wise 的 ULQ |
channel_wise语义:true表示每个 channel 独立量化、量化因子不同(推荐配置,通常精度更好);false表示所有 channel 共享量化因子。ARQ 算法详情可参见 ARQ 权重量化算法。
实现细节佐证:proto 中
dst_type字段均带[default = INT8],解析层_parse_data_type将枚举值 0/1/2 分别映射为 INT4/INT8/INT16;_get_retrain_weight_config会按arq_retrain或ulq_retrain二选一解析出algo、channel_wise、dst_type三项(见 retrain_proto.py)。同时 retrain_config_base.py 中的check_dst_type_legal会校验激活与权重的位宽组合(形如 A8W8),不在白名单RETRAIN_ACT_WTS_TYPES内的组合会被拒绝。
五、按层差异化配置:RetrainOverrideLayer 与 RetrainOverrideLayerType
当全局量化配置(如 INT8)不满足个别层需求时,可通过这两个消息做差异化覆盖。当前版本仅支持 INT8 量化(INT4 差异化配置为预留能力,需以版本实际支持为准)。
RetrainOverrideLayer(按层名重写):
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| layer_name | required | string | 层名 |
| retrain_data_quant_config | required | RetrainDataQuantConfig | 重写的数据层量化参数 |
| retrain_weight_quant_config | required | RetrainWeightQuantConfig | 重写的权重层量化参数 |
| prune_config | optional | PruneConfig | 重写的稀疏配置参数 |
RetrainOverrideLayerType(按层类型重写):
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| layer_type | required | string | 层类型 |
| retrain_data_quant_config | required | RetrainDataQuantConfig | 重写的数据层量化参数 |
| retrain_weight_quant_config | required | RetrainWeightQuantConfig | 重写的权重层量化参数 |
| prune_config | optional | PruneConfig | 重写的稀疏配置参数 |
实现细节佐证:
RetrainProtoConfig.get_override_layers()与get_override_layer_types()会检测 override 中是否存在重复的层名/层类型,重复会直接raise ValueError("Please delete repeated items..."),因此编写配置时务必保证层名唯一、层类型唯一;随后read_override_config/read_override_type_config按命中项读回重写后的 data、weight、prune 三组参数(见 retrain_proto.py)。
六、稀疏配置:PruneConfig、FilterPruner 与 NOutOfMPruner
简易配置文件同时支持结构化稀疏配置,顶层通过prune_config开启,内部按 oneof 选择两种稀疏策略之一:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| filter_pruner | - | FilterPruner | filter(输出维度通道)稀疏的配置 |
| n_out_of_m_pruner | - | NOutOfMPruner | 4选2稀疏的配置 |
硬件约束提醒(文档明确):由于硬件约束,Ascend 950PR / Ascend 950DT 不支持 4选2 结构化稀疏特性,在目标硬件为这两类产品时应使用 filter 稀疏或仅量化方案。
FilterPruner 与 BalancedL2NormFilterPruner(通道稀疏)
FilterPruner仅支持balanced_l2_norm_filter_prune字段,即BalancedL2NormFilterPruner(简称 BCP)算法。该算法通过计算权重各个 filter(输出维度通道)的 L2 范数(各元素平方和再开方)对输出通道做重要性排序,优先裁剪重要性低的通道(算法介绍见手工通道稀疏算法)。
BalancedL2NormFilterPruner字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| prune_ratio | required | float | 稀疏率 = 被稀疏的 filter 数量 / filter 总数。推荐配置为 0.2,即裁剪 20% 的输出通道 |
| ascend_optimized | optional | bool | 是否做昇腾亲和优化。如果稀疏后的模型要部署在昇腾 AI 处理器上,建议配置为 true(proto 中默认值即[default = true]) |
NOutOfMPruner 与 L1SelectivePruner(4选2结构化稀疏)
NOutOfMPruner仅支持l1_selective_prune字段,即L1SelectivePrune 算法:通过比较权重的 l1 值(绝对值)决定保留哪些权重,每 4 个连续权重中保留 l1 值最大的 2 个(算法介绍见4选2结构化稀疏算法)。
L1SelectivePruner字段:
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| n_out_of_m_type | optional | NOutOfMType | 目前仅支持 M4N2,即每 4 个连续权重中保留 2 个(proto 中默认值[default = M4N2]) |
| update_freq | optional | uint32 | 更新 4选2 稀疏选择的间隔。update_freq=0时仅在第一个 batch 更新稀疏选择;update_freq=2时每 2 个 batch 更新一次,以此类推。默认 0 |
实现细节佐证:在重训练过程中权重会随每个训练 batch 改变,l1 值排序也可能随之变化(比如原本保留 4 个元素中的前两个,更新后可能变成保留第 1、第 3 个),
update_freq正是控制这一"重新选择"的频率;_parse_n_out_of_m_type中非 M4N2 的值会直接报错(见 retrain_proto.py)。prune_ratio为balanced_l2_norm_filter_prune的必填字段,缺失时解析层会报 "prune_ratio is required for balanced_l2_norm_filter_prune, please add it."。
七、实战:四类典型简易配置文件样例
以下样例均直接基于retrain_config_pytorch.proto构造(Opname需替换为真实层名,Optype需替换为真实层类型),可供create_quant_retrain_config的config_defination参数直接使用。
7.1 量化感知训练简易配置文件(quant.cfg)
# global quantize parameter retrain_data_quant_config: { ulq_quantize: { clip_max_min: { clip_max: 6.0 clip_min: -6.0 } fixed_min: true dst_type: INT8 } } retrain_weight_quant_config: { arq_retrain: { channel_wise: true dst_type: INT8 } } skip_layers: "Opname" skip_layer_types: "Optype" override_layer_types : { layer_type: "Optype" retrain_weight_quant_config: { arq_retrain: { channel_wise: false dst_type: INT8 } } } override_layer_configs : { layer_name: "Opname" retrain_data_quant_config: { ulq_quantize: { clip_max_min: { clip_max: 3.0 clip_min: -3.0 } dst_type: INT8 } } }要点解读:
- 全局数据量化采用 ULQ,初始化上下限为 [-6.0, 6.0],
fixed_min: true表示下限固定为 0 且不学习(适合量化层前一层为 ReLU 的场景); - 全局权重量化采用 ARQ,channel-wise 打开;
- 通过
skip_layers/skip_layer_types全局跳过指定层; override_layer_types对某类层关闭 channel-wise;override_layer_configs对某个具体层重写数据量化上下限为 [-3.0, 3.0](按优先级,层级覆盖 > 类型覆盖 > 全局)。
7.2 通道稀疏简易配置文件(prune.cfg)
# global prune parameter prune_config{ filter_pruner { balanced_l2_norm_filter_prune { prune_ratio: 0.3 ascend_optimized: True } } } # skip layers regular_prune_skip_layers: "Opname" regular_prune_skip_layers: "Opname" # overide specific layers override_layer_configs: { layer_name: "Opname" prune_config : { filter_pruner: { balanced_l2_norm_filter_prune: { prune_ratio: 0.5 ascend_optimized: True } } } }要点解读:
- 全局通道稀疏率 0.3(裁剪 30% 输出通道),并开启昇腾亲和优化;
regular_prune_skip_layers可重复出现以列出多个跳过层(repeated 字段);override_layer_configs对单个层将稀疏率差异化调整为 0.5——该层级的prune_config优先级高于全局prune_config。
7.3 4选2结构化稀疏简易配置文件(selective_prune.cfg)
# global prune parameter prune_config{ n_out_of_m_pruner { l1_selective_prune { n_out_of_m_type: M4N2 update_freq: 0 } } } # skip layers regular_prune_skip_layers: "Opname" regular_prune_skip_layers: "Opname" # overide specific layers override_layer_configs: { layer_name: "Opname" prune_config : { n_out_of_m_pruner: { l1_selective_prune: { n_out_of_m_type: M4N2 update_freq: 1 } } } }要点解读:
- 全局采用 M4N2 结构化稀疏,
update_freq: 0表示只在第一个 batch 更新稀疏选择; - 对指定层通过 override 将
update_freq调整为 1(每 1 个 batch 更新一次),适应权重快速变化的层; - 再次提醒:该特性不受 Ascend 950PR/Ascend 950DT 支持,部署目标为上述硬件时应改用 filter 稀疏。
7.4 组合压缩(通道稀疏 + INT8 量化)简易配置文件(compressed1.cfg)
prune_config : { filter_pruner : { balanced_l2_norm_filter_prune : { prune_ratio : 0.3 ascend_optimized: True } } } # skip_layers: "skip_layers_name_0" skip_layer_types: "Optype" quant_skip_layers: "Opname" quant_skip_types: "Optype" retrain_weight_quant_config: { arq_retrain: { channel_wise: true dst_type: INT8 } } override_layer_types : { layer_type: "Optype" retrain_weight_quant_config: { arq_retrain: { channel_wise: false dst_type: INT8 } } retrain_data_quant_config : { ulq_quantize : { clip_max_min : { clip_max : 6.0 clip_min : -6.0 } } } prune_config : { filter_pruner : { balanced_l2_norm_filter_prune : { prune_ratio : 0.5 ascend_optimized: True } } } }要点解读:
- 同一份配置文件内同时出现
prune_config(通道稀疏)与retrain_weight_quant_config(INT8 权重量化),即"通道稀疏 + INT8 量化"组合压缩; skip_layer_types是全局跳过(稀疏与量化共同生效),quant_skip_layers/quant_skip_types只跳过量化、不跳稀疏,二者并集生效;override_layer_types中同时重写了权重量化(关闭 channel-wise)、数据量化(设定上下限)与稀疏(提高稀疏率到 0.5)三组参数。
7.5 组合压缩(4选2结构化稀疏 + INT8 量化)简易配置文件(compressed2.cfg)
prune_config{ n_out_of_m_pruner { l1_selective_prune { n_out_of_m_type: M4N2 update_freq: 0 } } } # skip_layers: "skip_layers_name_0" skip_layer_types: "Optype" quant_skip_layers: "quant_skip_layers_name_0" quant_skip_types: "Optype" retrain_weight_quant_config: { arq_retrain: { channel_wise: true dst_type: INT8 } } override_layer_types : { layer_type: "Optype" retrain_weight_quant_config: { arq_retrain: { channel_wise: false dst_type: INT8 } } retrain_data_quant_config : { ulq_quantize : { clip_max_min : { clip_max : 6.0 clip_min : -6.0 } } } prune_config{ n_out_of_m_pruner { l1_selective_prune { n_out_of_m_type: M4N2 update_freq: 1 } } } }要点解读:与 7.4 结构对称,区别仅在于全局与层级的prune_config均改用n_out_of_m_pruner(M4N2 结构化稀疏),并在 override 中把该类型层的update_freq调整为 1。
组合压缩场景的源码佐证:在 retrain_config_base.py 的
create_config_from_proto中,当enable_prune and enable_retrain同时为 True(即压缩场景)时,会先通过proto.parse_proto_enable()探测 proto 中量化与稀疏各自是否被启用,再分别调用_generate_retrain_config与_generate_prune_config生成两套配置并合并到同一 JSON 中。相关解析与异常分支(如 prune 配置缺失prune_ratio、override 重复等)均有对应单元测试覆盖,可参见 test_retrain_config.py 及配置样例目录 configuration/utils。
八、与其他文档的衔接
- 算法原理:ULQ、ARQ、BalancedL2Norm(BCP)、L1SelectivePrune 的算法介绍见 算法简述;
- 接口用法:
create_quant_retrain_config的参数说明、调用示例及 JSON 配置文件落盘样例见 create_quant_retrain_config; - JSON 配置调参:当接口生成的 config.json 精度不满足要求时,按量化感知训练配置参数手动调整
version、batch_num、retrain_enable、retrain_data_config、retrain_weight_config、algo、channel_wise、fixed_min、clip_max、clip_min、dst_type等字段(修改 json 时请确保层名唯一); - QAT 完整流程与训练/保存接口:参见 量化感知训练 相关章节(
create_quant_retrain_model、save_model等接口文档)。
九、编写与排障要点速查
- 必填字段检查:
retrain_data_quant_config、retrain_weight_quant_config为顶层必填;clip_max/clip_min成对出现;balanced_l2_norm_filter_prune的prune_ratio必填。 - 唯一性:
override_layer_configs的层名、override_layer_types的层类型不可重复,重复会导致解析报错。 - 跳层取并集:全局
skip_layers/skip_layer_types与各场景专用 skip 参数并存时取并集,无需重复配置。 - 优先级记忆:
override_layer_configs>override_layer_types> 全局配置(量化与稀疏场景一致)。 - 硬件约束:Ascend 950PR / Ascend 950DT 不支持 4选2 结构化稀疏;INT8 为当前版本唯一实际支持的量化位宽。
- 部署前检查:稀疏场景建议
ascend_optimized: true;clip_max_min初始值应贴近真实数据分布,否则影响量化后精度。
【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考