尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

高通跃龙IQ-9075平台的开发记录(1): 边缘农业AI助手的端到端部署

高通跃龙IQ-9075平台的开发记录(1): 边缘农业AI助手的端到端部署 设备: 高通跃龙IQ-9075 EVKSA8775PHexagon v7316 GB系统: Ubuntu 24.04.4 LTS内核 6.8.0-1071-qcomQNN 2.43Genie 1.14.0模型: Qwen2.5-7B-Instructw8a166-split约 4.7 GB代码: ThunderSoft-XA/Edge-AI-agriculture-assistant这是一次把「端侧 7B 咨询 温湿度传感器 Web 告警」串起来的 demo。板子上离线推理浏览器里能看实时读数、能对话超温超湿时会主动推建议。下面按做过的顺序写模型怎么编、板怎么备、传感器怎么接、应用怎么上、知识库怎么选。步骤写清代码不全贴。前言硬件平台与目标本项目使用的是高通跃龙IQ-9075开发板做成什么样设备上常驻两个进程服务端口作用genie-server8081C HTTP 包一层 Geniedlopen libGenie.so模型常驻 HTPFastAPI Uvicorn8080Modbus 轮询、拼接ChatML、FTS5 检索、SSE 聊天与告警推送数据流大致是浏览器 ──HTTP/SSE──▶ FastAPI (:8080) ├─▶ genie-server (:8081) ──▶ Hexagon HTP / Qwen2.5-7B ├─▶ pymodbus TCP ──▶ 仁科温湿度 (192.168.2.100:502) └─▶ SQLite读数 / 告警 / 对话 / FTS5 知识库为什么拆成两进程Genie 要长时间占住 HTP 与数 GB 权重业务侧要做轮询、检索、Web。HTTP 隔开后模型加载只发生在推理进程启动时聊天请求不必每次冷启动。网络拆成两路WiFiubuntu.local管 SSH 和 Web以太网口直连传感器板子192.168.2.1/24传感器192.168.2.100。管理面和传感面不共用同一二层网段避免传感器静态地址和办公 DHCP 抢地址。仓库Edge-AI-agriculture-assistant。应用说明在app/README.md推理服务在app/inference-service/。模型准备走高通官方 LLM on Genie 教程本文按实际编译过程记录关键步骤和参数。板端实测量级Genie 1.14.0 QNN 2.43常驻加载约 2.2 sTTFT 约 176 ms约 8.3 tok/s单次回复常见 7–37 s。一、模型准备目标产物6 个 context binary genie_config.jsontokenizer.json合计约 4.7 GB放到板上/opt/qc-ai/models/qwen2.5-7b-local-6split/。流水线与高通 LLM on Genie 一致预量化 ONNX → 拆分 → DLC → HTP context binary → Genie 加载。拆成 6 份是因为整模一次编进 HTP 上下文太大拆分后每段图单独编译、运行时再串起来prompt 图与 token 图还可共享权重省一份拷贝。1.1 主机环境用途环境云编译Python 3.11 venvqai_hub_modelsAI Hub API token本地编译Python 3.10 venvQAIRT SDK 2.42内存建议 40 GBQAIRT 自带的.pyd扩展是按 Python 3.10 ABI 编的3.11 装不上所以本地编译必须另开 3.10 环境。云编译走 AI Hub 的 Python 包用 3.11 即可。克隆并检出测过的ai-hub-models版本云路径安装带qwen2_5_7b_instruct的 extra本地再装 onnx / transformers 等。云编译前python-m qai_hub configure--api_token YOUR_TOKEN本地编译$env:QNN_SDK_ROOT C:\Qualcomm\AIStack\QAIRT\2.42.0.2512251.2 下载预量化包高通提供约 14.9 GB 的预量化 ONNX zip里面已有 AIMET encodings。放到qai-hub-models约定的 cache 目录后导出脚本会自己读。可用curl -C -断点续传。预量化在主机侧完成权重量化与校准信息后面编译主要是把这些张量与图结构变成 HTP 能执行的 context binary而不是从浮点大模型重新训。1.3 云编译与本地编译日常复现优先走云编译把拆分、上云、回拉交给export参数与官方设备表对齐减少因为 SDK 或环境差异造成的坑。python-m qai_hub_models.models.qwen2_5_7b_instruct.export --deviceDragonwing IQ-9075 EVK--output-dirworkspace\output--synchronous--device会选中目标 SoC 的编译配置例如 Hexagon 代数、VTCM、soc 相关选项编错设备二进制可能能加载但行为不对。中断后重跑同一条命令即可已完成的 job 会复用缓存。本地编译在需要离线、或要改编译开关时用。仓库脚本对应云路径里的三步只是落在本机 QAIRT 上prepare_onnx_6split.py— 拆成 6 份 ONNX encodingsconvert_6split_to_dlc.py --convert-only— ONNX 转 DLCDLC 是 QNN 的中间图格式compile_6split_from_dlc.py—qnn-context-binary-generator出 HTP context binary本地须与云端对齐的关键开关参数取值说明soc_model77SA8775P。写成 0 时离线编译走通用路径板上常出现乱码dsp_archv73与板子 Hexagon 代数一致weights_packingTrue把低比特权重打进 binary 内部布局体积约减半须走 Python APICLI 会忽略该键weight_sharing_enabledTrueprompt / token 两套图共用一份权重vtcm_size_in_mb8片上 VTCM 配额和云编译一致图名称prompt_ar128_cl4096_N_of_M等Genie 从图名解析自回归长度ar与上下文长度clsoc_model决定编译器按哪颗 SoC 的算子与内存模型出码图名称则不是给人看的标签运行时要靠它配置 KV 与序列行为编错只能重编二进制事后改名会撞完整性校验。云、本地在开关对齐时产物体积应接近文件约大小part_1_of_6.binembedding1.0–1.1 GBpart_2–part_5decoder各约 677 MBpart_6.binLM head约 975 MB合计约 4.7 GBgenie_config.json常见项context.size4096n-vocab152064samplertemp0.6 / top-k30 / top-p0.85backend.typeQnnHtp。1.4 模型侧踩过的坑FastRPC 单缓冲大约 1 GB 的 SMMU 上限。AP 经 FastRPC 把权重缓冲映射进 DSP 的 SMMU 时单块连续缓冲大约有 1 GB 的硬限制。嵌入层单独约 1040 MB刚好超过这个限制加载时报错fastrpc memory map ... failed板子物理内存非常充足小缓冲也能映射成功就是这一块过不去。早期的做法是把 embedding 改到 CPU 侧用查找表LUT处理这样这块权重就不必整块映射到 DSP。后来打开weights_packing当前这套 6-split 包在 IQ-9075 上不必再使用 LUT。图名称写错会乱码。本地曾编成qwen2_5_7b_instruct_prompt_2_of_8这类名字模型能加载输出却是乱码。Genie 会从图名里解析ar自回归长度和cl上下文长度正确形态类似prompt_ar128_cl4096_2_of_8。二进制事后改名会撞完整性校验只能按正确格式重编。soc_model一定要写正确。如果本地编译模型x86 主机推断不出板端特性。IQ-9075 / IQ-9100 这一路要显式正确配置soc_model77否则输出不对很难debug。QAIRT 2.35 的--float_bitwidth 16。该选项曾错误改写 RmsNorm 里本该保持量化的张量类型HTP 校验报失败。当时改用--float_bitwidth 32绕过。另外设备上的 DSP 固件要和编译用的 SDK 版本匹配不能只升主机这边的编译器。本地编译体积曾是云端的两倍。早期本地不用weights_packing时合计大约 9 GB云端同配置大约 4.7 GB。差异在 context binary 生成阶段。打开 packing 并用 Python API 编译后两边体积才对齐。硬件上也从 Thundercomm Ride / 旧 QCS9100 栈迁到过 Addons IQ-9075 EVK。换板本身不用重写应用但网络、PPA 里的 QNN 版本、FastRPC 的重试行为要对一下。新板上偶发非致命的failed to map buffer运行时会换 context bank 再试不影响输出。二、板端环境与模型上板2.1 刷机与基础系统板子需已刷镜像并完成 Ubuntu 初始化高通文档刷机与 Use Ubuntu on IQ9。SSHubuntuubuntu.local。同网段 WiFiWindows 侧要能解析.local否则直接用 IP。2.2 安装 QNN / FastRPCsshubuntuubuntu.localsudoaptupdatesudoaptinstall-yqcom-fastrpc1 libqnn1 qnn-toolsls/dev/fastrpc-cdsplibqnn1提供 HTP 后端FastRPC 设备节点是用户态把缓冲交给 CDSP 的入口。没有/dev/fastrpc-cdsp后面 Genie 无法把图卸到 DSP。本 demo 实测libqnn12.43.0ADSP 库路径/usr/lib/rfsa/adsp。ADSP_LIBRARY_PATH要指到 skel 等 DSP 侧库否则 stub 找不到对端。2.3 安装 GenieGenie 不在 Ubuntu PPA 里从主机 QAIRT 的 aarch64 产物拷scp..\QAIRT\..\aarch64-oe-linux-gcc11.2\genie-t2t-runubuntuubuntu.local:/tmp/ scp..\QAIRT\..\aarch64-oe-linux-gcc11.2\libGenie.soubuntuubuntu.local:/tmp/板上sudocp/tmp/genie-t2t-run /usr/local/bin/sudocp/tmp/libGenie.so /usr/local/lib/sudoldconfigGenie 负责按genie_config.json加载多份 context binary、管理 KV、做采样底层仍调 QNN HTP。genie-t2t-run是命令行入口libGenie.so是同一套运行时。2.4 推送模型包ssh ubuntuubuntu.localmkdir -p /opt/qc-ai/models/qwen2.5-7b-local-6splitscp bundle\*ubuntuubuntu.local:/opt/qc-ai/models/qwen2.5-7b-local-6split/目录内需同时有.bin、genie_config.json、tokenizer.json配置里的相对路径按该目录解析。2.5 先用 CLI 验证推理cd/opt/qc-ai/models/qwen2.5-7b-local-6splitexportADSP_LIBRARY_PATH/usr/lib/rfsa/adsp genie-t2t-run-cgenie_config.json-p|im_start|system You are a helpful assistant. Do not repeat yourself.|im_end| |im_start|user What is 23?|im_end| |im_start|assistant 期望看到正常英文或数字答案而不是乱码。Prompt 必须是 ChatML模型按该模板微调缺 system/user/assistant 标记时行为不稳定。system 里固定带Do not repeat yourselfGenie 侧没有好用的 repeat_penalty 时开放题容易循环复读。每调一次genie-t2t-run都要重新加载模型大约十几秒。后面改成常驻genie-server就是为了把这几十秒从每次请求里拿掉。三、推理服务 genie-serverFastAPI 不直接起子进程跑genie-t2t-run而是通过 HTTP 调本机genie-server。模型在进程内只加载一次请求只做 prompt → token 流。3.1 编译main.cpp用dlopen/dlsym解析 Genie编译期不链接高通头文件与.so交叉工具链不必安装 QAIRT。在 WSL 或 Linux 上cdapp/inference-service ./build.sh--cross# 产物build/genie-serveraarch64scpbuild/genie-server ubuntuubuntu.local:/tmp/sshubuntuubuntu.localsudo cp /tmp/genie-server /usr/local/bin/也可在板子上原生./build.sh需 cmake / g。3.2 接口与常驻genie-server-c/opt/qc-ai/models/qwen2.5-7b-local-6split/genie_config.json# 默认 127.0.0.1:8081方法路径说明GET/health存活POST/generatebody 带完整 ChatMLpromptSSE 回{token:...}结束[DONE]POST/reset清 KV cacheHTP 上同一时刻只跑一路生成更稳所以忙时回 429由业务侧排队或重试。systemd 单元见app/inference-service/genie-server.serviceqc-ai-app.service通过Requires依赖它避免应用起来时推理口还没听。四、传感器选型与接线4.1 选型工业上比较常用的是Modbus TCP协议的传感器这里我们选用了仁科RS-WS-ETH-6J-ModbusTCP温湿度一体Modbus TCP传感器作 TCP Server端口 502供电 DC 7–30 V精度大约温度 ±0.5°C、湿度 ±3%RH。选 TCP Server是因为板子作 Client 定时去读即可传感器侧不用知道板子 IP寄存器只有湿度和温度两个应用映射简单。地址内容0湿度 %RH原始值 ÷101温度 °C原始值 ÷10例如原始562→ 56.2%RH236→ 23.6°C。温度大于 32767 按有符号补码处理。4.2 Windows 上首次配网出厂 IP 不一定落在要用的网段须用官方RS-ModBusTCP-Config写一次静态参数传感器网线接 Windows PC本机网卡设成同网段例如192.168.2.10/24上电。打开配置工具 →「搜索」→ 双击设备。网络参数工作模式TCP Server端口502静态 IP192.168.2.100掩码255.255.255.0网关192.168.2.1IP 获取 StaticIP清掉多余 server 项。4.「参数配置」保存有「设备参数」页再读一次、配一次。断电重启传感器。搜不到时先关 Windows 防火墙并确认 PC 与传感器同网段。部分参数写在传感器非易失配置里不掉电重启可能仍跑旧 IP 或旧模式。4.3 接到 IQ-9075板子连接传感器会占用有线网卡我们先用无线网络连接开发机和板子。传感器从 PC 改接到板子 ETH板子的以太网口是end0。板上建静态以太网本 demo 用 NetworkManager连接名sensor-netsudonmcli connectionaddtypeethernet ifname end0 con-name sensor-net\ipv4.method manual\ipv4.addresses192.168.2.1/24\connection.autoconnectyes板子与传感器必须落在同一子网/24且板子不要跟传感器抢192.168.2.100。连通性ping-c3192.168.2.100timeout2bash-cecho /dev/tcp/192.168.2.100/502echoOPEN||echoCLOSED应用默认SENSOR_HOST192.168.2.100SENSOR_PORT502SENSOR_POLL_INTERVAL5秒pymodbus异步轮询。轮询结果进 SQLite供仪表盘、告警阈值和拼进 LLM 的「当前读数」共用同一数据源。实机曾读到约23.6°C / 56.2%RH。没有硬件时可用app/tests/mock_sensor.py与mock_sensor_extreme.pysystemd drop-in 把SENSOR_HOST/PORT指到 mock。五、应用部署5.1 目录与依赖应用源码在仓库app/services/sensor / llm / alert / database / event_bus、routers/、static/、data/knowledge/、deploy/。一键部署Git Bash 或 WSLcdapp/deploy ./deploy.sh ubuntuubuntu.local脚本会建/opt/qc-ai/app/、SCP 文件、pip装依赖、装 systemd 并启动。手动时建目录并chown→ SCPmain.py、config.py、services/、routers/、static/、data/、deploy/→ 板上cd/opt/qc-ai/app pip3install--break-system-packages-rrequirements.txtsudocpdeploy/qc-ai-app.service /etc/systemd/system/sudosystemctl daemon-reloadsudosystemctlenable--nowqc-ai-app--break-system-packages是 Ubuntu 3.12 对系统 Python 的 pip 限制下的写法包版本见app/README.md。5.2 配置均在config.py用 systemd drop-in 覆盖即可不必改代码。常用项变量默认含义SENSOR_HOST/PORT/SLAVE_ID192.168.2.100/502/1ModbusSENSOR_POLL_INTERVAL5.0轮询秒LLM_INFERENCE_URLhttp://127.0.0.1:8081genie-serverLLM_TIMEOUT120推理超时秒ALERT_EXTREME_HEAT40.0极端高温Critical会调 LLM 出建议ALERT_FROST_WARNING0.0霜冻CriticalALERT_HIGH_TEMP/LOW_TEMP35/5Warning记日志ALERT_HIGH_HUMIDITY/LOW_HUMIDITY95/20WarningALERT_COOLDOWN_SECONDS300同类告警去重间隔DB_PATH/opt/qc-ai/app/data/qc-ai.dbSQLiteKB_ENABLEDtrue是否注入知识库KB_TOP_K3注入段落数KB_MAX_CHARS_PER_PASSAGE500单段截断Critical 与 Warning 分开只有极端温湿度才再跑一轮 LLM 生成防护建议避免阈值抖动时把 HTP 打满。ALERT_COOLDOWN_SECONDS用来在冷却期内合并同类告警。5.3 前端与 API浏览器打开http://ubuntu.local:8080/仪表盘、流式对话、告警条。前端无构建步骤静态文件由 FastAPI 直接送。接口作用POST /api/chat咨询SSE 流式GET /api/sensors/current、/history当前与历史读数GET /api/alerts告警历史GET /api/events传感器、告警等实时推送对话路径取当前读数 → 可选 FTS5 检索 → 拼 ChatML →genie-server→ SSE 回浏览器。Critical 告警走并行路径同样经 SSE 推到页面用户不用先发问。六、端侧知识检索6.1 选型约束推理时 HTP 打满上下文 4096检索不能拖成秒级。考虑过几种做法A. SQLite FTS5 / BM25关键词倒排Top-K 塞进 prompt。不加额外神经网络毫秒级可离线同义词靠词典补齐。B. 在线 API拉天气、农情。要外网延迟受外网影响。C. AB本地静态知识加在线动态。信息更全但本 demo 未接外网。D. 本地 embedding 向量库在 ARM CPU 上编向量语义匹配更好但对这份 FAQ 来说太重。这里只采用方案 A。FTS5 建倒排索引BM25 按词稀有度与词频打分农业术语相对固定关键词命中率够用。「番茄 / 西红柿」要对上就把同义写进用户词典而不是先上向量库。检索通常不到 5 ms。Token 预算system 传感器 2–3 段知识约 800–1500 token 用户问句留给生成大约两千 token。6.2 接入方式首次启动把data/knowledge/*.txt导入 SQLite建 FTS5 虚表。用 external content 模式时索引不复制一份全文省空间。对话前search_knowledge命中段落进 systemCurrent readings: Temperature {temp}C, Humidity {humidity}% Relevant knowledge: {retrieved_passages} ... Do not repeat yourself.原理上这就是检索增强模型参数不改只在上下文里塞可引用的条文回答更贴本地农技材料塞太多会挤占生成长度所以要KB_TOP_K与单段截断。知识文件命名{category}_{标题}.txt例如tomato_高温防护措施.txt。段落约 300–400 字在句号处切可留几十字符 overlap避免知识点卡在边界上丢半句。PDF/Word 在开发机先转明文再上板。KB_*可关检索或改 Top-K。知识文本的免责声明见app/data/knowledge/DISCLAIMER.md。七、端到端确认模型、Genie、传感器、应用都起来后可以按下面几项快速确认链路是否跑通。推理curl http://127.0.0.1:8081/health或再跑一次带 ChatML 的短问看中英文是否正常、会不会循环复读。传感器curl http://127.0.0.1:8080/api/sensors/current温湿度与寄存器换算一致即可。Web打开http://ubuntu.local:8080/仪表盘有数聊天框能流式出字。告警用mock_sensor_extreme或临时改阈值看 Critical 会不会推告警并带建议Warning 是否进历史。知识库问一句知识库里有的作物问题看回复是否用到检索段落也可在 prompt 组装处对一下。sudosystemctl status genie-server qc-ai-appsudojournalctl-uqc-ai-app-f八、性能对照指标子进程genie-t2t-run常驻genie-server模型加载每次请求约 15–20 s启动一次约 2.2 sTTFT含加载约 20 s约 176 ms吞吐约 8.3 tok/s约 8.3 tok/s内存每请求 fork常驻RSS 峰值约 1.1 GB吞吐差不多差在是否把加载摊到启动期。应用层单次回复时间主要跟生成长度走常见 7–37 s。九、扩展和完善方向本项目是可跑通的边缘农业咨询 demo不是成品产线系统。已经覆盖模型上板、常驻推理、真机温湿度、Web 咨询、阈值告警、本地 FTS5 知识注入。若往产品方向靠比较自然的扩展包括知识库加领域词表或第二期接天气 API、告警按作物季节调阈值、多传感器与读数导出等。这些是 demo 之上的完善方向。参考仓库https://github.com/ThunderSoft-XA/Edge-AI-agriculture-assistant应用与传感器仓库文档app/README.md推理服务仓库文档app/inference-service/README.md高通教程LLM on Genie设备列表AI Hub devices上面记录的是实际搭通这条链路时用到的步骤和结论SMMU、soc_model、packing、图名称等若还要往下挖可以对照高通官方文档和设备侧日志继续调查。
返回列表