YOLO v8.4.56 修复 QNN 导出兼容性:builtin provider wheels 也能稳定导出,Linux x86-64 更友好
Ultralytics v8.4.56 已于 2026年5月27日发布这一版本的重点非常明确修复 QNN export 与 built-in provider wheels 的兼容问题。如果你正在使用 Qualcomm QNN 相关部署流程尤其是面向 edge hardware、YOLO26 等模型导出场景那么这次更新值得重点关注。它不是一次模型结构更新也不是训练能力的大版本升级而是一次非常关键的部署稳定性修复。一、v8.4.56 发布概览Ultralytics v8.4.56 的核心目标只有一个让 QNN 导出流程在不同 onnxruntime-qnn 打包形式下都能正常工作。这次更新的背景是onnxruntime-qnn在不同平台和不同 wheel 版本中暴露 QNN Execution Provider 的方式并不一致有些是plugin-based QNN wheels有些是built-in QNN wheels旧逻辑在处理这些情况时倾向于一律按“插件方式”去注册 QNN Execution Provider这在部分 Linux x86-64 环境下会引发问题甚至可能因为符号找不到而崩溃。v8.4.56 的改动就是让 Ultralytics 能够先判断当前 onnxruntime-qnn 属于哪种布局再选择正确的 session 创建方式如果是插件式 QNN wheels继续沿用原先的注册路径如果是内建式 QNN wheels则不再强行注册插件而是直接使用已经内置好的 QNN provider这意味着 QNN 导出流程变得更智能也更稳。二、这次更新解决了什么问题1. 修复 built-in provider wheels 的 QNN 导出问题这是本次更新的标题级修复点。以前 Ultralytics 在导出 QNN 时会默认尝试注册QNNExecutionProvider但对于某些新版本的onnxruntime-qnn来说QNN provider 已经是直接内置在 ONNX Runtime 里的不需要再作为独立插件注册。如果还按照旧流程去注册就可能导致导出失败。2. 避免 Linux x86-64 上的已知失败更新说明里特别提到一个痛点Linux x86-64 wheels 在插件注册时可能会触发 undefined symbol error。这类错误通常意味着运行时尝试加载一个本不该再加载的插件或者库之间的符号解析方式与当前 wheel 打包结构不匹配v8.4.56 通过区分 built-in 和 plugin-based 两种 QNN 包装方式避免了这类失败。3. 兼容两种 QNN 打包风格这次更新明确支持了两种形式plugin-based QNN wheels这种情况下QNN provider 需要手动注册。Ultralytics 会继续使用原本的逻辑先注册执行 provider 库再创建 session。built-in QNN wheels这种情况下QNN 已经是 ONNX Runtime 的内置 provider不需要再注册。Ultralytics 会直接用 QNN provider 创建 ONNX Runtime session。这就让 QNN 导出流程不再依赖“你安装的到底是哪一种 wheel”而报错。三、为什么这次修复很重要1. QNN 导出本身就是高敏感部署流程QNN 导出不是普通推理流程而是典型的部署前处理环节主要用于把模型转换成适合 Qualcomm QNN 环境的上下文二进制文件。这种流程本身就对环境、依赖、库版本、平台结构非常敏感。因此任何一个 provider 注册逻辑上的偏差都可能导致导出失败运行时报错生成失败但日志不够直观平台兼容性问题2. 之前的固定注册方式已经不适配新 packaging过去一套固定逻辑适合的是“QNN 以插件形式存在”的情况。但随着onnxruntime-qnn的打包方式演进QNN provider 可能已经被直接集成在 ONNX Runtime 内部。如果程序没有识别这个变化就会产生“重复注册”或者“错误加载”的问题。3. 对 Linux 环境特别关键官方说明中强调了 Linux x86-64 的风险。这意味着在这类环境中旧流程可能会因为插件注册引发底层符号错误导致导出失败。v8.4.56 的价值就在于它把这类环境问题前置识别掉了从而提升了导出稳定性。四、这次更新在用户体验上的变化1. 导出更稳定最直接的结果就是QNN 导出不再因为 provider 注册方式不匹配而轻易失败。2. 环境适配更强用户不再需要手动猜测当前安装的是 plugin-based wheel 还是 built-in wheel。Ultralytics 会自动处理。3. 对部署流程更友好如果你面向 Qualcomm 和 edge hardware 做部署这类修复会明显降低导出时的折腾成本。简单说就是减少环境配置和导出阶段的故障概率。五、代码层面的具体变化这次版本更新虽然只有 1 个 commit、2 个文件变化但内容非常精准几乎全部聚焦在 QNN export 路径上。1. 版本号从 8.4.55 升级为 8.4.56在ultralytics/__init__.py中版本号更新为__version__ 8.4.55改为__version__ 8.4.56这是标准版本迭代标识说明本次发布是一次正式更新。2.qnn_library_paths()的返回类型和逻辑增强在ultralytics/utils/export/qnn.py中函数签名发生了变化原来返回tuple[str, str]更新后返回tuple[str | None, str]这意味着第一个返回值ep_library_path可能为None。这个设计非常关键因为它表达了一个新事实当 QNN 已经内置在 ONNX Runtime 中时不需要再返回可注册的 provider 库路径。文档说明也随之更新原先描述是onnxruntime-qnn通过onnxruntime_qnnhelper module 暴露 QNN Execution ProviderWindows/Linux-aarch64 wheel 与 Linux x86-64 wheel 的差异只体现在库路径更新后改为plugin builds 暴露onnxruntime_qnnhelper modulemonolithic builds 直接暴露QNNExecutionProviderbackend libraries 仍然位于onnxruntime/capi这个变化本质上是把“QNN provider 可能存在两种形态”写进了逻辑和注释中。3. 在onnxruntime可用 provider 中检测QNNExecutionProvider更新后的逻辑会在onnxruntime导入后检查QNNExecutionProvider是否已经存在于onnxruntime.get_available_providers()如果存在说明当前属于 built-in QNN wheels处理方式不同ep_lib None如果不存在则继续按原先路径寻找插件库Windows 下onnxruntime_providers_qnn.dllLinux 下libonnxruntime_providers_qnn.so也就是说Ultralytics 现在不是“默认认为要注册”而是“先判断需不需要注册”。4. QNN session 创建逻辑分支处理在onnx2qnn()中session 创建逻辑也发生了关键变化。旧逻辑旧逻辑的流程比较固定注册 QNN provider library获取 QNN devices添加 provider 配置创建InferenceSession反注册 provider library新逻辑新逻辑会根据ep_library是否存在分成两条路径情况一ep_library存在说明是 plugin-based wheels继续按以前的流程注册 execution provider library通过ort.get_ep_devices()查找 QNN device如果找不到 device就抛出错误QNN EP registered but no QNN devices were found by ONNX Runtime.将 devices 与 provider options 传给 session创建InferenceSession最后 unregister情况二ep_library不存在说明 QNN 已经 built-in不需要注册插件直接创建InferenceSession传入providers[ep_name]provider_options[ep_options]这就是本次更新最重要的行为变化。它避免了“明明已经内置却还要手动注册”的问题。5. 资源清理也同步调整在finally中旧逻辑会直接unregister_execution_provider_library(ep_name)。更新后则是只有当ep_library存在时才执行 unregister这样可以避免在 built-in 场景下执行不必要甚至可能有副作用的注销动作。六、更新说明中的重点信息整理根据本次更新内容可以总结出几个非常关键的事实。1. QNN now has two packaging stylesQNN 不再只有一种加载方式而是分为plugin-basedbuilt-in2. Ultralytics now detects provider availabilityUltralytics 会检查onnxruntime.get_available_providers()判断当前环境是不是已经内置了QNNExecutionProvider。3. Linux x86-64 的注册失败问题被规避这次修复直接针对某些 Linux x86-64 wheel 的已知问题减少 undefined symbol error 风险。4. 代码逻辑更加自适应不再把所有 wheel 当成同一种情况处理而是根据实际环境动态分支。七、文档注释也做了同步更新这次不仅改了逻辑还修订了说明文字让代码语义和实际行为保持一致。新的注释中明确提到onnxruntime-qnn可能暴露为 plugin也可能暴露为 built-in provideronnxruntime/capi中仍然包含 backend librariesQNN 在不同 wheels 中的布局不同这对后续维护很重要因为它避免了开发者继续沿用“QNN 一定要注册插件”的旧认知。八、这次更新对哪些用户最有价值1. 使用 QNN 导出流程的用户如果你正在使用 QNN 导出模型这次修复会明显影响你的体验。2. 面向 Qualcomm 平台部署的用户如果你的目标是 Qualcomm 相关硬件或 edge hardware 场景这次更新能减少导出故障。3. Linux x86-64 环境用户这是受影响最明显的一类环境。旧版本可能会因为 provider 注册导致失败而 v8.4.56 专门处理了这个问题。4. 使用新版本 onnxruntime-qnn 的用户如果你安装的是 built-in provider wheels那么这次更新几乎就是为你准备的。九、这次更新的总结Ultralytics v8.4.56 的内容非常聚焦核心就是一个方向让 QNN export 同时兼容 plugin-based wheels 和 built-in provider wheels。这带来的直接收益包括避免 Linux x86-64 上的 undefined symbol error减少 QNN 导出失败自动适配不同 wheel 打包风格让 session 创建更智能让部署流程更稳、更少依赖人工判断从版本性质上看这不是一次“增加新模型能力”的更新而是一次非常实用的导出与部署稳定性修复。对于日常训练和普通推理用户来说体感可能不大但对于走 QNN、Qualcomm、edge deployment 的用户来说这个修复非常关键。十、结语代码地址github.com/ultralytics/ultralytics如果你正在跟进 Ultralytics 的部署链路尤其是 QNN 相关导出那么 v8.4.56 值得尽快关注。它不改变模型架构也不增加新训练特性但它通过识别onnxruntime-qnn的不同包装方式解决了一个非常实际、非常容易踩坑的问题。简单来说这次升级让 QNN 导出流程从“固定假设”变成了“动态适配”这正是一个成熟部署工具链应该具备的能力。