Ollama 进阶指南
在本文中,我们将探索Ollama提供的高级选项,以自定义我们的模型,以及如何使用其API来充分发挥其潜力并构建AI应用程序。
正如我们在上一篇文章中所看到的,Ollama允许我们以简单和透明的方式与LLM进行交互。远远超出运行基本测试或开始使用LLM来了解它们的工作原理,软件开发通常需要更多高级和定制化的选项。
在本文中,我们将探索Ollama提供的这些高级选项,以自定义我们的模型,以及如何使用其API来充分发挥其潜力并构建AI应用程序。
1、前置概念
在上一篇文章中,我们讨论了一些与使用Ollama本地运行LLM相关的理论内容。随着我们进入更复杂的用例,也需要考虑新的概念。
需要注意的是,这些理论概念是适用于LLM的通用概念,无论讨论的是什么工具。有时,工具本身可能无法直接实现某个概念(例如:Ollama不能从头开始训练模型,但可以应用LoRA/QLoRA适配器来进行微调)。
以下是这些概念:
1.1 微调
微调是调整预训练模型以适应特定任务的过程。这是通过使用与该特定任务相关的数据集来完成的,该数据集可以部分或完全更新神经网络的权重。这使得通用模型能够适应特定任务,而无需从头开始重新训练——从而节省大量时间和资源。
如前所述,LLM通过预测上下文中的下一个词来工作。如果没有精心设计的提示(提示工程),未经微调的LLM可能会产生连贯但与用户意图不一致的答案。
例如,如果你问:“如何制作简历?”,LLM可能会回答“使用Microsoft Word”。这个答案是有效的,但可能不符合用户的期望——即使LLM对撰写简历有广泛的知识。
微调在定制LLM的风格(例如聊天机器人)或添加领域特定知识(例如法律、金融或医疗领域的专业术语)时特别有用,这些知识是基础模型未训练过的。
一些微调类型包括:
- 全量微调:更新神经网络的所有权重——类似于原始训练,但从预训练模型开始。
- 部分微调:仅更新一部分权重——通常是与预期任务最相关的部分。
- 加法方法:而不是修改现有权重,添加新的权重或层。这一类中一个流行的方法是LoRA。
微调方法的另一种分类是是否为人工监督(SFT — Supervised Fine-Tuning)、半监督或无监督。
1.2 文件格式:Safetensors 和 GGUF
张量是一个数学对象(本质上是一个多维数组),用于表示数据。Safetensor是由Hugging Face开发的一种文件格式,旨在安全地存储此类张量。与其他格式不同,Safetensor是只读的,防止意外代码执行,并且专为效率和可移植性而设计。

为了说明张量在现实生活中的代表意义:
- 标量(0维张量):例如灰度图像中像素的强度值。
- 向量(1维张量):灰度图像中的一行像素。
- 矩阵(2维张量):完整的灰度图像。
- 3维张量:彩色图像——每个像素有三个值(RGB),可以看作是三个堆叠的矩阵(每个通道一个)。
另一种文件格式是GGUF(GPT-Generated Unified Format),它支持LLM的优化管理。GGUF可以存储张量加上元数据,并支持不同类型的量化和微调。
GGUF设计为可扩展和多功能,允许添加新信息而不破坏与旧模型的兼容性,并支持未来使用。

2、模型参数
就像应用程序有可配置的参数(多货币、多语言等),模型也暴露了可配置的参数。除了模型特定的参数外,还有一些对优化至关重要的常见参数:
- temperature:调整模型输出的概率分布——即控制“创造力”。较低的值使输出更加确定;较高的值产生更随机或更具创意的回答。典型值范围从0到1,通常默认为0.7或0.8。
- top_p:导致模型从最小的可能集合中选择输出标记,其累积概率至少为p。值在0到1之间。
- top_k:选择k个最可能的标记(根据其概率)作为可能的输出。
- num_predict:模型一次响应中将生成的最大标记数。值为“-1”时,它会生成标记直到遇到明确的停止条件。
- stop:一组字符串——如果模型生成其中任何一个,生成就会停止。有助于强制模型在所需点结束。
- num_ctx:定义上下文窗口(context-window)的大小——模型一次可以处理的标记总数。这是最重要的参数之一(见下文)。
这些是最相关的参数,但还有许多其他参数。根据与Ollama的交互模式(CLI、API、modelfile),并非所有参数都可以配置。
3、上下文长度
上下文长度定义了模型一次可以处理的最大标记数。这包括:
- 用户输入标记(提示)。
- 记忆或历史标记(之前的对话状态、存储的对话等)。
- 输出标记(响应)。
- 系统提示标记(对LLM如何行为的指示)。
上下文长度至关重要,因为它直接影响模型输出的质量。在长对话或提供大量信息(例如文档)时,超过上下文限制可能导致响应不稳定或重复,或者失去参考早期信息的能力。
虽然可以调整,LLM在预训练时都有最大上下文长度(例如2048、4096、8192……高达128K;一些先进模型如Gemini 1.5 Pro声称支持200万个标记)。超过模型限制增加上下文长度可能导致不连贯的响应和大量的资源使用(RAM、CPU),可能导致性能问题。
你可以通过以下方式修改此参数:
- CLI:例如,对于使用ollama run的交互式会话,可以通过:/set parameter num_ctx < value > 设置。

- API:通过在请求体中指定参数来使用options。
curl http://localhost:11434/api/generate -d '{
"model": "llama3.2:1b",
"prompt": "地球旋转有多快?",
"options": {
"num_ctx": 1024
}
}'

- Modelfile:稍后将介绍这种方法,只需在Modelfile中包含指令:PARAMETER num_ctx < value > 即可。
4、API
除了其交互命令外,Ollama提供了一个API,允许你以编程方式与LLM进行交互。这个API在与其他应用程序集成时特别有用(例如,来自Spring AI),因为只需调用相应的REST端点即可。
默认情况下,API在端口11434上公开(http://localhost:11434 或 http://127.0.0.1:11434),尽管可以配置。API公开了以下端点:
- /api/generate: POST 方法。用于使用单个提示从LLM获取响应的端点,没有对话问答序列。适合文本生成或翻译等任务。

- /api/chat: POST 方法。用于对话问答交互的端点。

- /api/embeddings: POST 方法。为输入生成嵌入(数值向量表示)。

- /api/tags: GET 方法。相当于交互命令 ollama list,显示系统中所有可用的模型。

- /api/show: POST 方法。相当于 ollama show,提供有关特定模型的详细信息,如参数、模板、许可证等。

- /api/delete: DELETE 方法。相当于 ollama rm 命令,用于从本地系统中删除一个模型。

- /api/pull: POST 方法。相当于 ollama pull,用于从远程注册表下载一个模型到本地系统。

- /api/create: POST 方法。相当于 ollama create,允许你从Modelfile创建一个自定义模型。

- /api/copy: POST 方法。相当于 ollama cp,用于在本地复制一个现有的模型。

- /api/push: POST 方法。用于将模型上传到远程注册表的端点。
4.1 OpenAI API 兼容性
众所周知,OpenAI 是当前基于LLM的AI浪潮的主要推动者,因此许多应用程序依赖于其API。为了保持集成的简单性,Ollama提供了一个兼容层,匹配OpenAI API格式。
这意味着,除了上述端点外,Ollama还通过 /v1/ 路径(http://localhost:11434/v1/)公开其他端点,遵循OpenAI API结构。目前支持的一些兼容端点包括:
- /v1/chat/completions: 等同于 /api/chat 端点。

- /v1/embeddings: 等同于 /api/embeddings 端点。

- /v1/models: 等同于 /api/tags 端点。

有了这个兼容层,许多与OpenAI API集成的库只需要最小的配置更改就可以与Ollama一起工作。一些关键设置包括:
- base_url: 设置为Ollama的v1端点 →
<http://localhost:11434/v1/> - api_key: 任何非空值都可以;Ollama不验证此参数。
5、Modelfiles
从早期阶段开始,Ollama就设计为具有模块化和可扩展性(其创始人包括之前曾在Docker工作的人员)。这就是Modelfiles存在的原因:配置文件,作为定义LLM的分层配方,类似于Dockerfile描述容器镜像的方式。
一个Modelfile结合了模型的GGUF权重、模板、系统提示和其他指令。
信息分为特定的Modelfile指令,其精神类似于Dockerfile。一些最重要的包括:
FROM:必需的指令。指定模型构建的基础。允许几种形式:
- 现有模型:引用本地或Ollama注册表中已有的模型。
- 示例:
FROM llama3.2:1b - Safetensors权重:相对或绝对路径到safetensors文件和必要的配置。目前支持的架构包括llama、mistral、gemma或phi3。
- 示例:FROM ./models/llama_safetensors/
- GGUF模型:相对或绝对路径到GGUF文件。
- 示例:FROM ./models/llama-3–2.gguf
PARAMETER:设置执行参数的默认值。
- 示例:PARAMETER temperature 0.3 ; PARAMETER num_ctx 8192
- 一些最重要的参数包括:

- TEMPLATE:用于定义LLM输入提示格式结构的指令。这是聊天或基于指令模型非常重要的一条指令,因为模板指定了系统消息、用户回合、助手回合等是如何分隔的,以确保问答循环的正确运行。模板使用Go模板语法编写。关键变量是:

一个模板指令的例子可能是:
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""
- SYSTEM:配置默认的系统提示。这允许你定义LLM应该如何表现(旅行代理、财务代理、数学老师等)。例如:
SYSTEM """ 你是一个提供有用信息的旅行代理,例如法律、价格、重要的旅游景点、用餐地点、住宿和其他重要的旅游信息。 """
- ADAPTER:使用文件路径,此指令允许你指定一个LoRa或QLoRa适配器,应用于FROM指令中指示的基础模型上。需要注意的是,在FROM指令中的基础模型必须是适配器最初训练时所用的模型,否则模型可能会表现出不可预测的行为。
路径可以指向:
- 一个GGUF格式的单个文件:modelo-lora.gguf。
- 一个包含Safetensor格式权重的文件夹:
- adaptador-modelo.safetensors, adaptador-config.json.
ADAPTER ./llama3.2-lora.gguf
- LICENCE:指定模型分发的许可证。例如:
LICENSE """ MIT License """
MESSAGE:包含示例对话回合的指令,以帮助LLM遵循特定的风格或格式。可能的角色包括:
- System:定义系统提示的另一种方式。
- User:用户问题的示例。
- Assistant:模型应如何回应的示例。
消息指令的一个例子可能是:
MESSAGE user 马德里在西班牙吗?
MESSAGE assistant 是的
MESSAGE user 巴黎在西班牙吗?
MESSAGE assistant 不是
MESSAGE user 巴塞罗那在西班牙吗?
MESSAGE assistant 是的
需要注意的是,Modelfile是不区分大小写的——指令以大写字母书写只是为了清晰。此外,指令不需要遵循严格的顺序(尽管建议将FROM指令放在最前面以提高可读性)。
考虑到上述要点,一个简单的Modelfile示例可能是:
FROM llama3.2:1b
PARAMETER temperature 0.3
PARAMETER num_ctx 8192
SYSTEM 你是一个提供有用信息的旅行代理,例如法律、价格、重要的旅游景点、用餐地点、住宿和其他重要的旅游信息。
保存此文件后,将执行以下命令来创建它:
ollama create custom-model -f ./ModelfileCustom
一旦创建,你可以确认它现在与其他模型一起列出,并且可以开始与之交互:

6、导入外部模型
Ollama支持执行其自身仓库以外的模型,只要它们以标准格式分发,如GGUF或Safetensors,或带有微调适配器。以下是一些示例:
6.1 GGUF
a) 下载以 .gguf 格式的文件。你可以在这个链接找到一个示例。
b) 生成引用下载文件的Modelfile。
FROM ./external-models/gguf/llama-3.2-1b-instruct-q4_k_m.gguf
PARAMETER num_ctx 4096
SYSTEM "你是一个只讲笑话的聊天机器人。"
c) 创建模型以便以后执行:
ollama create custom-gguf-model -f ./Modelfile_gguf

6.2 Safetensors
a) 将所需的文件下载到同一文件夹中。你可以在这个链接找到一个示例。
b) 生成引用文件所在路径的Modelfile。
FROM ./external-models/safetensors/llama3_2_instruct_st/
PARAMETER num_ctx 4096
PARAMETER temperature 0.7
c) 创建模型以便以后执行:
ollama create custom-st-model -f ./modelfile
6.3 适配器
a) 将所需的文件下载到同一文件夹中。你可以在这个链接找到一个示例。
b) 生成引用文件所在路径的Modelfile。
FROM llama-3.2-3b-instruct-bnb-4bit
ADAPTER ./adapters/llama3_2_lora/llama3.2_LoRA_Spanish.gguf
PARAMETER temperature 0.5
SYSTEM "你现在以LoRA教授的风格进行回答。"
c) 创建模型以便以后执行:
ollama create custom-lora-model -f ./modelfile
7、使用Ollama进行量化
Ollama还提供了在创建模型时对模型进行量化(即降低其权重的数值精度)的选项。这是通过在create命令中指定 -q(或 --quantize)参数来完成的,如下所示:
ollama create llama-quantized -f ./Modelfile -q q4_K_M
根据以下Modelfile,你可以检查量化结果(可以看到结果模型的大小更小):
FROM llama3.2:1b-instruct-fp16
PARAMETER temperature 0.9
SYSTEM """ 你是一个叫Mr Travel的旅行代理。"""

在内部,使用来自llama.cpp库的量化指令来执行此过程,并以适当的名称保存模型。一些可能的量化选项包括:q4_0、q5_0、q6_K、q8_0、q4_K_S、q4_K_M等。
8、结束语
本文探讨了Ollama的更高级交互选项。我们测试了Ollama API的工作方式,以及重要的参数和配置,以确保模型的最佳性能。
我们还测试了Ollama最强大的功能之一:定制模型,使其更好地适应特定用例,并在AI驱动的应用程序中提供更好的用户体验。
在下一篇文章中,我们将介绍其他用于本地运行LLM的工具。
原文链接:Running LLMs Locally: Advanced Ollama
汇智网翻译整理,转载请标明出处