专栏算法工具链QAT - 异构与非异构方案使用简介

QAT - 异构与非异构方案使用简介

颜值即正义2022-12-28
239
0

1 前言

在阅读后文plugin使用方式之前,为避免理解歧义,我们先定义一下异构和非异构的概念:异构模型是指部署时一部分运行在 BPU 上,一部分运行在 CPU 上的模型。而非异构模型部署时则完全运行在 BPU 上。

地平线基于PyTorch开发的horizon_plugin_pytorch量化训练工具(该工具将随2023年初的OE开发包释放给XJ3用户)同时支持Eager和fx两种模式。其中,fx模式是从plugin-1.0.0版本之后才开始支持的,相较于Eager方案,他们有如下不同:

eager模式的使用方式建议参考用户手册-4.2量化感知训练章节(4.2.2. 快速上手中有完整的快速上手示例,各使用阶段注意事项建议参考4.2.3. 使用指南)。后文关于异构以及非异构方案的使用方式介绍均基于 fx 模式,fx模式的相关API介绍请参考用户手册-4.2.3.4.2. 主要接口参数说明章节。

2 异构&非异构方案的使用方式

异构以及非异构方案的优缺点如下图所示:

通常来说,我们只会在以下两种情形时使用异构方案:

  1. 模型中包含 BPU 不支持的算子。

  2. 模型量化精度误差过大,需要将某些算子放到 CPU 上进行高精度计算。

2.1 非异构方案

由于BPU算子性能远高于CPU算子,从性能优化的角度出发,建议您尽可能使用纯BPU算子搭建模型。

非异构方案的使用步骤大致如下:

1. 浮点模型准备:完成算子替换(参考算子支持列表)、插入量化和反量化节点

2. 设置硬件架构

3. 校准(可选)

4. 模型量化

a. 设置qconfig(推荐先设置全局 qconfig 为get_default_qat_qconfig(),在此基础上根据需求修改,一般而言,只需要对 int16 和高精度输出的 op 单独设置 qconfig)

b. 转qat模型

5. 量化训练&精度验证

6. 转定点模型&精度验证

7. 模型编译

参考代码:

2.2 异构方案

异构方案的使用步骤大致如下:

1. 浮点模型准备

a. 完成算子替换(参考ptq方案算子支持列表)

① 对于非 module 的运算,如果需要单独设置 qconfig 或指定其运行在 CPU 上,需要将其封装成 module,参考后文示例中的_SeluModule

b. 插入量化和反量化节点

① 如果第一个 op 是 cpu op,那么不需要插入 QuantStub

② 如果最后一个 op 是 cpu op,那么可以不用插入 DeQuantStub

2. 设置硬件架构

3. 校准(可选)

4. 模型量化

a. 设置qconfig:推荐先设置全局 qconfig 为get_default_qat_qconfig(),在此基础上根据需求修改,一般而言,只需要对 int16 和高精度输出的 op 单独设置 qconfig

b. 转qat模型:设置 hybrid=True,并通过 hybrid_dict 指定需要运行在cpu上的节点

5. 量化训练&精度验证

6. 导出onnx

7. 评测定点精度

8. 使用hb_mapper工具完成定点转换&模型编译

参考代码:

8. 使用hb_mapper工具完成定点转换&模型编译

最简config.yaml配置示例:

模型转换:

从转换日志可见,selu、layer1.conv以及conv0都运行到了cpu上:

使用hb_perf工具生成模型结构图,可观察到第一段以及第二段bpu结尾的conv未设置高精度输出,仅对第三段bpu的尾部节点设置了高精度输出:

3 其他常见问题

  1. 打印qat_model发现多出了一些generated_add节点,这是为什么?

答:这是因为模型中直接使用了“+”号运算符,工具会通过新注册的generated_add来实现将其自动替换为FloatFunctional.add。建议大家最好在浮点模型准备阶段自行完成算子替换,因为工具自动转换时会依据执行顺序为add命名,若您后续修改了模型,可能会出现无法加载原ckpt的问题。

算法工具链
征程5征程3杂谈
评论0
0/1000