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 Provider- Windows/Linux-aarch64 wheel 与 Linux x86-64 wheel 的差异只体现在库路径
更新后改为:
- plugin builds 暴露
onnxruntime_qnnhelper module - monolithic builds 直接暴露
QNNExecutionProvider - backend 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.dll - Linux 下:
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 styles
QNN 不再只有一种加载方式,而是分为:
- plugin-based
- built-in
2. Ultralytics now detects provider availability
Ultralytics 会检查 onnxruntime.get_available_providers(),判断当前环境是不是已经内置了 QNNExecutionProvider。
3. Linux x86-64 的注册失败问题被规避
这次修复直接针对某些 Linux x86-64 wheel 的已知问题,减少 undefined symbol error 风险。
4. 代码逻辑更加自适应
不再把所有 wheel 当成同一种情况处理,而是根据实际环境动态分支。
七、文档注释也做了同步更新
这次不仅改了逻辑,还修订了说明文字,让代码语义和实际行为保持一致。
新的注释中明确提到:
onnxruntime-qnn可能暴露为 plugin- 也可能暴露为 built-in provider
onnxruntime/capi中仍然包含 backend libraries- QNN 在不同 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 导出流程从“固定假设”变成了“动态适配”,这正是一个成熟部署工具链应该具备的能力。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)