1. 部署总览与前置条件

1.1 本次部署范围

底层 Debian 12 系统已由厂家预装并启动,本次部署覆盖以下内容(从「软件环境」开始,不含系统烧录):

  1. Python 3.11 虚拟环境 + RKNN Lite SDK(NPU 推理)
  2. 项目代码(main.py + src/ 15 类算法)传输到盒子
  3. 15 个 .rknn 模型文件部署到 models/ 目录(核心步骤)
  4. config.yaml 配置 MQTT 服务器地址 + 摄像头 RTSP 地址
  5. 单次运行验证 → systemd 服务自启动 → 验收

1.2 硬件确认

项目确认值检查方式
SoC 型号RK3588(4×A76 + 4×A55)cat /proc/cpuinfo
内存4GB LPDDR4Xfree -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-ai

2. 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.py

3.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_hatP0safety_hat.rknn640×640检测帽/未戴帽
反光衣 reflective_vestP0reflective_vest.rknn640×640检测穿/未穿
区域入侵 intrusionP0intrusion.rknn640×640人员检测
人脸识别 face_recognitionP1face_detect.rknn + face_feature.rknn320 / 112检测+特征提取(双模型)
吸烟 smokingP1smoking.rknn416×416检测吸烟
打电话 phoneP1phone.rknn416×416检测打电话
人员聚集 gatheringP1gathering.rknn640×640人员计数+聚集判断
车辆属性 vehicleP1vehicle_detect.rknn + vehicle_attr.rknn640检测+类型/颜色
在离岗 on_off_dutyP1person_detect.rknn416×416行人检测
人流量 people_countP1people_count.rknn(可复用 person_detect)640×640V3.2 虚拟线计数
车辆结构化 vehicle_structP0vehicle_struct_detect.rknn + vehicle_struct_type.rknn + vehicle_struct_color.rknn + vehicle_struct_dir.rknn640V3.2 4 模型:检测+车型6+颜色14+方向4
车辆违停 vehicle_parkingP0vehicle_parking.rknn(可复用 vehicle_detect)640×640V3.2 停留时长分级
品牌型号 vehicle_brandP1brand_detect.rknn + brand_class.rknn320V3.2 2000 类分类
烟雾 smokeP0 消防smoke_detect.rknn + smoke_type.rknn640V3.2 白/黑/灰烟
火焰 fireP0 消防fire_detect.rknn + fire_type.rknn640V3.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-box

7.2 日志轮转(防磁盘写满)

cat > /etc/logrotate.d/edge-ai-box << EOF
/opt/edge-ai/logs/*.log {
    daily
    rotate 7
    maxsize 100M
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
EOF

7.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_saving

8.2 CPU 性能模式(车载稳定优先可跳过)

echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor

8.3 跳帧策略(平衡算力)

# config.yaml
recognition:
  frame_interval: 5   # 安全帽/反光衣等低频场景
  # 吸烟/打电话: 3     # 中等频率
  # 入侵/聚集: 2       # 高频场景

8.4 预期指标

指标目标说明
单帧推理延迟< 50msNPU 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 failedNPU 被占用/内核异常rmmod rknpu && modprobe rknpu
MQTT connection refusedBroker 未运行/防火墙检查 Broker 状态与网络
Failed to open RTSP stream摄像头掉线检查供电/网络,配置自动重连
CUDA/OpenCL not available正常(NPU 推理)忽略

10. 验收 Checklist