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