如何将 GGUF 模型导入 Ollama?完整操作指南
学习将 Hugging Face 或本地 GGUF 文件导入 Ollama 的两种方法。本文详细说明如何编写 Modelfile 以及如何修复模型导入后因聊天模板不匹配导致的乱码问题,确保模型在本地运行正常。
将 GGUF 模型导入 Ollama 的两种方法
将 GGUF 模型导入 Ollama 有两种方法,具体选择取决于文件当前所在的位置。如果模型位于 Hugging Face 仓库中,可以使用一条 ollama run 命令拉取并运行模型,无需使用 Modelfile。如果 .gguf 文件已经位于服务器磁盘上,则编写一个两行的 Modelfile,然后运行 ollama create。
两种方法最终都会得到相同的结果:模型会以指定名称存储在本地 Ollama 库中,并可由 ollama run 和 Ollama API 提供服务。文件由其他人发布时,使用第一种方法。如果模型由您自行量化,文件通过 scp 或 rsync 传输到服务器,或者服务器无法访问 Hugging Face,则使用第二种方法。
GGUF 文件是一个二进制文件,其中包含模型权重、分词器和模型元数据。llama.cpp 可以读取这种格式,而 Ollama 基于 llama.cpp 构建,因此几乎所有开源模型都有社区提供的 GGUF 转换版本。Ollama 也可以导入包含 .safetensors 权重的目录,但这是另一条路径。下面关于 --quantize 的章节会说明它适用的场景。
以下内容均假设 Ollama 已安装且其服务正在运行。如果尚未安装,请先阅读在 VPS 上安装 Ollama,然后返回此处。先运行 ollama list。如果该命令返回一个表格(即使表格为空),而不是连接错误,则表示服务器已启动,本指南的其余内容可以正常执行。
路线一:无需 Modelfile,直接运行 Hugging Face 上的 GGUF
Ollama 可以直接从 Hugging Face 仓库拉取 GGUF。命令格式是在仓库路径前加上 hf.co/:
ollama run hf.co/{username}/{repository}hf.co 和 huggingface.co 都可用作域名。Hugging Face 文档中的实际示例:
ollama run hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF首次运行时会下载文件,因此下载完成前不会出现聊天提示符。之后模型会保存在本地库中,启动速度会更快。打开第二个 shell,运行 ollama list,查看模型保存时使用的名称。该名称是完整的 hf.co/... 字符串及其标签,每次输入都很长。为它设置一个简短别名:
ollama cp hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF my-llama
ollama run my-llama此方法仅适用于实际包含 GGUF 文件的仓库。只发布 .safetensors 权重而不包含其他文件的仓库无法通过此方法获取模型,你需要使用后文介绍的本地导入方法之一。
Ollama 会选择哪种量化格式?
截至 2026 年 10 月 10 日阅读的 Hugging Face Ollama 文档明确说明了默认行为:“默认情况下,如果模型仓库中存在 Q4_K_M 量化格式,就使用该格式。如果不存在,则从仓库中选择一种合理的量化格式。”因此,发布 10 种量化格式的仓库会为你提供 Q4_K_M;如果仓库没有 Q4_K_M,Ollama 会替你选择一种格式。依赖此行为前,请重新阅读该页面,因为默认设置可能会变化。
在标签中指定所需的量化格式:
ollama run hf.co/{username}/{repository}:{quantization}ollama run hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF:Q8_0
ollama run hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF:iq3_m
ollama run hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-IQ3_M.gguf量化名称不区分大小写,因此 :iq3_m 和 :IQ3_M 表示相同的格式。你也可以将确切的文件名作为标签传入;当仓库中的短名称存在歧义时,这是更安全的形式。标签必须对应仓库中实际存在的文件,因此输入前请打开 Files and versions 标签页,确认真实文件名。选择哪种量化格式取决于内存和质量需求,Q4、Q8 和 FP16 的差异会详细说明这种权衡。
路线二:从自己的磁盘导入 .gguf 文件
如果文件已经在服务器上,则需要一个 Modelfile。它可以只有一行。创建一个目录,将 Modelfile 放入其中,然后让 FROM 指向该文件:
mkdir -p ~/models/my-model
cd ~/models/my-modelFROM /home/you/models/my-model-Q4_K_M.gguf将其保存为 Modelfile,然后构建模型:
ollama create my-model默认情况下,ollama create 会读取当前目录中名为 Modelfile 的文件。如果文件使用其他名称或位于其他位置,请使用 -f,例如 ollama create my-model -f /home/you/models/my-model/Modelfile。运行 ollama create --help,查看当前构建中该标志及其默认值。FROM 中的路径可以是绝对路径,也可以是相对于 Modelfile 的路径,因此当两个文件位于同一目录时,FROM ./my-model-Q4_K_M.gguf 也能正常工作。使用绝对路径则无需考虑路径解析问题。
在信任结果前先检查:
ollama list
ollama show my-model
ollama run my-model "Reply with one short sentence."此时,ollama list 应包含 my-model。ollama show my-model 会显示 Ollama 从文件自身元数据中读取的架构、参数数量、上下文长度和量化类型。应读取这些值,而不要相信文件名,因为文件名只是某人手动输入的字符串。如果模型能用正常语言回答测试提示,然后停止生成,则说明导入成功。如果不能,请查看下面的模板部分,因为这几乎总是由模板导致的。
需要注意磁盘空间:ollama create 会将 GGUF 复制到 Ollama 自己的模型存储中,而不是引用原文件所在的位置。在删除原文件前,权重会在磁盘上保留两份。确认 ollama run my-model 正常工作后删除源文件,或者将源文件放在无需重复占用磁盘空间的位置。Ollama 在磁盘上的模型存储位置介绍了其目录结构以及迁移方法。
--quantize 何时适用,何时不适用
ollama create 提供 --quantize 标志。目前,该标志仅适用于一种情况:从包含 .safetensors 权重的目录导入模型。当前 Ollama 源代码中的帮助文本(于 2026 年 10 月 10 日检查)为“将 safetensors 模型量化到此级别(例如 nvfp4)”,可接受的值为 int4、int8、nvfp4、mxfp4 和 mxfp8。诸如 q8_0 或 q4_K_M 的 GGUF 量化名称会被拒绝,并提示类型不受支持。Ollama 的导入文档明确说明了 GGUF 的情况:“Ollama 不会在导入期间量化 GGUF 模型。”
ollama create --quantize int8 my-model该命令假设 Modelfile 中的 FROM 行指向包含 .safetensors 文件的目录。
当 FROM 指定的是 .gguf 时,不要传递该标志,无论其精度如何。FP16 或 FP32 GGUF 与 Q4_K_M 一样都会被拒绝,并返回以“create-time quantization is only supported for safetensors imports”开头的错误。文件名中包含 Q4_K_M 或 Q5_K_S 的 .gguf 已经完成量化,量化时丢弃的精度无法恢复。传递 --allow-requantize 后,llama.cpp 的 llama-quantize 可以将此类文件重新编码为其他类型,包括 Q8_0;但其手册警告,这样做“与从 16bit 或 32bit 量化相比,可能会严重降低质量”。将 Q4 文件重写为 Q8 后,文件更大,质量却不会更好。要缩小全精度 GGUF,先对其运行 llama-quantize。这是 Ollama 文档推荐使用的工具,然后再导入该工具生成的文件。如果源文件来自包含 .safetensors 文件的 Hugging Face 仓库,可以让 FROM 指向该目录并由 ollama create 完成导入;如果希望减小文件,还可以使用 --quantize。也可以使用 llama.cpp 仓库中的 convert_hf_to_gguf.py 进行转换,然后导入该脚本生成的 GGUF。Ollama 与 llama.cpp 的关系解释了这些工具为何属于另一个项目。
为什么导入的 GGUF 模型回复乱码或无法停止?
这是大多数导入教程都会忽略的故障,也是你必然会遇到的问题。其症状看起来像是模型损坏。控制标记以可见文本形式出现在回复中,例如 <|im_start|>assistant 或 <|end|>。模型在回答完问题后,会自行编写一个新的用户提问并继续回答。生成过程会一直持续,直到你按下 Ctrl+C。
模型本身没有问题,是聊天模板(chat template)配置错误。聊天模板是一个包装器,它将你的消息转换为模型训练时所使用的精确标记序列,并包含系统提示词结束和用户对话开始的特定标记。Ollama 会为你选择一个模板:文档称,基于 GGUF 文件内存储的内置 tokenizer.chat_template 元数据,系统会“从常用模板列表中自动选择一个”。当该元数据缺失,或与列表中的任何项都不匹配时,系统会使用一个通用包装器。模型看到的提示词格式与其训练数据完全不同,因此它永远无法识别出它所学到的停止标记(end-of-turn marker)。
打印 Ollama 实际选择的模板:
ollama show --template my-model
ollama show --modelfile my-model如果输出为空或明显是通用模板,则证实了问题所在。请在 Modelfile 中手动编写模板:
FROM /home/you/models/my-model-Q4_K_M.gguf
TEMPLATE """{{ if .System }}<|system|>
{{ .System }}<|end|>
{{ end }}{{ if .Prompt }}<|user|>
{{ .Prompt }}<|end|>
{{ end }}<|assistant|>
{{ .Response }}<|end|>"""
PARAMETER stop "<|end|>"使用 ollama create my-model 重新构建,并再次发送相同的测试提示词。stop 参数是你的安全保障:它告诉 Ollama 在出现该字符串时切断生成,即使你仍在调试包装器本身,这也能解决“无法停止”的问题。如果回复仍然持续运行,是因为你指定的标记从未出现,此时 设置 num_predict 上限 可以强制其在达到固定标记数量时停止,无论模板输出什么内容。
该模板必须是 Go 模板,而不是 Jinja 模板。 Hugging Face 文档对此有直接说明,这一点至关重要,因为原始模型仓库中的 tokenizer.chat_template 字段使用的是 Jinja 格式。直接粘贴该内容是无效的。Ollama 的语法包含三个变量:{{ .System }} 代表系统提示词,{{ .Prompt }} 代表用户消息,{{ .Response }} 代表模型回复。请在模型卡片或其 tokenizer_config.json 中查找模型真实的对话轮次标记,然后手动将其重写为 Go 语法。
有一个捷径可以节省大部分工作。许多模型共享通用的提示词格式,因此如果你的库中已有其他模型使用相同的格式,请对该模型运行 ollama show --template 并复制其输出内容。
Hugging Face 仓库中的模板、系统提示词和参数文件
Hugging Face 路径提供的控制方式与仓库中的文件一致,而非 Modelfile 中的指令。如果您拥有该仓库,或者正在发布自己的量化版本,请将这些文件添加到仓库中,这样每个 ollama run hf.co/... 都会自动获取它们。
- 名为
template的文件用于存放 Go 模板。规则相同:使用 Go 语言,而非 Jinja。 - 名为
system的文件用于存放系统提示词。 - 名为
params的文件用于存放采样参数,且必须为 JSON 格式。
一个最小化的 params 文件示例:
{
"stop": ["<|end|>"],
"temperature": 0.7
}如果您不是仓库的所有者,则无法添加这些文件。请先拉取一次模型,运行 ollama show --modelfile hf.co/... 导出当前配置,并将输出保存为 Modelfile。其中的 FROM 行指向 Ollama 已下载的 blob,因此您可以编辑 TEMPLATE 和 PARAMETER 行,然后运行 ollama create 构建一个固定的本地副本,无需再次下载。这是修复他人损坏的量化版本时的标准做法。
如何导入私有 GGUF 仓库
私有仓库需要将 Ollama 的 SSH 密钥添加到您的 Hugging Face 账户中。此路径的官方文档方法使用 SSH 密钥而非 API 令牌,因此您现有的令牌无法用于访问私有仓库。
打印公钥。在通过官方脚本安装 Ollama 的 Linux 服务器上,该服务以 ollama 用户身份运行,因此密钥位于该用户的主目录下:
sudo cat /usr/share/ollama/.ollama/id_ed25519.pub如果您以当前用户身份自行启动 ollama serve,则路径应为 ~/.ollama/id_ed25519.pub。复制整行内容,打开您的 Hugging Face 账户设置页面 https://huggingface.co/settings/keys,并将其添加为新的 SSH 密钥。随后,常规命令即可用于您的私有仓库:
ollama run hf.co/{username}/{repository}如果添加密钥后拉取仍然失败,您可能打印了错误的文件。服务器执行下载操作时会提供其自身的密钥;由 systemd 启动的服务器从不读取您用户目录下的 ~/.ollama,因此您主目录下的密钥并非 Hugging Face 所识别的那个。
该模型能否在您的 VPS 上运行?
决定因素是磁盘上的文件大小加上上下文窗口所需的内存。权重加载到内存中的大小与文件占用空间接近,上下文分配则在此基础上叠加,并随您允许的 token 数量增加。运行 ollama list 查看 Ollama 记录的模型大小,将其与 free -h 在服务器上的数值进行对比,并为操作系统及服务器运行的其他进程预留空间。如果您希望查看针对真实模型的计算示例,在 VPS 上运行 Nemotron 3.5 Lightning 提供了具体的拉取标签、所需内存大小以及纯 CPU 服务器是否能满足性能要求。
上下文是容易被忽略的部分。如果模型在默认窗口下加载,一旦您调高 num_ctx,模型可能会运行失败,因为内存分配会随您设置的窗口大小进行扩展。设置 num_ctx 及其内存开销 提供了详细的计算方法。当总内存需求过大时,通常的解决方法是使用同一模型的更小量化版本,Q4 与 Q8 的对比 涵盖了这种权衡。
运行失败的表现非常明显。在纯 CPU 的 VPS 上,内核的 OOM killer 会终止进程,journalctl -u ollama -n 50 配合 dmesg 可以查看到终止记录。在配备 GPU 的服务器上,ollama ps 会打印出 PROCESSOR 列,告知您加载的模型是进入了 GPU 内存、系统内存,还是分布在两者之间。溢出到系统内存的模型仍然可以响应,但速度较慢。测量每秒 token 数 可以将“较慢”转化为可量化的数值,以便您在不同量化版本之间进行比较。
检查导入结果
在执行任何导入操作后,请按此顺序运行以下四条命令:
ollama list
ollama show my-model
ollama show --modelfile my-model
ollama run my-model "Reply with one short sentence."ollama list 用于验证模型是否存在,并显示 Ollama 记录的模型大小。ollama show 用于验证 Ollama 是否已从 GGUF 文件中读取所需的元数据。ollama show --modelfile 用于确认模型实际使用的模板和参数;这是在用户发现输出乱码前,拦截此类故障的关键检查步骤。测试提示词会完整测试整个链路,因为模板损坏的模型即使在处理极短的请求时也会失败。一旦提示词返回结果正常,该模型名称即为您后续调用 Ollama API 时使用的名称,包括 指向您自建服务器的编程助手。若导入失败,请使用 ollama rm my-model 删除并重新构建。该命令仅删除 Ollama 的副本,不会改动您的源文件 .gguf。
FAQ
我可以在不编写 Modelfile 的情况下将 GGUF 导入 Ollama 吗?
可以,前提是该文件位于 Hugging Face 仓库中。ollama run hf.co/{username}/{repository} 会直接拉取并运行它,ollama run hf.co/{username}/{repository}:{quantization} 用于选择特定的量化版本。只有在导入已经位于本地磁盘上的 .gguf 时才需要 Modelfile,此时只需写入单行 FROM /path/to/file.gguf,然后执行 ollama create my-model。
未指定量化版本时,Ollama 会下载哪种量化版本?
截至 2026 年 10 月 10 日,Hugging Face 文档说明:如果仓库中存在该量化版本,则使用 Q4_K_M;否则,Ollama 会从仓库中选择一种合适的量化类型。添加类似 :Q8_0 的标签即可指定版本。使用 ollama show <model> 确认实际接收的文件。该命令会读取文件元数据中的量化信息,而不是读取文件名。
为什么导入的模型会重复内容,或者一直生成而不停止?
聊天模板与模型不匹配。Ollama 会根据 GGUF 中的 tokenizer.chat_template 元数据自动选择模板。如果该元数据缺失或无法识别,Ollama 就会使用通用包装模板,因此模型看不到训练时使用的回合结束标记。使用 ollama show --template <model> 输出当前模板,然后在 Modelfile 中添加 TEMPLATE 块和 PARAMETER stop 行,再次运行 ollama create。模板必须使用 Go 模板语法。原始仓库中的 Jinja 模板无法使用。
我应该对下载的 GGUF 使用 --quantize 吗?
不应该。--quantize 仅在 ollama create 期间对 safetensors 导入执行量化,并且会拒绝所有 GGUF 源文件,包括 FP16 或 FP32 文件,并提示应在导入前先对 GGUF 模型进行量化。文件名中已经包含 Q4_K_M 等量化标记,说明该文件已经完成转换。再次量化无法恢复已丢失的精度:llama-quantize --allow-requantize 可以将其重写为 Q8_0,但生成的文件更大,质量并不会更好。若要从全精度 GGUF 生成更小的文件,请对其运行 llama.cpp 的 llama-quantize,然后导入生成的文件。
如何拉取私有 GGUF 仓库?
将 Ollama 的 SSH 公钥添加到 Hugging Face 账户。在标准 Linux 安装中使用 sudo cat /usr/share/ollama/.ollama/id_ed25519.pub 输出该密钥;如果以自己的用户身份运行服务器,则使用 ~/.ollama/id_ed25519.pub 输出。然后在账户的 SSH 密钥设置页面中添加该密钥。完成后,ollama run hf.co/{username}/{repository} 即可访问你自己的私有仓库,以及你所属组织中的仓库。