首页
/ llama.cpp INI Presets:用 preset.ini 与系统级 config.ini 构建可复用的参数配置

llama.cpp INI Presets:用 preset.ini 与系统级 config.ini 构建可复用的参数配置

2026-09-04 12:51:21作者:尤峻淳Whitney

本文基于 docs/preset.md 展开,系统讲解 llama.cpp 的 INI Preset 机制:如何用 preset.ini 为模型固化可复用的推理参数、如何通过 Hugging Face 仓库分发命名预设、以及如何在系统级 config.ini 中为所有工具共享默认选项。读完本文,你将掌握预设文件的完整语法、参数覆盖优先级、服务端路由模式(router mode)下的加载流程,并能定位到 common/preset.cppcommon/arg.cpp 中对应的解析与生效逻辑。

INI Presets 是什么

INI Preset 功能由 PR #17859 引入,允许用户把 llama.cpp 的一组 CLI 参数写成标准 INI 配置文件,实现可复用、可分享的参数组合。其核心数据结构与接口定义在 common/preset.h 中:

  • common_preset:单个预设,内部是一个 std::map<common_arg, std::string>,即"CLI 参数 -> 字符串值"的映射;
  • common_presetsstd::map<std::string, common_preset>,表示一个 INI 文件中的多个预设(按 section 名索引);
  • common_preset_context:预设的加载与编辑上下文,提供 load_from_iniload_from_cacheload_from_models_dirload_from_argscascade 等入口。

从源码结构看,预设本质上就是"一份待解析的 CLI 参数集合"。common_preset::to_args()(见 common/preset.cpp#L37-L79)可以把它还原成命令行参数列表,apply_to_params()(见 common/preset.cpp#L142-L168)则逐项调用对应参数的 handler,把值写入 common_params。因此预设中支持的任何键,都是该工具本来就认识的命令行参数。

preset.ini 的语法与键名规则

INI 文件的解析实现位于 common/preset.cpp#L170-L249parse_ini_from_file(),它使用 llama.cpp 内置的 PEG 语法解析器(common/peg-parser.h)构建了一份 INI 文法:

  • 注释:以 ;# 开头,到行尾为止;
  • 行结构[section] 表头行、key = value 键值行、注释行、空行,四者之一;
  • 键名[a-zA-Z_][a-zA-Z0-9_.-]*,值可以包含空格。

关于键名的对应关系,get_map_key_opt()(见 common/preset.cpp#L251-L262)会为每个参数建立两类索引:去除前导 -参数名(长参数如 n-gpu-layers、短参数如 cngl)和环境变量名(如 LLAMA_ARG_N_GPU_LAYERS)。因此按 服务端文档 的说法,以下三种写法都是合法的键:

; 长参数名
n-gpu-layers = 8
; 短参数名(例如上下文长度)
c = 4096
; 环境变量名
LLAMA_ARG_CACHE_RAM = 0

几个需要注意的细节(均可在源码中确认):

  1. version 键被跳过load_from_ini()version 是保留键,供未来使用(见 common/preset.cpp#L305-L308);
  2. 布尔值的否定写法parse_bool_arg()(见 common/preset.cpp#L268-L277)支持以 no- 为前缀的否定参数名。例如参数同时注册了 --jinja--no-jinja 时,写 no-jinja = true 等价于把 jinja 置为 false;
  3. section 名中的量化 tag 会被规范化canonical_tag() 会把形如 xxx:q4_K_M 的 tag 统一转为大写 Q4_K_M(见 common/preset.cpp#L20-L35),与 GGUF tag 的书写习惯保持一致;
  4. 未知键的两种策略:默认情况下,预设中出现工具不认识的键会直接报错 option 'xxx' not recognized in preset 'yyy';而共享配置场景可以设置 ignore_unknown_keys = true,此时未知键只打印警告 ignoring option 'xxx' from yyy: not supported by this program(见 common/preset.cpp#L325-L332)。

在服务端路由模式中使用本地预设文件

llama-server路由模式(router mode)是预设最主要的消费场景:启动时不指定模型,主进程作为路由器,把请求转发给动态加载的模型实例。路由模式下模型文件有三个来源(见 服务端文档):

  1. 缓存中的模型(由 LLAMA_CACHE 环境变量控制);
  2. 自定义模型目录(--models-dir 参数);
  3. 自定义预设文件(--models-preset 参数,对应环境变量 LLAMA_ARG_MODELS_PRESET)。

指定预设文件的方式:

llama-server --models-preset ./my-models.ini

INI 中每个 section 定义一个预设,section 名可以是服务器中已存在的模型名(作为该模型的默认配置),也可以是自定义名称(此时 section 内必须至少给出 modelhf 指向的模型)。官方示例:

version = 1

; (可选)全局设置,所有预设共享;
; 若具体预设中定义了同名键,将覆盖全局值
[*]
c = 8192
n-gpu-layers = 8

; 若键对应服务器上已有的模型,则作为该模型的默认配置
[ggml-org/MY-MODEL-GGUF:Q8_0]
; 字符串值
chat-template = chatml
; 数值
n-gpu-layers = 123
; 标志位(部分标志需用 "no-" 前缀表示否定)
jinja = true
; 短参数(例如上下文长度)
c = 4096
; 环境变量名
LLAMA_ARG_CACHE_RAM = 0
; 文件路径相对于服务器 CWD
model-draft = ./my-models/draft.gguf
; 但推荐使用绝对路径
model-draft = /Users/abc/my-models/draft.gguf

; 若键不对应已有模型,必须指定至少模型路径或 HF 仓库
[custom_model]
model = /Users/abc/my-awesome-model-Q4_K_M.gguf

预设参数的优先级规则为:

  1. 命令行参数(传给 llama-server 本身,优先级最高);
  2. 模型专属 section 中的选项(如 [ggml-org/MY-MODEL...]);
  3. 全局 section [*] 中的选项。

另外有三个仅预设可用(不出现在 CLI)的选项,定义于 common_params_add_preset_options()(见 common/arg.cpp#L4742-L4766,通过 set_preset_only() 标记,to_args() 会跳过它们):

选项 类型 说明
load-on-startup 布尔 服务器启动时是否自动加载该模型。仅在启动时生效;之后重新加载模型列表时,新增模型只列出、不加载
stop-timeout 整数(秒) 请求卸载后等待优雅退出的最长时间,超时强制终止(默认 10)
dedup-cache-models 布尔 当预设的 hf-repo 指向已下载的模型时,从 GET /models 中隐藏对应的缓存模型条目(预设条目保留)。写入 [*] 可对所有预设生效

服务端加载自定义预设的入口在 tools/server/server-models.cpp#L518-L520:当 --models-preset 非空时,调用 ctx_preset.load_from_ini() 读取文件并打印 Loaded N custom model presets from ... 日志。

使用 Hugging Face 预设

重要:只使用你信任的预设!来自不明来源的预设可能不安全(可以覆盖任意参数,相当于远程代码配置注入面)。

你可以把预设推送到 Hugging Face Hub 与用户共享,步骤:

  1. 在 Hugging Face 上创建一个空的模型仓库
  2. 在仓库根目录放置一个 preset.ini 文件。

官方给出的 preset.ini 示例(来自 docs/preset.md):

[*]
ctx-size             = 0
mmap                 = 1
kv-unified           = 1
parallel             = 4
spec-default         = 1

[Qwen3.5-4B]
hf                   = unsloth/Qwen3.5-4B-GGUF:Q4_K_M
ctx-size             = 262144
batch-size           = 2048
ubatch-size          = 2048
top-p                = 1.0
top-k                = 0
min-p                = 0.01
temp                 = 1.0

[gpt-oss-120b-hf]
hf                   = ggml-org/gpt-oss-120b-GGUF
ctx-size             = 262144
batch-size           = 2048
ubatch-size          = 2048
top-p                = 1.0
top-k                = 0
min-p                = 0.01
temp                 = 1.0
chat-template-kwargs = {"reasoning_effort": "high"}

其中 [*] 是全局 section(spec-default = 1 对应 CLI 中的 --spec-default 开关,其默认配置见 common/arg.cpp#L4722-L4737),其余 section 每个对应一个模型,hf 键指向 Hugging Face 仓库(可带量化 tag)。

由于预设的加载方式与 --models-preset 相同,命令行参数仍然可以覆盖预设中的值:

# 强制 temp = 0.1,覆盖预设中的值
llama-cli -hf username/my-preset --temp 0.1

底层加载流程(源码印证)

当你用 -hf 指向一个包含 preset.ini 的仓库时,仓库扫描阶段会识别它:common/download.cpp#L744-L750 中,若仓库根目录存在 preset.ini,则只下载这一个文件并填入 plan.preset,不再按常规方式寻找 GGUF 模型文件。随后在 common/arg.cpp#L677-L684

// if HF repo is a preset repo, we simply run server in router mode with the preset.ini file
params.models_preset_hf = params.model.hf_repo; // only for showing a warning
params.models_preset    = hf_cache::finalize_file(plan.preset);
params.model = common_params_model{}; // make sure to clear model, so server starts in router mode

也就是说:预设仓库的 preset.ini 被下载到本地缓存后,等价于给用户传了 --models-preset <本地文件>,同时清空模型字段,使 llama-server 以路由模式启动。服务器启动时会打印提示(见 tools/server/server.cpp#L525-L526):NOTE: using preset.ini from HF repo 'xxx'。相关端到端行为在 tests/test-model-resolution.cpp 中有覆盖,例如断言 params.models_preset 指向缓存中的 preset.ini(见 tests/test-model-resolution.cpp#L463)。

命名预设(Named Presets)

如果一个预设文件要为多个 GGUF 模型提供配置,推荐做法是:创建一个空白 HF 仓库,其中只放一个 preset.ini,各 section 通过 hf 键引用真实的模型仓库:

[*]
mmap = 1

[gpt-oss-20b-hf]
hf          = ggml-org/gpt-oss-20b-GGUF
batch-size  = 2048
ubatch-size = 2048
top-p       = 1.0
top-k       = 0
min-p       = 0.01
temp        = 1.0
chat-template-kwargs = {"reasoning_effort": "high"}

[gpt-oss-120b-hf]
hf          = ggml-org/gpt-oss-120b-GGUF
batch-size  = 2048
ubatch-size = 2048
top-p       = 1.0
top-k       = 0
min-p       = 0.01
temp        = 1.0
chat-template-kwargs = {"reasoning_effort": "high"}

然后可以直接用 llama-clillama-server 加载,通过 仓库:section 选择具体预设:

llama-server -hf user/repo:gpt-oss-120b-hf

文档特别提醒:请务必为每个子预设填写正确的 hf 仓库地址。如果 section 名被误当作"仓库 + tag"去解析而找不到匹配的量化文件,就会得到报错 The specified tag is not a valid quantization scheme.

系统级配置(System-level Config)

系统级配置由 PR #26118 加入,目的是让多个工具和示例程序共享同一组选项——与上文不同,它不受限于服务端场景。

文件位置与加载顺序

这些文件在程序启动时若存在则自动加载,后加载的文件覆盖先加载的(见 common/arg.cpp#L716-L760common_params_apply_system_config()):

  1. 系统级:/etc/llama.cpp/config.ini(Windows 上为 %PROGRAMDATA%\llama.cpp\config.ini);
  2. 用户级:$XDG_CONFIG_HOME/llama.cpp/config.ini,默认即 ~/.config/llama.cpp/config.ini(Windows 上为 %APPDATA%\llama.cpp\config.ini)。

源码中的实现与文档一致:非 Windows 平台先探测 /etc/llama.cpp/config.ini,再尝试 fs_get_config_directory() + "config.ini" 得到的用户级目录;文件存在才加入加载列表,加载时打印 using config file: <path>

生效优先级

配置文件最先应用,其选项随后被环境变量、CLI 参数、模型预设(路由模式下)依次覆盖。完整的优先级链条是:

  1. 系统级 config.ini;
  2. 用户级 config.ini(覆盖 1);
  3. 环境变量(如 LLAMA_ARG_*);
  4. 命令行参数;
  5. 模型预设 section(仅路由模式,且 CLI > 模型 section > [*])。

common/arg.cpp#L762-L769 中可以看到,common_params_parse_ex() 的第一步就是调用 common_params_apply_system_config(),注释明确写着 "config file applies first, so env variables and CLI arguments override it"。

使用限制与注意事项

  1. 只使用 [*] 和默认 section:写在任何表头之前的键属于默认 section;命名 section(如 [my-model])会被忽略。源码中对应逻辑是:load_from_ini()[*] 的内容装入 global 预设,随后 apply_system_config() 依次应用 global 和名为 default 的预设(见 common/arg.cpp#L750-L759);
  2. 工具专属选项会被静默容忍:同一份配置文件被所有 llama.cpp 程序共享,因此这里使用 ignore_unknown_keys = true。例如你写了 port = 1234,只有 llama-server 会采用,其他工具打印警告后忽略;
  3. 不建议在系统级配置 modelhf-repo:它们可能引入冲突。典型坑是——配置文件中的 hf-repo 在命令行传了 -m 时仍然生效,导致实际加载的不是你以为的那个模型。

一个用户级 config.ini 的保守示例(只放通用、低冲突的选项):

; ~/.config/llama.cpp/config.ini
[*]
mmap = 1

预设的组合与转换:从源码结构看更多能力

除文档主线的三个场景外,common/preset.h 还暴露了若干组合工具,可用于理解(或二次开发)预设的流转方式:

  • cascade(base, added):两套预设按名合并,同名预设用后者覆盖前者选项(merge()),类似 CSS 层叠;
  • cascade(base_preset, presets):把某个基础预设作为底,叠加到一组命名预设上;
  • load_from_cache():为每个已缓存的模型(LLAMA_CACHE 目录)自动生成一个预设,hf 键指向该模型(见 common/preset.cpp#L350-L362)——这就是路由模式"默认从缓存发现模型"的实现;
  • load_from_models_dir():扫描本地模型目录生成预设,支持单文件、分片(-00001-of-)、多模态 mmproj 伴生文件,以及 mtp- / dspark- / dflash- 前缀的投机解码 draft 伴生文件(见 common/preset.cpp#L387-L463);
  • load_from_args():把一次 CLI 调用直接固化为 default 预设,便于"命令行试出来的参数组合"转写成 INI。

小结与相关资源

场景 入口 关键文件
本地预设(路由模式) llama-server --models-preset ./my-models.ini tools/server/server-models.cpp
HF 预设 仓库根目录 preset.inillama-server -hf user/repo[:section] common/download.cppcommon/arg.cpp
系统级配置 /etc/llama.cpp/config.ini~/.config/llama.cpp/config.ini common/arg.cpp
解析与数据结构 PEG 文法 INI 解析、common_preset* common/preset.hcommon/preset.cpp

使用前提:INI Presets 是较新的功能(PR #17859 / #26118),请以当前仓库构建版本的行为为准;HF 预设涉及联网下载,需确保来源可信;version 键目前仅为保留字段,写不写均可。更多路由模式的模型目录结构与 API 细节,可继续参考 tools/server/README.md

登录后查看全文
热门项目推荐
相关项目推荐