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,比什么都准。
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐