解决方法:建议参考文档中 环境部署 章节中 GPU Docker 部分的描述。
不考虑训练的随机性,对于同一模型来说,Calibration 精度和 QAT 精度是正相关的,正相关程度因模型而异,没有明确指标。
单纯调整校准参数对于精度的提升比较小,建议校准完成后进行一次 QAT 训练:
如果校准精度几乎达到目标,那么调整校准参数可能能解决问题。
如果 QAT 精度比校准精度高,但比目标还差的比较多,那么留在校准阶段做精度 debug,改掉一些量化不友好的问题,直到校准精度有比较明显的提升再 QAT。
如果 QAT 精度没有校准高,那么先定位 QAT pipeline 和训练策略的问题。
loss,精度等表现出来的现象应该与浮点基本一致。发生不一致时建议优先排查 QAT pipeline 是否存在使用问题。
解决方法:QAT/Quantized 精度不符合预期、出现 NAN 或 QAT 初始 loss 相对 float 明显异常。请参考 精度调优工具使用指南。
开启多机训练后 batchsize 成倍增大,此时需要同步调整 LR 等超参来进行平衡。
地平线提供的 Qconfig
定义了 activation 和 weight 如何进行量化,目前支持 FakeQuantize
、LSQ
、PACT
等量化算法。
请参考如下代码实现:
该问题的影响因素较多,建议从以下几个方面检查:
检查输入数据是否含 nan。
检查浮点模型是否收敛。未收敛的浮点模型针对某些微量化误差可能会导致很大波动。
检查是否开启 calib。建议开启,可以给模型更好的初始系数。
检查训练策略是否适合。不适合的训练策略也 会导致出现 NAN 值,例如学习率 lr 过大(可通过调低学习率或使用梯度截断方式)等。在训练策略上,默认 QAT 与浮点保持一致,如果浮点训练采用的是 OneCycle 等会影响 LR 设置的优化器,建议使用 SGD 替换。
该现象可能是因为错误配置 module_name 导致,module_name 字段只支持 string,不支持按 index 索引进行配置。
可以打印 qat_model 的所在层,查看该层是否有 (activation_post_process): FakeQuantize
,若没有,则说明其为高精度输出。例如 int32 高精度 conv 打印如下:
int8 低精度 conv 打印如下:
建议仅对部署上板的模型部分插入伪量化节点。由于 QAT 训练为全局训练,辅助分支的存在会导致训练难度增加,若辅助分支处的数据分布与其他分支差异较大还会加大精度风险,建议去除。
horizon_plugin_pytorch 中的 gridsample 算子非公版实现,其 grid 输入(输入 2)是 int16 类型的绝对坐标,而 torch 公版是 float32 类型的归一化坐标,范围是 [-1, 1]
。
因此,从 torch.nn.functional.grid_sample
路径导入 grid_sample 算子后,可以通过如下方式归一化 grid:
可以依次检查如下:
prepare 是否在 optimizer 定义之前。因为 prepare 会进行算子融合,导致模型结构发生变化。
fake_quant_enabled 和 observe_enabled 是否为 1。
module 中的 training 变量是否为 True。
解决方法:只对需要量化的模块设置 qconfig。
解决方法:根据要部署的处理器选择正确的 BPU 架构,如 S100 需要使用 Nash:
错误示例如下:
假设模型定义如下:
解决方法:为了提高模型精度,模型输出节点设置成高精度,示例如下:
由于底层限制,Calibration 目前不支持多卡,请使用单卡进行 Calibration 操作。
由于 Horizon 硬件支持的图像格式为 centered YUV444,因此建议您从模型训练开始就直接使用 YUV444 格式作为网络输入进行训练。
导致 QAT 与 Quantized 误差的原因是 QAT 阶段不能完全模拟 Quantized 中纯定点计算逻辑,建议使用 quantized 模型进行模型精度评测和监控。
FloatFunctional()
定义的成员。错误示例如下:
解决方法:禁止在 forward 中多次调用同一个通过 FloatFunctional()
定义的变量。
Quantized 阶段并非完全不能直接添加算子,如颜色空间转换算子等,具体添加指南详见文档。但是并非所有算子都可以直接添加,比如 cat,这种算子必须在 calibration 或 QAT 阶段统计获得的真实量化参数才能不影响最终精度,有类似需求需要调整网络结构,可以咨询框架研发。
模型过拟合常见判定方法:
对输入数据稍加变换之后,输出结果变化较大。
模型参数赋值较大。
模型 activation 较大。
解决方法:自行解决浮点模型过拟合问题。
QAT 训练阶段的查表是前后加了伪量化的浮点算子,导出时才会真正变成查表,可以通过如下代码验证是否查表算子导致了精度损失:
如果仍不能解决问题,请反馈地平线技术支持人员。
如果模型只包含部署逻辑,就没有导出和训练代码不一致的问题,否则需要通过下面的方法处理。