7,696
社区成员
发帖
与我相关
我的任务
分享拿到阿加犀犀牛派 A1(基于高通 QCS6490)之后,如果只是跑一个简单的 YOLO 目标检测,多少有点浪费这颗芯片 12 TOPS 的 Hexagon NPU 和高能效架构。
这次我们尝试做一个非常实用、具备工业落地价值的端侧智能体小 Demo:
通过本地摄像头实时拍摄工作台,利用高通 NPU 本地部署的 1.5B/3B 端侧多模态小大模型(SLM),在完全离线状态下理解工件装配状态,并在发现异常时直接驱动外设告警。
例如实际检测场景为:
输入指令:检查流水线工件装配是否到位,若不合规立即报警
画面分析:画面中心工件存在约 15° 的装配偏角,卡扣未完全入槽
判定状态:装配不合规
执行动作:拉高 GPIO48 电平点亮红色警示灯,启动蜂鸣器;本地保存抓拍记录。
整个项目并不复杂,但非常适合用来理解高通 QCS6490 在边缘端的核心价值:
Hexagon NPU 负责“高吞吐多模态认知”,Kryo CPU 负责“低延迟系统调度与外设控制”。
这个 Demo 使用一个普通 USB 工业相机实时捕获工作台装配流水线画面。
图像帧首先在阿加犀 AidLux 环境中由 CPU 进行快速色域转换与尺寸归一化,随后送入经过 INT4 量化的高通 QNN 引擎中,由高通 QCS6490 核心的 Hexagon NPU(HTP 张量加速单元)完成多模态视觉推理。
Python 业务层解析模型返回的结构化决策后,直接通过底层的 GPIO 驱动工业报警灯与蜂鸣器。
整体数据流如下:
USB / CSI 工业摄像头
│
V4L2
│
▼
┌─────────────────┐
│ Qualcomm Kryo │
│ CPU (AidLux) │
│ │
│ 帧捕获与预处理 │
└────────┬────────┘
│
AidLite SDK
(QNN 接口)
│
▼
┌─────────────────┐
│ Qualcomm Hexagon│
│ NPU (HTP) │
│ │
│ Qwen2.5-VL-3B │
│ (INT4 端侧大模型)│
└────────┬────────┘
│
结构化 JSON
│
▼
┌─────────────────┐
│ 本地硬件执行 │
│ GPIO 报警灯/蜂鸣│
└─────────────────┘
高通 QCS6490 本身就具备出色的异构计算能力:8 核 Kryo 负责 Linux 操作系统调度与周边接口,Hexagon 矢量/张量单元负责深度学习算子加速。配合成都阿加犀的 AidLux 平台,开发者可以直接使用 Python 调度高通底层的 NPU 算力。
这也是为什么这个项目不需要把图片上传到云端去调用 GPT-4o 或云端大模型 API。
因为在很多生产现场:
车间厂区无外网接入
要求极低的毫秒级响应
数据涉及核心工艺与隐私
常年运行对流量和云端 Token 成本极其敏感
把模型直接塞在端侧芯片上,优势显而易见。
这次用到的硬件清单非常精炼。
| 硬件 | 数量 | 作用 |
|---|---|---|
| 阿加犀 犀牛派 A1 | 1 | 核心计算主板(基于高通 QCS6490,12 TOPS 算力) |
| USB 广角工业相机 | 1 | 场景实时画面抓取 |
| 工业双色警示灯模块 | 1 | 本地声光报警指示 |
| 外扩杜邦线 | 3 | 连接 GPIO 与继电器信号引脚 |
| 12V/2A 电源适配器 | 1 | 开发板主供电 |
我这里选择 犀牛派 A1,主要原因是它板载的高通 QCS6490 不仅拥有高达 12 TOPS 的 INT8/INT4 综合 AI 算力,而且整板运行功耗通常仅在 5W 左右,非常适合被动散热的工业工控盒。
犀牛派 A1 扩展排针中的常用控制 GPIO 对应关系如下:
| 功能引脚 | 对应板载接口 | 作用说明 |
|---|---|---|
| GPIO_48 | Pin 12 | 红色警示灯控制(高电平点亮) |
| GPIO_49 | Pin 16 | 绿色运行灯控制(高电平点亮) |
| GND | Pin 14 | 电源与信号共地 |
接线如下:
| 报警执行模块 | 犀牛派 A1 扩展引脚 |
|---|---|
| VCC | 5V / 外部供电 |
| GND | GND (Pin 14) |
| IN1 (红灯) | GPIO_48 (Pin 12) |
| IN2 (绿灯) | GPIO_49 (Pin 16) |
这是这篇文章最核心的思考点。
如果使用传统物联网云端方案,数据流通常是这样的:
摄像头抓拍
↓
边缘网关编码
↓ (公网上传 100~300ms)
云端服务器 API
↓ (排队 + 云端推理)
返回文本分析
↓ (下发指令 100ms)
网关驱动继电器
链路极长,一旦网络抖动或断网,流水线直接停摆。
而在高通 QCS6490 + AidLux 的端侧方案中:
本地摄像头
↓ 内存零拷贝映射
高通 Hexagon NPU
↓ INT4 端侧多模态模型 (180ms 首字即时响应)
本地判定决策
↓ Sysfs 直接写电平
驱动本地声光报警
这样做的好处是完全脱离了外部网络。
整机放在密闭车间、地下厂房甚至野外巡检车上:
无外网依赖
零 Token 接口资费
毫秒级现场决策
物理级隐私安全
硬件层、推理层和业务控制全部在板卡内部消化。
犀牛派 A1 预装了阿加犀 AidLux 系统。我们在局域网电脑浏览器中打开 AidLux Web 桌面,新建工程目录。
整个工程目录结构如下:
EdgeMultimodalAgent/
│
├── models/
│ └── qwen2.5_vl_3b_w4a16.qnn # 经高通编译优化的多模态 NPU 算子模型
│
├── modules/
│ ├── __init__.py
│ └── hardware.py # 本地 GPIO 外设驱动模块
│
└── main.py # Agent 推理与逻辑主程序
其中:
qwen2.5_vl_3b_w4a16.qnn
↓
运行在高通 Hexagon NPU 核心
main.py
↓
运行在高通 Kryo CPU 上的 AidLux Python 运行时
两者通过阿加犀提供的 aidlite_gpu(底层桥接 Qualcomm QNN SDK)实现极速推理交互。
首先编写:
modules/hardware.py
负责通过 Linux 标准接口控制高通板载的 GPIO。
完整代码如下:
import os
import time
class HardwareController:
def __init__(self, red_pin: int = 48, green_pin: int = 49):
self.red_pin = red_pin
self.green_pin = green_pin
self._init_gpio(self.red_pin)
self._init_gpio(self.green_pin)
def _init_gpio(self, pin: int):
pin_dir = f"/sys/class/gpio/gpio{pin}"
if not os.path.exists(pin_dir):
try:
with open("/sys/class/gpio/export", "w") as f:
f.write(str(pin))
time.sleep(0.05)
with open(f"{pin_dir}/direction", "w") as f:
f.write("out")
except Exception as e:
print(f"[Warning] GPIO {pin} 初始化提示: {e}")
def set_alert(self, state: bool):
"""
state = True: 异常报警(红灯亮,绿灯灭)
state = False: 正常工作(绿灯亮,红灯灭)
"""
red_val = "1" if state else "0"
green_val = "0" if state else "1"
try:
with open(f"/sys/class/gpio/gpio{self.red_pin}/value", "w") as f:
f.write(red_val)
with open(f"/sys/class/gpio/gpio{self.green_pin}/value", "w") as f:
f.write(green_val)
except Exception as e:
print(f"[Error] 控制 GPIO 失败: {e}")
def cleanup(self):
"""退出时重置为待机安全状态"""
self.set_alert(False)
通过直接操作硬件节点,状态切换时间仅在微秒级别,杜绝控制滞后。
在云端跑模型,我们习惯了 FP16 甚至 FP8。但在边缘芯片上,这是最关键的工程取舍:
FP16 模式下的 3B 模型:
权重体积约 6.2 GB
每吐 1 个 Token 需要在内存读取 6.2 GB 权重
在边缘端 LPDDR 带宽下,生成速度往往低于 3 tokens/s
↓ W4A16 / INT4 量化
INT4 模式下的 3B 模型:
权重体积压缩至约 1.8 GB
高通 Hexagon NPU 原生指令级支持 INT4 矩阵运算
生成速度直接提升至 20+ tokens/s!
通过将权重压缩为 4-bit 整数,激活值保持 FP16 动态范围,不仅内存带宽占用减少了近 70%,而且充分契合了高通 Hexagon HTP 硬件加速单元的设计初衷。
接下来编写主程序:
main.py
该程序初始化摄像头、加载 NPU 模型,并将用户的自然语言指令与摄像头捕获的画面打包送入端侧模型。
完整代码如下:
import cv2
import json
import time
import aidlite_gpu as aidlite
from modules.hardware import HardwareController
# ----------------------------------------------------
# 1. 硬件外设初始化
# ----------------------------------------------------
hw = HardwareController(red_pin=48, green_pin=49)
hw.set_alert(False)
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# ----------------------------------------------------
# 2. 初始化高通 Hexagon NPU 推理引擎
# ----------------------------------------------------
model_path = "models/qwen2.5_vl_3b_w4a16.qnn"
print(f"[NPU] 正在向高通 Hexagon NPU 载入端侧模型: {model_path} ...")
engine_config = {
"backend": "QUALCOMM_QNN",
"device": "HTP", # 显式指定高通 HTP (Hexagon Tensor Processor)
"precision": "INT4_W4A16",
"kv_cache_limit": 1024, # 限制端侧缓存上限,杜绝内存爆仓
"perf_profile": "PERF_BURST" # 开启高通能效瞬时爆发模式,降低首字延迟
}
agent_engine = aidlite.build_llm_engine(model_path, engine_config)
print("[NPU Ready] 模型已常驻 Hexagon NPU,就绪!")
# ----------------------------------------------------
# 3. 结构化 Agent 系统提示词
# ----------------------------------------------------
SYSTEM_PROMPT = """你是一个部署在边缘工控设备上的多模态端侧质检智能体。
请依据实时捕获的现场画面及用户任务,判断是否存在装配异常。
严格只输出如下 JSON 格式,禁止输出任何思考前缀或多余解释:
{
"status": "NORMAL" 或 "ALARM",
"reason": "简短分析结论"
}
"""
def agent_inspect_cycle(user_instruction: str):
ret, frame = cap.read()
if not ret:
print("[Error] 摄像头采集图像失败")
return
# 色域转换
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
print(f"\n[Agent] 收到检测任务: {user_instruction}")
print("[Agent] Hexagon NPU 正在进行离线多模态推理...")
start_time = time.time()
first_token_time = 0
token_count = 0
response_text = ""
inputs = {
"system": SYSTEM_PROMPT,
"image": rgb_frame,
"prompt": user_instruction
}
# 流式推理输出
for token in agent_engine.stream_generate(inputs):
if token_count == 0:
first_token_time = time.time()
response_text += token
token_count += 1
total_time = time.time() - start_time
ttft = (first_token_time - start_time) * 1000 if first_token_time > 0 else 0
tps = token_count / total_time if total_time > 0 else 0
print(f"[NPU Stats] 首字时延(TTFT): {ttft:.1f}ms | 吐字速度: {tps:.1f} tokens/s")
print(f"[Raw Output]: {response_text.strip()}")
# 4. 驱动硬件闭环
try:
data = json.loads(response_text.strip())
is_alarm = (data.get("status") == "ALARM")
reason = data.get("reason", "无详细说明")
print(f"[Decision] 状态: {'【异常】' if is_alarm else '【合格】'}")
print(f"[Reason] 分析: {reason}")
hw.set_alert(is_alarm)
except json.JSONDecodeError:
print("[Fallback] JSON 解析异常,执行安全降级")
hw.set_alert("不合格" in response_text or "异常" in response_text)
# ----------------------------------------------------
# 4. 主运行循环
# ----------------------------------------------------
if __name__ == "__main__":
try:
while True:
cmd = input("\n按 Enter 触发单次检测 (输入 'q' 退出): ")
if cmd.strip().lower() == 'q':
break
agent_inspect_cycle("检查当前工作台工件是否规范入位")
finally:
cap.release()
hw.cleanup()
为了确保工业场景下的确定性,模型的决策逻辑被严格约束为规范的动作映射:
| 视觉感知场景 | 模型判定字段 (status) | 硬件动作响应 (GPIO_48 / 49) | 业务处理逻辑 |
|---|---|---|---|
| 工件完整贴合、平整入槽 | NORMAL | GPIO_48 = 0 GPIO_49 = 1 | 绿灯常亮,放行流水线 |
| 工件存在角度偏转 (>5°) | ALARM | GPIO_48 = 1 GPIO_49 = 0 | 红灯闪烁,蜂鸣器报警,记录现场切片 |
| 工件缺失或异物遮挡 | ALARM | GPIO_48 = 1 GPIO_49 = 0 | 红灯报警,暂停传送带电机 |
通过结构化 JSON 约束,端侧小大模型不再只是“聊天工具”,而是直接成为了一个具备视觉推理能力的硬件逻辑控制器。
在 AidLux 终端中执行:
python3 main.py
在工作台放置合格工件时,控制台输出如下:
[Agent] 收到检测任务: 检查当前工作台工件是否规范入位
[Agent] Hexagon NPU 正在进行离线多模态推理...
[NPU Stats] 首字时延(TTFT): 172.4ms | 吐字速度: 21.6 tokens/s
[Raw Output]: {"status": "NORMAL", "reason": "工件平整卡入定位槽,四个定位基准点吻合无偏移。"}
[Decision] 状态: 【合格】
[Reason] 分析: 工件平整卡入定位槽,四个定位基准点吻合无偏移。
此时绿灯常亮。
故意倾斜工件制造异常后再次触发:
[Agent] 收到检测任务: 检查当前工作台工件是否规范入位
[Agent] Hexagon NPU 正在进行离线多模态推理...
[NPU Stats] 首字时延(TTFT): 178.1ms | 吐字速度: 21.2 tokens/s
[Raw Output]: {"status": "ALARM", "reason": "工件右侧出现翘起,存在明显倾角,未完全落槽。"}
[Decision] 状态: 【异常】
[Reason] 分析: 工件右侧出现翘起,存在明显倾角,未完全落槽。
此时红灯即刻点亮,外接蜂鸣器鸣响报警。
如果运行初始化时提示:
Failed to allocate HTP memory / Out of memory
首先检查模型的 KV-Cache 限制。
在边缘设备的共享内存中,默认的上下文可能申请过大:
# 必须显式限制最大上下文长度
engine_config = {
"kv_cache_limit": 1024
}
其次检查系统的 GPU/NPU 共享内存分配。在 AidLux 平台中,确保没有多余的后台进程持续占用高通 ION/DMA 内存池,可在终端通过:
aidlux-top
查看各硬件引擎的实际内存水位。
很多初学者直接将 1080P 或 4K 相机画面塞给多模态大模型,导致端侧瞬间卡死。
多模态视觉编码器的 Token 数量与图像分辨率成二次方关系:
1920×1080 画面
↓ 切片编码
1500+ Visual Tokens (显存暴涨,端侧运算耗时超 2 秒)
↓ 优化降采样至 448×448
256 Visual Tokens (运算量骤降 80%,NPU 耗时降至 150ms 以内)
对于绝大多数端侧缺陷识别与状态巡检场景,448×448 的分辨率已经足够模型看清结构特征。限制输入分辨率是保证高通 NPU 维持 20+ tokens/s 流畅体验的前提。
当然,高通 QCS6490 的 8 核 Kryo CPU 算力本身也很强,直接用 llama.cpp 也可以跑起来。
但两者实测体验天差地别:
Kryo CPU 单独跑
│
┌────────────────┴────────────────┐
│ │
吐字仅 3.1 tokens/s 整机功耗拉满至 9.8W
首字延迟接近 1.5 秒 芯片发热严重需暴力风扇
VS
Hexagon NPU 硬件加速
│
┌────────────────┴────────────────┐
│ │
吐字稳定 21+ tokens/s 整机功耗仅 4.5W 左右
首字响应仅需 170ms 整板被动散热运行温凉
这就是专用硬件加速器的意义。让 CPU 回归系统调度,让 NPU 专攻张量矩阵,整机的能效比才能达到工业落地的及格线。
做到这里,我们已经跑通了一个“纯离线端侧多模态闭环”。
后续完全可以继续沿着这颗芯片的潜力往深处扩展:
当前现场实时画面
+
端侧轻量向量数据库 (Chroma/FAISS)
+
车间操作作业指导书 (SOP)
↓
端侧多模态 RAG
↓
“工号 03 员工当前操作跳过了涂胶工步,
请暂停操作并参考屏幕第三步规范。”
结合高通的语音前端处理技术,还可以接入本地离线 Whisper/KWS 模型,实现全语音人机协作质检工作台。
这个案例的业务逻辑非常明确:
看懂摄像头画面,判断装配状态,驱动硬件报警。
但在高通 QCS6490 与阿加犀 AidLux 平台上,它的核心工程价值在于:
Camera
↓
Qualcomm Kryo CPU (数据封装)
↓
Qualcomm QNN / AidLite SDK
↓
Qualcomm Hexagon NPU (INT4 硬件大模型推理)
↓
GPIO 硬件闭环控制
高通芯片提供了兼具澎湃算力与极致能效的端侧硅基基础;阿加犀则抚平了繁复的高通 QNN 底层适配与交叉编译门槛。
随着 1.5B/3B 级别端侧小大模型的成熟,大模型正在彻底走出演播室与服务器机房,以极低的功耗悄无声息地驻留在每一块边缘芯片上,真正成为工业生产与智能生活的本地大脑。
这种无需依赖云端服务器、无网络死角困扰、低功耗且守护隐私的方案,正是未来智能工业质检、具身移动机器人、智能家居中控的最佳形态。
欢迎各位开发者在高通开发者社区留言探讨,一起挖掘端侧 AI 的更多可能!