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_qnn helper module 暴露 QNN Execution Provider
  • Windows/Linux-aarch64 wheel 与 Linux x86-64 wheel 的差异只体现在库路径

更新后改为:

  • plugin builds 暴露 onnxruntime_qnn helper 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 创建逻辑也发生了关键变化。

旧逻辑

旧逻辑的流程比较固定:

  1. 注册 QNN provider library
  2. 获取 QNN devices
  3. 添加 provider 配置
  4. 创建 InferenceSession
  5. 反注册 provider library
新逻辑

新逻辑会根据 ep_library 是否存在分成两条路径:

情况一:ep_library 存在

说明是 plugin-based wheels,继续按以前的流程:

  1. 注册 execution provider library
  2. 通过 ort.get_ep_devices() 查找 QNN device
  3. 如果找不到 device,就抛出错误:
    • QNN EP registered but no QNN devices were found by ONNX Runtime.
  4. 将 devices 与 provider options 传给 session
  5. 创建 InferenceSession
  6. 最后 unregister
情况二:ep_library 不存在

说明 QNN 已经 built-in,不需要注册插件:

  1. 直接创建 InferenceSession
  2. 传入:
    • 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 导出流程从"固定假设"变成了"动态适配",这正是一个成熟部署工具链应该具备的能力。

相关推荐
DYWorker00137 分钟前
Linux驱动:RK3568 GMAC + YT8531C 千兆以太网全流程解剖
linux
吴声子夜歌2 小时前
Nginx应用与运维——Nginx负载均衡应用实战(二)
运维·nginx·负载均衡
lisanmengmeng2 小时前
NRPE 添加命令(一)
linux·运维·服务器
pt10432 小时前
CML网络仿真入门-2:使用CML模拟网络实验环境
运维·网络协议
树下水月3 小时前
Typora破解
linux·服务器·前端
沫璃染墨3 小时前
《从零入门Linux系统篇(五十七):线程篇·十——生产者消费者模型进阶:从环形缓冲区到POSIX信号量》
linux·运维·服务器·开发语言·c++·系统架构·信号处理
wuminyu4 小时前
LockStack在虚拟线程Mount和Unmount拷贝过程剖析
java·linux·c语言·jvm·c++
深念Y4 小时前
rime-雾凇拼音-配置记录
linux·junit·软件·拼音·kde
HAHAXX84 小时前
电商RPA批量上架通用方案:一套流程如何同时跑通拼多多、抖店、淘宝和跨境平台
java·运维·rpa
零基础1234 小时前
LLM Agent 驱动的物模型构建:从设备手册到边缘接入的自动化实践
运维·人工智能·经验分享·python·自动化