在 310B4 的 NPU 上 跑出第一个字:生态不支持
收藏回复举报
在 310B4 的 NPU 上 跑出第一个字:生态不支持
新人帖
发表于2026-07-25 19:24:05
0 查看

Orange Pi AI Pro · 昇腾 310B4 · CANN 8.5.1 · llama.cpp

整整一天,隧道通了,编译过了,模型就位了,但 NPU 推理本身一次都没成功跑完过。板子三次卡死,NPU 内存泄漏,只能靠重启解决。

这是踩坑记录,不是成功教程。

第一章

板子在办公室,我在远端——先把手伸进去

Orange Pi AI Pro 放在办公室角落,接着网线,不在身边。要操作它,第一步不是跑模型,而是想办法远程连进去。

这块板子没有公网 IP,但有 Cloudflare Zero Trust 隧道可以用。挑了个闲置域名 bopomofo.top,建了一个叫 orangepi 的隧道,把 SSH 暴露到 ssh.bopomofo.top

cloudflared tunnel create orangepi
cloudflared tunnel route dns orangepi ssh.bopomofo.top

连通性检测跑完,region2 的 TCP 有一条 FAIL,cloudflared 自动降级走 QUIC——不影响用,SSH 连上了。

小插曲

当时没意识到的问题:cloudflared 只是在前台手动跑着,一旦断连或板子重启,隧道就没了。这个埋雷埋了一整天。

SSH 一进去,马上踩坑。grepunamedirnamesed——这些连 Linux 用户都不会多想的命令,全部 command not found

排查了一会儿才明白:通过 CF 隧道进来的 SSH session,PATH 是空的。系统二进制路径根本没有被加进去。以后每次登录,都得先手动 export 一遍:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

不是什么大问题,但它会在之后的每一步操作里默默埋坑。


第二章

编译:通了——但我开始怀疑它有没有意义

目标是用 llama.cpp 的 CANN 后端把语言模型跑在 NPU 上。310B4 是华为昇腾芯片,它的 AI 框架叫 CANN,不是 CUDA。llama.cpp 官方支持 CANN 后端,但需要手动编译,并且踩坑从编译阶段就开始了。

按照官方文档配置好 cmake,开始构建。跑了一会儿,报错停了下来:

编译错误

get_row_q4_0.cpp: error:
  Cast<half, int4b_t> is not implemented for DAV-M200

Q4_0 量化格式的自定义内核需要 half → int4b_t 的类型转换,310B4 的核心架构 DAV-M200 没有实现这个操作。硬件级别的限制。

这里卡了一段时间。搜了社区,没找到针对 310B4 的现成 patch。然后出现了第一个真正的纠结:

纠结时刻 #1

Q4_0 内核编不过,怎么办?

绕过去

加 -DGGML_CANN_CUSTOM_KERNELS=OFF,禁用自定义内核,编译通过。快,今天能看到结果。

找根本解法

找华为 ATC 工具链,把模型转成 .om 格式,这才是 310B4 的设计用途。但工作量大,可能要几天。

选了绕过去。加了一个 cmake flag,编译顺利跑完,产出了完整的 llama.cpp 套件——llama-clillama-serverllama-bench……看起来一切就绪。

事后复盘

Q4_0 是最普遍的量化格式。把承载这组格式的内核全部关掉,NPU 能接的算子已经残缺了。这个绕路方案,从一开始就注定了 NPU 利用率会很低,只是当时没意识到。

还有一个小插曲:source CANN 环境变量脚本时,终端刷了几十行报错:

setenv_main:8: command not found: dirname
remove_env:5: command not found: tr
remove_env:5: command not found: grep
...

一开始以为环境没配成功,慌了一下。后来发现 LD_LIBRARY_PATH 其实已经设进去了——set_env.sh 的那些报错是 PATH 为空导致的副作用,不致命。先 export PATH 再 source,报错消失。这个坑的解法其实在第一章就埋好了,只是没及时用上。


第三章

板子第一次卡死

编译完,模型也有了——qwen2.5-7b-instruct-q4_k_m.gguf,Qwen2.5-7B Q4_K_M,放在 /root/llama.cpp/ 下。万事俱备,跑推理:

source /usr/local/Ascend/cann-8.5.1/set_env.sh
cd /root/llama.cpp
./build/bin/llama-cli \
  -m qwen2.5-7b-instruct-q4_k_m.gguf \
  -p "Hello" -n 20 --device CANN0

命令发出去,终端在等待。等了十几秒,没有输出。再等,还是没有。然后——

SSH 断了。

不是超时,是板子卡死了。llama-cli 开始把 7B 模型往 NPU 显存加载,这个过程把 CPU 和内存同时打满,整块板子失去响应。局域网直连 SSH 断,CF 隧道 SSH 也断。

只剩一条路:从 Pi5 通过 CF 隧道发一个杀进程的命令,赌 tunneld 还活着:

ssh root@ssh.bopomofo.top \
  'export PATH=...; pkill -9 llama-cli'

赌赢了,进程被杀。板子缓过来,SSH 重新能连。

整个过程没有看到任何推理输出,也不知道 NPU 有没有真的接到任务。唯一能确定的是:板子被搞崩了。


第四章

NPU 的&quot;残影&quot;:内存不释放,Alarm 状态

重新连进去,第一件事是看 NPU 状态:

| NPU Name | Health | Power(W) Temp(C) Hugepages
| Chip Device| Bus-Id | AICore(%) Memory-Usage(MB)
|============|============|==================================|
| 0 310B4 | Alarm | 0.0 52 |
| 0 0 | NA | 0 10658 / 15610 |

进程已死,NPU 却还占着 10658MB——超过总显存的三分之二。ps 里看不到任何模型推理进程,但 NPU 死活不肯释放这块内存,Health 也挂着 Alarm。

这时想到,应该有办法软件重置 NPU。试了:

npu-smi reset -i 0 -c 0
npu-smi reset

报错

Command or option is not found.
npu-smi Command: info / set / clear / upgrade

npu-smi 根本没有 reset 子命令。支持的只有 info、set、clear、upgrade。

纠结时刻 #2

NPU 内存泄漏,无法软件解决,怎么办?

找驱动层方案

尝试 rmmod / insmod NPU 驱动,重新挂载。风险高,可能让系统进入更糟的状态。

重启板子

最稳妥,也是唯一确定有效的方法。内存完全清零,状态归位。代价是要等。

选择等重启——但板子在办公室,已经快晚上了。


第五章

&quot;整整一天了,毛进展都没&quot;

这是真实说过的一句话。

白天折腾了隧道、SSH 的 PATH、CANN 的环境变量、Q4_0 内核报错、绕路编译、第一次跑推理卡死……每一步都在解决上一步暴露出来的问题,解决完又发现新的坑。进度感很强,但实际上往后退一步看:NPU 推理,一次都没真正跑通过。

最讽刺的是当时 npu-smi info 显示的状态:

Health: AlarmNPU 内存: 10658/15610 MBAICore: 0%llama.cpp: 编译完成模型文件: 就位cloudflared: 手动跑着

万事俱备,但 NPU 已经是一个半残废的状态,而且唯一的修复方法是重启,而重启意味着明天再说。

好不容易折衷再折衷,然后现在回家了,你跟我说连 SSH 进去都不行了。

是的。这就是这一天的结局:隧道断了,NPU 卡着,板子在办公室,人在回家的路上。


第六章

回头看:哪里走错了,下次怎么做

错误一:前台跑推理

直接 SSH 前台执行 llama-cli,模型加载时板子卡死,SSH 直接断。正确做法是用 nohup 后台跑,把日志写到文件,另开窗口 tail -f 监控,板子卡了还能从别的 SSH 窗口处理。

错误二:没验证 NPU 真的在用

在尝试推理之前,其实应该先确认 -DGGML_CANN_CUSTOM_KERNELS=OFF 的代价——运行一个最小模型,盯着 watch npu-smi info 看 AICore% 有没有变化。如果始终是 0%,说明 NPU 根本没接任务,后面所有推理尝试都是白费。

错误三:没装 systemd 服务

cloudflared 手动跑,板子一重启隧道就没了。应该第一天就装好 systemd 服务,之后所有连接才是可靠的。

下次重启后的正确操作顺序

Step 1 — 确认 NPU 干净

npu-smi info
# 确认 Memory-Usage 接近 0/15610,Health 为 OK

Step 2 — 装 cloudflared 服务(只需一次)

cloudflared service install
systemctl enable cloudflared
systemctl start cloudflared

Step 3 — 后台跑推理 + 同步监控

# 窗口 1:启动推理
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
source /usr/local/Ascend/cann-8.5.1/set_env.sh
source /usr/local/Ascend/ascend-toolkit/set_env.sh 2>/dev/null
cd /root/llama.cpp

nohup ./build/bin/llama-cli \
  -m qwen2.5-7b-instruct-q4_k_m.gguf \
  -p "你好,请介绍一下自己。" \
  -n 50 --device CANN0 \
  > /tmp/llama_run.log 2>&1 &
echo $! > /tmp/llama_run.pid
# 窗口 2:监控 NPU(AICore% > 0 才是真在用)
watch -n 1 npu-smi info

# 窗口 3:看推理输出
tail -f /tmp/llama_run.log

如果推理过程中 AICore% 一直是 0,就可以断定:-DGGML_CANN_CUSTOM_KERNELS=OFF 绕路方案行不通,需要换路线——找社区里针对 310B4 维护的 llama.cpp fork,或者走华为官方的 ATC + .om 格式转换流程。

那就是另一天的故事了。


第七章 · 终章

真相:这条路根本不存在

第二天,重启板子,NPU 内存清零,换了 Q8_0 格式的模型,29 层全部卸进 NPU 显存(7165MB 成功加载)——然后推理一启动就崩:

最终错误

AclNN_Runtime_Error(EZ9903): support for Ascend310B is not implemented
ggml_cann_mul_mat_quant → Get Allocation Granularity failed

不是量化格式问题,不是编译参数问题——310B 这颗芯片在 llama.cpp 的 CANN 后端里,矩阵乘法计算根本没有实现。

去查了 vLLM-Ascend 的支持矩阵,所有支持的硬件清一色是 A2/A3——也就是昇腾 910 系列,服务器级大卡。310B4 根本不在列。整个主流开源 LLM 推理生态(llama.cpp、vLLM、MindSpore-LLM 社区版)都是围绕 910 系列建的。

最终结论

310B4 是边缘推理芯片,设计目标是跑预编译的 .om 格式模型——YOLO、分类、OCR 这类固定计算图。它能跑 LLM,但唯一成熟的路径是用华为 ATC 工具把模型转成 .om 格式,完全绕开 Python/GGUF 生态。

不是没人试过,而是生态就没往这个方向走。

两天,六个坑,最后发现撞的不是墙,是悬崖。模型加载进了 NPU 内存,距离真正推理只差一步——但那一步,需要整个生态系统补齐才能迈出去。

310B4 跑 YOLO 目标检测是完全成熟的,NPU 在那个场景里能发挥真实价值。LLM 这条路,至少在 2026 年中,还是死路。

结案 · NPU LLM 推理:生态不支持

我要发帖子