
地平线 征程 6 部署 YOLO26从 INT64 Div 算子约束到 Cast 修复全流程本文记录了在地平线 RDK 征程 6 平台Nash-E 架构上部署 YOLO26 检测模型时遇到的 INT64 类型 Div 算子 BPU 不支持问题以及从定位到修复的完整过程适合有一定 ONNX 和地平线部署基础的读者参考。一、YOLO26 的结构与创新YOLO26 是基于 YOLOv8 架构改进的新一代目标检测模型主要特征包括DFL 移除分布焦点损失DFL模块虽然有效但导出复杂且硬件兼容性有限。YOLO26 完全取消了 DFL简化了推理并拓宽了对边缘和低功耗设备的支持。端到端无 NMS 推断与依赖 NMS 作为独立后处理步骤的传统探测器不同YOLO26 本身是端到端的。预测数据直接生成降低延迟使得与生产系统的集成更快、更轻便、更可靠。ProgLoss STAL 改进的损失函数提高了检测精度显著提升了小物体识别能力这是物联网、机器人、航拍及其他边缘应用的关键需求。MuSGD 优化器一款结合 SGD 与 Muon 的新型混合优化器。受 Moonshot AI 的 Kimi K2 启发MuSGD 将 LLM 训练的先进优化方法引入计算机视觉实现更稳定的训练和更快的融合。二、问题出现HMCT 转换时的 Warning在使用地平线模型转换工具 HMCThb_mapper将 YOLO26 的 ONNX 模型转换为 。hbm 格式时出现如下警告Warning: HMCT does not support input qtype: float32 for node: /model.23/Div_1; INT64 cant be quantized to float32 Warning: HMCT does not support input qtype: float32 for node: /model.23/Gather_3; INT64 cant be quantized to float32这说明模型的后处理部分存在 INT64 类型的算子HMCT 无法对其进行量化处理。三、根本原因INT64 数据链路分析通过诊断脚本分析 ONNX 模型中所有 INT64 节点可以看到问题的完整链路TopK (/model.23/TopK_1) └── 输出 indices: INT64 ← ONNX 规范强制无法修改 ↓ Div (/model.23/Div_1) 输入: INT64 / 常量80(INT64) ↓ 输出: INT64 ↓ Gather 等后续节点为什么 TopK 的输出必须是 INT64****这是 ONNX 算子规范的硬性规定TopK 算子的 indices 输出类型固定为 INT64开发者无法通过修改节点属性来改变它。只要 Div 的输入来自 TopK它们的数据类型就是 INT64。四、征程 6E/M BPU 对 Div 算子的约束查阅地平线 征程 6E/M 的 ONNX 算子 BPU 约束列表Div 算子的约束如下lhs: quantized type 支持 int8, int16, int32 其他类型支持 int16, int32, float16, float32 rhs: lhs 和 rhs 的类型必须相同 output: quantized type 支持 (int8/int16/int32 → int8/int16/int32) 其他类型输入输出类型必须一致关键结论BPU 支持的整数类型是 int8、int16、int32但不支持 INT64。这带来了两个严重后果后果一HMCT 转换时报 WarningHMCT 发现 Div 节点的输入是 INT64无法对其量化输出警告Warning: HMCT does not support input qtype: float32 for node: /model.23/Div_1; INT64 cant be quantized to float32后果二算子被迫回退到 CPU 执行更严重的问题是由于 INT64 不在 BPU 算子约束的支持列表中HMCT 无法将 Div 及其下游节点调度到 BPU 上执行这些节点会自动回退到 CPU 运行。这意味着整个推理流程变成 BPU 执行主干网络 ↓ CPU 执行 Div 等节点 ← 严重拖慢推理速度 ↓ 输出结果BPU 和 CPU 之间的数据搬运内存拷贝本身就有开销加上 CPU 串行执行这些节点在实时检测场景下会造成明显的延迟瓶颈无法充分利用 BPU 的算力优势。修复目标因此非常明确将 Div 的数据类型改为 INT32使其满足 BPU 算子约束从 CPU 回退变为 BPU 执行恢复完整的 BPU 推理链路。五、为什么不能直接把 Div 改成 INT32一个直觉上的想法是直接修改 Div 节点的类型为 INT32 不就行了答案是不行原因如下ONNX 计算图中节点的输出类型由其输入类型推断得出。Div 的第一个输入来自 TopK 的 INT64 输出类型是固定的。即使强行修改节点的类型声明shape_inference 和 checker 也会检测到输入输出类型不一致模型校验失败onnxruntime 加载时同样会报错。六、解决方案在关键节点前插入 Cast正确的做法是在类型不兼容的节点之间插入 Cast 算子来做类型转换Cast 是 ONNX 中专门负责 tensor 类型转换的算子输入 tensor(INT64) → Cast → 输出 tensor(INT32)完整的修复链路如下TopK 输出 INT64 ↓ Cast(INT64 → INT32) ← 必须TopK 强制 INT64Div 不接受 INT64 ↓ Div (INT32输入 → INT32输出) ← 满足 BPU 约束可在 BPU 上执行 ↓ GatherElements 等后续节点INT32BPU 执行真正需要做的只有两件事第一在 TopK 输出后插入一个 CastINT64→INT32切断 INT64 的传播源头。第二把所有相关的旧 value_info 记录提前清理干净让 shape_inference 从零重新推断整条链路的类型自然收敛为 INT32不会出现旧 INT64 声明和新推断结果冲突的问题。同时Div 共用的常量输入 Constant_21值为 80INT64也需要同步转换为 INT32保证 lhs 和 rhs 类型一致满足 BPU 约束中lhs 和 rhs 类型必须相同的要求。七、总结核心经验在地平线等 BPU 平台上部署模型时INT64 是高频踩坑点。问题不只是 Warning 那么简单——INT64 算子会因为不满足 BPU 约束而被整体回退到 CPU 执行造成 BPU/CPU 频繁切换和数据搬运开销严重影响推理性能。ONNX 规范中部分算子如 TopK强制输出 INT64解决思路不是修改算子本身而是在类型边界处插入 Cast 算子做类型转换将整条链路改为 BPU 支持的 INT32从而让这些节点重新回到 BPU 上执行。