news 2026/11/2 8:05:21

端侧Agent模型部署实战:从硬件选型到推理调优

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
端侧Agent模型部署实战:从硬件选型到推理调优

1. 为什么端侧 Agent 的第一道坎是模型部署

1.1 端侧 Agent 与云端方案的本质差别

这一篇是"深入理解端侧 Agent"系列的第二讲,主角是端侧 LLM 部署。上一篇我们聊过端侧 Agent 的整体架构:感知、记忆、规划、工具、执行,最后所有模块都要围绕一个核心决策引擎转,这个引擎就是 LLM。当时很多朋友留言问:模型到底怎么跑到 RK3588、Jetson Orin 这类硬件上?跑起来之后为什么速度忽快忽慢?为什么同一个模型在别人的板子上能跑出 15 token/s,自己只能跑出 3 token/s?

这些问题恰好就是端侧 LLM 部署的核心内容。云端方案里,模型部署是运维工程师的事:买 GPU、起容器、上推理服务,开发者只需要调 API。可到了端侧,模型部署变成每一个做智能体的人都要亲自动手的活。你既没有机房里的 A100,也没有等着被调用的现成接口,硬件资源抠抠搜搜,散热、功耗、内存带宽全都得自己操心。

端侧 Agent 和云端 Agent 的定位差别,决定了部署思路完全不同。云端智能体追求"能力上限":模型越大越好,上下文越长越好,工具越多越好。端侧智能体追求"响应闭环":摄像头拍到画面,传感器读到数据,用户说出指令,模型要在几百毫秒到几秒内给出决策,而且很多场景要求断网可用、数据不出本地。换句话说,云端部署考虑的是吞吐,端侧部署考虑的是时延和功耗。

很多人在这一步犯了认知错误:以为把一个大模型塞进开发板就是端侧部署。实际上,端侧 Agent 要的从来不是"模型能跑",而是"模型跑得够快、够可靠、能支撑完整任务链路"。一个 32B 模型在 RK3588 上跑出 1 token/s,对智能体来说基本没法用,因为一次工具调用加上上下文回传,用户要等几分钟。部署这件事,本质是在硬件约束下,把模型的能力和响应速度压到任务可接受的区间里。

1.2 部署要解决的核心矛盾

端侧 LLM 部署有四个绕不开的矛盾,我习惯称之为"端侧四象限":模型容量、推理速度、工具能力、功耗。这四个维度相互制约,任何一个被拉满,另外三个就要让路。

模型容量看的是硬件内存能装下多大的模型。端侧设备的内存通常只有 4GB 到 64GB,而且不像服务器那样可以弹性扩展。推理速度看的是内存带宽和算力:LLM 解码是典型的内存密集型任务,权重传输速度决定 token 生成速度,而不是单纯看 NPU 有多少 TOPS。工具能力看的是模型对 Function Calling 的支持程度,这直接决定智能体能不能可靠地调用摄像头、传感器、外部程序,这个能力在端侧小模型上往往比答题能力更重要。功耗看的是设备的散热设计:开发板没有数据中心那种恒温机房,长时间满载推理,温度一上来就会降频,速度断崖式下跌。

这四个矛盾里,最容易踩坑的是"只看 TOPS 不看带宽"。很多人看到 RK3588 标称 6 TOPS NPU,觉得跑个 7B 模型绰绰有余,实际部署后傻眼了:NPU 算力再高,权重从内存搬到计算单元的路上就卡死了。我见过不少项目,模型确实在跑,但 CPU 算出来比 NPU 还快,就是因为整机内存带宽成了瓶颈。

理解了这四个矛盾,后面选硬件、选模型、选引擎、调参数,本质上都是在同一个坐标系里找平衡点。这一篇会按照"硬件评估→模型选型→推理引擎→智能体对接→问题排查"的顺序把整个链路过一遍,所有操作都以能实际落地为准。

2. 动手之前先算账:硬件带宽与内存容量

2.1 常见端侧平台的底细

选硬件之前先看一张参数表。这里列的都是目前端侧智能体项目里最常见的平台,指标有差异,适合的场景也明显不同。

平台内存内存带宽(理论)典型算力能跑的模型档位典型功耗
Raspberry Pi 54/8GB约 34GB/sCPU 为主1.5B~3B 量化5~10W
RK35888/16GB34~51GB/s6 TOPS NPU3B~7B 量化5~15W
Jetson Orin Nano(8GB)8GB约 68GB/s40 TOPS7B~8B 量化7~15W
Jetson Orin NX(16GB)16GB约 102GB/s100 TOPS8B~14B 量化10~25W
Apple M 系列16/24/32GB100~200GB/s统一内存8B~32B 量化10~30W

这张表里最该记住的不是 TOPS,而是内存带宽。端侧平台的内存带宽差距非常大:树莓派 5 的 34GB/s 和 Orin NX 的 102GB/s,虽然都叫"开发板",实际能流畅运行的最大模型差了一整个档位。

这里补充一个容易被忽略的点:内存带宽是理论值,实际可用要打折扣。DDR/LPDDR 实测带宽通常是理论值的 60%~80%,而且并发读写、缓存命中率、NPO 与 CPU 共享内存总线都会进一步影响实际吞吐。所以我更建议大家按"理论带宽乘以 0.6~0.7"来估算下限,"乘以 0.8"来估算上限,这样规划出来的方案才不容易翻车。

2.2 内存带宽决定 Token 速度

LLM 在推理时的生成阶段,每一步都要把模型全部权重从内存读一遍,然后做一次前向计算。这个过程是内存带宽主导的,可以用一个很粗糙但很实用的公式估算:

预估 Token 速度 ≈ 可用内存带宽 ÷ 模型文件体积

举例来说,一个 7B 模型做 Q4_K_M 量化后,GGUF 文件大约 4.5GB。放在 Jetson Orin Nano 8GB 上,按 68GB/s 的 70% 折算,可用带宽约 47GB/s,那么预期速度大约是 47÷4.5 ≈ 10 token/s。换到 RK3588,按 51GB/s 的 70% 折算,可用带宽约 35GB/s,预期速度大约是 35÷4.5 ≈ 7.7 token/s。这个估算和社区里大家实测的 llama.cpp 跑 Qwen2.5-7B 的成绩基本对得上。

这个公式有两点使用前提。第一,它只适用于自回归解码阶段,也就是生成每个 token 的过程;模型预热加载、处理长 Prompt 的预填充阶段,更依赖算力,速度规律不一样。第二,它假设内存带宽是唯一瓶颈,现实中还要看引擎是否支持权重缓存、是否用到了硬件加速单元、是否存在 CPU 算力不足的情况。但它已经足够在买板子之前帮我们判断"这个硬件跑这个模型大概什么速度"。

2.3 除了权重,还要给 KV Cache 留位置

模型文件大小是内存开销的大头,但绝对不是全部。生成过程中,Transformer 会把已经见过的历史 token 的 Key 和 Value 缓存下来,避免重复计算,这部分内存叫 KV Cache。上下文越长,KV Cache 越大,而且增长得很快。

KV Cache 的占用有个估算公式:

KV Cache 体积 ≈ 2 × 层数 × KV头数 × 头维度 × 上下文长度 × 每项字节数

以 Qwen2.5-7B 为例,它一共 28 层,KV头数 4,头维度 128,如果用 FP16 存储,每项占 2 字节,那么每 token 的 KV 占用是 2 × 28 × 4 × 128 × 2 ≈ 57344 字节,约 56KB。把上下文设为 8192 token,KV Cache 就要吃掉约 458MB;上下文拉到 32K,就要超过 1.8GB。在 8GB 内存的开发板上,这个数字已经相当可观了。

所以部署时要算的账应该是:模型文件体积 + 目标上下文长度的 KV Cache + 运行时系统占用 ≤ 硬件可用内存 × 安全系数。安全系数我建议至少留 20%。别小看这 20%,内存占满之后触发的 swap 和进程被杀,是端侧部署最常见的翻车方式。

这个账本一定要在选模型之前算,而不是部署之后再看。我见过一个项目,板子只有 8GB 内存,硬要跑 8B 模型加 32K 上下文,部署过程很顺利,一旦上下文涨上去,系统直接 OOM 把进程杀了,智能体动不动就中断,整个链路完全不可用。

3. 模型选型与量化:性能与可用性的第一道分水岭

3.1 参数规模怎么匹配任务

端侧模型选型有一个很实在的规律:任务难度决定参数规模下限,硬件内存决定参数规模上限,两者取交集。

如果你的智能体只需要做意图识别、简单问答、固定流程的工具调用,1.5B~3B 的模型完全够用。这类模型量化后只有 1~2GB,在大多数开发板上都能跑出不错的响应速度。社区里现在很流行用蒸馏模型,比如 DeepSeek-R1 蒸馏出来的 Qwen2.5-1.5B/7B 系列,推理能力比同尺寸的基座模型强不少,特别适合端侧做需要一点思考链的场景。蒸馏模型的代价是输出会变长,每个任务消耗的 token 数更多,实际响应时间未必比非推理模型快。

如果你的智能体要处理复杂指令、多轮对话、阅读理解、结构化信息抽取,7B~8B 是一个比较舒服的档位。Qwen2.5-7B-Instruct、Llama-3.1-8B-Instruct 都是这个档位的主力,工具调用能力经过针对性训练,配合正确模板可以做到不错的可靠性。8B 模型在 Jetson 平台上属于"可以日常用"的级别,在 RK3588 上属于"能跑但别太贪上下文"的级别。

再往上,14B 甚至 32B 的模型在端侧不是不能跑,但一般只建议出现在 64GB 统一内存的 Apple Silicon 或者 Orin AGX 这类高端平台上。以我的经验,端侧智能体项目里,7B 是性能和成本平衡点最好的一档:能力够用、量化后体积可控、推理速度勉强能支撑实时交互。3B 是低功耗和低内存平台的保险牌;除非任务确实复杂,否则不太建议在 8GB 以下内存的设备硬上 8B。

3.2 GGUF、AWQ 还是 INT8:量化方案怎么选

模型选好后,还要定量化方案。量化就是降低权重精度,把原本 FP16 的 2 字节权重压缩到 4 位甚至更少,用轻微的能力损失换体积和速度。端侧主流的量化方案有三类:GGUF 的 K-quant、AWQ/GPTQ 的 INT4、以及各类 INT8。

GGUF 是 llama.cpp 生态的标准格式,也是端侧 CPU/GPU 混合推理场景最通用的方案。它提供了 Q2_K、Q3_K、Q4_K_M、Q5_K_M、Q6_K、Q8_0 等档位,其中 Q4_K_M 是默认首选,能力损失通常在 5% 以内,文件体积接近原模型的 1/3.5。Q5_K_M 比 Q4_K_M 大 15% 左右,质量略好,适合内存有余量的平台。Q8_0 几乎无损,但体积只比 FP16 小一半,适合内存宽裕且对输出质量要求高的场景。

AWQ 和 GPTQ 主要面向 GPU 推理框架,Jetson 平台用 TensorRT-LLM 时会用到。它们的好处是优化了某些权重的重要性感知,在 INT4 下的能力保留通常优于普通均匀量化,但配置门槛也高,需要跑校准流程,而且格式绑定特定引擎,不如 GGUF 灵活。

INT8 是另一个常见选择,尤其适合 RK3588 的 NPU 路线。Rockchip 的 RKLLM 工具链普遍支持 W8A8(权重 8 位、激活 8 位)量化,转换出来的模型体积比 INT4 大,但 NPU 加速效果明显。这里有个取舍:INT4 体积小、带宽压力小,但很多端侧 NPU 对 INT4 的支持不完善;INT8 对 NPU 更友好,但模型体积大一倍,内存带宽压力也翻倍。

实际操作中,我建议普通场景直接用 Q4_K_M,别纠结。先把链路跑通,再对比 Q5_K_M / Q8_0 的实际输出质量差异,用你自己的任务测,而不是凭感觉。很多模型从 Q4_K_M 升到 Q8_0,能力提升远没有文件体积带来的内存压力那么明显。

3.3 参考榜单但别迷信榜单

模型选型时,大家都会去翻 Open LLM Leaderboard 之类的公开榜单。榜单有价值,但一定要明白它衡量的东西和端侧 Agent 要的东西不完全是一回事。

公开榜单主要测常识问答、数学推理、代码生成这类"静态能力",而端侧智能体最需要的是工具调用可靠性、指令遵循、多轮一致性,以及低量化下的能力保留程度。这些恰恰是榜单很少覆盖的维度。我测试模型时,会自己准备三组评估集:第一组是典型工具调用场景,比如"从传感器读取温度,超过阈值就调用报警脚本";第二组是多轮对话一致性,比如反复追问同一件事,看模型会不会自相矛盾;第三组是格式约束场景,比如要求输出严格的 JSON,看成功率。这三组测试跑完,基本就知道这个模型在本地任务里靠不靠谱。

另外还有一个很实用的做法:用 LLM as Judge 做自动化评估。把模型的输出和标准答案一起丢给一个更强的模型打分,比如拿云端 API 当裁判,本地模型当选手。虽然不能完全替代人工评测,但能快速筛掉明显不行的模型,节省大量手动测试时间。注意,裁判模型本身可能有偏好,尤其是对格式长一点的回答打分偏高,所以评估时最好混合使用规则判断和模型判断。

4. 选引擎、跑服务、调性能:实操部署全流程

4.1 推理引擎的对比

模型和量化定了,接下来要选推理引擎。端侧常用的引擎有这么几个,各有各的适用场景。

引擎硬件支持特点适合场景
llama.cppCPU、CUDA、Metal、Vulkan、OpenCL格式统一、部署简单、社区活跃绝大多数端侧开发板首选
Ollama基于 llama.cpp,封装命令行一条命令拉模型起服务,接口 OpenAI 兼容快速原型和中小型项目
MLC-LLM支持 iOS/Android/WebGPU移动端和浏览器端优化好手机、边端 Web 应用
RKLLM-ToolkitRockchip NPU模型转成 RKLLM 格式,走 6 TOPS NPU瑞芯微平台,省 CPU 资源
TensorRT-LLMJetson/英伟达 GPU官方优化,延迟低Jetson 平台追求极致性能
vLLM服务器 GPUPagedAttention,高吞吐多并发设备服务,端侧一般用不到

这里面 vLLM 需要单独说一句:它是为高并发、高吞吐设计的服务端框架,端侧设备内存小、并发低,硬上 vLLM 只会徒增开销。端侧智能体通常是单用户或低并发场景,llama.cpp 或 RKLLM 就够了。很多项目把"能上 vLLM"当成技术先进性的象征,其实在端侧这叫杀鸡用牛刀。

4.2 llama.cpp 从源码到服务

llama.cpp 是目前端侧部署最通用的选择,我直接演示一遍完整流程,以 RK3588 的 Ubuntu 系统和 Jetson 的 JetPack 系统为例。第一步拉源码编译:

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

如果是在 Jetson 平台,并为其他平台做评估,可以加上 CUDA 支持编译:

cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=87 cmake --build build --config Release -j$(nproc)

在纯 CPU 平台上,也可以加上 OpenBLAS 或者 OpenCL 后端,让矩阵计算快一些。编译完先跑一下内置的测试,确认二进制没问题,再下载模型。模型用 Hugging Face 下载比较方便:

huggingface-cli download Qwen/Qwen2.5-7B-Instruct-GGUF \ qwen2.5-7b-instruct-q4_k_m.gguf --local-dir ./models

然后启动 OpenAI 兼容的服务:

./build/bin/llama-server \ -m ./models/qwen2.5-7b-instruct-q4_k_m.gguf \ --host 0.0.0.0 --port 8080 \ -c 4096 \ --chat-template chatml

启动之后,用 curl 请求一次就能验证:

curl http://127.0.0.1:8080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen2.5-7b","messages":[{"role":"user","content":"你好"}],"stream":false}'

这一步成功,说明模型部署通了。接着用一个关键参数把服务的上下文限制好:-c 4096表示最多缓存 4096 个 token 的上下文,这个值要根据之前算过的 KV Cache 账来定,不是越大越好。很多新手把上下文拉到 32K,然后发现速度慢得像蜗牛,就是因为 KV Cache 把内存带宽吃掉了。

这里提示一个部署时特别容易忽略的参数:--chat-template。不同模型使用不同的对话模板,Qwen 系用 ChatML,Llama 系用 Llama Chat,模板错了模型会输出乱码或者答非所问。llama.cpp 模型文件里通常自带模板信息,但有些 GGUF 文件模板不全,手动指定--chat-template是保险做法。

4.3 RK3588 走 NPU 的路线

如果用 RK3588 做端侧智能体,还有一个不同于纯 CPU 路线的选项:走 Rockchip 的 NPU。RK3588 的 6 TOPS NPU 对端侧来说不算小,关键是它能把 CPU 解放出来,让模型推理和图像采集、视频编解码并行处理,这对带摄像头的智能体项目特别重要。

NPU 路线的工具链叫 RKLLM-Toolkit。流程大致是:先在 PC 上把模型转换成 RKLLM 格式,再用板子上的 runtime 加载推理。转换过程类似:

# 在 PC 端用 rkllm-toolkit 转换 rkllm_toolkit --model_path qwen2.5-3b-sft \ --target_platform rk3588 \ --quantize w8a8 \ --output qwen2.5-3b.rkllm

转换完成后,把.rkllm文件传到板子上,用官方提供的 RKLLM runtime 库集成调用。runtime 提供 C 和 Python API,可以直接把输出接进智能体逻辑。

走 NPU 路线要注意的点不少。第一,RKLLM 对模型支持有名单,不是所有模型都能直接转换,Qwen2.5 系列、Phi 系列这类主流小模型基本没问题,但太新的模型可能要等工具链适配。第二,W8A8 量化下体积偏大,3B 模型大约 3GB 多,7B 模型要 7GB 以上,8GB 版本跑 7B 会很紧张。第三,NPU 推理时的 concurrency 支持有限,串行调用为主,智能体如果频繁并行发请求,要考虑排队策略。

从我自己的实测看,RK3588 上 Qwen2.5-3B 走 NPU 可以获得比纯 CPU 快不少的速度,而且 CPU 几乎不占用。但如果只是做原型验证,纯 CPU 的 llama.cpp 会省心很多,等逻辑全部跑通再换 NPU 也不迟。

4.4 Jetson Orin 用 CUDA 加速的路线

Jetson 平台和 RK3588 路线不同。Jetson 自带 CUDA 核心和 Tensor Core,llama.cpp 编译 CUDA 版本就能直接用,不需要额外转换模型。Orin Nano 建议从 7B 起步,Orin NX 16GB 能扛到 14B。

Jetson 上首先确认 JetPack 版本。JetPack 5 和 6 的 CUDA 环境有差异,llama.cpp 编译时用-DGGML_CUDA=ON会自动检测。编译前注意设置前面提到的CMAKE_CUDA_ARCHITECTURES=87,因为 Orin 系列是 Ampere 架构,不指定架构会导致生成的 cubin 无法在目标 GPU 上运行。

启动服务时,Jetson 平台可以加几个参数:

./build/bin/llama-server \ -m ./models/qwen2.5-7b-instruct-q4_k_m.gguf \ --host 0.0.0.0 --port 8080 \ -c 8192 \ -ngl 99 \ --chat-template chatml

-ngl 99表示把所有层都加载到 GPU 上,数字改成某个具体数值就是只放一部分层到 GPU。这里有一个经验:如果 GPU 内存不够,把模型切成一半在 GPU 一半在 CPU,性能会大打折扣,因为 CPU 和 GPU 之间反复搬运权重的开销比想象中大得多。与其这样,不如换更小的量化档位或者更小的模型,保证所有层都能放进 GPU。

Jetson 的另一个特色是电源模式。用nvpmodel和jetson_clocks可以切换运行模式:

sudo nvpmodel -m 0 # 最大性能模式 sudo jetson_clocks # 锁住高频

默认的低功耗模式下,GPU 频率被限制得很低,模型推理速度会明显偏慢。很多玩家说自己 Orin 上 7B 模型只有 5 token/s,一问就是忘了调电源模式。但也要提醒一句:锁高频之后功耗和发热都会上去,如果设备是闷在壳子里的,长时间跑可能降频甚至重启。工业场景建议根据散热条件选一个折中的电源模式,而不是无脑拉满。

5. 从模型服务到智能体:Function Calling 与框架对接

5.1 让模型学会调用工具的三种做法

模型跑起来了,服务也起来了,但这只是第一步。端侧智能体和普通聊天机器人的区别,在于能不能可靠地调用工具。常见的实现方式有三种,按推荐程度排。

第一种是模型原生支持工具调用。Qwen2.5-Instruct、Llama-3.1 这类模型在训练阶段就加入了工具调用数据,只要你按正确格式把工具描述、系统提示和用户请求喂给它,它就能输出结构化 JSON,告诉你该调哪个函数、参数是什么。这是目前最推荐的方案,可靠性最高,但要确认你选的模型确实支持这个能力,并且用对了模板。

第二种是纯提示词约束。把工具列表写进系统提示,约束模型只能输出某种格式,然后用代码解析输出。这种方式对模型要求高,小模型很容易在复杂任务里无视格式,输出一段废话。一般只作为后备方案。

第三种是用推理引擎的 JSON 输出约束。llama.cpp 支持 GBNF 语法和 JSON schema 约束,可以在解码阶段强制模型输出合法 JSON。配合工具调用模板,能明显提升输出格式的可靠性。代价是约束过强时可能影响模型语义理解,需要在约束和自由发挥之间调平衡。

无论用哪种方式,工具定义本身很重要。工具描述要具体,参数类型要明确,枚举值要写清楚。端侧模型能力有限,一个含糊的工具描述就会让它乱传参数。我在项目里会把工具描述当成给实习生写需求文档来对待:每一步都讲清楚,禁止使用模糊词汇。

5.2 用 OpenAI 兼容接口接入智能体框架

模型服务搭好后,接入智能体框架的方式通常非常统一:不管用 LangGraph、CrewAI、AutoGen 还是自研调度逻辑,只要模型服务提供 OpenAI 兼容的/v1/chat/completions接口,就直接替换base_url。

以 LangChain 生态为例,代码长这样:

from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="qwen2.5-7b-instruct", base_url="http://127.0.0.1:8080/v1", api_key="not-needed", temperature=0.3, timeout=60, ) # 然后直接把 llm 传给 Agent 节点

Ollama 更省事,一条命令启动:

ollama pull qwen2.5:7b ollama run qwen2.5:7b

它的默认端口是 11434,接口同样是 OpenAI 兼容路径/v1/chat/completions,智能体框架里把base_url指过去就能用。

这步操作门槛很低,但有个隐藏重点:超时配置。端侧模型推理速度比云端慢一个数量级,云端习惯设置的 5~10 秒超时在端侧根本不够用。我一般建议至少 60 秒起步,涉及长上下文或复杂工具调用时直接 120 秒。否则智能体框架很容易因为超时而把正常的慢响应当成故障,触发重试或者直接中断任务。重试问题也很烦:云端模型重试一次问题不大,端侧模型重试一次就意味着用户要多等一整轮推理,而且同一请求重试还会空耗算力。

5.3 并发调度与功耗控制

端侧模型服务默认一次只能处理一个请求,或者支持极有限的小批量。不是引擎做不到,而是硬件资源摆在那里。智能体框架如果设计成多个任务并行,每个任务调一次模型,请求就会在服务端排队,整体体验反而变慢。

解决方法是智能体侧做请求串行化。框架里用一个信号量或队列把所有 LLM 请求串起来,保证同时只有一个请求到达模型服务。实测下来,串行请求 + 较短上下文,比并行请求 + 内存溢出或者频繁换页的体验好得多。这点和服务器端高并发是反着来的,也别指望用"扛并发"的思路去优化端侧模型服务,那是硬件的天花板决定的。

功耗控制同样重要。开发板不是服务器,长时间满负荷推理会让电源和散热都吃紧。我的建议是三层控制:第一层,模型量化档位决定基础功耗,Q4 比 Q8 省接近一半的带宽和功耗;第二层,在智能体逻辑里减少无效调用,比如能走规则判断的简单分支就不要让模型介入,给模型"减负"才是最大的省电;第三层,在系统层面做频率管理,Orin 用 nvpmodel,RK3588 可以用 DTS 调频策略,让设备在低负载时自动降频。

特别提醒:端侧智能体如果涉及摄像头持续采集,CPU 和 NPU 会争抢内存带宽。模型推理和图像处理同时发生时,两者都会变慢。解决思路是错峰处理,或者把图像预处理放到独立的视频处理单元上,尽量别让两个重负载任务同时抢总线。

6. 常见问题与排查实录

6.1 推理速度慢得离谱

速度慢是端侧部署最常遇到的问题,而且原因五花八门。排查时我会按以下顺序走一遍。

先看模型体积和内存带宽的比例。如果用的模型是 Q8 量化、文件体积快 9GB,而板子带宽只有 34GB/s,那 3~4 token/s 就是物理极限,不是调优能解决的。这种就换 Q4 量化或者换更小的模型。

再看引擎配置。llama.cpp 启动参数里,-t线程数设置太小时 CPU 核心用不满,-ngl层数设置太小时 GPU 加速等于摆设。还有一个常见坑:CPU 设备的--mlock参数,如果不锁内存,模型权重可能在内存和 swap 之间来回搬运,速度慢到让人怀疑人生。内存够用的板子建议把模型权重锁进内存。

接着看系统状态。用top、htop看 CPU 占用率,用nvidia-smi看 Jetson 的 GPU 占用和温度。查到温度 90 度以上,就去调整电源模式和散热。开发板散热不是"能开机就行",满载推理十分钟和满载推理两小时的温度完全不同。

最后还要看是不是上下文拉太长。KV Cache 占用过大会挤占内存带宽,同样一个模型,4096 上下文和 32K 上下文的实测速度可能差出一倍。这个因素最隐蔽,但影响最直接。

6.2 内存不够与进程被杀

OOM 的表现通常是进程直接被系统杀掉,日志里出现 "Killed" 字样。排查思路是看 dmesg 或者journalctl,确认是不是 OOM。然后回到第 2.3 节的那本账:模型体积 + KV Cache + 系统占用是不是超过了内存上限。

解决方案按优先级排列:减少上下文长度;换更低档位的量化;换更小的模型;关闭模型服务里不必要的内存缓存。实在不行,把系统里不需要的服务关掉,给模型腾地方。

要特别说一句,swap 不是端侧 LLM 的救星。虽然开 swap 可以让进程不立刻被杀,但模型权重一旦换出内存,推理速度会跌到不可用的程度,而且反复换页会大量磨损 SD 卡或者固态盘。开发板上的 NVMe 一般是 TLC 颗粒,频繁 swap 会明显缩短寿命。所以我通常不建议靠 swap 硬撑。

6.3 输出乱、格式错、工具调用失效

输出乱码或者答非所问,排第一的原因一定是对话模板错误。用 llama.cpp 时,--chat-template指定的模板必须和模型训练时一致;用 Ollama 时,默认模板一般是对的,但如果你是自己下载 GGUF 手动起服务,就很容易错。典型症状是模型重复系统提示、把用户消息原样吐回来、或者在回答前加一堆神秘字符。

格式错是另一类高频问题。模型该输出 JSON 的时候输出了一段解释文字,这在工具调用场景里意味着解析失败。排查顺序是:确认模型本身支持工具调用;确认工具描述和 JSON schema 没有冲突;确认系统提示有没有要求模型输出 JSON;最后再考虑用引擎的 JSON 约束功能强制格式。

工具调用失效还有一种情况:模型把函数名或者参数名改了。这通常是模型太小的原因,3B 以下模型在这种场景最容易出问题,解决办法是换大模型或者在工具描述里写得更死板。我见过一个项目,工具名叫turn_on_light,模型每次都输出turn_on_the_light,这就是典型的语义过度泛化。

6.4 智能体链路超时与崩溃

模型服务本身正常,但智能体框架一直报超时或连接错误,这种情况大多出在接口对接层。先检查base_url是否拼对,OpenAI 兼容接口基本都要求/v1结尾;再检查超时参数,端侧按第 5.2 节说的调大;最后检查模型服务是否还在运行,端侧设备上服务被 OOM 杀掉是常有的事,建议用 systemd 或者 supervisor 把服务守护起来,崩溃后自动拉起。

还有一个很多人会忽略的问题:流式输出。智能体框架默认经常开启stream=true,如果模型服务的流式输出实现不标准,框架解析会有问题。通信时如果发现首帧迟迟不来,可以在模型侧检查是否预填充耗时过长。长 Prompt 场景下,几千个 token 的预填充可能要好几秒,这在端侧很正常,不要因为首字太慢就觉得服务卡死了。

链路稳定性建议做一个最简单的健康检查脚本:定期请求一次/v1/models,连续失败就重启服务。这个脚本放 cron 里每两分钟跑一次,开销可以忽略,但对生产环境的保障价值极高。机器重启后模型服务也要能自动起来,这些细节看着不酷,却是端侧智能体真正"能落地"和"只停留在 demo"的分水岭。

排查问题的时候,最好养成一个习惯:每次改动只改一个变量。先固定模型,调引擎参数;引擎参数固定了,再动模型。很多朋友喜欢一次性改动三个配置,出了问题根本分不清是谁导致的。端侧环境不像云端那样可以随便上监控平台,排查问题靠的其实就是这种朴素的控制变量法。

最后再分享一个我做端侧 Agent 项目的习惯:所有部署文档里,一定把"硬件型号、内存规格、JetPack 或系统版本、引擎版本、模型文件 ID、量化档位、启动参数"这七项完整记录下来。同样一个模型,别人能跑你不能跑、昨天能跑今天不能跑,排查时往往就是这七项里某一项对不上。本地部署这行,所谓经验,很大一部分就是把每次踩坑的环境快照保存下来,下次对照着少走弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 8:03:39

MySQL binlog 在哪里?路径定位、解析恢复与容量治理全解析

凌晨两点被磁盘告警叫醒,登上机器一看数据目录占了三百多 G,第一反应就是 binlog 攒太多了。结果ls翻了半天没看到熟悉的 mysql-bin 开头文件——这就是“mysql binlog 在哪里”这个问题最典型的现场。很多人以为这是个一条命令就能回答的小问题&#xf…

作者头像 李华
网站建设 2026/11/2 8:03:38

聊天里的“额呃呃呃”正在毁掉你的职场沟通?从口头禅到表达训练

聊天框里输入“额呃呃呃”,自动回复了一个“额”,然后这轮对话就死了。你在微信、钉钉、飞书里一定遇到过这种对话,自己也是“额呃呃呃”的惯犯。我做了几年表达训练和职场沟通相关的项目,说真的,“额”这个字几乎是被…

作者头像 李华
网站建设 2026/11/2 8:03:33

mattpocock-skills实战:用TypeScript从环境配置到待办服务

作为被 TypeScript 类型系统反复折腾过、又靠它避免过无数次线上事故的开发者,我拿到mattpocock-skills这个项目时是有点兴奋的。Matt Pocock 在前端圈子里几乎是“TypeScript 教育”的代名词,他这套技能集不像普通文档那样教你一个个语法点,…

作者头像 李华
网站建设 2026/11/2 8:03:29

AI Agent在机器学习全流程中的创新应用与实践

1. 项目概述:AI Agent在机器学习全流程中的创新应用这个项目探索了如何将AI Agent技术深度整合到机器学习的三个关键环节:特征工程、代码评审和模型训练。不同于传统的自动化工具,我们设计的AI Agent系统能够理解数据科学家的意图&#xff0c…

作者头像 李华
网站建设 2026/11/2 8:02:25

MPC在无人驾驶轨迹跟踪中的核心技术与实践

1. 项目概述:MPC在无人驾驶轨迹跟踪中的核心价值在自动驾驶技术快速发展的今天,模型预测控制(MPC)因其出色的多变量处理能力和约束处理机制,已成为轨迹跟踪领域的主流解决方案。不同于传统的PID控制或LQR方法,MPC通过滚动优化和反…

作者头像 李华
网站建设 2026/11/2 8:01:14

电压跟随器原理、阻抗匹配与高精度测量应用解析

简介:面向电子工程课程设计与测量仪器入门学习者的技术文档,围绕电压跟随器在高精度智能电阻测量仪器及数字电压表课程设计中的应用展开。内容从运算放大器负反馈结构讲起,说明输出电压近似跟随输入电压的原因,并梳理高输入阻抗、…

作者头像 李华