模板
Ollama 提供了一个强大的模板引擎,基于 Go 语言内置的模板引擎构建,用于为大型语言模型构造提示词。这个功能是充分发挥模型潜力的重要工具。
基础模板结构
一个基础的 Go 模板由三个主要部分组成:
- 布局:模板的整体结构
- 变量:动态数据的占位符,在渲染模板时会被实际值替换
- 函数:可用于操作模板内容的自定义函数或逻辑
以下是一个简单的聊天模板示例:
{{- range .Messages }}
{{ .Role }}: {{ .Content }}
{{- end }}
在这个示例中,我们有:
- 基础的消息结构(布局)
- 三个变量:
Messages、Role和Content(变量) - 一个自定义函数(动作),用于迭代项目数组(
range .Messages)并显示每个项目
为模型添加模板
默认情况下,导入到 Ollama 的模型具有默认模板 {{ .Prompt }},即用户输入会原样发送到大型语言模型。这对于文本或代码补全模型是合适的,但对于聊天或指令模型缺少必要的标记。
在这些模型中省略模板会将正确格式化输入的责任转移给用户。添加模板可以让用户轻松获得模型的最佳结果。
要在模型中添加模板,需要在 Modelfile 中添加 TEMPLATE 命令。以下是使用 Meta 的 Llama 3 的示例。
FROM llama3.2
TEMPLATE """{{- if .System }}<|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|>
{{- end }}
{{- range .Messages }}<|start_header_id|>{{ .Role }}<|end_header_id|>
{{ .Content }}<|eot_id|>
{{- end }}<|start_header_id|>assistant<|end_header_id|>
"""
变量
System(字符串):系统提示词
Prompt(字符串):用户提示词
Response(字符串):助手回复
Suffix(字符串):插入到助手回复后的文本
Messages(列表):消息列表
Messages[].Role(字符串):角色,可以是 system、user、assistant 或 tool 之一
Messages[].Content(字符串):消息内容
Messages[].ToolCalls(列表):模型想要调用的工具列表
Messages[].ToolCalls[].Function(对象):要调用的函数
Messages[].ToolCalls[].Function.Name(字符串):函数名称
Messages[].ToolCalls[].Function.Arguments(映射):参数名称到参数值的映射
Tools(列表):模型可以访问的工具列表
Tools[].Type(字符串):架构类型。type 始终为 function
Tools[].Function(对象):函数定义
Tools[].Function.Name(字符串):函数名称
Tools[].Function.Description(字符串):函数描述
Tools[].Function.Parameters(对象):函数参数
Tools[].Function.Parameters.Type(字符串):架构类型。type 始终为 object
Tools[].Function.Parameters.Required(列表):必需属性列表
Tools[].Function.Parameters.Properties(映射):属性名称到属性定义的映射
Tools[].Function.Parameters.Properties[].Type(字符串):属性类型
Tools[].Function.Parameters.Properties[].Description(字符串):属性描述
Tools[].Function.Parameters.Properties[].Enum(列表):有效值列表
技巧和最佳实践
在使用 Go 模板时,请记住以下技巧和最佳实践:
- 注意点号(dot):像
range和with这样的控制流结构会改变.的值 - 超出作用域的变量:使用
$.来引用当前作用域之外的变量,从根开始 - 空白字符控制:使用
-来去除前导({{-)和尾随(-}})空白字符
示例
消息示例
ChatML
ChatML 是一种流行的模板格式。它可以用于 Databrick 的 DBRX、Intel 的 Neural Chat 和 Microsoft 的 Orca 2 等模型。
{{- range .Messages }}<|im_start|>{{ .Role }}
{{ .Content }}<|im_end|>
{{ end }}<|im_start|>assistant
工具示例
通过在模板中添加 {{ .Tools }} 节点,可以为模型添加工具支持。这个功能对于训练调用外部工具的模型很有用,是检索实时数据或执行复杂任务的强大工具。
Mistral
Mistral v0.3 和 Mixtral 8x22B 支持工具调用。
{{- range $index, $_ := .Messages }}
{{- if eq .Role "user" }}
{{- if and (le (len (slice $.Messages $index)) 2) $.Tools }}[AVAILABLE_TOOLS] {{ json $.Tools }}[/AVAILABLE_TOOLS]
{{- end }}[INST] {{ if and (eq (len (slice $.Messages $index)) 1) $.System }}{{ $.System }}
{{ end }}{{ .Content }}[/INST]
{{- else if eq .Role "assistant" }}
{{- if .Content }} {{ .Content }}</s>
{{- else if .ToolCalls }}[TOOL_CALLS] [
{{- range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ json .Function.Arguments }}}
{{- end }}]</s>
{{- end }}
{{- else if eq .Role "tool" }}[TOOL_RESULTS] {"content": {{ .Content }}}[/TOOL_RESULTS]
{{- end }}
{{- end }}
填充中间示例
通过在模板中添加 {{ .Suffix }} 节点,可以为模型添加填充中间支持。这个功能对于训练在用户输入中间生成文本的模型很有用,比如代码补全模型。
CodeLlama
CodeLlama 7B 和 13B 代码补全模型支持填充中间。
<PRE> {{ .Prompt }} <SUF>{{ .Suffix }} <MID>
注意: CodeLlama 34B 和 70B 代码补全以及所有指令和 Python 微调模型不支持填充中间。
Codestral
Codestral 22B 支持填充中间。
[SUFFIX]{{ .Suffix }}[PREFIX] {{ .Prompt }}