☰
端侧Agent部署实战:从LLM选型到推理调优
2026/11/2 17:30:35 网站建设 项目流程

做端侧 Agent 的朋友应该都有同感:Agent 的编排、记忆、工具调用这些逻辑,在云端随便接一个大模型 API 就能跑通,但一旦要把整套东西搬到端侧设备上,第一道坎就是端侧 LLM 部署。我说的“端侧 LLM 部署”,不是把模型文件下载到手机里装装样子,而是让模型在目标硬件上真正跑起来、能稳定服务、能支撑 Agent 的多轮交互和工具调用。这篇是“深入理解端侧 Agent”系列的第二篇,我把自己在端侧 LLM 部署上踩过的坑、做过的选型、实测过的结果整理出来,重点覆盖本地部署的动机、硬件门槛、工具链选型、量化调优,以及部署完成后把 Agent 接上去的那些工程细节。

1. 端侧 Agent 为什么需要本地 LLM:延迟、隐私与成本账

1.1 云端 API 看着省事,但 Agent 场景经不起反复往返

先泼盆冷水:如果你的 Agent 只是一个聊天机器人,那端侧部署意义不大,云端 API 完全够用。但 Agent 和聊天机器人的本质区别在于,Agent 要在一个任务里反复调用工具、观察结果、决定下一步,每一轮“思考-调用-观察”都要一次模型推理。这意味着网络延迟会乘着一个不小的系数。

举个例子,一个简单任务“把会议记录里的待办事项提取出来,按优先级排好,再发给对应同事”,云端 API 方案里每一步都需要把上下文重新构建一次,多轮下来光网络中转时间就占到整个执行时间的 20% 甚至更多。端侧部署的最大收益就是把推理从“远程调用”变成“本地函数”,延迟从一次请求往返几十上百毫秒降低到本地首 token 几十毫秒量级。对实时性敏感的 Agent 场景,比如语音交互助手、机器人控制、车载助理,这种差异是决定性的。

还有一点经常被忽略:端侧部署之后,推理费用变成零边际成本。Agent 是高 token 消耗大户,一次任务可能反复调用工具,上下文不断累积,云端按 token 计费会很快吃掉预算。本地部署是一次性硬件投入,虽然在模型能力上限上做了妥协,但对高频、固定场景来说,综合成本反而低很多。

1.2 隐私、离线和数据安全:三个容易被低估的“硬需求”

Agent 想做好工作,往往需要访问本机文件、通讯录、邮件、传感器数据。把这些数据转发到云端大模型,等于把最敏感的信息交给第三方。我接触过不少做企业内部 Agent、医疗辅助 Agent、工业巡检 Agent 的团队,他们第一条需求就是“数据不能出设备”,这种情况下云端 API 再强也没有讨论空间。

其次是离线可用。车载、工控、野外巡检、安全内网,这些都是典型的断网或弱网环境。Agent 在这种环境里不能因为网络抖动就罢工,本地推理是唯一可以稳定工作的选择。依赖公共大模型接口的 Agent,一旦链路抖动,整个任务就卡住;端侧部署则天然免疫这一类故障。

这里有个常见误区:大家总觉得端侧部署是“为了省钱所以选差的”。实际上,很多 Agent 场景根本不需要 70B+ 大模型的常识广度,需要的是低延迟、稳定输出、以及对固定领域工具的熟练调用。1.5B 到 7B 的小模型在这些场景里是够用的。

1.3 端侧部署的边界:哪些场景不适合全本地

也要说清楚端侧的局限。常识问答、复杂推理、跨领域规划这类任务,小模型和云端大模型差距悬殊。我个人的经验是“端云混合”是当前最务实的架构:本地小模型负责快交互、敏感数据处理、固定工具调用;云端大模型作为仲裁者,在遇到超出本地能力的问题时才接管,或者定期把困难样本蒸馏成小模型的知识。换句话说,端侧 LLM 部署不是要取代云端,而是给 Agent 装一个“本地小脑”。

我的判断标准很简单:如果任务有明确步骤、有固定领域工具、对隐私和延迟敏感,就本地做;如果任务需要开放常识、模糊推理、全局规划,就交给云端。把这两类任务在 Agent 框架里用路由逻辑分开,比硬扛端侧、硬扛云端都可靠。

2. 端侧部署 LLM 的三道硬门槛:内存、算力、功耗

2.1 内存公式:模型加载量先算清楚

选端侧硬件,第一步不是看算力,而是先算内存。模型加载占用有个很简单的公式:

加载内存(GB)约等于参数量(B)乘以每参数位宽除以 8。

7B 模型在 FP16 下是 7×2=14GB;量化到 INT4 则约 3.5GB。但这只是模型权重部分,推理时还有 KV cache 和临时激活层。KV cache 的粗略计算公式是:

KV cache 大小约等于 2(K 和 V 两组)× 层数 × 隐藏维度 × 上下文长度 × 每元素字节数。

以 Qwen2.5 7B 为例,32 层、hidden 3584、上下文 8192、FP16 存储,KV cache 大概 2×32×3584×8192×2,约 3.8GB。所以同样是 7B 模型,8GB 内存设备跑 INT4 量化并把上下文控制在 4K 到 8K 是可行的,但 16GB 以下的设备跑 FP16 基本不现实。

这也是为什么端侧 LLM 部署总是和量化绑定在一起。模型权重和 KV cache 这两块占用算清楚,再决定是否加外接内存/交换分区。我见过不少项目上来就下载 FP16 原始权重,结果在 8GB 开发板上直接 OOM,最后还得回头做量化,白白浪费时间。

2.2 算力与 token 速度:端侧的度量衡

推理速度在端侧通常用 token/s 衡量。可用底线是多少?回答类场景每分钟 100 token,也就是 1.7 token/s 左右,勉强能互动;但 Agent 场景建议至少要 10 token/s。原因很简单,Agent 的生成结果里有大量“无效 token”,比如计划文本、JSON 结构、思考过程,速度太低会让一个任务的总体完成时间完全不可接受。

端侧硬件形态差异很大。CPU 推理兼容性最好但慢;GPU 推理快但受显存和内存带宽限制;NPU 能效高,但在算子支持、量化格式上常常有很多限制,很多产品宣传的“NPU 几十 TOPS”实际利用率非常低。选型时建议先去查目标引擎对该 SoC 的算子支撑情况,别拿营销数字当真。

2.3 主流硬件平台怎么选:一份实测视角的对照

平台内存推理形态能稳定跑的模型规模实际速度参考注意点
RK35888/16GBCPU 为主,NPU 支持有限1.5B-3B INT4 流畅,7B INT4 可用7B INT4 CPU 约 5-12 token/sNPU 生态仍需踩坑,成本低
Jetson Orin Nano/NX8-16GBCUDA GPU7B-8B INT4 流畅7B INT4 约 20-40 token/s系统占用大,散热影响明显
骁龙 8 Gen2 以上手机12-16GBNPU/GPU 异构3B-8B INT48B INT4 约 10-25 token/s散热降频严重,持续性能打折
苹果 M 系列8-32GB统一内存/GPU7B-13B INT47B INT4 约 30-50 token/s生态好,成本高
树莓派 58GBCPU1B INT4 边缘,3B 很勉强1B 约 5-8 token/s适合原型演示,不适合产品

这些数字是“常见实测区间”,不是理论峰值。RK3588 和 Jetson Orin 是两条典型路线:前者便宜、功耗低、NPU 有但成熟度弱;后者重、贵、但 CUDA 生态省心,跑开源模型的坑明显少。如果做产品原型,我建议直接上 Orin Nano,省下的时间比硬件差价值钱得多。

3. 推理引擎与模型格式选型:GGUF 为什么在端侧赢了

3.1 端侧推理引擎横评

端侧 LLM 部署不是只能选一个框架,不同阶段适合不同工具。

  • llama.cpp:纯 C/C++ 实现,GGUF 格式,CPU/GPU 都能跑,Android/iOS/Linux 全覆盖,是端侧事实标准。缺点是动态 shape 支持弱、服务端化需要自己封装。
  • Ollama:基于 llama.cpp 的二次封装,自带模型管理、OpenAI 兼容 API,几乎开箱即用。适合快速原型验证,但不适合深度定制。
  • MLC LLM:基于 TVM 编译,对移动端 NPU 支持较好,但编译配置复杂,生态相对封闭。
  • MediaPipe LLM Inference API:Google 面向 Android 的推理方案,量化格式与 AOT 编译绑定,适合纯移动端产品,定制性不够。
  • vLLM:云端服务引擎,用显存换性能,端侧没有这个条件,别碰。
  • llamafile:Mozilla 出的单文件分发方案,把模型加引擎打包成一个可执行文件,适合给非技术同事做演示。

我的建议是:自己研究选 llama.cpp,快速演示选 Ollama,产品化落地如果主要面向 Android 再考虑 MLC 或 MediaPipe。不要一上来就迷信某个框架,先跑通最小链路最重要。

3.2 模型选型:端侧 Agent 到底该上多大参数

判断原则:先定上下文长度和工具调用需求,再定参数规模。当前端侧小模型里,Qwen2.5-3B、Llama 3.2-3B、Phi-3.5-mini 是三个很能打的 3B 级选项,其中 Qwen 的中文指令遵循和 function calling 能力明显强于同规格开源模型。7B 级主要是 Qwen2.5-7B-Instruct、Llama-3.1-8B-Instruct 和 Gemma-2-9B。

在 8GB 内存的端侧设备上,7B INT4 已经是“上限配置”,上下文还得控制在 4K 左右;3B INT4 是舒适区,能留出足够余量给 Agent 框架的其他组件。如果设备只有 4GB 内存,老老实实上 1.5B。Agent 场景里,模型“能稳定调用工具”比“知识丰富”重要得多,3B 模型在固定领域任务上往往和 7B 拉不开差距,但速度差一大截。

3.3 GGUF 量化分层:为什么是事实标准

GGUF 能把权重、tokenizer、模板、超参数打包成单文件,支持从 F16 到 Q2_K 的多种量化层级。Q4_K_M 是端侧公认的平衡点,速度快、占内存适中、质量损失可控。除了权重量化,GGUF 还支持 KV cache 量化,把长上下文内存占用再压低一个档位,这对 Agent 的长会话场景非常关键。

从原始 Hugging Face 权重转 GGUF 的工具链也成熟:llama.cpp 仓库里的 convert_hf_to_gguf.py 负责权重转换,llama-quantize 负责量化。只要模型是常见架构,基本都能一键跑通。相比之下,Safetensors 原始权重文件体积大、格式分散,ONNX 在端侧引擎上算子支持参差不齐,所以 GGUF 在现阶段确实是端侧部署最省心的选择。

4. 从零跑通 RK3588/Jetson Orin 上的端侧 LLM 服务

4.1 环境准备:两条路线的依赖差异

RK3588 路线,建议用 Ubuntu 22.04 ARM 版,装好 Python 和 CMake 后直接编译 llama.cpp:

git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j$(nproc)

如果是 Jetson Orin,先装好 JetPack(推荐 5.1.4 以上或 6.x),它自带 CUDA 工具链,编译时开启 GPU 后端:

cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON cmake --build build -j$(nproc)

有个小坑:系统自带 CMake 版本如果太老,编译会出现一堆莫名其妙的报错,建议直接用 3.24 以上版本。Jetson 上还要注意确认 CUDA 路径被正确找到,否则-DGGML_CUDA=ON会被静默忽略,推理还是走 CPU,速度直接差一个数量级。

4.2 模型获取与量化转换

国内下载模型建议直接用 ModelScope,或者给 Hugging Face 配镜像源,否则大文件下载会等到怀疑人生。用 ModelScope 下载现成 GGUF:

pip install modelscope modelscope download --model Qwen/Qwen2.5-7B-Instruct-GGUF --local_dir ./qwen7b

如果手里只有原始 HF 权重,转 GGUF 再量化也很简单:

python convert_hf_to_gguf.py ./Qwen2.5-7B-Instruct --outfile qwen7b-f16.gguf ./llama-quantize ./qwen7b-f16.gguf ./qwen7b-q4_k_m.gguf Q4_K_M

Q4_K_M 是端侧 7B 模型的默认选择。如果你需要更快的速度,可以尝试 Q3_K_M,但说实话质量下降明显;如果内存有富余,Q5_K_M 的精度恢复有限,性价比一般。

4.3 启动推理服务并接到 Agent 框架

llama.cpp 自带 llama-server,一条命令起服务:

./build/bin/llama-server -m ./qwen7b-q4_k_m.gguf -c 8192 --host 0.0.0.0 --port 8080 -ngl 99

-ngl 99表示把能 offload 的层尽量全部放到 GPU。Orin 上走 CUDA,RK3588 上如果没配 GPU 后端就是纯 CPU 推理。

不想编译的话,Ollama 是更快的启动方式:

ollama pull qwen2.5:7b-instruct-q4_K_M ollama serve

两种方式都暴露 OpenAI 兼容的/v1/chat/completions,可以用 curl 快速验证:

curl http://localhost:8080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen2.5","messages":[{"role":"user","content":"用一句话说明你是本地模型"}]}'

Agent 框架对接通常只需要改 base_url 和模型名。比如自研 ReAct loop 里的 LLM client,把请求地址指向http://127.0.0.1:8080/v1,然后把工具定义放到tools参数里,而不是塞进 prompt。大部分开源 Agent 框架都兼容 OpenAI 的 tools 格式,这一步基本没有额外开发量。

4.4 实测数据:不同硬件组合的参照

硬件模型上下文后端速度参考内存占用
RK3588 16GBQwen2.5-3B-Instruct-Q4_K_M8192CPU10-15 token/s约 4GB
RK3588 16GBQwen2.5-7B-Instruct-Q4_K_M4096CPU5-9 token/s约 6GB
Jetson Orin Nano 8GBLlama-3.2-3B-Instruct-Q4_K_M8192GPU30-45 token/s约 5GB
Jetson Orin NX 16GBQwen2.5-7B-Instruct-Q4_K_M8192GPU30-50 token/s约 8GB

注意 Jetson 的电源模式和省电设置会明显影响速度,跑满 GPU 30 分钟以上还要考虑散热降频。RK3588 的 NPU 目前对 llama.cpp 的支持还很有限,现阶段以 CPU 推理为主,后续再看 NPU 生态的发展。

5. 量化精度与推理速度的真实权衡:部署完不等于调优完

5.1 量化给 Agent 带来的三个隐性伤害

量化之后模型确实能跑了,但 Agent 场景会暴露出三个问题。第一,指令遵循变弱,低比特模型偶尔会漏掉“只输出 JSON”这类指令,导致工具调用解析失败。第二,函数调用格式不稳定,模型可能把 function name 或 arguments 字段写成不规范的格式。第三,长上下文能力退化,Q4 量化在上下文接近极限时注意力崩溃更明显。

我实测过同一任务在 Q8 和 Q4_K_M 下的对比:简单问答几乎没有差别,但涉及多步工具调用的 Agent 任务,Q4 的成功率会下降 5 到 10 个百分点。这不是说量化不能用,而是提醒你部署完一定要做 Agent 层的兜底,不能拿原始模型的测试结果直接当量产依据。

5.2 实测提速的几招

限制上下文比限制模型更有效。7B 模型上下文 4K 和 8K 的 KV cache 内存差一倍,很多 Agent 单轮任务 4K 已经够用,没必要硬上 8K。

开启 prefix caching。系统提示词和工具 schema 在一整个会话里是固定的,缓存之后每次请求只计算新输入部分的 prefill,长上下文场景提速非常明显。llama.cpp 和 Ollama 都支持这类缓存,记得在服务端配置里打开。

线程数不是越多越好。在 RK3588 这种多核 CPU 上,实测 4 到 6 线程往往比 8 线程快,因为内存带宽不够时线程竞争反而拖慢速度。这个完全靠实测调参,别照着默认值用。

最后就是流式输出。端侧模型首 token 延迟虽然低,但完整生成量很大,Agent 在“计划阶段”可以先流式把思路反馈出来,用户感知会好很多。

5.3 并发与多 Agent 请求:端侧扛并发的现实约束

很多团队问我“AI Agent 怎么扛并发”,如果在端侧场景,答案是:单张开发板或单台手机通常只适合服务 1 到 2 个并发 Agent 会话。原因在于 KV cache 可能比模型权重还大,并发请求都要独立分配 KV cache 和推理计算资源。

实操思路有几个。用--parallel控制并发 slot 数,超出部分排队;做优先级队列,交互式请求优先,后台批处理任务让路;如果流量确实高,从单设备升级为多设备负载均衡,但那已经不是端侧部署的范畴,需要网关层做路由。端侧并发拼的不是吞吐,是响应延迟和资源利用率的平衡。

6. 部署之后接入 Agent:工具调用、记忆与工程坑

6.1 结构化输出:让 LLM 的“思考”变成可执行计划

端侧 Agent 和语言模型最关键的接口不是聊天文本,而是函数调用。部署服务时要确认三件事:引擎是否支持 OpenAI 兼容的 tools 参数;模型的 chat template 是否包含 function calling 指令,Qwen 系列原版模板自带,老模型可能需要自己拼;输出是否走 grammar 约束而不是自然生成。

实际操作里,我建议把工具调用拆成两步:第一轮让模型输出“行动计划”,一个纯 JSON 数组,性能压力小;第二轮为每个步骤执行本地函数并观察结果。“计划-执行-观察”的循环比让模型一步到位更稳,而且就算中间某一步失败,Agent 可以针对失败结果重新生成局部计划,不需要整轮重来。

6.2 知识注入:用本地 embedding 给 Agent 建稳定指涉

端侧 Agent 经常要操作一套固定的领域实体,比如设备名称、账号、配置项。如果只靠 LLM 常识,会出现幻觉引用不存在的实体。务实的做法是用本地 embedding 模型加向量库,把领域文档和实体词典做成本地索引。这也正是热词里那个 LLM ontology 概念的意思:先给知识建本体结构,再让 LLM 去检索。

部署层面就是再起一个 embedding 服务,Agent 在调用 LLM 前先检索相关资料,拼到 system prompt 里。小模型上下文里带与任务强相关的高质量上下文,比给它完整文档更有效。拼不相关的资料反而会稀释注意力,导致指令遵循进一步下降。

6.3 Token 视角看 Agent 记忆:Key、Query、Value 的真实用法

很多人第一次接触大模型时看到 K、Q、V 三个矩阵就头晕,其实放在 Agent 记忆系统里理解特别自然:你把“用户当前的目标”当成 Query,把“记忆库里的历史事件”拆成 Key,把“检索到的完整线索”当成 Value。向量检索的过程本质就是注意力机制的外化:Query 去匹配 Key,返回 Value。

所以设计端侧 Agent 的记忆模块,完全可以借用 Transformer 这三个角色的思路。给每个记忆条目标好可检索的 Key,比如时间、事件类别、实体名;用户请求进来先做 Query 编码;再用向量匹配召回 Value 片段。这样 Agent 的长期记忆和 LLM 部署服务之间,只需要一个统一的 embedding 模型就能串起来。

我自己的实现是:每条记忆存成结构化元数据加文本片段,元数据生成也交给本地 LLM,这比纯向量检索更精准。端侧模型虽然小,但做“给一段文本打三个标签”这种分类任务完全够用。

6.4 几条部署侧的工程坑

最后分享一组实测总结。第一,别忘了给系统留内存,模型权重加 KV cache 再叠加操作系统,8GB 设备的可用内存往往只剩 1 到 2GB,很容易 OOM,部署前先算好总账。第二,长时间运行监控温度,Jetson 跑满 GPU 30 分钟以上容易降频,Agent 服务的峰值 token 速度会垮掉,一定要在业务侧留 graceful degradation 策略。第三,GGUF 文件动辄几个 GB,必须做版本管理,否则线上模型文件被替换后,Agent 行为漂移都查不到原因。

我个人做端侧 Agent 最大的体会是:瓶颈往往不在模型不够聪明,而在部署链路不够稳。模型选 1.5B 还是 7B 不是最值得纠结的事,真正花时间的永远是 KV cache 够不够、输出格式稳不稳、温度控制好不好。如果你刚开始做端侧 Agent,建议先用 1.5B 模型在一块 RK3588 上把整个 Agent 链路完整跑通,再去调模型规格。链路通了,其他都是参数问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询