模型部署与推理优化

端侧部署:ONNX Runtime 与 llama.cpp 两条路径

kp-025核心25 分钟07-端侧与实践

一句话定义

端侧部署有两条主流路径:通用模型走"导出 ONNX → ONNX Runtime 按 CPU/GPU/NPU 后端执行",LLM 专用走"转 GGUF → llama.cpp 推理",共同约束是终端内存、带宽与功耗。

为什么重要

隐私合规(数据不出设备)、离线可用、无 GPU 成本,使端侧成为很多产品的必选项;而端侧的资源约束比云端苛刻一个量级——选型、量化、内存管理的方法论(前几模块)在这里必须全部收紧使用。两条路径覆盖了从传统小模型到 1–8B LLM 的完整落地需求。

前置知识

  • kp-004(显存/内存账本——端侧唯一区别是"内存"且要给系统留余量)。
  • kp-006(weight-only 量化机制)。

核心概念

  • ONNX 路径:把模型导出为 ONNX 计算图,ONNX Runtime(ORT)以执行提供器(Execution Provider:CPU、CUDA、DirectML、CoreML、NNAPI)跑在不同硬件上;优点是通用、跨平台、模型交换标准;对 Transformer 类 LLM 支持完备但优化深度不如专用引擎。
  • llama.cpp 路径:C/C++ 手写 kernel 的 LLM 专用引擎,GGUF 权重(kp-026),支持 CPU、Metal、CUDA、Vulkan 部分卸载(-ngl 指定卸载到 GPU 的层数);macOS 统一内存与移动端的事实标准。
  • 内存映射(mmap):权重文件按需映射进内存、缺页才真正读取,冷启动快、多进程共享只读页——端侧内存管理的核心技巧。
  • 内存账(端侧版):系统+App 占 4–5GB 后,8GB 手机实际可分配给模型约 2.5–3.5GB → 对应 3–4B 模型 Q4(权重约 2–2.5GB)加 KV 留量。

原理与机制

两条路径的分野在"谁来生成执行计划":ONNX 把模型翻译成标准算子图,由 ONNX Runtime 按设备选择实现——通用性强,深度取决于运行时算子库的覆盖;llama.cpp 则为 Transformer 推理手写量化 kernel 与内存布局,用广度换深度。端侧 decode 是带宽问题,胜负手是谁能让权重字节流以最接近内存带宽上限的速度进入计算单元——这决定了同一颗芯片上两条路径的实测差距。

实践步骤(可执行操作)

  1. 定内存预算:目标设备可用内存 − 系统/应用余量 = 模型权重上限。
  1. 选路径:LLM 且需要生态成熟 → llama.cpp/GGUF;已有训练框架模型、需跨 NPU → ONNX 导出 + ORT。
  1. 转换与量化:llama.cpp 的 convert/预转 GGUF 选 Q4_K_M(kp-026);ONNX 走 opset 17+ 导出并跑 ORT 量化工具链(W4/W8)。
  1. 集成与实测:用 kp-002 口径测 TTFT(含加载时间与首 token 分开)、TPOT、内存峰值、发热降频后的持续速度。
  1. 兜底设计:加载超时、内存告警时降级到更小模型或缩短上下文。

排错清单

  • 启动 OOM/被系统杀:上下文长度或 batch 设太大 → 降 max context、确认 mmap 生效、检查量化档位。
  • 首字特别慢:冷加载 + KV 初始化 → 预热一次小请求、保留进程常驻。
  • 跑几分钟后变慢:热节流(thermal throttling)→ 限流、降线程数、后台任务让路。
  • 算子不支持/结果异常:ONNX opset 与 EP 能力不匹配 → 升级 ORT、降 opset 或替换算子。

实例或案例

同一 3B Q4 模型在 某 Windows 笔记本上的对比:走 DirectML NPU 路径实测 12 tokens/s,换 llama.cpp Vulkan 混合卸载(-ngl 20,部分层上核显)后 19 tokens/s——NPU 名义算力更高,但算子覆盖不全导致频繁回退。结论:端侧选型必须以目标设备实测为准,跑分表只能用来排除选项,不能用来拍板。

常见误区

  • "参数量=内存占用":实际=权重(量化后)+ KV + 运行时开销,8B Q4 也要按约 5–6GB 峰值预算。
  • "NPU 一定最快":取决于算子覆盖与量化格式支持,很多场景优化好的 CPU/Metal 路径反而更快——必须实测。
  • "端侧能跑=能上线":发热降频后的持续 TPOT 才是真实体验,瞬时分数会骗人。

自测题

  1. 8GB 内存手机(系统占 4GB)想跑 Q4 LLM,权重预算多少?对应多大参数量?

要点:约 2.5–3GB → 4B 级(Q4 约 2.3GB)加 KV 余量。

  1. mmap 在端侧的两个好处?

要点:冷启动快(按需加载)+ 多进程共享只读页省内存。

  1. 两条路径怎么选?

要点:LLM/移动端生态选 llama.cpp+GGUF;已有模型需跨 NPU/通用部署选 ONNX+ORT。

与其他知识点的关系

账本沿用 kp-004;量化档位细节在 kp-026;端侧排错与 kp-027 共享方法论;模型来源常是 kp-012 流水线的产物。

延伸阅读

llama.cpp 项目讨论区与 ORT 文档对 EP 支持矩阵的说明(名词级,按需查阅)。

#端侧#ONNX Runtime#llama.cpp#内存映射#移动端