训练后量化(MindSpore)
训练后量化过程中,用户需自行提供训练好的权重文件和一小批验证集用来矫正量化因子,调用API接口完成模型的调优过程。目前支持MindSpore框架模型的量化调优。模型量化期间,用户可手动配置参数,并使用部分数据完成对模型的校准,获取一个量化后的模型。
执行训练后量化前,需参考环境准备,完成CANN开发环境的部署及Python环境变量配置。
操作步骤
- 用户自行准备预训练模型和数据集。本样例以 ResNet50为例,获取模型结构定义脚本,并参考README下载所需数据集, 以cifar10为例,在config/resnet50_cifar10_config.yaml里配置data_path和checkpoint_file_path,并在eval.py的基础上进行修改。
- 新建模型量化脚本resnet50_quant.py,将eval.py内容复制到该文件中,删除eval_net()函数中定义损失,定义metric,计算metric相关的代码,保留如下初始化模型和加载权重相关的代码,并修改加粗字体信息。
… target = config.device_target # init context ms.set_context(mode=ms.GRAPH_MODE, device_target=target, save_graphs=False) if target == "Ascend": device_id = int(os.getenv('DEVICE_ID')) ms.set_context(device_id=device_id) # create dataset dataset = create_dataset(dataset_path=config.data_path, do_train=False, batch_size=config.batch_size, eval_image_size=config.eval_image_size, target=target) # define net model = resnet(class_num=config.class_num) # load checkpoint param_dict = ms.load_checkpoint(config.checkpoint_file_path) ms.load_param_into_net(model, param_dict) net.set_train(False) …
- 在resnet50_quant.py中导入量化接口,接口说明请参考训练后量化(MindSpore)。
from modelslim.mindspore.quant.ptq_quant.quantize_model import quantize_model from modelslim.mindspore.quant.ptq_quant.create_config import create_quant_config from modelslim.mindspore.quant.ptq_quant.save_model import save_model
- (可选)调整日志输出等级,启动调优任务后,将打屏显示量化调优的日志信息。
import logging logging.getLogger().setLevel(logging.INFO) #请根据实际情况进行配置
- 准备预训练模型。当前脚本中已存在加载预训练模型的相关代码,可跳过此步骤,其他模型请参考以下内容进行配置。
model = get_user_network() #加载模型结构,返回模型实例 load_checkpoint(ckpt_file_path, model) #模型加载预训练参数,请根据实际情况配置
- 使用create_quant_config接口生成配置文件。
config_file = "./quant_config.json" #待生成的量化配置文件存放路径及名称,请根据实际情况配置 create_quant_config(config_file, model)
通过create_quant_config接口生成的默认配置文件,用户可以手动修改其中的配置项,以达到手动控制量化的目的。
- “fuse_bn”默认为“true”, 即默认融合BatchNormalization层,用户可修改为“false”以关闭融合。
- “quant”默认为“true”,即为量化API判定可以进行量化的网络层,用户可以修改为“false”,以关闭特定网络层的量化。由于MindSpore使用的dense算子变更,在生成的配置文件中,该算子后“quant”配置需修改为“false”。
- “num_rollback_nodes”默认为“0”,即为量化API判定需要精度回退层数,用户可以自行指定精度回退层数,取值范围为0<=num_rollback_nodes<可量化层数。
- 使用quantize_model接口修改原模型,进行量化算子插入,此处的input_data需要与预训练模型的input保持一致的shape。
input_data = ms.Tensor(np.random.uniform(size=[256, 3, 224, 224]), dtype=mstype.float32) #请根据实际情况配置 model_calibrate = quantize_model(config_file, model, input_data) #通过调用quantize_model接口生成的量化后的模型
若原模型包含logger,将无法对原模型进行deepcopy,影响后续量化算子的插入,用户在使用 quantize_mdoel() 接口前需删除原模型中的logger属性。
- 对量化模型进行校准。校准过程中会使用少量数据集进行前向传播,以校准量化算子中的参数,提高量化后的精度。
for i, data in enumerate(dataset.create_dict_iterator(num_epochs=1)): net(data['image']) if i >= 2: break
- 使用save_model接口保存量化后模型。
file_name = "./quantized_model" #指定量化后模型保存路径和文件名 save_model(file_name, model_calibrate, input_data, file_format="AIR") #请根据需要配置量化后模型的格式
“file_format”支持AIR、MINDIR两种格式,默认值为AIR。
- 启动模型量化调优任务,并在步骤9指定的目录获取一个量化完成的模型。
python3 resnet50_quant.py
父主题: 模型量化