你执行 ollama pull llama3.2:3b,进度条跑到 100%,最后一行打印 success,可紧接着 ollama list 却没有这个模型。ollama run llama3.2:3b 报 Error: model 'llama3.2:3b' not found。blob 文件明明在磁盘上 —— 你能在某个 models/blobs/ 目录里看到它 —— 所以这不是下载失败。blob 存在,但告诉 Ollama”这些 blob 组成了哪个模型”的 manifest 文件,要么缺失、要么损坏,要么躺在一个当前 Ollama 进程根本不读的目录里。
最快修复(约 80% 的情况有效): CLI 和 Ollama 守护进程读的是两个不同的模型目录。pull 和 list 都走同一个守护进程,所以真正的分裂几乎总是:你 shell 里的 OLLAMA_MODELS 值已经过期,跟服务实际使用的路径对不上。先跑一句 ollama show llama3.2:3b —— 如果 blob 在磁盘上、这条命令却失败,直接跳到 Step 1 把两个路径对齐。
Ollama 模型到底存在哪里(2026 年 6 月)
先把这件事搞清楚 —— 大多数”模型不见了”其实就是目录找错了。截至 2026 年 6 月 Ollama 0.x 的默认值:
| 平台 / 安装方式 | 默认模型目录 | 运行身份 |
|---|---|---|
macOS(App 或 brew) | ~/.ollama/models | 你自己的用户 |
| Linux(官方安装脚本 + systemd) | /usr/share/ollama/.ollama/models | ollama 服务用户 |
Linux(在 shell 里手动 ollama serve) | ~/.ollama/models | 你自己的用户 |
| Windows | C:\Users\%username%\.ollama\models | 你自己的用户 |
| Docker | 容器里挂载到 /root/.ollama 的路径 | 容器 root |
Linux 上最经典的坑:官方安装脚本会创建一个专用的 ollama 系统用户和一个 systemd 服务。该服务把模型存在 /usr/share/ollama/.ollama/models,而不是你的家目录。如果你在 shell 里 export OLLAMA_MODELS=/somewhere/else 再 pull,你以为拉到了自己的路径,可守护进程仍然只读它自己那个路径 —— 于是 ollama list 里就没有新模型。
常见原因
按命中率从高到低排列。
1. OLLAMA_MODELS 只设在了 shell 里,没设在服务里
你把 export OLLAMA_MODELS=/data/ollama 写进了 ~/.bashrc 或 ~/.zshrc。但 systemd 服务不会继承你登录 shell 的环境变量,守护进程会忽略它,继续用默认路径(Linux 上是 /usr/share/ollama/.ollama/models)。你以为 pull 进了 /data/ollama,可由于 pull 走的就是守护进程,结果要么落到守护进程的默认目录、要么因为目录跟你预期不一致而”看不见”。
怎么判断: 对比两个值。
echo "$OLLAMA_MODELS" # 你 shell 里的值
systemctl show ollama --property=Environment # 服务里的值(Linux/systemd)
如果两者不同,或者你 shell 里设了、服务那行却是空的 —— 这就是根因。
2. ollama 服务用户读不到(或写不进)你的自定义目录
如果你把 OLLAMA_MODELS 指向一个 ollama 用户读不了或写不了的路径(你 $HOME 下的目录、root 所有的目录、还没挂载的磁盘),守护进程会悄悄回退或写不出可用的文件。blob 可能落地了,但 manifest 从没写到守护进程查找的位置。
怎么判断:
ls -la /usr/share/ollama/.ollama/models/manifests/ # 谁是所有者?
# 以及你的自定义目录(如果有):
ls -ld /data/ollama
在 systemd 安装下,这个目录及其内容必须由 ollama:ollama 拥有。
3. manifest 缺失、零字节或不是合法 JSON
pull 被中断、pull 进行中守护进程重启、或磁盘写满之后,Ollama 可能保留了(很大的)blob,却让那个很小的 manifest 文件变成空的或被截断。ollama list 先读 manifest;零字节或格式损坏的 manifest 会让这个模型被悄悄跳过。
怎么判断: 在守护进程的目录下检查你那个标签对应的版本文件。
# 这里给的是 Linux systemd 路径;macOS/Windows 换成 ~/.ollama
sudo cat /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/llama3.2/3b \
| python3 -m json.tool
如果文件是空的、不存在,或者 python3 -m json.tool 报 JSON 错误,问题就出在 manifest 上。
4. pull 最后几秒磁盘写满了
blob 是分块下载的,绝大部分会在最后那个小小的 manifest 提交之前就写好。如果磁盘在这最后一步写满,你就会得到完整的 blob 加一个被截断或缺失的 manifest —— 而 success 可能照样一闪而过。
怎么判断: df -h /usr/share/ollama(macOS/Windows 用 df -h ~/.ollama)。如果使用率接近 100%,先腾空间再重新 pull。
5. 你用 sudo(或别的用户)pull,跟运行中的守护进程身份不一致
跑 sudo ollama pull ... 可能会走到一个绑定 root 的守护进程(或写到 root 的路径),把模型留在 /root/.ollama/models,而不是服务的 /usr/share/ollama/.ollama/models。然后你以普通用户 ollama list —— 它对接的是 systemd 守护进程 —— 自然什么都看不到。
怎么判断:
sudo ls /root/.ollama/models/manifests/registry.ollama.ai/library/ 2>/dev/null
ls /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/ 2>/dev/null
如果模型只出现在 /root/.ollama 下,那就是用 root pull 的。
6. 标签对不上 —— pull 的和 list/run 的不是同一个标签
ollama pull llama3.2(不带标签)解析成 llama3.2:latest。如果你接着 ollama run llama3.2:3b,那是另一个标签,即使 llama3.2:latest 就摆在那儿,也会报 “not found”。llama3:latest 和 llama3.3:latest 同样是完全不同的两个模型。
怎么判断: 看 ollama list 里确切的 NAME 列,跟你运行时输入的逐字符对一遍。
ollama list
# NAME ID SIZE MODIFIED
# llama3.2:latest a80c4f17acd5 2.0 GB ...
最短修复路径
Step 1:确认守护进程在读哪个目录
# 你 shell 以为的路径
echo "$OLLAMA_MODELS"
# 守护进程启动时拿到的值(Linux/systemd)
systemctl show ollama --property=Environment
# 直接问运行中的守护进程 —— 这个列表才是权威来源
curl -s http://localhost:11434/api/tags | python3 -m json.tool
# 查看守护进程的默认目录(Linux systemd 安装)
sudo ls /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/
# macOS / Windows / 手动 `ollama serve`:
ls ~/.ollama/models/manifests/registry.ollama.ai/library/
/api/tags 返回的内容跟 ollama list 完全一致;如果模型在这里也没有,说明守护进程是真的看不到它。
Step 2:检查并修复 manifest
# 这里给的是 Linux systemd 路径;macOS/Windows 换成 ~/.ollama
MANIFEST=/usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/llama3.2/3b
sudo ls -la "$MANIFEST"
sudo cat "$MANIFEST" | python3 -m json.tool # 是合法 JSON,还是报错?
# 如果是零字节 / 非法,只删掉 manifest 再重新 pull。
# Ollama 会按校验和复用磁盘上已有的 blob,只重写 manifest。
sudo rm -f "$MANIFEST"
ollama pull llama3.2:3b
Step 3:把 OLLAMA_MODELS 设进 systemd 单元(Linux),不要只设在 shell
sudo systemctl edit ollama
# 在编辑器里,[Service] 下加上:
# [Service]
# Environment="OLLAMA_MODELS=/data/ollama"
# ollama 用户必须拥有这个目录:
sudo chown -R ollama:ollama /data/ollama
sudo systemctl daemon-reload
sudo systemctl restart ollama
# 确认守护进程现在报告的是新路径
systemctl show ollama --property=Environment
macOS 上改成给 App 设置:launchctl setenv OLLAMA_MODELS "/path",然后退出并重新打开 Ollama。Windows 上在「系统环境变量」里设置,再从托盘重启 Ollama App。
Step 4:找回用 root 或错误用户 pull 的模型
# 从 /root 拷进服务目录,再修所有权
sudo cp -r /root/.ollama/models/manifests/* /usr/share/ollama/.ollama/models/manifests/
sudo cp -r /root/.ollama/models/blobs/* /usr/share/ollama/.ollama/models/blobs/
sudo chown -R ollama:ollama /usr/share/ollama/.ollama/
sudo systemctl restart ollama
ollama list
Step 5:重启守护进程并等它就绪
Ollama 在启动时加载模型注册表,所以任何路径改动都要重启之后 ollama list 才会反映出来。
sudo systemctl restart ollama # macOS/Windows:退出并重新打开 App
# 阻塞直到 API 有响应,再 list
until curl -s http://localhost:11434/api/version > /dev/null; do sleep 1; done
ollama list
Step 6:标签有歧义时,用完整标签重新 pull
ollama pull llama3.2:3b # 显式标签,不让 `latest` 自己猜
ollama list | grep llama3.2 # 确认确切的 NAME:TAG 在列表里
ollama run llama3.2:3b "say hello" # 用你 list 里那个标签来运行
如何确认已经修好
ollama list | grep llama3.2 # 1) 标签出现在列表里
ollama show llama3.2:3b # 2) manifest 能解析(不再 "not found")
ollama run llama3.2:3b "1+1=" # 3) 真能加载并回答(约等于 "2")
三条都通过,说明 manifest 和 blob 一致,且守护进程读的是正确的目录。
预防建议
OLLAMA_MODELS只在一个守护进程认账的地方设置 —— Linux 用 systemd override,macOS 用launchctl setenv,Windows 用「系统环境变量」。别指望~/.bashrc里的 export 能影响 systemd 服务。- Linux 上记住守护进程的家是
/usr/share/ollama/.ollama/models,不是~/.ollama。任何自定义目录都必须由ollama:ollama拥有。 - 除非守护进程也以 root 运行,否则别用
sudo ollama pull;用户身份不一致是”pull 成功但看不到”的头号原因。 - 每次 pull 后立刻验证:
ollama list | grep <model>(CI 里写成ollama list | grep -q "llama3.2:3b" || exit 1)。 - 模型磁盘留足余量,pull 几 GB 的大模型前先看
df -h,免得最后那步 manifest 写入被截断。 - 升级 Ollama 或操作系统后,重启服务以清空内存里的注册表。
常见问答 (FAQ)
Q: 我直接下了个 .gguf 文件(不是 ollama pull 来的),怎么让它出现在 ollama list 里?
A: 写一个一行的 Modelfile 指向这个文件,然后创建模型。在存放该文件的目录里执行:
echo 'FROM ./model.gguf' > Modelfile
ollama create mymodel -f Modelfile
通常 10–60 秒,之后 mymodel:latest 就会出现在 ollama list 里。注意分片(sharded)的 GGUF 不能直接导入,要先合并。
Q: blob 在磁盘上,但 ollama show <model> 报 “not found”,能不重新下载就恢复吗?
A: 可以,前提是你有那份 manifest。把 manifest JSON 还原到守护进程模型目录下的 .../manifests/registry.ollama.ai/library/<model>/<tag>,再重启 Ollama。由于 Ollama 按 SHA-256 匹配 blob,跑一句 ollama pull <model>:<tag> 也会重建 manifest 并复用现有 blob,而不会重新下载。
Q: 重启或升级 Ollama 之后我的模型全没了,为什么?
A: 几乎总是因为守护进程现在读的目录跟之前不一样了 —— OLLAMA_MODELS 改动没带过来、磁盘在服务启动之后才挂载、或者 /usr/share/ollama 的权限被改了。检查 systemctl show ollama --property=Environment,并确认模型目录由 ollama:ollama 拥有。blob 一般都还在,你只需要把守护进程重新指回去。
Q: 怎么把整个模型库搬到另一台机器?
A: 把整个 models/ 目录 —— blobs/ 和 manifests/ 都要 —— 复制到目标机的对应路径。如果用非默认路径,在目标机设好 OLLAMA_MODELS,修好所有权(systemd 安装是 ollama:ollama),再重启服务并 ollama list。manifest 到 blob 的目录结构必须保持完整。
Q: pull 到了 100% 又重置、再爬一遍才真正完成,是 bug 吗?
A: 不是。ollama pull 有「下载」和「校验 + 写 manifest」两个阶段,进度条会在两阶段之间重置。只要最后一行是 success 且 ollama list 能看到这个标签,就是正常完成。
相关阅读
- Ollama 下载模型卡在某个百分比
- Ollama 启动报 port already in use
- Ollama 探测不到 GPU,全跑在 CPU
- Ollama Modelfile 里的 SYSTEM prompt 被忽略
- llama.cpp 在网络盘上 mmap 失败
标签: #local-llm #ollama #排查