llama.cpp 参数调优指南:Jetson 8GB 实战手记

llama.cpp 参数调优指南:Jetson 8GB 实战手记

平台:Jetson Orin Nano Super 8GB(JetPack 6.2 / CUDA 12.6)

模型:Qwen2.5-3B Q4_K_M、Qwen2.5-VL-3B Q4_K_M + mmproj-f16

数据基准:全部真机实测(tegrastats + 自写 bench 脚本),未实测处明确标注

很多人用 llama.cpp 就是 ./llama-server -m model.gguf 一把梭,能用,但在 8GB 这种资源受限板子上,默认参数随时教你做人:上下文溢出、swap 抖动、功耗撞墙。这篇文章把我在 Jetson 8GB 上部署 Qwen2.5 系列时实际调过的参数整理成一份指南------每个参数说清楚干什么、怎么选、我踩过什么坑。

一、先建立心智:参数分五组

llama.cpp 的参数看着几十个,其实就五类问题:

分组

回答的问题

核心参数

① 模型加载

装什么、怎么装

-m、--mmproj、--mlock、--no-mmap

② GPU 卸载

多少层放 GPU

-ngl

③ 显存/上下文

8GB 怎么分

--ctx-size、--cache-type-k/v、-np、-cram

④ 性能并发

跑多快、扛几路

-t、-b/-ub、--flash-attn、--parallel

⑤ 生成采样

输出质量

--temp、--top-p、--top-k、--repeat-penalty

资源受限设备的调优顺序:先保证不崩(③)→ 再榨速度(②④)→ 最后调质量(⑤)。顺序反了就是白忙。

二、模型加载组

-m 主模型路径

没争议,但量化档位的选择是第一个分水岭:

档位

3B 模型体积

我的选择

Q4_K_M

~2GB

✅ 主力,体积/精度平衡点

Q5_K_M

~2.4GB

精度略好,8GB 上余量变薄

Q8_0

~3.4GB

❌ 8GB 上 KV cache 没空间了

经验:8GB 板子 + 3B 模型,Q4_K_M 是甜点;再往上每一 GB 都在抢 KV cache 的地盘。

--mmproj 视觉投影(VLM 专用)

部署 Qwen2.5-VL 这类多模态模型时必须单独挂:

--mmproj Qwen2.5-VL-3B-Instruct-mmproj-f16.gguf

坑 1(实测踩过):漏挂 mmproj,文本问答正常,一发图片请求直接 500。排查半天以为是服务崩了,其实是视觉塔没加载。

坑 2:mmproj 保持 f16 别量化。视觉编码器对精度敏感,量化后 grounding(坐标输出)容易漂移------f16 版本约 1.2--1.4GB,这钱省不得。

--mlock / --no-mmap

  • --mlock:把权重锁在物理内存,防 swap。8GB 板子上我强烈建议加------我实测常驻 7078MB 时被挤了 580MB 进 swap,推理延迟立刻抖。
  • --no-mmap:不用内存映射、启动时全量读入。启动慢一点,但首次推理不会因为按需调页而卡一下。SD 卡启动的板子别用(读盘慢),eMMC/SSD 随意。
    三、GPU 卸载组
    -ngl offload 层数
    -ngl 99 # 全部层卸载到 GPU
    直接给结论:Jetson 上无脑 99。 3B 模型 36 层,全扔 GPU 后 CPU 只剩预处理活,实测 CPU 六核基本 0--1%。唯一例外是模型+KV cache 真塞不下时,才减少层数让部分层回 CPU------但那是降级方案,速度掉一个量级,不如降量化档位。
    四、显存/上下文组(8GB 生死线)
    --ctx-size 上下文长度(最大的坑,重点讲)
    这个参数决定了 KV cache 预分配多少内存,是 8GB 板子上最先要算的账:
    KV cache 占用 ≈ 层数 × ctx × KV头维度 × 2(K+V) × 每元素字节数
    不用背公式,记住我实测的两个锚点就行:
  • ctx=2048 时 Qwen2.5-VL-3B 直接溢出:一张 768px 图片产生约 2716 个视觉 token,报错 2716 > 2048------图还没说话,上下文就满了。VLM 场景的 ctx 必须给视觉 token 留足预算,我后来调到 3072 才正常。
  • ctx 开大是有代价的:3072 比 2048 多占几百 MB,我实测常驻 RAM 到 7078MB、触了 580MB swap。权衡办法:ctx 该给够,但图片输入侧降分辨率(视觉 token 数随分辨率平方涨),两头挤一挤就平衡了。
    经验值(3B 模型 + 8GB):纯文本 2048 够用;VLM 至少 3072,且喂图前把长边压到 768px 以内。
    --cache-type-k / --cache-type-v KV cache 量化
    KV cache 默认 f16,可以量化成 q8_0 甚至 q4:
    --cache-type-k q8_0 --cache-type-v q8_0
    ctx 开大后 KV cache 成为大头时,这是不降 ctx 还能省内存的关键手段。q8_0 精度损失很小,q4 损失明显(尤其长上下文注意力)。我在 8GB 上的策略:宁肯 KV cache 上 q8_0,也不砍 ctx------上下文不够是直接报错,精度略降是软性损失。
    但注意:KV cache 量化是补救手段,不是默认配置。 纯文本 3B + ctx 2048 时 KV cache 才几百 MB,内存离红线还远(实测未触 swap),加了白吃精度损失------尤其 Function Calling 这类要确定性的场景,没病不吃药。真正的触发条件就一条:常驻内存逼近红线或已触 swap。 所以下面两份启动命令里,纯文本版不加、VLM 版(ctx 3072,实测触过 swap)才加。
    -np 并行序列数
    --parallel N 允许 N 路并发,但每路都独立吃一份 KV cache------8GB 板子上 -np 1 就是正确答案,开并发前先确认内存余量。这也是我 ROS2 机器人项目里坚持"单请求串行 + 请求缓存"的原因:板子就这点内存,并发是奢侈品。
    -cram / --cache-ram prompt 缓存上限(新版 server 参数,容易和前两个"cache"混淆)
    在内存有限的边缘设备部署时如果你的显存不够很容易
    -cram 2048 # prompt cache 上限 2048 MiB(默认 8192,-1 不限,0 禁用)
    llama-server 会把已算过的 prompt 前缀 KV 存进 RAM,下次请求前缀命中就跳过 prefill 直接续算------会话级缓存,思路和我在应用层做的 LRU 指令缓存一样,只是它藏在引擎内部。三个"cache"别搞混:
    参数
    缓存什么
    影响
    --ctx-size
    当前会话正在推理的 KV
    装不下直接报错
    --cache-type-k/v
    上面这个 KV 的存储精度
    省内存、略掉精度
    --cache-ram
    历史请求的 prompt 前缀 KV(供下次命中)
    命中省 prefill 时间
    8GB 上的坑:默认上限 8192 MiB 是照着桌面机给的,你的板子总共才 7607MB。它按实际使用增长、上限只是封顶,但长期跑多轮会话,prompt cache 悄悄吃掉 1--2GB 是真实风险。我的处理:机器人 FC 场景指令短、重复前缀少,且应用层已有指令缓存,直接 -cram 0 禁用;多轮长对话场景给 -cram 2048 折中。
    五、性能并发组
    -t CPU 线程数
    GPU 全卸载后 CPU 只干预处理,-t 4 足够(Orin Nano 6 核,留 2 核给系统)。-t 开满反而可能因为调度竞争更慢。
    -b / -ub batch 大小
    prefill 阶段一次处理多少 token。默认 512/2048 在 Jetson 上工作正常,我没动过------这是"调了也没明显收益"的一类参数,除非你 prefill 特别慢,否则别折腾。
    --flash-attn FlashAttention
    --flash-attn
    建议开。省 KV cache 访存带宽,长上下文下收益更明显。注意个别老模型架构不支持会告警,Qwen2.5 系列实测正常。
    功耗档位:不算 llama.cpp 参数,但比参数更猛
    这是我实测里收益最大的单一"调优",而且不在 llama.cpp 里:
    sudo nvpmodel -m 2 # 25W 模式(Orin Nano Super)
    sudo jetson_clocks # 锁最高频
    指标
    15W(默认)
    25W(超频)
    提升
    纯文本 Decode
    15.3 tok/s
    23.9 tok/s
    +56%
    图片理解 Decode
    15.2 tok/s
    23.5 tok/s
    +55%
    图片 TTFT
    2525ms
    1694ms
    −33%
    一句话:软件参数抠半天,不如功耗档位切一刀。 当然 25W 要主动散热,连续跑注意温度(Orin Nano 降频墙 ~87°C)。
    六、生成采样组(按场景抄作业)
    llama-server 支持 OpenAI 兼容参数,我的三组预设:
    场景
    temp
    top_p
    repeat_penalty
    理由
    Function Calling / 结构化输出
    0.1--0.2
    0.9
    1.0
    要确定性,乱发挥就是 bug
    问答 / VQA
    0.3--0.5
    0.9
    1.05
    少量灵活性,防复读
    闲聊
    0.7--0.8
    0.95
    1.1
    多样性优先
    机器人项目里我 FC 用 temp=0.1:3B 小模型本身就会漂,采样上绝不能再给它自由度。输出 JSON 格式错了靠双模式解析兜底,但源头能压就压。
    七、我的启动命令(实测版,直接抄)
    纯文本(机器人 Agent 后端):
    ./build/bin/llama-server
    -m ~/models/Qwen2.5-3B-Instruct-Q4_K_M.gguf
    -ngl 99
    --ctx-size 2048
    -np 1
    --flash-attn
    --mlock
    -t 4
    --host 0.0.0.0 --port 8080
    视觉理解(Qwen2.5-VL):
    ./build/bin/llama-server
    -m ~/models/qwen2.5-vl-3b/Qwen2.5-VL-3B-Instruct-Q4_K_M.gguf
    --mmproj ~/models/qwen2.5-vl-3b/Qwen2.5-VL-3B-Instruct-mmproj-f16.gguf
    -ngl 99
    --ctx-size 3072
    -np 1
    --cache-type-k q8_0 --cache-type-v q8_0
    --flash-attn
    --mlock
    -t 4
    --host 0.0.0.0 --port 8080
    差异就三处:VLM 多挂 mmproj、ctx 从 2048 提到 3072、KV cache 上 q8_0(ctx 开大后内存逼近红线,用 KV 量化换余量------纯文本版内存宽裕则不加)。
    注意两份命令都显式写了 -np 1:-np 默认是 -1(auto),服务器按需开槽位,内存行为不可预测。机器人场景必须锁单槽位------内存可预测(全系统就一份 KV)、行为确定性(车同一时刻只执行一条指令),并发调度交给应用层,引擎层不开多头。
    八、调优 SOP:四步走
  1. 空载基线:tegrastats 记一条(我的:RAM 2570MB / 整板 4.5W / ~50°C)
  2. 常驻采样:模型加载完、未发请求,记 RAM(我的:7078MB,注意 swap 是否为 0------不为 0 就先降 ctx 或加 --mlock)
  3. 负载采样:发真实请求,看 GR3D_FREQ(应 90%+)、VDD_IN 峰值、tj 温度
  4. 基准对比:固定 prompt 测 TTFT/Decode,改一个参数测一轮------一次只动一个变量,否则不知道是谁起的作用
    九、排错速查表
    症状
    最可能原因
    第一动作
    发图 500,文本正常
    漏挂 --mmproj
    查启动日志有没有 mmproj 加载行
    XXXX > 2048 报错
    ctx 装不下视觉 token
    升 ctx 或压图片分辨率
    推理中途变慢、抖动
    SWAP > 0
    tegrastats 确认,加 --mlock、降 ctx
    速度只有个位数 tok/s
    层没卸载到 GPU
    查 -ngl,看日志 CUDA 字样
    输出重复、漂移
    采样太自由
    temp 降到 0.3 以下
    温度撞墙降频
    25W 档散热不够
    tegrastats 看 tj,加强散热
    写在最后
    8GB 板子调 llama.cpp,本质是做预算:权重、KV cache、系统三家分 8GB,谁多谁少全凭参数权衡。我的原则就三条------先不崩(ctx 算够)、再求快(ngl 99 + 功耗档)、防抖动(mlock 看住 swap)。参数全都可以测,别信任何"推荐值",包括我这篇------在你的板子上跑一遍 tegrastats,比什么都准。
相关推荐
火山引擎开发者社区1 小时前
Viking AI 搜索 × SearchCLI:搭建售后助手,让搜索能力参与售后回答
人工智能
冬奇Lab1 小时前
一天一个开源项目(第210篇):herdr - AI 编程 Agent 的运行时底座
人工智能·开源·资讯
dadanhuang2 小时前
PyTorch深度学习与实践【04】【迭代周期、autograd、构建计算图、*params参数解包、.grad属性】
人工智能·pytorch·深度学习
JavaPub-rodert2 小时前
LangChain 从入门到 Agent 实战:用 Python 搭建一个真正能调用工具和知识库的 AI 助手
人工智能·python·langchain
米小虾2 小时前
告别逐 token 蹦字:扩散语言模型(dLLM)到底能不能终结自回归?
人工智能·llm
火山引擎开发者社区2 小时前
从多模态数据湖到 Agent 湖:Lance 的格式设计与实践|Lance Meetup 火热报名中
人工智能
一枚爱吃大蒜的程序员2 小时前
CSDN文章-注意力约束QLoRA教育大模型微调
人工智能·机器学习·语言模型·qlora·大模型微调·注意力约束
技术小事2 小时前
AI挖出6个curl漏洞 但另外23份是噪音
人工智能·网络安全·漏洞挖掘·cve·curl·ai安全
米小虾2 小时前
一周 AI 观察(9.1–9.7):模型能力开始"过剩",行业真正卷的是落地
人工智能·llm