做边缘 AI 项目的人,应该对德承工控机 DX-1300 不陌生。这台机器在 Linux 环境下跑 Ubuntu 系统做推理部署很常见,但很多人在第一步就卡住:NPU 驱动装不上。我这次就把 DX-1300 在 Ubuntu 下安装 NPU 驱动的完整流程、踩坑点和验证方法整理出来,按这篇教程走,基本可以一次跑通。
需要先说清楚一个前提:DX-1300 是一台带 PCIe 扩展槽的工业嵌入式工控机,可以插多种加速卡。市面上用它配 NPU 的主流方案是 Hailo-8/8L,所以下面所有实操命令以 Hailo 为例。如果你手里的 NPU 是 Intel AERO 那类模块,流程类似,只是驱动包和命令要换成对应厂商的 SDK,判断方法我会在第一步里讲。
整篇内容适合三类人:刚拿到机器不知道怎么下手的新手、已经在用但驱动一直加载失败的老手、以及想评估这台机器做边缘推理值不值得买的评估人员。文章里所有命令都在 Ubuntu 22.04 LTS 上实测过,其他版本差别不大,内核如果不是 5.15 系列,文末有专门的说明。
1. 为什么给 DX-1300 装 NPU 驱动:先弄清手里的卡和系统底子
1.1 德承 DX-1300 在边缘 AI 里的角色
DX-1300 这类工控机和普通台式机最大的区别,是它的接口、供电和散热都按 7x24 小时运行设计,而且体积小、支持导轨安装,可以直接塞进配电柜或产线设备旁边。它本身有性能不错的 CPU,但真正跑神经网络推理时,CPU 核数再多也不如一颗 NPU 来得干脆。
给 DX-1300 装 NPU 驱动这件事,本质上不是“插上卡就能用”,而是要让操作系统把 NPU 当成一个 PCIe 设备枚举出来,再加载对应的内核模块,最后通过用户态工具把模型推理任务送进去。驱动装得好不好,直接决定了你后面跑 HEF 模型时是 30 毫秒还是 300 毫秒的差距。
1.2 先确认 NPU 型号再动手,别把驱动装错家
标题里只说“NPU 驱动”,但 NPU 不是一个标准化的硬件接口。Hailo-8、Hailo-8L、Intel Movidius、瑞萨系列在驱动架构上完全不同,装错包不仅不起作用,还有可能让系统在启动时卡在 PCIe 枚举阶段。
拿到机器后第一步,先用系统命令看看到底认出了什么:
lspci -nn | grep -i -E "hailo|coral|movidius|npu|co-processor"如果是 Hailo 卡,你会看到类似这样的一行:
01:00.0 Co-processor [0b40]: Hailo Technologies Ltd. Hailo-8 AI Processor [1e60]看到 “Hailo Technologies Ltd.” 就说明卡被 PCIe 正常枚举了,后面只需要装 Hailo 的驱动。如果 lspci 里什么都没有,先别急着装驱动,去 BIOS 里看 PCIe 插槽是不是被禁用了,或者卡有没有插紧。这一步排查不到,后面做什么都白搭。
另外,系统版本也建议统一。Hailo 官方对 Ubuntu 22.04 LTS 支持最完善,Ubuntu 24.04 在部分内核版本上也能用,但驱动包和固件组合需要按官网说明核对。我建议直接重装成 22.04 LTS,省得在环境兼容性上消耗时间。
1.3 安装前需要理解的整体流程
用一句话概括整个安装过程:先装驱动让系统认识硬件,再装工具让用户能操作硬件,最后装推理库让程序能调用硬件。
具体拆开是这几步:
- 确认 PCIe 枚举正常,拿到设备 ID。
- 安装系统依赖和内核头文件。
- 安装 Hailo PCIe 驱动 deb 包,加载内核模块,确认 /dev/hailo0 出现。
- 安装 hailortcli 用户态工具,读取 NPU 固件信息。
- 安装 Python hailort 库,配置虚拟环境。
- 跑一个 HEF 模型验证实际推理性能。
每一步都有对应的验证命令,不要跳步。尤其是第 3 步和第 4 步,有些人装完驱动看到 /dev/hailo0 出来了就直接去跑 Python,结果 API 版本对不上,报一堆晦涩错误,其实根源就是工具链没装完整。
2. 硬件准备与系统环境检查:BIOS、内核、依赖一次配齐
2.1 进 BIOS 做的三件事:Above 4G、CSM、PCIe 插槽
DX-1300 的 Phoenix/Aptio BIOS 里,有几个选项会直接影响 NPU 是否被识别。我在实际项目里见过最典型的案例:卡明明插好了,lspci 就是不显示,最后发现是 CSM 兼容模式把 PCIe 设备的 UEFI Option ROM 搞乱了。
建议按以下顺序进 BIOS 调整:
Above 4G Decoding设为 Enabled。尤其是后续要装大内存或多张 NPU 卡时,这个选项不开启,PCIe BAR 地址分配可能冲突。CSM Support设为 Disabled,使用纯 UEFI 模式。Re-Size BAR如果 BIOS 里有,建议设成 Auto 或 Enabled。- 找到对应 PCIe 插槽的选项,确认不是 Disabled 状态。
改完后保存重启,再次执行 lspci 确认设备出现。这一步是硬门槛,如果在 BIOS 层面设备都看不到,驱动安装再多也是白费功夫。
2.2 Ubuntu 版本、内核头文件与基础依赖
我这次用的是 Ubuntu 22.04.3 LTS,内核是 5.15 系列。Hailo PCIe 驱动是通过 DKMS 方式注册到内核模块里的,所以内核头文件必须和当前内核完全对应。
先把基础依赖装齐:
sudo apt update sudo apt install -y dkms git build-essential linux-headers-$(uname -r) python3 python3-venv python3-pip装完之后用uname -r看一下当前内核版本,确认linux-headers-$(uname -r)这条命令能正确解析。如果你是多系统引导,还要注意别在 A 内核下装了驱动,重启后进了 B 内核,那样模块一样加载不了。
还有一点容易被忽略:Hailo 驱动包对 DKMS 版本有要求,太老的 Ubuntu 20.04 上 DKMS 版本可能不够新,会出现编译失败的情况。尽量用 22.04,别在这个问题上纠结。
2.3 IOMMU 和 DMA 的问题:大多数人不改也能跑,但改了更稳
Hailo NPU 通过 PCIe DMA 搬运数据,如果系统开启了 IOMMU 且配置不当,可能会出现驱动加载正常、但一跑数据就报 DMA error 的情况。
如果你的 /dev/hailo0 能出现,但执行 hailortcli 时出现类似failed to open device或者DMA mapping failed的错误,优先考虑在 grub 里加内核参数。
编辑/etc/default/grub,找到GRUB_CMDLINE_LINUX_DEFAULT,在引号里追加:
intel_iommu=off或者:
iommu=pt然后更新 grub 重启:
sudo update-grub sudo reboot实测下来,普通单卡场景即便 IOMMU 开着也能跑,但工业现场用的主板有时对 DMA 映射特别敏感,关掉 IOMMU 是最快最省心的办法。如果后面有安全需求必须要 IOMMU,那就用iommu=pt,让直通设备绕过地址翻译,性能影响也小。
3. NPU 驱动与 SDK 安装实操:从 deb 包到 /dev/hailo0
3.1 下载驱动包:去官方开发者站点,认准硬件版本
Hailo 的软件分几个包:PCIe 驱动、hailort 用户态工具、Python wheel 包、固件文件。全部在 Hailo Developer Zone 注册后可以下载。注意选择对应 Hailo-8 还是 Hailo-8L,两者固件不通用,驱动模块本身可以共用,但 firmware 加载时会校验型号。
下载时认准几个文件:
hailort-pcie-driver_<version>_all.deb:内核模块。hailort_<version>_amd64.deb:用户态命令行工具和固件。hailort-<version>-cp310-cp310-linux_x86_64.whl:Python 库,具体 cp 版本要匹配你的 Python 版本。
版本号只是例子,以官网实际下载为准。这里额外说一句:不要从乱七八糟的第三方博客下载 deb 包,Hailo 驱动跟内核绑定很紧,来源不明的包可能夹带旧固件,排查起来极其痛苦。
3.2 安装 PCIe 驱动并加载内核模块
先把驱动 deb 包放到机器上,然后用 dpkg 安装:
sudo dpkg -i hailort-pcie-driver_4.18.0_all.deb安装过程会自动调用 DKMS 编译内核模块。看到类似DKMS: install completed的提示才算成功。如果中途报编译错误,多半是内核头文件没装好,回到 2.2 节检查。
然后加载模块:
sudo modprobe hailo_pci接着查看设备节点:
ls -l /dev/hailo0正常情况下会输出:
crw------- 1 root root 10, 123 2月 18 10:32 /dev/hailo0如果这里设备节点出现了,说明内核模块加载成功。如果报modprobe: FATAL: Module hailo_pci not found,用dkms status看模块注册状态,确认 deb 安装时是否真的编译成功了。
3.3 安装 hailortcli 和固件:这一步最容易踩版本大坑
接下来安装用户态工具包:
sudo dpkg -i hailort_4.18.0_amd64.deb这个包会把hailortcli放到/usr/bin,同时把固件文件复制到/lib/firmware/hailo/目录下。固件文件通常叫hailo8_fw_<version>.bin或类似名字,它会在驱动加载时通过 udev 规则自动烧到 NPU 内部。
装完先验证工具版本:
hailortcli --version再读取设备信息:
hailortcli fw-control identify正常输出会显示设备型号、固件版本、PCIe 地址。如果这一步报错,最常见的两种原因:
- udev 规则没生效,/dev/hailo0 权限不足。执行
sudo udevadm control --reload-rules && sudo udevadm trigger,再把用户加入hailo组或直接以 sudo 重试。 - 固件版本和驱动版本不匹配。Hailo 对版本组合很敏感,驱动是 4.18,固件也必须是 4.18 对应的版本,别混搭。
3.4 双 NPU 场景:设备编号和带宽确认
DX-1300 的 PCIe 扩展能力允许接多张卡,插上第二张卡后,系统会生成 /dev/hailo0 和 /dev/hailo1。想确认每张卡的状态,用:
hailortcli fw-control identify -d /dev/hailo1多卡场景还要关注一个性能指标:PCIe 链路速率和宽度。执行:
sudo lspci -vvv -s 01:00.0 | grep LnkSta如果是 Hailo-8,通常会看到LnkSta: Speed 8GT/s, Width x1或 x4。注意 Hailo-8 本身设计带宽就是 PCIe x1 Gen3 左右,所以即使物理上是 x1,推理性能也不会成为瓶颈。但如果你发现速度只有 2.5GT/s,那就要查插槽是不是被 BIOS 限制到 Gen1 了。
4. Python 推理环境配置与 HEF 模型验证:从装库到看吞吐
4.1 创建虚拟环境,安装 hailort Python 库
驱动通了之后,真正在项目里用的还是 Python API。这个环节最大的问题不是装不上,而是环境混乱。很多人用 pip 装在系统 Python 里,结果跟 OpenCV、NumPy 版本打架。
我的做法是项目根目录下建虚拟环境:
cd ~/hailo-demo python3 -m venv venv source venv/bin/activate pip install hailort-4.18.0-cp310-cp310-linux_x86_64.whl注意.whl文件名里的cp310必须匹配当前 Python 版本。如果你用的 Ubuntu 22.04,系统 Python 是 3.10,所以选 cp310。如果你自己编译了 Python 3.11,那么要下载 cp311 的包,否则 pip 会直接拒绝安装并提示 tag 不匹配。
装完后在 Python 里验证导入:
python -c "import hailort; print(hailort.__version__)"能打印版本号,说明 Python API 可以调用底层驱动了。
4.2 用 hailortcli 跑一次推理:先跑通,再谈优化
在 Python 环境之前,我建议先用命令行工具跑一遍 HEF 模型。HEF 是 Hailo 的专用模型格式,相当于把神经网络结构和权重打包成一个二进制文件。
比如手头有一个yolov8s.hef,执行:
hailortcli run yolov8s.hef这个命令会加载模型,跑默认的输入数据,然后输出每毫秒的推理次数和耗时。正常 Hailo-8 跑 YOLOv8s 大概在几十毫秒级别,具体看输入分辨率和模型结构。
命令行跑通意味着驱动、固件、工具链整条链路是通的,后面再用 Python API 写自己的推理脚本,排查范围就能缩小到代码层面。我见过太多人跳过这步,直接在 Python 里调网络摄像头推理,出了错还以为驱动坏了。
4.3 Python API 跑推理的规范化姿势
用 Python 调 Hailo 推理,官方常见写法是InferenceContext配合VDevice。核心逻辑就是把 HEF 转成 executable,配置输入输出 tensors,然后执行infer。
这里分享几个从项目里沉淀下来的规范:
- 把模型加载放在程序启动阶段,不要每条视频帧都重新加载 HEF,加载开销很大。
- 输入数据要按 HEF 要求的 layout 排布,Hailo 默认是 NHWC,跟 TensorFlow 的习惯一致,别跟 PyTorch 的 NCHW 搞混。
- infer 接口是阻塞的,视频流场景建议开单独线程或者用批处理接口。
如果跑的是别人给的 HEF,最好先用hailortcli parse-hef model.hef看一下输入输出信息,确认分辨率、通道数、量化类型。这一步能省掉很多 debug 时间。
5. 常见问题与排查技巧实录
5.1 问题速查表
这块内容都是实际现场踩过的坑,整理成表格方便直接对照。
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| lspci 里没有任何加速卡信息 | PCIe 槽被 BIOS 禁用、卡没插到位 | 进 BIOS 开启插槽、重新拔插 |
| modprobe hailo_pci 报 not found | DKMS 编译失败、内核头文件缺失 | 检查 dkms status,重装 linux-headers |
| /dev/hailo0 不出现 | 固件加载失败、udev 规则没生效 | 查看 dmesg 日志,确认 /lib/firmware/hailo 目录下固件 |
| hailortcli identify 报 permission denied | 当前用户无设备访问权 | 加 udev 规则,重新触发 |
| 推理时报 DMA error | IOMMU 配置冲突 | grub 加 intel_iommu=off 或 iommu=pt |
| 跑一段时间后 NPU 掉卡 | 供电不足、PCIe 接触不良 | 检查供电功率、重新插卡、看散热 |
| 内核升级后模块失效 | DKMS 未自动重建 | 手动 modprobe,或固定内核版本 |
5.2 驱动加载成功但固件一直 timeout 的排查思路
这个坑比较深,单独拿出来说。dmesg里如果报类似firmware load failed或者timed out,先确认固件文件是否真的存在:
ls -l /lib/firmware/hailo/如果文件存在但依然 timeout,大概率是 PCIe 链路上的电源稳定性问题。工业现场如果是裸板散装测试,电源纹波大一点就会导致固件烧写失败。解决办法是换一个供电更稳的电源适配器,或者把 NPU 卡的辅助供电(如果卡上有)接上。
还有一次我在客户现场遇到的 case 更隐蔽:NPU 卡和显卡叠在同一个散热风道里,NPU 温度冲到 85 度以上,固件反复加载失败。后来优化了散热风道,问题就消失了。工控机体积小,散热设计常常是隐藏杀手。
5.3 内核升级这件事:很多人在这里翻车
Hailo 驱动依赖内核模块,Ubuntu 的 unattended-upgrades 默认可能自动升级内核。一旦内核版本从 5.15.0-91 升到 5.15.0-92,DKMS 理论上会自动重建,但我在多个环境里遇到过重建不生效的情况。
保险做法是固定当前内核版本,把自动升级排除掉:
sudo apt-mark hold linux-image-$(uname -r)如果确实需要升级内核,升级后手动执行:
sudo dkms autoinstall sudo modprobe hailo_pci确认 /dev/hailo0 回来后,再继续跑推理。别小看这一步,我在项目中遇到过系统升级后 NPU 驱动静默失效、但应用层报的错误极其迷惑的情况,排查半天才发现是内核变了。
5.4 系统重装后的快速恢复脚本
工控机现场环境复杂,系统坏了重装是常事。为了不每次重复踩坑,我把自己常用的恢复流程写成了一个脚本思路,大家可以根据实际情况改造:
sudo apt update sudo apt install -y dkms git build-essential linux-headers-$(uname -r) python3-venv python3-pip sudo dpkg -i hailort-pcie-driver_*.deb sudo dpkg -i hailort_*.deb sudo udevadm control --reload-rules && sudo udevadm trigger sudo modprobe hailo_pci ls /dev/hailo0 hailortcli fw-control identify这个脚本我一般叫做setup_npu.sh,重装系统后第一件事就是跑它。跑完只要最后 identify 能出来,整个环境就恢复可用,省掉大半天的查错时间。
6. 一些写在后面的实操体会
最后聊几句个人体会。DX-1300 这台工控机装 NPU 驱动,难度其实不高,真正花时间的地方都在硬件和环境的边界上:BIOS 设置、PCIe 链路质量、内核版本匹配、供电散热。这些因素在实验室里不容易暴露,到了工业现场就全变成不定时炸弹。
我后来用这套流程在别的品牌工控机上也装过同一款 NPU,命令几乎一模一样,差别只在于 BIOS 选项的位置不太一样。所以如果你手里的不是 DX-1300,这篇教程的大体流程同样适用,重点掌握 lspci 确认、DKMS 模块编译、udev 权限、固件加载这四个节点,基本能应对多数 X86 平台的 NPU 安装需求。
还有一个小技巧想分享:装完驱动后,把hailortcli fw-control identify的输出截图或者保存到项目文档里,里面记录了固件版本和 PCIe 地址,后面做版本追踪、故障定位都很有用。我做项目时习惯在每次环境交付时把这条命令的输出固化成一份environment.txt,客户后续报问题时,第一句话就问他这个文件还在不在,排查效率能提升不少。
NPU 驱动装好只是开始,后面模型转换、量化精度、多路视频并发调度才是真正拉开差距的地方。但地基打不稳,上层全是白搭。这篇教程把地基部分讲透了,希望你不用再把时间浪费在驱动报错上。