1. 部署总览与前置条件
1.1 本次部署范围
底层 Debian 12 系统已由厂家预装并启动,本次部署覆盖以下内容(从「软件环境」开始,不含系统烧录):
- Python 3.11 虚拟环境 + RKNN Lite SDK(NPU 推理)
- 项目代码(main.py + src/ 15 类算法)传输到盒子
- 15 个 .rknn 模型文件部署到 models/ 目录(核心步骤)
- config.yaml 配置 MQTT 服务器地址 + 摄像头 RTSP 地址
- 单次运行验证 → systemd 服务自启动 → 验收
1.2 硬件确认
| 项目 | 确认值 | 检查方式 |
|---|---|---|
| SoC 型号 | RK3588(4×A76 + 4×A55) | cat /proc/cpuinfo |
| 内存 | 4GB LPDDR4X | free -h |
| 存储 | 32GB eMMC(可扩 MicroSD) | df -h |
| NPU 设备节点 | /dev/galcore 存在 | ls -la /dev/galcore |
| 网络 | 有线 RJ45 / 4G 模块 | ip addr |
| 摄像头 | USB(UVC) 或 RTSP IP 摄像头 | lsusb / v4l2-ctl --list-devices |
⚠️ 部署前必查:若 /dev/galcore 不存在,说明 NPU 驱动未加载,不要继续安装,先执行 dmesg | grep rknpu 排查驱动,或联系厂家确认内核版本。
1.3 传输方式准备
从开发机传输代码与模型到盒子的三种方式:
# 方式 A:scp(推荐,同一局域网)
scp -r edge-ai-box/* root@192.168.1.200:/opt/edge-ai/
# 方式 B:U 盘拷贝(无网络时)
# U 盘挂载:mount /dev/sda1 /mnt && cp -r /mnt/edge-ai-box/* /opt/edge-ai/
# 方式 C:git 拉取(代码已托管时)
cd /opt && git clone <仓库地址> edge-ai2. Python 环境 + RKNN SDK 安装
2.1 安装 Python 3.11 与虚拟环境
# 1. 安装 Python 与基础工具
apt update
apt install -y python3.11 python3.11-dev python3.11-venv python3-pip vim curl git htop
# 2. 创建项目目录与虚拟环境
mkdir -p /opt/edge-ai
python3.11 -m venv /opt/edge-ai/venv
source /opt/edge-ai/venv/bin/activate
pip install --upgrade pip setuptools wheel
注意:若 apt 找不到 python3.11,先 apt install -y software-properties-common && add-apt-repository ppa:deadsnakes/ppa(Debian 需启用对应源)再重试。
2.2 安装 RKNN Lite2 SDK(NPU 推理引擎)
# 1. 下载适用于 RK3588 / aarch64 / Python3.11 的 RKNN Lite2 wheel
cd /tmp
wget https://github.com/airockchip/rknn-toolkit2/releases/download/v2.0.0/rknn_toolkit_lite2-2.0.0-cp311-cp311-linux_aarch64.whl
# 2. 安装(在 venv 内)
pip install rknn_toolkit_lite2-2.0.0-cp311-cp311-linux_aarch64.whl
# 3. 验证 NPU 可用
python3 -c "from rknnlite.api import RKNNLite; print('RKNN Lite OK')"
# 成功输出:RKNN Lite OK
⚠️ 版本一致性(最易踩坑):
① .rknn 模型文件必须用与盒子端 SDK 同大版本的 RKNN-Toolkit2(PC 端转换工具)生成——例如盒子装 rknn-toolkit-lite2 v2.0.0,模型须用 rknn-toolkit2 v2.0.0 在 PC 上导出;
② 若厂家固件预装了不同版本,先 pip show rknn-toolkit-lite2 确认版本,再决定模型转换端版本。
2.3 安装项目依赖
cd /opt/edge-ai
pip install -r requirements.txt
# 关键依赖:paho-mqtt / opencv-python / numpy / PyYAML / msgpack / colorlog / requests
# 可选(人脸识别 30 万库检索加速)
pip install faiss-cpu
# 摄像头依赖(Debian 需装系统级 OpenCV)
apt install -y libopencv-dev python3-opencv ffmpeg v4l-utils
# 验证 OpenCV
python3 -c "import cv2; print('OpenCV', cv2.__version__)"
注意:若 pip 安装 opencv 编译慢/失败,可改用 pip install opencv-python-headless(纯推理场景无需 GUI),再用 apt install python3-opencv 提供 GStreamer 加速。
3. 项目代码部署
3.1 目录结构
/opt/edge-ai/
├── main.py # 主程序入口
├── config.yaml # 运行配置(MQTT/摄像头/识别参数)
├── model_config.yaml # 15 类算法模型配置
├── requirements.txt
├── models/ # ← 15 个 .rknn 模型文件放这里(核心)
│ └── face_db/ # 人脸特征库
├── src/
│ ├── algorithms/ # 15 类算法实现(每类一个 .py)
│ ├── inference/ # RKNN 推理引擎
│ ├── mqtt/ # MQTT 上报客户端 + 协议
│ └── utils/
├── snapshots/ # 抓拍图(告警事件截图)
└── logs/ # 运行日志
3.2 代码传输与目录初始化
# 传输(按 1.3 任选一种),然后:
cd /opt/edge-ai
mkdir -p models/face_db snapshots logs
chmod 644 models/*.rknn 2>/dev/null || true
chmod +x main.py3.3 代码自检(可选但建议)
# 语法检查全部 Python 文件
find /opt/edge-ai -name "*.py" -exec python3 -m py_compile {} \;
echo "全部通过"4. 模型文件部署(核心步骤)
✅ 本步是部署的关键。15 类算法对应 20 个模型文件(部分算法复用同一模型),模型格式统一为 .rknn(RKNN-Toolkit2 从 PyTorch/ONNX 转换导出)。
4.1 模型文件清单(必须齐全)
| 算法 | 优先级 | 模型文件(models/ 下) | 输入尺寸 | 说明 |
|---|---|---|---|---|
| 安全帽 safety_hat | P0 | safety_hat.rknn | 640×640 | 检测帽/未戴帽 |
| 反光衣 reflective_vest | P0 | reflective_vest.rknn | 640×640 | 检测穿/未穿 |
| 区域入侵 intrusion | P0 | intrusion.rknn | 640×640 | 人员检测 |
| 人脸识别 face_recognition | P1 | face_detect.rknn + face_feature.rknn | 320 / 112 | 检测+特征提取(双模型) |
| 吸烟 smoking | P1 | smoking.rknn | 416×416 | 检测吸烟 |
| 打电话 phone | P1 | phone.rknn | 416×416 | 检测打电话 |
| 人员聚集 gathering | P1 | gathering.rknn | 640×640 | 人员计数+聚集判断 |
| 车辆属性 vehicle | P1 | vehicle_detect.rknn + vehicle_attr.rknn | 640 | 检测+类型/颜色 |
| 在离岗 on_off_duty | P1 | person_detect.rknn | 416×416 | 行人检测 |
| 人流量 people_count | P1 | people_count.rknn(可复用 person_detect) | 640×640 | V3.2 虚拟线计数 |
| 车辆结构化 vehicle_struct | P0 | vehicle_struct_detect.rknn + vehicle_struct_type.rknn + vehicle_struct_color.rknn + vehicle_struct_dir.rknn | 640 | V3.2 4 模型:检测+车型6+颜色14+方向4 |
| 车辆违停 vehicle_parking | P0 | vehicle_parking.rknn(可复用 vehicle_detect) | 640×640 | V3.2 停留时长分级 |
| 品牌型号 vehicle_brand | P1 | brand_detect.rknn + brand_class.rknn | 320 | V3.2 2000 类分类 |
| 烟雾 smoke | P0 消防 | smoke_detect.rknn + smoke_type.rknn | 640 | V3.2 白/黑/灰烟 |
| 火焰 fire | P0 消防 | fire_detect.rknn + fire_type.rknn | 640 | V3.2 明/暗火 |
共需文件:20 个 .rknn(15 类算法,其中人脸/车辆结构化等多模型组合)。
4.2 模型转换参考(PC 端,非盒子端)
模型须在 PC(x86)上安装 rknn-toolkit2 转换,盒子只运行 rknn-toolkit-lite2。转换脚本示例:
# PC: models/convert/convert_yolo.py
from rknn.api import RKNN
rknn = RKNN()
# target_platform 必须与盒子 SoC 一致:RK3588
rknn.config(
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]],
target_platform='rk3588',
optimization_level=3,
quantized_dtype='asymmetric_quantized-8', # INT8 量化
)
# 从 ONNX 转换(先导出 ONNX,再转 RKNN)
rknn.load_onnx(model='safety_hat.onnx')
rknn.build(do_quantization=True, dataset='./calibration.txt') # 需校准图集
rknn.export_rknn('safety_hat.rknn')
rknn.release()
⚠️ 转换要点:
① target_platform='rk3588'(注意:旧文档写 rk3576 是早期型号,本盒子是 RK3588);
② INT8 量化必须提供 calibration.txt 校准图片清单(每类 20-100 张代表性图片);
③ 分类模型(车型/颜色/方向/品牌/烟型/火型)输出层用 softmax,检测模型(YOLO)输出为 3 个 head;
④ 转换后务必在 PC 端用 rknn.build(do_quantization=True) 的模拟器验证精度(quantized 输出对比 float 输出)。
4.3 模型文件传输与校验
# 传输到盒子
scp models/*.rknn root@192.168.1.200:/opt/edge-ai/models/
# 校验完整性(数量 + 权限)
ls -la /opt/edge-ai/models/*.rknn | wc -l # 期望 20
chmod 644 /opt/edge-ai/models/*.rknn
# 单个模型推理冒烟(先验证 NPU 能跑通)
cd /opt/edge-ai && source venv/bin/activate
python3 -c "
from src.inference.engine import RKNNEngine
import cv2
engine = RKNNEngine('models/safety_hat.rknn', npu_core=2)
if engine.load():
img = cv2.imread('snapshots/test.jpg') # 放一张测试图
out = engine.infer(img)
print('推理 OK, 输出:', [o.shape for o in out])
engine.release()
else:
print('模型加载失败 — 检查 .rknn 文件与 SDK 版本')
"4.4 人脸库初始化(可选,仅启用 face_recognition 时)
# 人脸库路径:config.yaml 的 recognition.face_db_path
mkdir -p /opt/edge-ai/models/face_db
# 每个人员一个 .pkl:{"name": "张三", "features": np.ndarray(512,)}
# 从后端系统同步特征文件后构建 faiss 索引(30 万级加速)
python3 -c "
import faiss, numpy as np, pickle, os
features = []
names = []
for f in sorted(os.listdir('/opt/edge-ai/models/face_db')):
if f.endswith('.pkl'):
with open(f'/opt/edge-ai/models/face_db/{f}', 'rb') as fp:
d = pickle.load(fp)
features.append(d['features']); names.append(d['name'])
if features:
idx = faiss.IndexFlatIP(512)
idx.add(np.array(features, dtype=np.float32))
faiss.write_index(idx, '/opt/edge-ai/models/face_db/index.faiss')
print(f'人脸索引构建完成: {idx.ntotal} 人')
"5. 配置文件修改(MQTT / 摄像头)
5.1 MQTT 上报配置(config.yaml)
mqtt:
broker: "192.168.1.10" # ← 改为后端服务器 IP(必须改)
port: 1883
client_id: "edge-ai-box-001" # ← 每台盒子唯一
topic_recognition: "vehicle/ai/recognition"
topic_telemetry: "vehicle/telemetry"
topic_command: "vehicle/command"
username: "edge_box" # 后端 MQTT 账号(如有)
password: "your_password"
keepalive: 60
qos: 1
注意:MQTT broker 必须改成后端服务器实际 IP;若后端未启用 MQTT,可先用 HTTP 备用通道验证(main.py 检测到 MQTT 失败会降级为仅记录)。
5.2 摄像头配置(config.yaml)
cameras:
- id: 1
name: "大门/出入口"
rtsp_url: "rtsp://192.168.1.100:554/stream1" # ← 改为实际 RTSP 地址
vehicle_id: 1
detection_area: null # 区域入侵多边形 [[x1,y1],[x2,y2],...]
parking_area: null # 违停检测区域
count_line: [[0, 540], [1920, 540]] # 人流量虚拟线
enable_algorithms:
- safety_hat
- reflective_vest
- people_count
- vehicle_struct
- vehicle_brand
- vehicle_parking
- id: 2
name: "驾驶位/车厢"
rtsp_url: "rtsp://192.168.1.100:554/stream2" # ← 改为实际地址
vehicle_id: 1
enable_algorithms:
- smoking
- phone
- face_recognition
- on_off_duty
- gathering
- intrusion
- smoke
- fire
⚠️ 摄像头配置要点:
① USB 摄像头本地采集填 rtsp_url 也可写 /dev/video0(main.py 支持两种);
② enable_algorithms 按摄像头视角分配:室外大门配车辆类+安全帽,驾驶舱配行为类+消防类;
③ detection_area/parking_area 多边形坐标与后端「AI检测区域」配置一致(前端 Leaflet 绘制后下发)。
5.3 识别参数(按需调整)
recognition:
frame_interval: 5 # 每 5 帧推理 1 次(30fps → 6fps 推理)
min_confidence: 0.5 # 低于此置信度丢弃
auto_alert_confidence: 0.9 # ≥0.9 直接告警,不入复审
dedup_interval: 5 # 同类型同目标去重(秒)
gathering_threshold: 5 # 聚集人数阈值
people_count_interval: 60 # 人流量聚合周期
parking_duration_levels: [60, 300, 600] # 违停分级时长
fire_score_threshold: 0.6 # 消防更高阈值防误报6. 启动与功能验证
6.1 单次前台运行(先验证)
cd /opt/edge-ai && source venv/bin/activate
python3 main.py -c config.yaml -m model_config.yaml预期输出:
[INFO] 加载模型: safety_hat OK
[INFO] 加载模型: reflective_vest OK
...
[INFO] 15 类算法全部加载
[INFO] MQTT 连接成功: 192.168.1.10:1883
[INFO] 摄像头 1 打开成功: rtsp://...
[INFO] 开始推理循环6.2 模型加载失败排查(重点)
常见错误:E RKNN: RKNN_ERR_MODEL_INVALID → 模型文件损坏或版本不匹配;E RKNN: RKNN_ERR_PARAM_INVALID → input_size/anchors 与模型不符。
解法:① 确认 .rknn 与 SDK 同版本(4.2 节);② 核对 model_config.yaml 的 input_size 与模型实际输入一致;③ 重新导出模型。
6.3 端到端验证(识别上报 → 后端接收)
# 方式 1:订阅 MQTT 观察识别事件
apt install -y mosquitto-clients
mosquitto_sub -h 192.168.1.10 -t "vehicle/ai/recognition" -v
# 期望看到:{"type":"recognition","recognitionType":"safety_hat","confidence":0.95,...}
# 方式 2:后端 API 查询(确认已入库)
curl -H "Authorization: Bearer <token>" \
"http://192.168.1.10:8080/ai/recognition/list?pageNum=1&pageSize=5"
# 期望返回最近识别记录(含 recognitionType / confidence / snapshotUrl)6.4 消防事件验证(CRITICAL 最高优先级)
# 用打火机/手机屏幕模拟火焰靠近摄像头,期望:
# ① MQTT 收到 eventLevel=5 的 fire 事件
# ② 后端 /ai/fire-alarm/list 出现记录
# ③ 大屏触发全屏弹窗 + 声光报警(GPIO 联动)7. 自启动与守护
7.1 创建 systemd 服务
cat > /etc/systemd/system/edge-ai-box.service << 'EOF'
[Unit]
Description=Edge AI Box — Smart Access Vehicle Recognition
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/edge-ai
Environment="PYTHONUNBUFFERED=1"
Environment="RKNN_LOG_LEVEL=2"
ExecStartPre=/bin/sleep 10 # 等待网络就绪
ExecStart=/opt/edge-ai/venv/bin/python main.py -c config.yaml -m model_config.yaml
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=30
StandardOutput=append:/opt/edge-ai/logs/service.log
StandardError=append:/opt/edge-ai/logs/service_error.log
MemoryMax=2G
CPUQuota=300%
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable edge-ai-box
systemctl start edge-ai-box
systemctl status edge-ai-box7.2 日志轮转(防磁盘写满)
cat > /etc/logrotate.d/edge-ai-box << EOF
/opt/edge-ai/logs/*.log {
daily
rotate 7
maxsize 100M
compress
delaycompress
missingok
notifempty
copytruncate
}
EOF7.3 看门狗(防服务假死)
# systemd 定时器每 5 分钟健康检查,失败自动重启服务
cat > /etc/systemd/system/edge-ai-watchdog.service << 'EOF'
[Unit]
Description=Edge AI Watchdog
[Service]
Type=oneshot
ExecStart=/opt/edge-ai/venv/bin/python -c "
import requests, subprocess, sys
try:
r = requests.get('http://192.168.1.10:8080/ai/recognition/list?pageSize=1', timeout=5)
if r.status_code == 200:
sys.exit(0)
except: pass
subprocess.run(['systemctl', 'restart', 'edge-ai-box'])
"
EOF
cat > /etc/systemd/system/edge-ai-watchdog.timer << 'EOF'
[Unit]
Description=Edge AI Watchdog Timer
[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
EOF
systemctl enable edge-ai-watchdog.timer
注意:看门狗的健康检查请求会访问后端——若后端 IP 变化需同步修改;若部署离线(无后端),可改用本地进程检查(pgrep -f main.py)。
8. 性能调优
8.1 NPU 双核 + 半精度(model_config.yaml)
optimization:
npu_cores: 2 # RK3588 双核 NPU 并行
batch_size: 1
fp16: true # 半精度加速 1.5~2×
perf_profile: "balance" # performance / balance / power_saving8.2 CPU 性能模式(车载稳定优先可跳过)
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor8.3 跳帧策略(平衡算力)
# config.yaml
recognition:
frame_interval: 5 # 安全帽/反光衣等低频场景
# 吸烟/打电话: 3 # 中等频率
# 入侵/聚集: 2 # 高频场景8.4 预期指标
| 指标 | 目标 | 说明 |
|---|---|---|
| 单帧推理延迟 | < 50ms | NPU INT8 |
| 多模型并发 FPS | > 10fps | 双 NPU 核 + 跳帧 |
| CPU 使用率 | < 60% | 不含视频解码 |
| 内存 | < 1.5GB | 含模型加载 |
| NPU 温度 | < 80°C | 风扇自动调速 |
9. 常见故障排查
| 症状 | 排查步骤 |
|---|---|
NPU 推理失败RKNNAPI init failed | ① dmesg | grep rknpu 驱动是否加载;② ls /dev/galcore 设备节点;③ pip show rknn-toolkit-lite2 SDK 版本;④ 模型与 SDK 版本匹配(4.1/4.2);⑤ 模型权限 ls -la models/*.rknn |
| 模型加载报 MODEL_INVALID | .rknn 文件损坏或转换版本不匹配 → 用同版本 Toolkit2 重新导出(4.2) |
| MQTT 连不上 | ① ping 192.168.1.10;② nc -zv 192.168.1.10 1883;③ 账号密码是否正确;④ 后端 MQTT 是否启用(未启用则降级为仅记录) |
| 摄像头打不开 | ① USB: lsusb / v4l2-ctl --list-devices;② RTSP: ffprobe rtsp://...;③ 确认 rtsp_url 拼写 |
| 识别事件不上报 | ① 前台运行看日志;② 阈值太高(min_confidence);③ 去重间隔太短;④ MQTT topic 与后端订阅不一致 |
| 内存不足 MemoryError | 减少同时加载模型数 / 用 npu_cores=1 / 关闭 fp16 减小显存占用 |
日志关键词速查
| 日志关键词 | 含义 | 处理 |
|---|---|---|
RKNN init runtime failed | NPU 被占用/内核异常 | rmmod rknpu && modprobe rknpu |
MQTT connection refused | Broker 未运行/防火墙 | 检查 Broker 状态与网络 |
Failed to open RTSP stream | 摄像头掉线 | 检查供电/网络,配置自动重连 |
CUDA/OpenCL not available | 正常(NPU 推理) | 忽略 |
10. 验收 Checklist
- Debian 12 启动正常,
/dev/galcore存在(NPU 驱动就绪) - Python 3.11 venv + rknn-toolkit-lite2 安装成功(
RKNN Lite OK) - 项目代码部署到
/opt/edge-ai/,依赖安装完成 - 20 个 .rknn 模型文件放入
models/(ls | wc -l = 20) - 单模型推理冒烟通过(safety_hat.rknn)
- config.yaml 的 MQTT broker 改为后端 IP
- config.yaml 的摄像头 rtsp_url 改为实际地址
-
python3 main.py前台运行:15 类模型全加载、无报错 - 识别事件 MQTT 上报成功(mosquitto_sub 可见)
- 后端
/ai/recognition/list能查到识别记录 - 消防事件(烟雾/火焰)触发 CRITICAL + 大屏弹窗
- systemd 服务
edge-ai-box启动成功并enable -
reboot后服务自动恢复(自启动验证)