💡前言

上一篇我们讲述了基于高通跃龙IQ-9100的图像检测半自动化标注系统搭建实践中的系统背景、架构设计与模型选型,这一篇我们继续讲解高通跃龙IQ-9100的图像检测半自动化标注系统中的边缘部署实践、系统实现、性能优化与实战效果。

1. IQ-9100边缘部署实践

1.1 开发环境搭建

IQ-9100的开发环境搭建分为主机端(Host)和设备端(Target)两部分:

主机端环境(Ubuntu 20.04/22.04)

  • Qualcomm AI Runtime SDK (QAIRT v2.x):包含qnn-onnx-converter、qnn-net-run等模型转换和验证工具。
  • Qualcomm Package Manager (QPM):SDK包管理工具。
  • Python 3.8+ 和 PyTorch/ONNX 环境:用于模型训练和导出。
  • ADB工具:用于与IQ-9100开发板通信。

设备端环境(IQ-9100开发板)

  • Qualcomm Linux/Android BSP:预装设备驱动和运行时库。
  • QNN Runtime Libraries:libQnnHtp.so(NPU后端)、libQnnCpu.so(CPU后端)。
  • GStreamer Pipeline:用于摄像头视频流采集和ISP处理。
  • Python 3.8+ & FastAPI服务:标注后端运行环境。

实验中使用的硬件开发板是Thundercomm 的高通跃龙IQ-9100平台
在这里插入图片描述

1.2 模型部署流水线

从训练模型到设备运行的完整流水线:

# Step 1: 模型导出 (PyTorch → ONNX)
yolo export model=yolov8n.pt format=onnx imgsz=640

# Step 2: 模型转换 (ONNX → QNN)
qnn-onnx-converter \
  -i yolov8n.onnx \
  --input_list calib_list.txt \
  -o yolov8n_qnn

# Step 3: 编译模型库
qnn-model-lib-generator \
  -c yolov8n_qnn.cpp \
  -b yolov8n_qnn.bin \
  -t aarch64-ubuntu-gcc11.4

# Step 4: 生成Context Binary (离线编译)
qnn-context-binary-generator \
  --model libyolov8n_qnn.so \
  --backend libQnnHtp.so \
  --binary_file yolov8n.serialized.bin

# Step 5: 推送到设备并验证
adb push yolov8n.serialized.bin /data/models/
adb shell qnn-net-run \
  --model /data/models/yolov8n.serialized.bin \
  --input /data/images/test.jpg \
  --output_dir /data/output/

1.3 推理服务封装

为了让标注系统的后端能够方便地调用模型推理能力,我们将QNN推理过程封装为Python可调用的服务模块。核心采用QNN Python Binding或通过subprocess调用qnn-net-run,推荐方式是使用SNPE/QNN的Python API:

import numpy as np
from qnn_wrapper import QNNContext  # 封装的QNN Python接口

class DetectionEngine:
    def __init__(self, model_path, backend="htp"):
        self.ctx = QNNContext(model_path, backend)
        self.input_shape = (1, 3, 640, 640)
        self.conf_threshold = 0.6

    def preprocess(self, image):
        img = cv2.resize(image, (640, 640))
        img = img.transpose(2, 0, 1).astype(np.float32) / 255.0
        return np.expand_dims(img, axis=0)

    def predict(self, image):
        input_tensor = self.preprocess(image)
        outputs = self.ctx.execute({"images": input_tensor})
        return self.postprocess(outputs)

    def postprocess(self, outputs):
        # NMS + 置信度过滤 + 坐标还原
        boxes, scores, class_ids = nms_filter(
            outputs, self.conf_threshold
        )
        return [{"bbox": b, "score": s, "class_id": c} 
                for b, s, c in zip(boxes, scores, class_ids)]

2. 标注系统功能实现

2.1 后端服务设计 (FastAPI)

标注后端采用FastAPI框架,提供RESTful API和WebSocket接口。主要API接口设计如下:

接口 方法 功能描述
/api/images GET 获取待标注图像列表(支持分页/筛选)
/api/images/{id}/predict POST 触发AI预标注,返回检测结果
/api/images/{id}/annotations GET/PUT 读取/更新标注数据
/api/annotations/export POST 导出标注为COCO/VOC/YOLO格式
/api/sam/segment POST 交互式SAM分割(传入点/框Prompt)
/ws/realtime WebSocket 实时推理结果推送与标注同步
/api/models/status GET 查询当前模型状态和推理统计
/api/training/trigger POST 触发增量训练任务
from fastapi import FastAPI, WebSocket
from pydantic import BaseModel

app = FastAPI(title="Edge Annotation Service")

class PredictRequest(BaseModel):
    image_id: str
    conf_threshold: float = 0.6
    use_sam: bool = True

@app.post("/api/images/{image_id}/predict")
async def predict(image_id: str, req: PredictRequest):
    image = load_image(image_id)
    detections = detection_engine.predict(image)
    if req.use_sam:
        for det in detections:
            mask = sam_engine.segment(
                image, box_prompt=det["bbox"]
            )
            det["mask"] = mask_to_polygon(mask)
    save_annotations(image_id, detections)
    return {"annotations": detections}

2.2 前端标注界面

前端标注界面基于Vue.js 3 + Canvas API实现,核心功能模块包括:

  • 图像画布:支持缩放、平移、全屏查看,在Canvas上叠加渲染检测框和分割掩码。
  • 标注编辑工具栏:框选工具(拖拽创建/调整BBox)、多边形工具(顶点编辑)、橡皮擦工具(删除标注)。
  • 类别面板:显示预定义类别列表,支持快捷键切换,已标注数量实时统计。
  • 审核面板:逐帧浏览,一键确认/驳回,批量操作支持。
  • SAM交互面板:点击前景点(绿色)/背景点(红色),实时调用EdgeSAM生成分割建议。

前端与后端之间通过WebSocket保持长连接,当标注员在画布上点击触发SAM分割请求时,后端推理结果可在100ms内返回并渲染,实现流畅的交互体验。

2.3 标注数据管理

标注数据采用SQLite + JSON文件的混合存储策略:

  • SQLite数据库:存储图像元数据(路径、尺寸、标注状态、标注员ID、时间戳等),支持高效查询和状态管理。
  • JSON标注文件:每张图像对应一个JSON标注文件,记录完整的标注信息(检测框、分割多边形、类别、置信度、是否人工修改等)。
  • 版本追踪:每次修改生成diff记录,支持标注历史回溯和质量审计。

标注导出支持三种主流格式:

格式 文件结构 适用场景
COCO JSON annotations.json(含 images/annotations/categories) Detectron2、MMDetection
Pascal VOC 每张图一个XML文件 传统检测框架
YOLO TXT 每张图一个TXT文件(class cx cy w h) Ultralytics YOLO训练

3. 性能优化与调优经验

3.1 NPU推理优化

  • Context Binary缓存:首次加载模型时,QNN将网络图编译为设备特定的Context Binary并缓存,后续启动可直接加载,模型初始化时间从8秒缩短至0.5秒。
  • 批量推理:对于批量预标注场景,将多张图像组成mini-batch (batch_size=4~ 8)一次送入NPU,吞吐量可提升60%~80%。
  • 异步流水线:采用“采集-预处理-推理-后处理”四级流水线,各阶段异步并行,CPU负责预处理/后处理,NPU专注推理,避免算力空闲。
  • HTP性能模式:通过设置HTP Performance Mode为“Burst”或“High Performance”,提升NPU时钟频率,代价是功耗增加约20%。

3.2 内存与存储优化

  • 图像缓存池:预分配固定大小的图像缓冲区(如10帧环形队列),避免频繁的内存分配和释放。
  • 零拷贝推理:利用QNN的ION Buffer机制,ISP输出的图像数据可直接映射为NPU输入张量,减少一次CPU ↔ NPU的数据拷贝。
  • 标注数据压缩:分割掩码使用RLE(Run-Length Encoding)编码存储,相比原始二值掩码节省90%以上存储空间。

3.3 端到端延迟分析

以单张640×640图像的处理链路为例,各阶段的延迟分布:

处理阶段 执行单元 延迟(ms) 占比
ISP预处理 ISP/CPU ~3 7%
图像缩放+归一化 CPU ~2 5%
YOLOv8n推理 NPU (HTP) ~10 24%
NMS后处理 CPU ~2 5%
EdgeSAM推理 NPU (HTP) ~18 43%
掩码多边形化 CPU ~7 16%

端到端延迟约42ms(约24FPS),完全满足交互式标注的实时性要求。在批量预标注模式下(不启用EdgeSAM),仅运行YOLOv8n检测,端到端延迟可降至~17ms(约59FPS)。

4. 实战效果与数据分析

4.1 测试场景

我们在两个典型工业场景中验证了该系统的有效性:

  • 场景A:电子元器件质检——PCB板上的焊点缺陷检测(虚焊、桥接、偏移),共15个缺陷类别。
  • 场景B:安防监控——停车场的车辆与行人检测,共3个类别(轿车、卡车、行人)。

4.2 标注效率对比

指标 纯人工标注 半自动化标注 提升倍率
单图标注时间(场景A) 180秒 42秒 4.3x
单图标注时间(场景B) 90秒 18秒 5.0x
日均标注量(8小时) 160张 640张 4.0x
标注一致性(IoU) 0.78 0.91 +16.7%
首次预标注准确率 82.5%(场景A)
迭代3轮后预标注准确率 91.3%(场景A)

4.3 模型迭代效果

通过“标注 → 训练 → 部署”的迭代循环,模型的预标注精度持续提升:

迭代轮次 训练数据量 预标注 mAP@0.5 人工修正率
初始(预训练模型) 0(COCO预训练) 52.3% 47.7%
第1轮 500张 71.8% 28.2%
第2轮 1500张 83.5% 16.5%
第3轮 3000张 91.3% 8.7%
第4轮 5000张 94.1% 5.9%

可以看到,经过4轮迭代后,预标注准确率从初始的52.3%提升至94.1%,人工修正率降至5.9%。这意味着每100个标注中,平均只有约6个需要人工调整,标注效率接近全自动化水平。

5. 踩坑记录与实践经验

5.1 模型转换常见问题

问题1:ONNX算子不支持
YOLOv8的某些后处理算子(如ScatterND)可能不被QNN后端支持。解决方案是在导出ONNX时去除后处理头,将NMS等后处理逻辑放在CPU端用NumPy/C++实现。

问题2:量化精度陡降
某些层(如检测头的分类分支)对量化敏感。采用Mixed Precision策略,将敏感层保持FP16精度,其余层使用INT8,可在速度和精度之间取得平衡。

问题3:EdgeSAM的动态Shape
SAM的PromptEncoder包含动态形状输入(点数可变)。在QNN部署时需固定输入形状或使用padding策略,例如固定最多支持5个前景点+5个背景点的输入。

5.2 工程实践建议

  • 先CPU验证再上NPU:模型转换后,先在qnn-net-run的CPU后端验证输出正确性,确认无误后再切换到HTP后端。
  • 校准集要有代表性:PTQ量化的校准集应覆盖各类别和各种拍摄条件(光照、角度、背景),否则量化后模型在某些场景精度会明显下降。
  • 标注界面响应优先:前端Canvas渲染性能是用户体验的关键,避免在主线程执行重计算,善用Web Worker和requestAnimationFrame。
  • 建立标注规范文档:半自动化标注仍依赖人工审核,制定清晰的标注规范(如遮挡目标的处理、模糊边界的裁定标准)可显著提升标注一致性。
  • 监控NPU利用率:使用高通提供的QNN Profiler工具监控NPU利用率和各层耗时,找出推理瓶颈进行针对性优化。

6. 总结与展望

本文详细介绍了基于高通IQ-9100边缘计算平台搭建图像检测半自动化标注系统的完整实践。系统通过在IQ-9100的Hexagon NPU上部署YOLOv8n目标检测模型和EdgeSAM分割辅助模型,实现了高效的“AI预标注+人工精修”工作流。核心成果包括:

  • 实现了3~5倍的标注效率提升,单张图像端到端处理延迟仅42ms。
  • 通过4轮迭代训练,预标注准确率从52.3%提升至94.1%,人工修正率降至5.9%。
  • 完整的边缘部署方案,涵盖模型量化、QNN部署、推理服务封装和标注界面全链路。
  • 数据不出场的隐私保护方案,满足工业场景的数据安全要求。

未来可进一步探索以下方向:

  • 引入大语言模型(LLM)辅助标注规则自动生成
  • 支持更多边缘计算平台的跨平台部署
  • 结合主动学习(Active Learning)策略,自动筛选高价值样本进行人工审核,进一步降低标注成本

全系列完

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐