Ollama Modelfile 参考

2026-10-29 18:37 更新

Modelfile 是自定义模型的"配方文件"。想固定一个角色设定、改采样参数、换上自己的提示词模板,甚至导入外部的 GGUF 权重,全写在一个纯文本文件里,然后 ollama create 一下,就得到一个可以反复 run 的模型。

它比想象中简单——就是一个指令列表,一行一条。

版本基线 v0.40.12,官方 docs.ollama.com/modelfile。

一、基本格式

## 这是注释
INSTRUCTION arguments

就两条规则:# 开头是注释,其余每行是「指令 + 参数」。指令不区分大小写(示例里用大写只是为了和参数区分开),顺序也无所谓(示例把 FROM 放第一位纯粹为了好读)。

全部可用的指令:

指令 是否必需 作用
FROM 必需 指定基础模型
PARAMETER 可选 设置模型运行参数
TEMPLATE 可选 完整的提示词模板
SYSTEM 可选 系统消息(设定角色行为)
MESSAGE 可选 预置对话历史(few-shot 示例)
LICENSE 可选 声明许可协议
REQUIRES 可选 声明所需的最低 Ollama 版本
CAPABILITY 可选 额外声明模型能力

二、最简单的例子

FROM llama3.2
## 温度调到 1:数值越高越有创造性,越低越稳定一致
PARAMETER temperature 1
## 上下文窗口设为 4096:模型生成下一个 token 时最多能看到多少 token
PARAMETER num_ctx 4096

## 系统消息:让模型扮演马里奥
SYSTEM You are Mario from super mario bros, acting as an assistant.

四步就能用起来:

## ① 把上面的内容保存为 Modelfile
## ② 创建模型(-f 指定文件位置,名字自己取)
ollama create my-mario -f ./Modelfile

## ③ 运行
ollama run my-mario

三、FROM:基础模型从哪来

FROM 决定模型的权重来源,三种写法对应三种来源:

## ① 从已有的本地/官方模型出发(最常用)
FROM llama3.2

## ② 从 Safetensors 目录出发(需要受支持的架构)
FROM /path/to/model-directory

## ③ 从 GGUF 文件出发
FROM ./ollama-model.gguf

GGUF 路径可以是绝对路径,也可以是相对于 Modelfile 所在目录的路径——后者更方便把模型和配方一起打包分发。

分片 GGUF(大模型常切成多个文件)有两种处理方式,用通配符最省事:

## 保留原始分片文件名,用通配符一次匹配全部
FROM ./model-*.gguf

## 或者用多个 FROM 逐片列出
FROM ./model-00001-of-00004.gguf
FROM ./model-00002-of-00004.gguf
FROM ./model-00003-of-00004.gguf
FROM ./model-00004-of-00004.gguf

一个常见误解:FROM 只是引用基础模型,不会复制权重。所以基于 llama3.2 创建的模型不会额外占用一份磁盘——它记录的是"派生关系"。

四、PARAMETER:调模型的行为

PARAMETER <参数名> <值>

完整参数表(官方列出的是这些,其中前四个是日常最常改的):

参数 作用 取值范围 默认值
num_ctx 上下文窗口大小,决定模型能"记住"多少 token 整数 2048(见下方说明)
temperature 温度。越高越有创造性,越低越稳定 浮点 0.8
top_k 候选词数量。高(如 100)更发散,低(如 10)更保守 整数 40
top_p 与 top_k 配合的累积概率阈值,高(0.95)更发散,低(0.5)更聚焦 浮点 0.9
repeat_last_n 回看多少 token 以避免重复;0 关闭,-1 等于 num_ctx 整数 64
repeat_penalty 重复惩罚强度。高(1.5)惩罚更重,低(0.9)更宽松 浮点 1.0(关闭)
num_predict 最多生成多少 token 整数 -1(不限)
seed 随机种子。固定值可让相同提示词产出相同结果 整数 0
stop 停止序列,命中即停止生成;可写多个 字符串 无
min_p top_p 的替代方案,按"相对最高概率的比例"过滤 浮点 0.0
draft_num_predict 有草稿模型时,每步最多推测多少草稿 token;0 关闭推测解码 整数 4(内嵌 MTP 张量时需显式设置)

关于 num_ctx 的默认值要留个心:Modelfile 文档标的是 2048,而 FAQ 里说明当前默认上下文长度是 4096,并可用 OLLAMA_CONTEXT_LENGTH 覆盖。两处口径不完全一致,说明默认值随版本调整过。判断某个模型实际用多大上下文,最可靠的方式是 ollama show 模型名 看输出,而不是背默认值。

stop 值得单独提一句:写多个 stop 就写多行。

## 命中任意一个序列就停止生成
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"

五、TEMPLATE:提示词怎么拼

TEMPLATE 定义送给模型的完整提示词格式。这部分和模型强相关——不同模型训练时用的格式不一样(ChatML、Llama 3 的头标记、Gemma 的 turn 标记……),模板写错会导致模型输出混乱,甚至不停自问自答。

Ollama 使用 Go 的 text/template 语法,有三个核心变量:

变量 含义
{{ .System }} 系统消息
{{ .Prompt }} 用户输入
{{ .Response }} 模型输出。生成时,这个变量之后的内容会被忽略

一个 ChatML 风格的模板(<|im_start|> / <|im_end|> 系列模型使用):

TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""

注意结尾停在 assistant 标记处,没有闭合——因为接下来由模型续写,这正是「.Response 之后的内容被忽略」的实际体现。

绝大多数情况下不要手写 TEMPLATE。 官方模型都自带正确模板,FROM 一个官方模型就能继承。只有自己导入 GGUF/Safetensors、或官方模板确实不适合你的场景时才需要改。

六、SYSTEM:设定角色

SYSTEM """<系统消息>"""

三引号支持多行。这是最常用的自定义手段——不改模型、不动参数,只加一段行为约束:

FROM qwen3
SYSTEM """你是一位资深 Linux 运维工程师。
回答时先给结论,再给命令,最后解释原因。
不确定的地方明确说"需要确认",不要猜测。"""

MESSAGE 里也能写 system 角色,效果等同,但通常还是写在 SYSTEM 更清晰。

七、MESSAGE:用示例教它怎么答

MESSAGE 预置一段对话历史,让模型照着示例的风格回答(也就是 few-shot)。格式是 MESSAGE <角色> <内容>,角色只能取三个值:

角色 含义
system 另一种写系统消息的方式
user 示例中"用户会怎么问"
assistant 示例中"模型应该怎么答"

MESSAGE user Is Toronto in Canada?
MESSAGE assistant yes
MESSAGE user Is Sacramento in Canada?
MESSAGE assistant no
MESSAGE user Is Ontario in Canada?
MESSAGE assistant yes

这段示例的作用很直接:教模型只回答 yes 或 no,不要废话。比起在 SYSTEM 里写"请只回答是或否",给几个例子通常更有效——模型对模式的模仿能力强于对指令的遵守。

八、LICENSE / REQUIRES / CAPABILITY

这三个不常用,但需要时很关键。

LICENSE 声明模型的分发许可:

LICENSE """
<许可协议全文>
"""

REQUIRES 声明最低 Ollama 版本,避免别人在旧版本上跑出奇怪问题:

REQUIRES 0.14.0

CAPABILITY 给 GGUF 或 MLX 模型额外声明能力,不会影响已继承或推断出的能力。需要多个就写多行:

CAPABILITY decision

decision 这个能力只应对训练过 System One 决策提示词的权重声明——乱加不会让普通模型变成决策模型,只会让调用走错分支。

九、反查:看一个模型用的是什么配方

不知道某个模型的内置模板长什么样?直接反查:

ollama show --modelfile llama3.2

输出会打印一份完整的 Modelfile,包括模板和全部 PARAMETER:

## Modelfile generated by "ollama show"
## To build a new Modelfile based on this one, replace the FROM line with:
## FROM llama3.2:latest
FROM /Users/you/.ollama/models/blobs/sha256-00e131...
TEMPLATE """{{ if .System }}<|start_header_id|>system<|end_header_id|>

{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>

{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>

{{ .Response }}<|eot_id|>"""
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"

这是写自定义模板最好的起点:把官方的拷出来,只改你需要的部分,比从零手写安全得多。

注意那个 FROM 指向的是一个 blob 路径。想基于它再派生,按注释提示把 FROM 换回模型名即可(FROM llama3.2:latest)。

十、几个实用提醒

改完 Modelfile 要重新 create。 Modelfile 不是运行时配置,改完必须再跑一次 ollama create 让新配方生效;同名创建会覆盖旧模型。

参数优先级:请求 > Modelfile > 服务端环境变量。 运行时在 API 里传的 options 会覆盖 Modelfile 的 PARAMETER;Modelfile 又优先于服务端的 OLLAMA_CONTEXT_LENGTH 等全局设置。

模型体积按 blob 去重,但每个自定义模型仍占一份元数据。 基于同一基础模型派生十个角色,不会占十份权重,磁盘压力主要来自基础模型本身。

调试模板问题时先简化。 输出乱码、重复、停不下来,先把 TEMPLATE 去掉让 Ollama 用继承的默认模板试一次,能立刻判断问题是不是出在自己写的模板上。

完整的模型导入流程(GGUF/Safetensors 转 Ollama 格式)见 8.1 Ollama 导入自定义模型;想在命令层面查参数与环境变量,回看 4.1 Ollama CLI 参考。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号