首页 / 资讯中心 / 文章详情

端侧LLM部署实战:从模型量化到Agent工程化落地

端侧LLM部署实战:从模型量化到Agent工程化落地 ★ FEATURED ARTICLE
1. 端侧 LLM 部署到底在解决什么问题1.1 从云端 API 到端侧推理的动机转变过去两年大部分 Agent 项目都是把 LLM 放在云端端上只负责采集输入、渲染输出。这个模式在 Demo 阶段非常舒服但一旦进入真实产品问题就集中爆发了。最直接的是延迟一次请求要经过网络往返、排队、推理、回传用户说一句话到看到响应动辄两三秒起步。其次是成本按 token 计费的账在用户量上来之后会变得非常难看尤其是那些需要频繁调用工具、反复推理的 Agent 场景token 消耗是普通对话的好几倍。再往下是隐私和可用性用户的数据要离开设备网络断了整个功能就废了。端侧 LLM 部署要解决的就是这三件事把推理搬到设备本地让延迟降到几百毫秒级、让边际成本趋近于零、让数据不出设备。这不是一个能不能做的问题而是一个在什么约束下值得做的问题。端侧设备的算力、内存、功耗都是硬约束所以端侧部署的核心矛盾永远是模型能力与设备资源之间的平衡。我自己的判断是端侧 Agent 并不是要把云端大模型完全替换掉而是形成一个分层结构。高频、低复杂度、对延迟敏感的任务放在端侧比如意图识别、槽位抽取、简单工具调用低频、高复杂度、需要强推理的任务再交给云端。这种混合架构才是现阶段最务实的方案而端侧 LLM 部署就是这套架构的地基。1.2 端侧 Agent 对 LLM 的特殊要求端侧 Agent 和普通的端侧对话应用不一样它对 LLM 的要求更苛刻。普通对话只要生成流畅就行Agent 还要稳定输出结构化内容比如 JSON 格式的工具调用参数、固定的动作指令。这就要求模型不仅要小还要听话指令遵循能力不能太差。另一个关键点是首 token 延迟。Agent 的交互往往是多轮的用户能明显感知到每一轮的响应速度。如果首 token 要等一秒以上整个体验就崩了。所以端侧部署时prefill 阶段的性能比 decode 阶段更值得关注因为 Agent 的输入通常包含系统提示词、工具定义、历史上下文prompt 长度不短。还有一个容易被忽略的点是内存占用。端侧设备的内存是共享的模型占多了留给其他功能的空间就少了。一个 7B 模型用 FP16 存储要 14GB 左右这在很多设备上直接不可行。所以量化几乎是端侧部署的必选项而量化又会带来精度损失这个权衡贯穿整个部署过程。1.3 适合端侧部署的典型硬件盘点目前能跑端侧 LLM 的硬件大致分几类。第一类是手机 SoC比如高通的骁龙系列、联发科的天玑系列它们的 NPU 算力在几十 TOPS 级别内存通常 8GB 到 16GB。第二类是单板计算机和边缘计算盒子比如 RK3588 这类芯片NPU 算力 6 TOPS 左右内存可以做到 16GB 甚至 32GB性价比很高适合做固定场景的边缘 Agent。第三类是带独立 GPU 的嵌入式设备比如 Jetson Orin 系列算力从几十到两百多 TOPS能跑更大的模型适合机器人、工业质检这类场景。选硬件的逻辑很简单先看你要跑多大的模型再看你的延迟预算最后看功耗和成本。如果只是跑 1B 到 3B 的模型做意图识别RK3588 这种级别的板子就够了。如果要跑 7B 以上还要保证流畅那就得上 Orin 或者带独显的设备。别一上来就追求最强硬件端侧部署的性价比往往比绝对性能更重要。2. 模型选型与量化端侧部署的第一道坎2.1 参数量、上下文长度与设备内存的三角关系选模型的第一步是算内存账。一个模型在推理时占用的内存大致由三部分组成权重、KV Cache、运行时开销。权重占用等于参数量乘以每个参数的字节数FP16 是 2 字节INT8 是 1 字节INT4 是 0.5 字节。KV Cache 的占用和上下文长度、层数、隐藏维度、batch size 都相关公式是 2 × 层数 × 上下文长度 × 隐藏维度 × batch size × 精度字节数。举个例子一个 7B 模型32 层隐藏维度 4096上下文 4096batch size 为 1用 FP16 存 KV Cache占用大约是 2 × 32 × 4096 × 4096 × 1 × 2 字节算下来约 2GB。如果权重用 INT4 量化大约 3.5GB加上 KV Cache 和运行时开销总共 6GB 左右。这意味着 8GB 内存的设备勉强能跑但留给系统的余量很小。如果把上下文拉到 8192KV Cache 直接翻倍到 4GB就很可能 OOM 了。所以端侧选模型参数量和上下文长度要一起看。很多模型标称支持 32K 上下文但端侧根本用不起实际部署时往往要限制在 2K 到 4K。Agent 场景尤其要注意因为工具定义和系统提示词会吃掉大量上下文预算。2.2 量化方案怎么选INT8、INT4 与混合精度量化是端侧部署绕不开的环节。INT8 量化相对安全精度损失通常在 1% 以内内存直接减半是很多场景的首选。INT4 量化能把内存再砍一半但精度损失会明显一些尤其是对指令遵循和结构化输出要求高的 Agent 任务可能会出现格式错误、参数丢失的问题。现在主流的做法是混合精度量化也就是对敏感层用高精度对不敏感的层用低精度。比如权重用 INT4但 embedding 层和输出层保持 INT8 或 FP16因为这两层对精度更敏感。还有一些方案会对 attention 的某些部分保留高精度。实际选型时我建议先用 INT8 跑通确认效果达标后再尝试 INT4并且一定要用真实任务做评测不能只看困惑度这种指标。提示量化后的模型一定要做端到端的功能测试尤其是工具调用、JSON 输出这类结构化任务。困惑度下降一点点可能对应的是工具调用成功率下降一大截。2.3 主流端侧模型横向对比目前端侧常用的模型大致有这么几类。Qwen 系列的小尺寸版本在中文场景表现不错指令遵循能力较强社区量化版本也丰富。Llama 系列的小模型生态最成熟各种推理框架支持都很好。Phi 系列主打小体积强推理在数学和逻辑任务上有优势。Gemma 系列在英文场景表现均衡。还有一些专门为端侧设计的模型参数量在 0.5B 到 3B 之间牺牲一部分通用能力换取极致的体积和速度。选型时不要只看榜单分数要看你的任务类型。如果是中文 Agent优先考虑中文能力强的模型如果是纯工具调用重点看结构化输出稳定性如果要做多模态那可选范围会窄很多。我一般会准备两三个候选模型用同一套真实任务跑一遍看哪个在延迟和准确率上综合最优。模型类型参数量区间典型内存占用INT4适合场景超小模型0.5B-1.5B0.5-1GB意图识别、分类、简单抽取小模型3B-4B2-3GB工具调用、短对话、轻量 Agent中等模型7B-8B4-5GB复杂 Agent、多轮推理大模型13B8GB边缘服务器、高算力设备3. 推理框架与运行时环境搭建3.1 端侧推理框架选型逻辑端侧推理框架的选择核心看三件事硬件后端支持、量化支持、以及和你的 Agent 框架的集成难度。常见的框架有 llama.cpp 系列、MNN、NCNN、ONNX Runtime、TensorRT 等。llama.cpp 的优势是 CPU 推理优化好、量化格式丰富、跨平台在 ARM 设备上表现很稳。MNN 和 NCNN 是国内团队做的对移动端和国产芯片支持好。TensorRT 在 NVIDIA 设备上性能最强但绑定 CUDA 生态。ONNX Runtime 胜在通用但端侧性能不一定是最优。我的经验是如果目标是快速验证llama.cpp 是最省事的选择几乎什么设备都能跑起来。如果要榨干 NPU 性能那就得用芯片厂商提供的推理框架比如 RK3588 上用 RKNNJetson 上用 TensorRT。这里有个坑NPU 推理往往需要模型转换成特定格式转换过程可能遇到算子不支持的问题需要提前确认模型结构是否兼容。3.2 从模型文件到可运行服务的完整流程端侧部署的完整流程大致是拿到原始模型权重做量化或格式转换用推理框架加载封装成服务接口再接入 Agent 逻辑。每一步都有细节。以 llama.cpp 为例第一步是把 HuggingFace 格式的模型转成 GGUF 格式这一步会同时完成量化。转换命令大致是这样的python convert-hf-to-gguf.py ./model --outfile model-f16.gguf --outtype f16 ./quantize model-f16.gguf model-q4.gguf Q4_K_MQ4_K_M 是一种混合量化方案对关键层保留较高精度是端侧比较常用的档位。转换完成后用 llama-server 启动一个本地 HTTP 服务./llama-server -m model-q4.gguf -c 4096 -t 4 --host 127.0.0.1 --port 8080这里的-c是上下文长度-t是线程数。线程数不是越多越好一般设成物理核心数超线程反而可能因为调度开销导致性能下降。启动后就可以用标准的 OpenAI 兼容接口调用了Agent 框架接入非常方便。3.3 内存与线程参数的调优实操参数调优是端侧部署里最需要经验的部分。上下文长度-c直接决定 KV Cache 大小能小则小够用就行。线程数-t要实测不同设备差异很大。batch size 在端侧通常设为 1因为 Agent 场景大多是单用户交互增大 batch 只会增加内存占用。还有一个关键参数是是否把模型全部加载到内存。有些框架支持 mmap也就是内存映射模型文件不全部读入内存按需加载。这在内存紧张的设备上很有用但会增加磁盘 IO首次推理会慢一些。如果设备内存够建议全部加载延迟更稳定。我实测下来RK3588 上跑一个 3B 的 INT4 模型4 线程上下文 2048首 token 延迟在 300 到 500 毫秒decode 速度大概每秒 8 到 12 个 token。这个速度做 Agent 的工具调用是够用的但做长文本生成就偏慢。所以端侧 Agent 的设计要尽量让模型少生成多用结构化输出和工具调用。4. 把 LLM 接进 Agent端侧的特殊处理4.1 提示词工程在端侧的简化策略端侧模型能力有限提示词不能像云端那样写得很长很复杂。系统提示词要极度精简把最关键的规则放在最前面。工具定义也要压缩只保留必要的参数说明去掉冗余描述。我见过很多项目直接把云端的提示词搬到端侧结果模型根本处理不了那么长的上下文输出质量断崖式下跌。一个实用的做法是把复杂任务拆解成多个简单步骤每一步用短提示词单独调用模型。比如先做意图分类再做参数抽取最后做结果生成。虽然调用次数多了但每次调用都简单整体成功率反而更高。端侧模型的单次推理快多调用几次的延迟代价可以接受。4.2 工具调用与结构化输出的稳定性保障端侧模型做工具调用最大的问题是输出格式不稳定。有时候多输出一段解释有时候 JSON 少个括号。解决办法有几个层次。第一层是在提示词里明确要求只输出 JSON并给出格式示例。第二层是在推理时用 grammar 或 JSON schema 约束输出很多推理框架支持这个功能能从解码层面保证格式正确。第三层是在应用层做解析容错解析失败时尝试修复或重试。grammar 约束是最可靠的方案但会稍微增加推理开销。如果框架支持强烈建议开启。如果框架不支持那就得在提示词和解析容错上多下功夫。我一般会写一个健壮的 JSON 解析器能处理常见的格式问题比如多余的前后缀、单引号、尾随逗号等。4.3 多轮对话与上下文管理的端侧方案端侧内存有限上下文不能无限增长。多轮对话必须做上下文管理。最简单的策略是滑动窗口只保留最近 N 轮。但 Agent 场景里早期的工具调用结果可能对后续推理很重要直接丢掉会出问题。更好的做法是做摘要压缩把历史对话用模型压缩成简短摘要保留关键信息。但端侧模型做摘要本身也要消耗算力所以要权衡。我的做法是分层管理最近的几轮保留原文更早的做摘要再早的直接丢弃。同时把工具调用的结果结构化存储需要时按需检索而不是全部塞进上下文。注意端侧 Agent 的上下文预算要提前规划好系统提示词、工具定义、历史对话、当前输入各占多少心里要有数。否则很容易出现上下文溢出导致推理失败。5. 性能优化与常见问题排查5.1 首 token 延迟与吞吐的优化手段首 token 延迟主要受 prefill 阶段影响优化手段有几个。一是缩短 prompt能精简就精简。二是用 KV Cache 复用如果多轮对话的前缀相同可以复用之前计算的 KV Cache避免重复计算。很多推理框架支持 prompt cache开启后多轮对话的首 token 延迟会明显下降。三是用更快的量化格式比如 Q4 比 Q8 的 prefill 速度更快。吞吐优化主要看 decode 阶段。端侧 decode 速度受内存带宽限制很大因为每生成一个 token 都要读取全部权重。所以量化不仅省内存还能提升 decode 速度。另外减少生成 token 数也是提升整体吞吐的有效手段让模型尽量输出短内容。5.2 端侧部署典型故障速查表故障现象可能原因排查方向启动即 OOM模型太大或上下文过长降低量化精度、减小上下文首 token 极慢prompt 过长或未开 cache精简提示词、开启 prompt cache输出乱码量化精度过低或格式不兼容换量化档位、检查模型转换工具调用失败输出格式不稳定开启 grammar 约束、加解析容错推理速度波动大线程数设置不当或热降频调整线程数、检查散热NPU 不生效模型未转换或算子不支持确认模型格式、检查算子兼容性5.3 我踩过的几个坑与应对经验第一个坑是量化档位选太高。一开始为了省内存用了 Q3结果模型输出质量惨不忍睹工具调用基本全错。后来换成 Q4_K_M质量明显回升内存也没多多少。所以量化不要一味追求低比特Q4 通常是端侧的甜点档位。第二个坑是线程数设成 CPU 核心数。在 RK3588 上8 核全开反而比 4 线程慢因为大小核调度和内存带宽争抢。后来固定用 4 个大核性能稳定多了。这个必须实测没有通用答案。第三个坑是忽略了散热。端侧设备体积小长时间推理容易热降频速度会掉一半。做压力测试时一定要跑够时间观察速度是否稳定。如果降频严重要么加散热要么限制推理频率。第四个坑是上下文长度设太大。为了支持长对话把上下文设成 8192结果内存不够频繁 OOM。后来改成 2048 加滑动窗口稳定多了。端侧部署要学会做减法不是功能越多越好。6. 端侧 Agent 的工程化落地建议6.1 分层架构端侧与云端的协同设计纯端侧方案在很多场景下能力不够纯云端方案又有延迟和成本问题。最务实的是分层架构。端侧负责高频、低延迟、隐私敏感的任务云端负责低频、高复杂度、需要强推理的任务。端侧模型可以先做一轮判断简单任务直接处理复杂任务再转发云端。这个架构的关键是路由逻辑。路由本身也要轻量可以用端侧小模型做意图判断或者用规则引擎。路由错了会导致体验下降所以要有兜底机制比如端侧处理置信度低时自动转云端。6.2 模型更新与版本管理端侧模型更新是个麻烦事。模型文件动辄几个 GB不能像 App 那样频繁更新。我的做法是把模型和业务逻辑解耦模型文件独立管理支持增量更新和灰度发布。同时保留回滚能力新模型出问题能快速切回旧版本。版本管理还要考虑兼容性。不同版本的模型可能对提示词格式要求不同业务代码要能适配多个模型版本。建议在模型文件里带上版本元信息加载时校验避免版本错配。6.3 端侧 Agent 的评测与监控端侧部署不能只看能不能跑起来还要建立评测体系。评测要覆盖延迟、内存、准确率三个维度。延迟要分首 token 和 decode 分别测内存要测峰值和稳态准确率要用真实任务集测不能只看通用榜单。监控方面端侧设备资源有限不能做很重的埋点。我一般只采集关键指标推理耗时、内存峰值、失败率、降频次数。这些数据定期上报用于发现性能退化和定位问题。端侧 Agent 的稳定性比峰值性能更重要因为用户对卡顿和崩溃的容忍度很低。6.4 安全与隐私的端侧考量端侧部署的一大卖点就是隐私数据不出设备。但要注意模型本身也可能泄露信息比如通过提示词注入让模型输出系统提示词。端侧 Agent 要做好输入过滤和输出审查尤其是涉及工具调用时要防止恶意输入触发危险操作。另外端侧模型文件本身也要保护防止被提取或篡改。虽然端侧模型的价值相对云端低但如果模型是核心资产还是要做一定的保护措施。权限控制也很重要Agent 能调用的工具要严格限制不能给它过大的权限。我在实际项目里的体会是端侧 LLM 部署最难的不是把模型跑起来而是让它在资源约束下稳定地完成 Agent 任务。模型选型、量化、框架、提示词、上下文管理每一环都会影响最终效果而且这些环节是相互耦合的。调优的过程就是不断做权衡没有一劳永逸的配置。建议从最小的可用方案开始跑通端到端流程再逐步优化每个环节这样比一开始就追求完美配置要高效得多。
阅读完成 · 觉得有帮助?
咨询建站