真正重要的引擎旋钮
多数引擎默认对演示合理、对真实使用是错的。三四个旋钮改变结果:上下文长度、GPU 卸载、KV 缓存类型、flash attention。其余是边缘上的调音。本页用 llama.cpp 的标志名,结尾附 Ollama 等价物——概念迁移到每个引擎。
上下文长度:沉默默认的陷阱
引擎出厂带保守默认:llama.cpp 历史上 512 然后 4096、Ollama 2048–4096 视版本而定(截至本文写作 OLLAMA_CONTEXT_LENGTH 落在 4k 附近)。与此同时你的模型可能原生支持 32k–128k。把 20k 词元的文档粘进 4k 上下文,两件事之一发生、都很糟:硬错误("request exceeds available context")或最老消息被无声截断。两条错误信息都不向初学者解释自己。
算例:你把约 12k 词元的合同加一个问题、装进默认 4096 窗口。引擎保留最近材料、丢掉文档开头、模型自信地回答关于文件错误一半的问题。这看起来像愚蠢的模型;它是被截断的提示词。
修法是机械的:每次启动显式传上下文大小、按真实提示词加预期输出定尺寸、然后核实启动日志显示 n_ctx = 16384(或你选的任何值)。韩语注:同一分词器下韩语文本的分词密度常常低于英语——一页韩语可能比一页英语花更多词元(见 词元)——所以上下文压力比你预期来得早。
# 陷阱:默认值随引擎和版本而异
llama-server -m model.gguf # 以 n_ctx = 4096 左右启动
# 修法:显式、并在启动日志中核实
llama-server -m model.gguf -c 16384 # 日志打印:n_ctx = 16384
GPU 卸载:n_gpu_layers
-ngl / --n-gpu-layers 设定多少 transformer 层住在 GPU 上;用像 99 这样的大数(或支持的引擎用 -1)表示“全部”。部分卸载的症状很有辨识度:有好 GPU 的机器上 3–10 tok/s。用加载日志行核实,比如 offloaded 33/33 layers to GPU。如果显存装不下模型加 KV 缓存、诚实的选项是更小的量化、量化的 KV 缓存、或更少的卸载层——但要知道每层留在 CPU 上都把整个循环拖到 CPU 节奏(见 速度)。把一个差一点装得下的模型卸载一半、通常比降一档量化更糟。
反方向也要 sanity check:-ngl 0 强制纯 CPU,如果它跑得和你的“GPU”配置一样快,GPU 什么都没干。
线程(仅 CPU 模式)
CPU 模式下把 -t 设为物理核心数、不是 SMT 线程数:8 核 16 线程的芯片用 8。超过物理核心的线程数引起争用、拖慢解码。提示词处理有单独旋钮(--threads-batch);同一规则适用。
内存:mmap 与 --mlock
llama.cpp 默认内存映射模型文件:启动快、未触及的层不占内存。代价是 OS 可能在内存压力下驱逐页面、导致会话数小时后的神秘停顿。--mlock 把模型钉住不被驱逐——在繁忙机器上有用、代价是把几个 GB 从所有别的东西那里锁走。Ollama 内部处理这个;共享机器上的裸 llama.cpp 用户应该知道这个标志存在。
Flash attention
-fa / --flash-attn 减少注意力步的内存流量、近期 llama.cpp 构建中默认开启(或自动)。它在长上下文时最要紧、而且当前构建中量化 V 缓存需要它。如果新构建在你的 GPU 后端行为不端,这是第一个要拨的标志——在任何近期构建上、第一件要检查的是它没有无声地自己关掉。
KV 缓存量化
--cache-type-k q8_0 --cache-type-v q5_0 把 KV 缓存以 8 位/5 位而非 16 位浮点存储、以轻微质量代价把 KV 内存大致减半或更多——意味着同样显存装更长上下文。KV 缓存是什么和精确的尺寸数学:KV 缓存。
典型收益:q8_0 的 K 加 q5_0 的 V 大致把 KV 尺寸减半、聊天任务上几乎不可见——在你自己的工作负载上核实后再信任。
提示词批大小
-b / --batch-size 是预填充(提示词处理)的块大小。更大批次意味着长提示词上更快的首词元时间、代价是一点峰值显存。如果长粘贴开始得慢,先调它、再怪模型。
拉伸上下文:rope 缩放与 YaRN
--rope-scaling yarn --rope-factor 2.0 通过重缩放位置频率把 32k 原生模型向 64k 拉伸。有效、但有质量斜坡:原生窗口附近退化小、拉伸越过它后增长。对任何重要的东西,偏爱原生上下文已覆盖你需求的模型、胜过拉伸更小的窗口(见 选择模型)。
截至本文写作 Ollama 未在其 Modelfile 暴露 rope 缩放;拉伸上下文实验意味着直接启动 llama.cpp。
一行带注解的启动
llama-server -m qwen3-8b-q4_k_m.gguf --host 127.0.0.1 --port 8080 -c 16384 -ngl 99 -fa on -b 2048 --cache-type-k q8_0 --cache-type-v q5_0
| 标志 | 它做什么 | 当心 |
|---|---|---|
-c 16384 |
上下文窗口(提示词 + 输出共享) | 永不依赖默认;显式设置 |
-ngl 99 |
卸载到 GPU 的层数(99 = 全部) | 检查 offloaded N/N 日志行 |
-fa on |
Flash attention | 近期构建默认自动;V 缓存量化需要它 |
-b 2048 |
提示词处理批 | 略抬峰值显存;助 TTFT |
--cache-type-k/-v |
KV 缓存 dtype | V 量化需要 flash attention |
--host 127.0.0.1 |
仅绑回环 | 暴露规则在 服务 |
Ollama 等价物
# 按模型,写在 Modelfile 里:
PARAMETER num_ctx 16384
PARAMETER num_gpu 99
# 或全局,在服务启动前:
export OLLAMA_CONTEXT_LENGTH=16384
export OLLAMA_FLASH_ATTENTION=1
export OLLAMA_KV_CACHE_TYPE=q8_0
请求超过 num_ctx 时 Ollama 记一条警告——改过其中任何一项后把日志读一遍。通过环境变量的修改需要重启服务。
看 Ollama 实际应用了什么:ollama show model --modelfile 打印解析后的参数、OLLAMA_DEBUG=1 让服务记录真实上下文和卸载数。
采样器不是引擎旋钮
温度、top-p、重复惩罚——那些塑造哪个词元被选、不影响多快或内存装多少。它们住在 采样。如果输出怪但速度和内存正常,你要的是那一页、不是这一页。
规则
显式设上下文。每次改启动配置都用日志行核实——n_ctx = ... 和 offloaded N/N layers。默认值是为第一个演示能启动而调的、不是为你的工作负载被服务而调的。
llm_load_tensors: offloaded 33/33 layers to GPU
n_ctx = 16384
两行都在启动后数秒内打印。grep 它们一次、配置就不再是民间传说。