尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于 MKL-DNN 后端的 MXNet 模型 INT8 量化实战指南

基于 MKL-DNN 后端的 MXNet 模型 INT8 量化实战指南 深度学习机器学习人工智能【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxnet1/mxnet点击查看免费下载本指南以 Apache MXNet 的 MKL-DNN现已更名为 oneDNN后端为主线系统讲解如何在 Intel CPU 平台上将 FP32 模型量化为 INT8 模型的全流程从环境安装、图融合、quantize_graph量化到 naive/entropy 离线校准与部署推理。读完本文你将掌握 MXNet 量化工具链python/mxnet/contrib/quantization.py的完整调用方式并能把 Gluon 模型或自定义符号模型无缝接入 INT8 推理管线。概述与适用场景在 Intel CPU尤其是支持 AVX-512 的 Xeon 平台上INT8 计算可以显著降低内存带宽占用并提升推理吞吐。MXNet 通过MXNET_USE_MKLDNN构建的 MKL-DNN 后端提供了算子级子图subgraph融合与量化支持。本文档对应的量化流程适用于图像分类等以 Convolution 为主的网络如 ResNet、MobileNet、Inception、SqueezeNet、VGG 等也支持用户自定义符号模型。整个量化流程分为 4 个阶段前 3 步初始化模型、量化模型、评估调优即可用最少工作量获得可接受的精度第 4 步校准Calibration虽然在精度上贡献有限却能大幅减少推理时的运行时计算量是性能优化的关键。环境安装与前置条件使用 MKL-DNN 后端的 MXNet 有两种安装途径从源码构建参考 mkldnn_readme.md 中关于如何构建带 MKL-DNN 后端的 MXNet 的说明。构建时需启用 MKL-DNN 支持USE_MKLDNN1。直接通过 pip 安装release 或 nightly 版本# release 版本 pip install mxnet-mkl # nightly 版本 pip install mxnet-mkl --pre注意MKL-DNN 后端的量化算子目前仅支持 Linux 系统启用量化模型暂不支持在 Windows 上运行推理见 quantization.py 的源码说明。图像分类量化 Demoimagenet_gen_qsym_mkldnn.py仓库中提供了开箱即用的量化脚本 example/quantization/imagenet_gen_qsym_mkldnn.py。该脚本与 Gluon-CV ModelZoo 集成可自动下载预训练模型并转换为符号模型进行量化# 安装 gluoncv脚本依赖 pip install gluoncv # 以 ResNet50-V1 为例使用 naive 校准、5 个 batch 进行量化 python imagenet_gen_qsym_mkldnn.py --modelresnet50_v1 --num-calib-batches5 --calib-modenaive脚本支持的常用命令行参数如下完整列表见脚本的argparse定义参数默认值说明--modelresnet50_v1待量化模型名称支持resnet18_v1、resnet50_v1b、resnet101_v1、squeezenet1.0、mobilenet1.0、mobilenetv2_1.0、inceptionv3等 Gluon-CV 模型以及imagenet1k-resnet-152、imagenet1k-inception-bn等 MXNet ModelZoo 模型--epoch0模型 epoch 数--no-pretrainedFalse启用后不下载预训练模型用于量化自定义模型--batch-size32校准数据 batch 大小--calib-datasetdata/val_256_q90.rec校准数据集路径ImageRecordIter 格式--image-shape3,224,224输入图像 shapeInceptionV3 需改为3,299,299--num-calib-batches10用于校准的 batch 数--exclude-first-convFalse排除第一个卷积层不量化输入数据可能为负值--calib-modeentropy校准模式none/naive/entropy--quantized-dtypeauto量化目标类型auto/int8/uint8量化完成后符号与参数文件会保存到./model目录下例如resnet50_v1-quantized-5batches-naive-symbol.json与resnet50_v1-quantized-0000.params。随后可用 example/quantization/imagenet_inference.py 分别运行 FP32 与 INT8 推理并对比精度# FP32 推理 python imagenet_inference.py --symbol-file./model/resnet50_v1-symbol.json \ --param-file./model/resnet50_v1-0000.params \ --rgb-mean123.68,116.779,103.939 --rgb-std58.393,57.12,57.375 \ --num-skipped-batches50 --batch-size64 --num-inference-batches500 \ --dataset./data/val_256_q90.rec --ctxcpu # INT8 推理 python imagenet_inference.py --symbol-file./model/resnet50_v1-quantized-5batches-naive-symbol.json \ --param-file./model/resnet50_v1-quantized-0000.params \ --rgb-mean123.68,116.779,103.939 --rgb-std58.393,57.12,57.375 \ --num-skipped-batches50 --batch-size64 --num-inference-batches500 \ --dataset./data/val_256_q90.rec --ctxcpu脚本还支持--benchmarkTrue使用 dummy 数据测试纯推理性能。该脚本针对不同模型内置了excluded_sym_names默认排除规则如 ResNet50-V1 的resnetv10_conv0_fwd、MobileNet 的mobilenet0_pool0_fwd等细节可查看 imagenet_gen_qsym_mkldnn.py。将量化流程集成到自有项目量化流程同时支持符号Symbolic模型与 Gluon 模型。如果使用 Gluon请先将 HybridBlock 混合hybridize并导出为符号再执行量化。下文以 Gluon ResNet18-V1 为例逐步演示量化四步流程。第一步初始化模型从 Gluon ModelZoo 下载 ResNet18-V1 预训练模型hybridize 并导出为符号文件import logging import mxnet as mx from mxnet.gluon.model_zoo import vision from mxnet.contrib.quantization import * logging.basicConfig() logger logging.getLogger(logger) logger.setLevel(logging.INFO) batch_shape (1, 3, 224, 224) resnet18 vision.resnet18_v1(pretrainedTrue) resnet18.hybridize() resnet18.forward(mx.nd.zeros(batch_shape)) resnet18.export(resnet18_v1) sym, arg_params, aux_params mx.model.load_checkpoint(resnet18_v1, 0) # 可选可视化 FP32 模型 mx.viz.plot_network(sym)其中sym为符号图arg_params与aux_params分别为权重参数与辅助参数如 BN 的 running_mean / running_var。模型融合Model Fusion量化前必须先执行图融合以获得更优性能sym sym.get_backend_symbol(MKLDNN_QUANTIZE) # 可选可视化融合后的 FP32 模型 mx.viz.plot_network(sym)这一行代码会触发MKLDNN_QUANTIZE后端的图重写残差块中的 Batchnorm、Activation 与 elemwise_add 会被融合进 Convolution 算子如_sg_mkldnn_conv。融合后图结构更简洁、中间张量更少是量化与推理性能的基础。quantize_model_mkldnn等高层 API 内部也会自动调用该融合见 quantization.py。第二步量化模型MXNet 提供 Python 接口quantize_graph让数据科学家可以根据真实部署需求灵活构造量化模型# 量化配置 # 设置需要排除的层 excluded_names [] # 设置校准模式 calib_mode none # 设置需要校准的层 calib_layer None # 设置量化目标类型 quantized_dtype auto logger.info(Quantizing FP32 model Resnet18-V1) qsym, qarg_params, aux_params, collector quantize_graph(symsym, arg_paramsarg_params, aux_paramsaux_params, excluded_sym_namesexcluded_names, calib_modecalib_mode, calib_layercalib_layer, quantized_dtypequantized_dtype, loggerlogger) # 可选可视化量化模型 mx.viz.plot_network(qsym) # 保存量化模型 mx.model.save_checkpoint(quantized-resnet18_v1, 0, qsym, qarg_params, aux_params)对符号模型应用quantize_graph后会得到新的量化符号qsym及其量化后的参数。此时可以看到_contrib_requantize算子被插入到Convolution之后用于将 INT32 卷积累加结果转换回 FP32。quantize_graph的核心参数说明详见 quantization.py 源码参数类型说明excluded_sym_nameslist of strings不希望被量化的符号名称列表。典型用法是排除对精度影响大的层或输入首层卷积输入可能是负值excluded_op_nameslist of strings不希望被量化的算子类型名称列表calib_modestrnone不做校准requantization 阈值在推理时通过 min/max 算子运行时计算推理通常比带校准的模型慢 10%–20%naive直接把校准数据集上各层输出的 min/max 作为量化阈值entropy默认基于校准数据集求 FP32 层输出分布与量化输出分布 KL 散度最小的阈值calib_layerfunction输入层输出名字符串返回 True/False 决定该层是否参与校准统计。不提供时所有需要 requantization 的层输出都会被收集quantized_dtypestr输入数据的量化目标类型支持int8、uint8与auto。auto表示根据校准结果自动选择输出类型。默认int8从源码看quantize_graph内部通过_quantize_symbol完成符号替换并根据校准模式创建对应收集器entropy模式创建_LayerHistogramCollector层输出直方图naive模式创建_LayerOutputMinMaxCollector层输出 min/max见 quantization.py。第三步评估与调优量化完成后得到一对 quantized symbol 与 params 文件。对于 Gluon 推理只需用SymbolBlock加载模型与参数quantized_net mx.gluon.SymbolBlock.imports(quantized-resnet18_v1-symbol.json, data, quantized-resnet18_v1-0000.params) quantized_net.hybridize(static_shapeTrue, static_allocTrue) batch_size 1 data mx.nd.ones((batch_size, 3, 224, 224)) quantized_net(data)随后即可在验证集上评估量化网络的精度。若精度不达标可以通过excluded_sym_names参数选择不同的层或算子排除在量化之外反复试验直至得到可接受的精度。第四步离线校准性能关键可选前一步生成的量化模型因为要在推理时运行时计算 min/max 而可能较慢。推荐将calib_mode设为naive或entropy进行离线校准先用验证集子集调用set_monitor_callback收集层信息再进行 INT8 推理# 量化配置 excluded_names [] calib_mode naive calib_layer None quantized_dtype auto logger.info(Quantizing FP32 model resnet18-V1) cqsym, cqarg_params, aux_params, collector quantize_graph(symsym, arg_paramsarg_params, aux_paramsaux_params, excluded_sym_namesexcluded_names, calib_modecalib_mode, calib_layercalib_layer, quantized_dtypequantized_dtype, loggerlogger) # 下载 imagenet 验证集 mx.test_utils.download(https://data.mxnet.io/data/val_256_q90.rec, dataset.rec) # 设置数据 RGB 信息 mean_std {mean_r: 123.68, mean_g: 116.779, mean_b: 103.939, std_r: 58.393, std_g: 57.12, std_b: 57.375} # 设置 batch size batch_size 16 # 创建 DataIter data mx.io.ImageRecordIter(path_imgrecdataset.rec, batch_sizebatch_size, data_shapebatch_shape[1:], rand_cropFalse, rand_mirrorFalse, **mean_std) # 创建 module mod mx.mod.Module(symbolsym, label_namesNone, contextmx.cpu()) mod.bind(for_trainingFalse, data_shapesdata.provide_data, label_shapesNone) mod.set_params(arg_params, aux_params) # 校准配置 # 设置用于校准的 batch 数 num_calib_batches 5 max_num_examples num_calib_batches * batch_size # 监控 FP32 推理 mod._exec_group.execs[0].set_monitor_callback(collector.collect, monitor_allTrue) num_batches 0 num_examples 0 for batch in data: mod.forward(data_batchbatch, is_trainFalse) num_batches 1 num_examples batch_size if num_examples max_num_examples: break if logger is not None: logger.info(Collected statistics from %d batches with batch_size%d % (num_batches, batch_size))之后层信息会被填充到quantize_graph返回的collector中再调用calib_graph将层信息写入 INT8 模型# 将 scaling factor 写入量化符号 cqsym, cqarg_params, aux_params calib_graph(qsymcqsym, arg_paramsarg_params, aux_paramsaux_params, collectorcollector, calib_modecalib_mode, quantized_dtypequantized_dtype, loggerlogger) # 可选可视化量化模型 mx.viz.plot_network(cqsym)naive 校准后可以看到min_calib_range与max_calib_range被写入_contrib_requantize算子。从源码看calib_graph在entropy模式下通过_get_optimal_thresholds基于_smooth_distribution与直方图求最优阈值生成阈值字典在naive模式下直接使用collector.min_max_dict随后用_calibrate_quantized_sym把阈值写入符号见 quantization.py。得到带校准的量化模型后务必再次调用融合 API因为后量化融合可以把部分requantize或dequantize算子进一步融合进卷积从而提升性能# 执行后量化融合 cqsym cqsym.get_backend_symbol(MKLDNN_QUANTIZE) # 可选可视化后量化模型 mx.viz.plot_network(cqsym) # 保存量化模型 mx.model.save_checkpoint(quantized-resnet18_v1, 0, cqsym, cqarg_params, aux_params)后量化融合后_contrib_requantize算子会被融合进Convolution算子中。此外也可以直接修改 JSON 符号文件中的min_calib_range与max_calib_range字段来手工微调阈值例如{ op: _sg_mkldnn_conv, name: quantized_sg_mkldnn_conv_bn_act_6, attrs: { max_calib_range: 3.562147, min_calib_range: 0.000000, quantized: true, with_act: true, with_bn: true } }量化 API 全景除quantize_graph与calib_graph外python/mxnet/contrib/quantization.py 还提供两个高层封装quantize_model_mkldnnL576一键完成「融合 量化 可选校准」内部自动调用get_backend_symbol(MKLDNN_QUANTIZE)前后各一次返回量化符号与参数。仅支持 Intel CPU 平台非 CPU context 会抛出ValueError是示例脚本imagenet_gen_qsym_mkldnn.py使用的核心入口。quantize_netL758面向 Gluon 用户的 API直接接受 HybridBlock 网络并返回量化的SymbolBlock支持exclude_layers、exclude_layers_match、exclude_operators等排除选项。校准调优技巧精度调优优先尝试entropy校准模式其通过最小化 FP32 与量化输出分布的 KL 散度求阈值通常精度最优尝试通过excluded_sym_names排除导致明显精度下降的层例如输入首层卷积、对量化敏感的 BN 层等更换校准数据集调整num_calib_batches的数量或对验证数据集做 shuffle保证校准数据分布与推理数据分布一致。性能调优量化前务必执行图融合get_backend_symbol(MKLDNN_QUANTIZE)如果量化图中存在大量requantize层校准后务必再执行一次后量化融合对比 FP32 与 INT8 推理的 MXNet profiler 输出或MKLDNN_VERBOSE日志定位未融合的算子与性能瓶颈。使用 Python/C 部署量化模型量化模型同样支持通过 MXNet C 包部署。C 端加载-symbol.json与.params文件后即可在 Intel CPU 上执行 INT8 推理相关示例与说明可参考 cpp-package/example/inference 目录及 cpp-package/README.md。对于纯 C 推理场景还可参考 amalgamation 的预测库封装方式。注意当前 MKL-DNN 后端量化算子仅针对 Linux 系统启用跨平台部署前请先确认目标环境。总结MXNet 的 MKL-DNN 后端量化链路由「图融合 → 符号量化 → 离线校准 → 后量化融合」四段式构成核心 API 集中在 python/mxnet/contrib/quantization.py配套示例位于 example/quantization。按照本指南的步骤你可以在 Intel CPU 上把 FP32 图像分类模型转换为 INT8 模型在保持精度的前提下获得显著的推理性能提升。建议从imagenet_gen_qsym_mkldnn.py脚本入手跑通流程再迁移到自定义模型并结合excluded_sym_names与校准模式做精度/性能的联合调优。赞分享深度学习机器学习人工智能【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxnet1/mxnet点击查看免费下载相关推荐MXNet 模型量化实战基于 MKL-DNN 与 CUDNN 的 FP32→INT8 校准量化与推理指南MXNet 模型量化实战基于 MKL DNN 与 CUDNN 的 FP32→INT8 校准量化与推理指南 本文围绕 MXNet 仓库中 example/qua深度学习机器学习人工智能飞桨PaddlePaddleQAT INT8 MKL-DNN 量化推理全指南Quant2Int8OnednnPass 模型转换与基准复现飞桨PaddlePaddleQAT INT8 MKL DNN 量化推理全指南Quant2Int8OnednnPass 模型转换与基准复现 本文以飞桨Pa人工智能深度学习大模型分布式训练预训练MXNet 集成 Intel MKL-DNN 编译部署指南从源码构建、算子加速到 INT8 量化MXNet 集成 Intel MKL DNN 编译部署指南从源码构建、算子加速到 INT8 量化 导读 本文以 MXNet 官方 MKL DNN 集成指南深度学习机器学习人工智能上一篇YuriKey高级配置教程自定义keybox和配置优化技巧下一篇AutoPrompt项目实战自动化提示优化的五大应用场景解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表