Ultralytics YOLO 的 DeepXBackend:DEEPX NPU 推理后端源码解析与部署实战
发布时间:2026/9/8 20:04:57来源:尧图网络
Ultralytics YOLO 的 DeepXBackendDEEPX NPU 推理后端源码解析与部署实战【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics本篇技术文章以 DeepX API Reference 为骨架深入剖析ultralytics/nn/backends/deepx.py中的DeepXBackend类它如何加载编译好的.dxnn模型、如何在 DEEPX DX-Runtime 上执行推理、输入输出的张量契约是什么。读完后你将掌握在 DEEPX NPU 硬件如 Raspberry Pi 5 DX-M1 模块上部署 Ultralytics YOLO 模型的完整路径以及该后端在自动后端选择机制中的注册与调用关系。DeepXBackend 在 Ultralytics 推理架构中的位置DeepXBackend是 Ultralytics 统一推理后端体系中面向 DEEPX NPU 硬件的实现。整个体系由三层构成抽象基类BaseBackendultralytics/nn/backends/base.py定义所有后端必须实现的load_model(weight)与forward(im)两个抽象方法并提供 metadata 读取read_metadata、metadata 应用apply_metadata等公共能力具体后端实现DeepXBackend继承BaseBackend只负责 DEEPX 格式特有的模型加载与张量转换自动分发层AutoBackendultralytics/nn/autobackend.py根据模型路径后缀自动选择后端。在 AutoBackend 的_BACKEND_MAP中可以看到 DEEPX 的注册_BACKEND_MAP { ... deepx: DeepXBackend, ... }AutoBackend的格式判定逻辑依赖 exporter.py 中的导出格式表其中 DEEPX 的后缀是*_deepx_model/目录。因此当你执行YOLO(yolo26n_deepx_model)时框架从目录名识别出deepx格式实例化DeepXBackend其__init__最终调用你在导出时生成的.dxnn目录路径作为weight。需要注意几个与AutoBackend相关的约束见 autobackend.pyFP16 仅对{pt, torchscript, onnx, openvino, engine, triton}生效DEEPX 后端天然运行在 INT8 编译产物上fp16参数会被忽略非 PyTorch 系后端包括 DEEPX若显式指定了 CUDA 设备会自动回退到 CPU 上的推理入口——实际的矩阵运算发生在 NPU 硬件上CPU 侧只承担前后处理。load_model加载 .dxnn 编译模型DeepXBackend的完整实现位于 ultralytics/nn/backends/deepx.py核心是load_model方法deepx.py#L21-L48def load_model(self, weight: str | Path) - None: Load a DEEPX model from a directory containing a .dxnn file. Args: weight (str | Path): Path to the DEEPX model directory containing the .dxnn binary. Raises: ImportError: If the dx_engine Python package is not installed. FileNotFoundError: If no .dxnn file is found in the given directory. try: from dx_engine import InferenceEngine except ImportError as e: raise ImportError( DEEPX inference requires the DEEPX DX-Runtime and dx_engine Python package. See https://docs.ultralytics.com/integrations/deepx#runtime-installation for installation instructions. ) from e LOGGER.info(fLoading {weight} for DEEPX inference...) w Path(weight) found next(w.rglob(*.dxnn), None) if found is None: raise FileNotFoundError(fNo .dxnn file found in: {w}) self.model InferenceEngine(str(found)) self.apply_metadata(self.read_metadata(found))该方法的关键设计点有三处1. 延迟导入 dx_enginefrom dx_engine import InferenceEngine被包裹在try/except ImportError中。dx_engine是 DEEPX DX-Runtime 的 Python 封装包不随ultralytics主包分发必须在安装了 NPU 驱动与libdxrt运行时的目标设备上单独安装。这种延迟导入保证了在没有 DEEPX 硬件的环境中ultralytics依然可以被正常安装和 import只有在真正加载 DEEPX 模型时才会抛出带安装指引的ImportError。2. 递归查找 .dxnn 文件weight参数指向的是导出目录如yolo26n_deepx_model/而非具体文件。后端通过w.rglob(*.dxnn)递归搜索目录下的第一个.dxnn编译产物交给InferenceEngine(str(found))加载。这意味着部署时只需要把整个_deepx_model/目录拷到设备端不需要关心内部文件名。3. 元数据回填self.apply_metadata(self.read_metadata(found))是继承自 BaseBackend 的通用能力read_metadata会在.dxnn文件所在目录寻找同级的metadata.yaml侧车文件sidecar解析出imgsz、stride、names、task、channels等字段apply_metadata再将其类型转换后逐一setattr到后端实例上。这一步至关重要——正是靠它Ultralytics 的推理流水线才能知道模型有多少类别、输入尺寸是多少、是否为端到端 NMS 模型从而在 NPU 原始输出之上正确执行后处理与可视化。导出阶段由 onnx2deepx 写入metadata.yaml推理阶段由BaseBackend读回二者首尾衔接。forwardDEEPX 运行时的张量契约forward方法deepx.py#L50-L70是DeepXBackend最核心的实现def forward(self, im: torch.Tensor) - np.ndarray | list[np.ndarray]: outputs [] for sample in im.cpu().numpy(): sample np.ascontiguousarray(np.clip(np.transpose(sample, (1, 2, 0)) * 255, 0, 255).astype(np.uint8)) for i, out in enumerate(map(np.asarray, self.model.run([sample]))): if i len(outputs): outputs.append([]) outputs[i].append(out if out.ndim and out.shape[0] 1 else out[None]) y [np.concatenate(x, axis0) for x in outputs] return y[0] if len(y) 1 else y对照 BaseBackend.forward 的抽象契约——输入为 BCHW、归一化到 [0,1] 的torch.Tensor返回可能需要后处理的原始输出——DeepXBackend在两者之间做了一次显式转换这是理解 DEEPX 部署的关键输入端BCHW float32 → HWC uint8DEEPX NPU 的运行时契约是HWC 布局、uint8 [0, 255] 精度的图像输入。因此每张图片在送入self.model.run([sample])前会经历im.cpu().numpy()把批次张量搬回 CPUNPU 通过主机内存交换数据不走 CUDA 设备np.transpose(sample, (1, 2, 0))单张样本从 CHW 转为 HWCnp.clip(...) * 255→astype(np.uint8)反归一化到 [0, 255] 并量化为 8 位整型np.ascontiguousarray保证内存连续避免运行时拷贝。值得强调的是模型内部的归一化÷255、BGR→RGB、resizepad 预处理已在导出编译期固化进.dxnn图中见 onnx2deepx 的 config.json 里div: 255.0、convertColor: BGR2RGB、resize: pad等预处理链所以推理端只需还原到 uint8 HWC 即可不会重复做数据增强式的前处理。逐样本运行与批量拼接DEEPX 运行时按单张图像调用self.model.run([sample])forward通过 Python 循环遍历批次内的每张图将多个输出张量按索引累加进outputs[i]最后np.concatenate(..., axis0)沿批维度拼回完整结果。多输出模型如检测 分割掩码返回list[np.ndarray]单输出模型返回单个np.ndarray——这与BaseBackend.forward的返回值类型声明一致。从源码结构看逐样本循环意味着 DEEPX 后端的吞吐优化主要依赖 NPU 内部的执行效率而非批量并行调度输出拼接后AutoBackend.forwardautobackend.py#L290-L326会通过from_numpy把np.ndarray转回torch.Tensor交给统一的 NMS/解码后处理。运行环境DX-Runtime 安装与验证DeepXBackend依赖 DEEPX 软件栈的三个组件按 DEEPX 集成文档 的说明在目标设备安装NPU 驱动dxrt-driver-dkms内核态驱动通过 .deb 包安装libdxrt运行时库用户态推理库dx_enginePython 包由libdxrt的make_whl.sh脚本生成本地 wheel 后pip install安装即DeepXBackend中 import 的那个InferenceEngine。# Install the NPU driver and libdxrt runtime sudo apt update wget https://github.com/DEEPX-AI/dx_rt_npu_linux_driver/raw/main/release/2.4.1/dxrt-driver-dkms_2.4.1-2_all.deb sudo apt install ./dxrt-driver-dkms_2.4.1-2_all.deb wget https://github.com/DEEPX-AI/dx_rt/raw/main/release/3.3.2/libdxrt_3.3.2_all.deb sudo apt install ./libdxrt_3.3.2_all.deb # Create dx-engine wheel cd /usr/share/libdxrt/python_package sudo ./make_whl.sh # Install the bundled dx_engine Python wheel pip install dx_engine-*.whl安装后可以用dxrt-cli --version验证正常输出会显示DXRT版本、最低驱动版本要求以及.dxnn文件格式版本当前为 v6。平台约束方面DEEPX 运行时同时支持 x86-64 Linux 与 ARM64 Linux如 Raspberry Pi 5即推理端跨架构但导出编译端只支持 x86-64 Linux——exporter.py#L1609 中export_deepx首行就是assert LINUX and not ARM64, DEEPX export only supported on non-aarch64 Linux。典型工作流是在 x86-64 Linux 服务器上执行yolo export modelyolo26n.pt formatdeepx编译出_deepx_model/再把整个目录部署到 ARM64 的 NPU 设备上由DeepXBackend加载。端到端使用Predict 与 Validate导出产物yolo26n_deepx_model/目录的标准结构为yolo26n_deepx_model/ ├── yolo26n.dxnn # Compiled DEEPX model binary (NPU executable) ├── config.json # Calibration and preprocessing configuration └── metadata.yaml # Model metadata (classes, image size, task, etc.)其中.dxnn由InferenceEngine直接加载metadata.yaml则被前述read_metadata读回。安装好运行时的设备上Predict 与 Validate 与 PyTorch 模型的使用方式完全一致from ultralytics import YOLO # Load the exported DEEPX model model YOLO(yolo26n_deepx_model) # Run inference results model(https://ultralytics.com/images/bus.jpg)yolo predict modelyolo26n_deepx_model sourcehttps://ultralytics.com/images/bus.jpg yolo val modelyolo26n_deepx_model datacoco8.yaml从 predictor.py 与 validator.py 的文档字符串示例可以看到yolo26n_deepx_model目录已被列为与.pt、.onnx并列的合法模型输入。补充导出端如何生成 DeepXBackend 可加载的模型DeepXBackend只负责用而造出.dxnn的是导出链 ultralytics/utils/export/deepx.py 中的onnx2deepx函数由 Exporter.export_deepx 调用流程为PyTorch → ONNX → dx_com 编译 → .dxnn自动从 DEEPX SDK 索引安装dx_com编译器deepx.py#L34-L38对应的 pyproject.toml 定义了export-deepx可选依赖生成config.json校准配置calibration_num: 100、calibration_method: emaEMA 校准并把校准数据集的图像目录写入default_loader.dataset_path调用dx_com.compile(...)完成 INT8 量化与硬件优化输出.dxnn二进制再落盘metadata.yaml强制 INT8exporter.py#L624-L631 中若quantize不为 8 会告警并自动改为 8显式请求quantize32则直接抛ValueError——因为 DEEPX NPU 以 INT8 为原生高效计算精度。这解释了DeepXBackend的输入为何是 uint8整个量化标定EMA 校准集与预处理链在编译期已经固化推理端只需要把图像还原回量化前约定的原始格式。小结与使用要点定位DeepXBackendultralytics/nn/backends/deepx.py是 UltralyticsBaseBackend体系下 DEEPX NPU 的推理实现经AutoBackend._BACKEND_MAP以_deepx_model/目录后缀自动分发加载load_model递归查找.dxnn文件用dx_engine.InferenceEngine加载并通过metadata.yaml侧车回填类别名、输入尺寸等元数据缺少dx_engine会抛出带安装指引的ImportError找不到.dxnn会抛FileNotFoundError推理契约forward将 BCHW float[0,1] 张量逐张转为 HWC uint8[0,255]逐样本调用model.run多输出时按批维度拼接单输出返回np.ndarray多输出返回list[np.ndarray]平台边界导出编译仅限 x86-64 Linux推理DeepXBackend所在环节支持 x86-64 与 ARM64 LinuxINT8 精度强制生效相关文档更完整的编译参数imgsz需为方形、data校准集、optimize等与基准数据参见 DEEPX 集成指南导出函数参考见 utils.export.deepx API。【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网