根据你的描述,问题核心是:删除 Dequantize 节点后,int32 累加器输出值域严重偏负,导致 sigmoid 后全为 0 或噪声。这是典型的量化参数(zero_point/bias)未正确传递导致的。
结论:选方案 B(保留 Dequantize 节点)
理由:
- 方案 A 是"治标不治本":调高 CONF_THRES 只能过滤噪声,但置信度失去物理意义,且无法解决值域偏移的根本问题
- 方案 B 才是正确路径:Dequantize 节点包含反量化所需的 scale 和 zero_point,删除后这些信息丢失,导致 int32 值无法正确还原为 logit
排查步骤
1. 验证量化参数是否完整
# 检查原始量化模型的输出节点信息
hb_tool inspect yolov5_best_quant.bin --outputs
# 对比删除 Dequantize 后的模型
hb_tool inspect yolov5_best_quant_modified.bin --outputs
2. 正确做法:保留 Dequantize,优化后处理
参考社区已有案例 RDK X5部署yolov8,全int16量化完成后python部署识别不到:
步骤:
- 不删除 Dequantize 节点,让 BPU 自动完成反量化
- 检查输出头顺序是否与后处理代码匹配(常见问题)
- 如果帧率低,检查是否有多余的 CPU 后处理算子
3. 如果必须用 int32 输出(高级用法)
参考 请问如何去除 Yolov5s 模型最后的 Dequant 层?:
# 只删除输出端的 Dequantize,保留中间节点的
hb_model_modifier yolov5_best_quant.bin -a Dequantize -o yolov5_int32.bin
# 手动应用量化参数
# 需要从量化日志中提取每个输出头的 scale 和 zero_point
# 然后在后处理中手动计算:logit = (int32_val - zero_point) * scale
建议行动
- 优先尝试方案 B:重新导出模型,不删除 Dequantize 节点
- 测试帧率:如果帧率>15 FPS 且精度正常,直接使用
- 如果帧率确实低:再考虑方案 A,但需要:
- 从量化日志中提取每个输出头的
scale和zero_point - 在后处理中手动应用:
logit = (int32_val - zero_point) * scale - 然后再做 sigmoid
- 从量化日志中提取每个输出头的
社区资源
- 反量化节点的融合实现 - 理解反量化原理
- 模型精度验证及调优建议 - 量化调试流程
- RGB模型的量化部署实战-以YOLOv5为例 - 完整量化案例
建议先把你的量化日志(hb_mapper 输出)和模型结构图贴出来,社区可以帮你确认 zero_point 是否正确传递。