导读:端侧 AI 项目的难点,往往不止于“模型能否运行”,而在于模型选型、部署形态、推理路径与应用集成方式能否形成完整闭环。本文结合 PCBA Assistant 的实践,重点总结两条关键技术链路:一是PCB 板图 OCR 模型的选型与 ONNX/QNN 部署路径,二是本地 LLM 的 Genie 服务化接入方式,并补充少量与交付稳定性直接相关的运行时经验。
一、项目背景PCBA
Assistant 面向 PCB/PCBA 工程场景,目标并非实现单一的聊天能力,而是形成一条完整的端侧工作流:系统首先需要解析 BOM,再从 PCB 板图中识别位号,并将其与 BOM 记录建立映射关系,随后在板图中完成器件定位,最终再结合当前上下文完成本地问答。正因为如此,本项目从一开始就同时依赖两类核心模型能力。OCR 负责从板图中提取位号并提供空间位置,LLM 则负责结合 BOM、位号、板图上下文和用户问题完成本地语义理解。两者在系统中都不是附属功能,而是共同支撑应用闭环的主干能力。
二、OCR 模型选型
PCB 板图 OCR 与通用文档 OCR 存在明显差异:位号尺寸通常较小,文字方向并不统一,底图线条复杂,标注颜色和背景之间容易相互干扰,而且最终真正有业务价值的并不是全部文本,而是能够与 BOM 建立对应关系的位号。因此,这里的 OCR 选型不能只看通用识别效果,还必须兼顾小目标文本处理能力、复杂背景适应性以及后续工程链路的可控性。在具体方案上,本项目最终采用了 PaddleOCR 这一路线,并将部署资源收敛为检测模型、识别模型与对应字典文件的组合形式。PaddleOCR 已经是当前通用 OCR 工程实践里较成熟的一条主流路线,识别精度、轻量化程度以及部署工具链都比较均衡;同时,检测与识别解耦的结构也更适合板图场景。对本项目而言,这种结构的价值不仅在于识别本身,更在于它天然更适合作为后续结构化处理的前置阶段。换言之,我们选择 PaddleOCR,不只是因为它能把文字识别出来,更因为它能够为从视觉结果到工程信息的过渡提供一个稳定、也更容易控制的基础。
三、OCR 部署路径
在 OCR 部署阶段,本项目采用了 ONNX Runtime + QNNExecutionProvider 的推理路径,并保留 CPUExecutionProvider 作为回退方案。这样做的核心目的,是在统一推理入口的前提下尽量利用 高通Snapdragon 平台的端侧能力,同时保留异常场景下的可用性。之所以在部署阶段选择 ONNX,而不是继续保留训练框架原生形态,主要还是出于统一性、可维护性和平台适配性的考虑。ONNX 作为跨框架中间表示,更适合交给统一推理引擎管理;而 ONNX Runtime 提供的 Execution Provider 机制,又使同一套模型资源可以自然接入 QNNExecutionProvider 和 CPUExecutionProvider。对当前项目来说,这一点尤其重要:运行环境是 Snapdragon X Elite AI PC,OCR 推理需要尽可能体现端侧 AI 平台能力,因此优先使用 QNNExecutionProvider;但工程实现不能只考虑理想状态,所以仍然要保留 CPU 回退能力,以保证 provider 不可用时服务依然能够工作。OCR 在本项目中并不是一条独立黑盒链路,而是业务逻辑的一部分。部署完成后,系统还需要围绕它继续处理 tile 切分、多角度旋转、候选 mask 粗筛、坐标映射以及 BOM 匹配评分等环节。因此,相比完全黑盒化的 OCR 方案,当前部署方式更有利于在应用层继续做调度优化。与此同时,模型采用固定方形输入尺寸这一约束,也会直接影响 tile 设计、粗筛策略和视野取舍,必须在部署阶段提前纳入考虑。
四、本地 LLM 部署方案选型
在 LLM 侧,本项目最终选择了基于 QAI AppBuilder 生态的 GenieAPIService,因为本地问答能力更适合以服务形态接入应用,而不是直接嵌入主进程。对这类工程场景来说,LLM 除了要能在本地运行,更重要的是要便于资源准备、配置管理、生命周期控制以及后续交付,因此服务化方案天然更合适。相比直接将模型推理逻辑嵌入主应用进程,本地服务化也更容易把模型资源与应用本体解耦,避免整条链路在部署阶段变得过于脆弱。当前项目在业务层采用 OpenAI Compatible API 方式接入本地问答能力,这使上层调用方式能够保持统一,也降低了模型服务替换和后续扩展的成本。更重要的是,业务代码可以与底层推理实现保持解耦,不必围绕某一套本地模型接口单独组织应用逻辑。在当前版本里,默认采用的是 Qwen2.0-7B-SSD,主要考虑是它在端侧资源占用、响应速度和接入稳定性之间更容易取得平衡,适合作为本地问答能力的默认承载模型。对本项目的任务类型来说,这一点尤其关键,因为本地问答并不是独立聊天功能,而是围绕器件解释、板图辅助定位、BOM 上下文理解和结构化动作返回展开。也正因为如此,这里的模型选型更强调端侧可运行性、服务接入稳定性和工程可控性,而不是单纯追求更大参数规模。
五、本地LLM部署检查和接入
在 Genie 接入阶段,真正影响交付稳定性的并不是 API 调用本身,而是模型资源和配置文件的组织方式。本项目最终采用了固定资源组织方案,由准备脚本统一完成资源检查、Genie 服务解压、模型目录整理以及 config.local.json 生成。这样做的直接好处在于,发布包目录结构始终保持一致,服务启动时不需要临时判断资源位置,模型准备过程也可以重复执行。对交付和演示场景来说,这种方式比手工解压、手工改配置、手工指定资源路径更稳,也更便于后续排查问题。至于原始配置中面向移动端或嵌入式目录结构的模型引用,则在本地配置生成阶段一并完成环境适配,从而把这类差异收敛在准备步骤内部,而不是暴露给最终使用者。当 OCR 与 Genie 的部署路径固定下来之后,运行时层面的重点也会随之转向另一组问题:环境依赖是否完整,服务进程能否按统一入口拉起,启动日志是否能够快速暴露故障位置。对端侧项目来说,模型能够完成推理只是起点,真正进入交付阶段之后,还需要把依赖检查、进程编排和日志收集组织成一套稳定的本地运行流程。运行时工程因此并不是部署之后的附带工作,而是模型部署方案在交付阶段的自然延伸。
六、结语
这次实践最终落回到一个很具体的工程判断上:端侧项目真正需要尽早收敛的,不是某个单独的启动细节,而是模型以什么形态进入推理栈、由什么 provider 执行、受什么输入约束影响,以及本地 LLM 以什么服务形态接入应用。只有这些问题在方案阶段先被统一起来,后面的资源组织、环境检查、进程编排和日志治理才会变成顺着主线展开的交付工作;如果前面的部署边界始终摇摆,后面的运行时处理往往只能围着问题被动修补。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。