端侧LLM部署实战:模型选型、量化压缩与推理引擎优化指南
发布时间:2026/10/2 11:12:11 作者:尧图编辑部 阅读量:1,286

端侧 Agent 这件事真正落到工程上第一个绕不开的坎就是模型到底怎么塞进设备里。我见过太多团队在云端把 Agent 跑得风生水起一到端侧就卡在部署环节——显存不够、量化掉点、推理延迟飙到没法用。这一篇就专门聊端侧 LLM 部署这件事从模型选型、量化压缩、推理引擎到内存调度把我自己踩过的坑和验证过的方案完整摊开讲。不管你是刚接触端侧 AI 的新手还是已经在 RK3588、Jetson Orin 这类板子上折腾过的老手下面这些内容应该都能帮你少走几段弯路。1. 端侧 LLM 部署到底难在哪1.1 端侧和云端的本质差异不是小一点很多人第一次做端侧部署脑子里想的是把云端那套缩小版搬过来就行。这个认知会让你在第一个月就撞墙。端侧和云端的差异不是规模问题是约束条件完全不同。云端部署 LLM你关心的是吞吐、并发、GPU 利用率显存不够就加卡带宽不够就加节点。端侧呢内存是焊死的算力是固定的功耗有硬上限散热靠被动方案。你面对的是一个封闭系统所有资源都是零和博弈——模型多占 100MB 内存留给 KV Cache 的就少 100MB直接影响能支持的上下文长度。更关键的是端侧设备通常没有独立的显存。CPU、GPU、NPU 共享同一块物理内存这意味着模型权重、激活值、KV Cache、系统进程全在抢同一池子。你在云端习惯的显存不够就 offload 到内存这套玩法在端侧直接失效因为内存本身就是瓶颈。1.2 三个硬约束内存、算力、功耗我把端侧部署的约束归纳成三条线任何一条踩线都会导致方案不可用。内存墙是最先撞上的。一个 7B 参数的模型FP16 精度下光权重就要 14GB这还没算 KV Cache 和运行时开销。而主流端侧设备的可用内存通常在 4GB 到 16GB 之间还要分给操作系统和其他应用。所以模型压缩不是可选项是必选项。算力墙决定了你的推理速度上限。端侧 NPU 的算力通常标称几十 TOPS但实际能跑 LLM 的效率要打很大折扣因为 LLM 是访存密集型任务不是纯计算密集型。很多 NPU 标称算力很高但内存带宽跟不上实际 token 生成速度惨不忍睹。功耗墙是最容易被忽略的。设备跑起来发热一发热就降频一降频延迟就上去。我实测过某款开发板冷机状态下能跑到 15 tokens/s连续跑十分钟后掉到 6 tokens/s就是因为温控降频。所以做端侧部署散热设计必须和模型选型一起考虑。1.3 一个真实的部署失败案例说个我自己的经历。早期做一个端侧语音助手项目选了个 13B 的模型想着量化到 4bit 应该能塞进 8GB 内存。理论计算13B × 0.5 字节 ≈ 6.5GB加上 KV Cache 和运行时8GB 勉强够。实际部署上去模型加载就失败了。排查发现几个问题叠加量化后的模型实际占用比理论值高 15% 左右因为有些层没法量化到 4bit得保留 8bit 甚至 FP16运行时框架本身有 500MB 到 1GB 的开销KV Cache 在长上下文场景下能吃掉 1GB 以上。三项一加直接爆内存。最后降到 7B 模型才跑通。这个教训让我明白端侧部署的内存预算理论值至少要留 40% 的余量否则一定翻车。2. 模型选型不是越小越好也不是越大越强2.1 参数量、量化精度、内存占用的三角关系选模型本质上是在参数量、量化精度、内存占用之间找平衡点。我整理了一个实用的对照表基于实际部署经验不是理论值。参数量FP16 内存8bit 内存4bit 内存适用设备内存1.5B3GB1.5GB0.8GB2GB3B6GB3GB1.6GB4GB7B14GB7GB3.8GB8GB13B26GB13GB7GB16GB34B68GB34GB18GB32GB注意这里的 4bit 内存是含运行时开销的实测值比纯权重大概多 10% 到 20%。选型时先看设备可用内存再倒推能上多大的模型。2.2 小模型的能力边界在哪里很多人对小模型有误解觉得 3B 以下就是玩具。实际上在特定任务上小模型经过微调后完全可用。关键是要认清小模型的能力边界。我实测下来1.5B 到 3B 这个区间的模型适合做这几类任务意图识别和分类、简单的信息抽取、固定格式的文本生成、作为 Agent 的 router 层做任务分发。不适合做复杂推理、多步规划、长文本理解、需要世界知识的问答。7B 是个分水岭。7B 模型在量化到 4bit 后能在 8GB 设备上跑同时具备基本的推理能力和指令遵循能力可以作为端侧 Agent 的主模型。13B 以上在端侧就比较尴尬了要么设备内存够大要么只能跑很低的量化精度掉点严重。2.3 选型时容易忽略的隐性成本除了内存还有几个隐性成本必须算进去。Tokenizer 的开销。不同模型的 tokenizer 效率差异很大同样一段中文有的模型切成 50 个 token有的切成 80 个。token 数直接决定推理时间和 KV Cache 大小。选型时一定要用你的真实业务语料测一下 tokenizer 效率。上下文长度。标称支持 32K 上下文不代表端侧能跑 32K。KV Cache 大小和上下文长度成正比7B 模型在 4bit 量化下32K 上下文的 KV Cache 能吃掉 2GB 以上内存。端侧实际能用的一般是 2K 到 8K。推理框架的适配程度。有些模型架构新推理框架还没做好优化跑起来效率很低。选型时优先选社区支持好、有成熟端侧部署案例的模型架构。3. 量化端侧部署的核心技术3.1 量化到底在做什么量化的本质是用更少的比特表示权重和激活值。FP16 用 16 位表示一个数INT8 用 8 位INT4 用 4 位。位数越少内存占用越小但精度损失越大。用一个生活化的类比FP16 像是用一把刻度很细的尺子量东西INT4 像是用一把只有几个刻度的尺子。大部分时候够用但遇到需要精确测量的场景就会出问题。量化的核心挑战是如何在压缩的同时尽量保留模型的能力。这里的关键是找到权重分布中的重要区域对这些区域用更高的精度不重要的区域大胆压缩。3.2 主流量化方案对比目前端侧常用的量化方案有这么几类我按实际使用体验做个对比。GPTQ是训练后量化用校准数据集来最小化量化误差。优点是压缩率高4bit 下效果不错缺点是需要校准数据量化过程比较慢而且对校准数据的选择敏感。AWQ的核心思路是保护重要权重通过激活值分布识别出对输出影响大的权重通道对这些通道保留更高精度。实测下来 AWQ 在 4bit 下的效果通常比 GPTQ 好一点尤其是对指令遵循能力的保留。GGUF是 llama.cpp 生态的格式支持多种量化等级从 Q2 到 Q8。它的优势是灵活可以根据设备内存选不同等级而且 CPU 推理优化做得好。端侧如果 NPU 支持不好用 GGUF 走 CPU 推理是个稳妥选择。动态量化是在推理时实时量化激活值权重保持较高精度。这种方式精度损失小但推理时有额外计算开销端侧不一定划算。方案压缩率精度保留量化速度端侧适配GPTQ高中慢好AWQ高较好中好GGUF灵活好快很好动态量化中很好快一般3.3 量化掉点的真实表现和补救量化一定会掉点关键是掉在哪里。我的经验是量化对模型的影响不是均匀的有些能力掉得厉害有些几乎不受影响。掉得厉害的是数学计算、代码生成、需要精确记忆的任务。这些任务对权重的细微变化敏感量化后错误率明显上升。掉得少的是文本分类、情感分析、简单的信息抽取。这些任务对精度要求没那么高量化后基本能用。补救手段有几个。一是混合精度量化对敏感层保留 8bit其他层用 4bit。二是量化后做轻量微调用少量数据把掉的能力找回来一部分。三是 prompt 工程补偿在提示词里加更多约束和示例引导模型输出正确格式。我实测过一个 7B 模型4bit 量化后在数学题上准确率从 65% 掉到 42%但经过 500 条数据的 LoRA 微调后恢复到 58%。这个恢复程度在端侧场景下已经够用了。4. 推理引擎选对了省一半力气4.1 端侧推理引擎的几种路线端侧 LLM 推理引擎大致分三条路线各有适用场景。通用推理框架比如 ONNX Runtime、TensorFlow Lite优势是跨平台、生态成熟缺点是针对 LLM 的优化不够深KV Cache 管理、注意力计算这些没有专门优化。LLM 专用框架比如 llama.cpp、MLC-LLM、MNN这些是专门为 LLM 设计的在内存管理、量化支持、注意力计算上做了大量优化。端侧部署优先考虑这类。厂商 NPU 工具链比如各家芯片厂商提供的推理 SDK能充分利用 NPU 算力但适配成本高模型转换麻烦而且不同厂商的工具链差异很大。4.2 llama.cpp 在端侧的实战配置llama.cpp 是我在端侧用得最多的方案这里给一份实测可用的配置。编译时关键选项cmake -B build \ -DCMAKE_BUILD_TYPERelease \ -DLLAMA_CURLOFF \ -DGGML_OPENMPON \ -DGGML_BLASON \ -DGGML_BLAS_VENDOROpenBLAS运行时的关键参数./llama-cli \ -m model-q4_k_m.gguf \ -c 4096 \ -n 512 \ -t 4 \ --mlock \ --no-mmap \ -ngl 0几个参数的解释-c 4096是上下文长度端侧建议不要超过 8K-t 4是线程数一般设成物理核心数--mlock锁定内存防止被换出端侧内存紧张时慎用--no-mmap禁用内存映射加载慢但运行时更稳定-ngl 0表示不用 GPU 层纯 CPU 推理如果有 GPU 可以调大。4.3 NPU 加速的坑与收益用 NPU 跑 LLM 听起来很美实际有不少坑。第一个坑是算子支持不全。LLM 里有些算子 NPU 不支持会 fallback 到 CPU导致频繁的数据搬运反而比纯 CPU 还慢。部署前一定要确认模型的所有算子都能在 NPU 上跑。第二个坑是量化格式不匹配。NPU 通常要求特定的量化格式比如 INT8 对称量化而你在 PC 上量化好的模型可能不兼容需要重新量化。第三个坑是动态 shape 支持差。LLM 推理时序列长度是变化的很多 NPU 对动态 shape 支持不好要么固定长度浪费算力要么频繁重编译。收益方面如果算子适配好、量化格式对NPU 相比 CPU 能有 2 到 5 倍的加速。但这个收益需要投入大量适配工作项目周期紧的话先用 CPU 方案跑通再逐步优化 NPU 是更稳妥的路径。5. 内存管理与 KV Cache 优化5.1 KV Cache 为什么是内存杀手KV Cache 是 Transformer 推理时缓存的历史键值对避免重复计算。它的存在让自回归生成成为可能但也带来了内存问题。KV Cache 的大小计算公式2 × 层数 × 头数 × 头维度 × 序列长度 × 精度字节数。以一个 7B 模型为例32 层、32 头、头维度 128序列长度 4096FP16 精度2 × 32 × 32 × 128 × 4096 × 2 ≈ 2GB。这 2GB 是纯 KV Cache还没算模型权重。端侧设备总共就 8GB 内存模型权重占 4GBKV Cache 占 2GB系统和其他应用占 1GB只剩 1GB 余量。这就是为什么端侧上下文长度通常限制在 2K 到 4K。5.2 几种 KV Cache 压缩策略针对 KV Cache 的内存压力有几种优化策略。量化 KV Cache。把 KV Cache 从 FP16 量化到 INT8内存直接减半。实测下来对生成质量影响很小是性价比最高的优化。llama.cpp 里可以用--cache-type-k q8_0 --cache-type-v q8_0开启。滑动窗口注意力。只保留最近 N 个 token 的 KV更早的丢弃。Mistral 系列模型用的就是这个方案。优点是内存恒定缺点是丢失长距离依赖。分页注意力。把 KV Cache 分成固定大小的页按需分配减少内存碎片。vLLM 用的就是这个方案端侧也有框架在借鉴。KV Cache 驱逐。根据注意力权重驱逐不重要的 KV 对。这个方案实现复杂端侧框架支持还不多。5.3 内存预算的实操分配方法我总结了一个端侧内存预算的分配方法按这个来基本不会爆。先确定设备可用内存比如 8GB 设备系统和其他应用占 2GB留给推理的 6GB。然后按比例分配模型权重占 60% 到 70%KV Cache 占 20% 到 30%运行时开销占 10%。6GB 的预算下模型权重最多 4GB对应 7B 模型 4bit 量化KV Cache 留 1.5GB对应 4K 上下文运行时留 0.5GB。这个配置实测能稳定跑。如果内存更紧张比如 4GB 设备那就得上 3B 模型或者把上下文压到 2K。不要试图在 4GB 设备上跑 7B 模型即使量化到 4bit 也很勉强运行时容易 OOM。6. 部署流程与实测调优6.1 从模型到设备的完整链路端侧 LLM 部署的完整链路是这样的原始模型 → 量化 → 格式转换 → 部署到设备 → 运行时调优。每一步都有坑。量化阶段要选对方案和校准数据格式转换要确保目标框架支持部署阶段要处理依赖和权限调优阶段要平衡速度和内存。我建议的实操顺序是先在 PC 上用目标框架跑通量化模型确认效果可接受再交叉编译到设备架构最后在设备上做性能和内存调优。不要一上来就在设备上折腾调试效率太低。6.2 首 token 延迟和生成速度的平衡端侧部署有两个关键指标首 token 延迟TTFT和生成速度tokens/s。这两个指标往往互相矛盾。首 token 延迟取决于 prompt 处理速度prompt 越长延迟越高。生成速度取决于单 token 的计算和访存效率。优化首 token 延迟的手段prompt 缓存、prefix sharing、更激进的量化。优化生成速度的手段KV Cache 量化、算子融合、NPU 加速。实际场景下如果是对话类应用首 token 延迟更重要用户等 2 秒没反应就跑了。如果是批量生成任务生成速度更重要。根据场景选优化方向。6.3 实测数据与调优记录分享一组我在某款 8GB 内存开发板上的实测数据模型是 7B 的 4bit 量化版本。配置首 token 延迟生成速度内存占用纯 CPU4 线程1.8s8 tokens/s5.2GB纯 CPU8 线程1.2s11 tokens/s5.4GBCPU NPU 部分层0.9s16 tokens/s5.6GB上述 KV Cache INT80.9s15 tokens/s4.3GB可以看到KV Cache 量化后生成速度略降但内存省了 1.3GB这个 trade-off 在内存紧张时非常值得。NPU 加速收益明显但适配成本高。调优过程中发现一个反直觉的点线程数不是越多越好。8 线程相比 4 线程提升有限但功耗和发热明显增加长时间跑反而因为降频导致速度下降。最终稳定在 6 线程是个平衡点。7. 端侧 Agent 场景下的部署特殊考量7.1 Agent 对模型调用的特殊需求端侧 Agent 和单纯的对话应用不一样它对模型的调用模式更复杂。Agent 通常需要多次调用模型一次做意图理解一次做工具选择一次做结果总结。每次调用都有延迟累加起来用户体验就很差。所以端侧 Agent 的模型部署要考虑多轮调用的总延迟而不只是单次推理速度。另一个需求是结构化输出。Agent 需要模型输出特定格式的 JSON 或函数调用这对模型的指令遵循能力要求高。量化后模型的结构化输出能力容易掉点需要额外验证。7.2 多模型协同的部署策略端侧 Agent 常见的一个优化是大小模型协同。用一个小模型1.5B 到 3B做 router判断任务类型简单任务小模型直接处理复杂任务交给大模型。这种策略下两个模型都要部署在设备上内存压力更大。解决方案是模型分时加载router 模型常驻大模型按需加载。但加载模型本身有延迟7B 模型从存储加载到内存要几秒这个延迟要算进用户体验里。另一个方案是模型共享。如果两个模型架构相同只是参数量不同可以共享部分层。这个方案实现复杂端侧框架支持有限。7.3 端侧 Agent 的降级与容错端侧环境不稳定内存可能被其他应用挤占温度可能过高这些都会影响推理。Agent 必须有降级策略。我的做法是设置三级降级正常状态下用 7B 模型跑完整流程内存紧张时切换到 3B 模型牺牲部分能力极端情况下只跑规则引擎不调用 LLM。降级触发条件要提前定义好可用内存低于阈值、推理延迟超过阈值、连续推理失败次数超过阈值。这些监控逻辑要集成到 Agent 框架里不能等到 OOM 了才处理。8. 一些踩坑之后的经验部署端侧 LLM 这几年有几个经验是文档里不会写、但实际很重要的。第一永远在真实设备上测不要在 PC 上模拟。PC 的内存带宽、散热条件、调度策略和端侧设备完全不同PC 上跑得好不代表设备上能跑。我吃过好几次亏PC 上流畅的配置到设备上直接卡死。第二量化模型要重新验证能力不能假设和原模型一致。尤其是你的业务场景涉及特定领域知识时量化可能把相关能力压没了。上线前一定要用业务测试集跑一遍。第三内存监控要常态化。端侧内存是动态变化的其他应用可能随时占用。部署时要加内存监控接近阈值时主动降级而不是等系统杀进程。第四散热设计要和模型选型一起做。被动散热的设备持续推理能力比峰值性能更重要。选模型时按持续性能算不要按峰值算。第五留足调试时间。端侧部署的调试效率远低于云端交叉编译、日志抓取、性能分析都更麻烦。项目排期时部署调试的时间要按云端的两到三倍来估。端侧 LLM 部署这件事没有一劳永逸的方案只有针对具体设备和场景不断调优的过程。上面这些是我在实际项目中验证过的思路和方法具体参数还需要根据你的设备实测调整。如果遇到奇怪的性能问题先查内存和温度这两个是最常见的元凶。