Ollama pull 卡住或下载进度回退 — 修复方法

ollama pull 停在某个百分比、进度条往回跑、或报 max retries exceeded: EOF。分析网络、磁盘、partial 分片三类原因,给出可干净续传的修复步骤。

你在一条不慢的网络上执行 ollama pull llama3.3:70b,爬到 47% 后进度条就不动了。有时还会往回跑、总大小变小;有时直接报 max retries exceeded: EOFconnection reset by peer。这几乎不是注册表挂了。截至 2026 年 6 月(Ollama v0.30.x),一次 pull 会被拆成最多 16 个并行的字节范围分片,并且大的 layer 会从 registry.ollama.ai 重定向到 Cloudflare R2 对象存储——所以问题通常出在你到 R2 的链路上:掐断长连接的代理或 VPN、写满的磁盘,或者一个校验不过的 -partial 残留分片。

最快的修复(对大多数卡顿有效): 关掉 VPN,删掉残留的 partial 文件,然后原样重跑同一条 ollama pull 命令——Ollama 会复用已下载完成的分片,只重新拉取失败的部分:

# 1. 关掉 VPN;如果必须开,就把 ollama 流量做 split-tunnel 排除
# 2. 清掉写了一半的分片(不是整个 blob)
find ~/.ollama/models/blobs -name '*-partial-*' -delete
# 3. 续传
ollama pull llama3.3:70b

如果这样还不动,就按下面的分类逐项排查。

先判断你属于哪一类

你看到的现象最可能的原因跳转
每次重试都卡在同一个百分比-partial 分片损坏,校验不过原因 3
长时间停顿后报 max retries exceeded: EOF到 R2 的 TCP 流被断开(代理/VPN/空闲超时)原因 1
只有在公司网络或 VPN 下才卡代理/VPN 没放行 *.r2.cloudflarestorage.com原因 4
no space left on device 或临近结束静默冻结写入途中磁盘或 inode 写满原因 2
下载不报错但很慢,且写到 NAS/SMB 路径OLLAMA_MODELS 指向了网络挂载点原因 5
进度条明显往回跑然后又恢复正常现象:某个分片失败被丢弃后重下常见问答

常见原因

按命中率从高到低排列。

1. 到 Cloudflare R2 的 TCP 流被断开

每个 blob layer 都用并行的 HTTP range 请求拉取,其中大的 layer 会从 registry.ollama.ai 重定向到 *.r2.cloudflarestorage.com。企业代理、空闲连接超时设置激进的家用路由器,以及很多 VPN,会在 30-120 秒后悄悄掐掉一条长连接 TLS 会话。Ollama 的下载器把”某个分片 30 秒没有写入新字节”判定为卡死并重试(指数退避,截至 v0.30.x 每个分片最多重试 6 次);6 次都用光后你就会看到 max retries exceeded: EOF

怎么判断。 pull 卡住时盯一下实时连接:

# Linux
ss -tn state established '( dport = :443 )' | grep -iE 'r2|cloudflare|ollama'
# macOS
netstat -an | grep '\.443 .*ESTABLISHED'

如果到 R2 主机的连接每隔几十秒就消失一次,就是 TLS 会话在被断开。VPN 是最常见的单一诱因——在做任何其他操作之前,先关掉 VPN 再重试。

2. 下载途中目标磁盘写满

Ollama 把 blob 写到 ~/.ollama/models/blobs/(macOS)、/usr/share/ollama/.ollama/models/blobs/(Linux 系统服务安装)或 C:\Users\%username%\.ollama\models\blobs\(Windows)。如果下载途中这个卷的空间或 inode 用尽,写入会静默阻塞,或者报 no space left on device

怎么判断。 卡住时两条都跑:

df -h ~/.ollama       # Use% 是否接近 100%?
df -i ~/.ollama       # IUse% 是否到了 100%?(inode 耗尽)

llama3.3:70b 默认的 Q4_K_M 量化大约需要 40 GB 可用空间;Q8_0 变体约需 70 GB。建议预留至少 1.2 倍模型大小的余量。

3. 上次中断留下的 -partial 分片损坏

被强制结束或崩溃的 pull 会在 blobs 目录里留下可续传的分片文件,命名形如 sha256-<digest>-partial-*。下次 pull 时 Ollama 会扫描这些文件并续传——但如果某个分片只刷了一半、字节与预期的范围校验和不符,这个 layer 就会在每次重试时卡在同一个百分比。

怎么判断。 列出残留的分片:

ls -lh ~/.ollama/models/blobs/ | grep -- '-partial-'

任何上一次会话留下、又反复卡在同一点的 *-partial-* 文件都很可疑。只删 partial 文件会强制干净地重拉那个失败的 layer,已完成的 blob 会保留。

4. 代理或 VPN 只放行了注册表,没放行 R2 CDN

这是公司网络的经典坑。你的代理规则或 VPN split-tunnel 放行了 registry.ollama.ai,所以 manifest 秒下完;但大的 layer 请求会重定向到 *.r2.cloudflarestorage.com,而这个域名没在白名单里,于是第一个大 layer 就卡住或被重置。

怎么判断。 手动跟随重定向,看字节到底来自哪里:

# -L 会跟随重定向到 R2;观察最终的 Location / host
curl -sIL https://registry.ollama.ai/v2/ | grep -i '^location\|^http/'

修复。 两个主机都要放行。Ollama 拉模型只走 HTTPS,所以设置 HTTPS_PROXY(官方文档明确警告不要用 HTTP_PROXY,拉模型时 Ollama 会忽略它):

export HTTPS_PROXY=http://your-proxy:port
# 或者直接让 Ollama 流量绕过代理
export NO_PROXY=registry.ollama.ai,.r2.cloudflarestorage.com
ollama pull llama3.3:70b

如果你的代理做了 TLS 拦截,它的 CA 证书必须装进系统信任库,否则到 R2 的握手会失败。

5. OLLAMA_MODELS 指向了网络挂载路径

如果你设了 OLLAMA_MODELS=/mnt/nas/ollama 之类,持续 5-40 GB 的写入在 NFS 或 SMB 上可能先缓冲、等服务端写缓存填满后就阻塞,下载器表现为卡死。

怎么判断。 echo $OLLAMA_MODELS——如果它解析到一个网络共享,先下到本地磁盘,再把整个 models/ 目录搬过去。

6. 实时杀毒扫描每个 blob 写入

实时杀毒在每个几 GB 的文件落盘时都扫一遍,会把磁盘 I/O 拖慢到触发每个分片 30 秒的卡死超时。

怎么判断。 临时关掉实时防护,重启 pull,观察吞吐是否回升。Windows 上把 %USERPROFILE%\.ollama 加进 Microsoft Defender 排除项(设置 → 隐私和安全性 → Windows 安全中心 → 病毒和威胁防护 → 管理设置 → 排除项)。

最短修复路径

Step 1:清掉 partial 分片并确认磁盘余量

# 删掉写了一半的可续传分片(保留已完成的 blob)
find ~/.ollama/models/blobs -name '*-partial-*' -delete

# 删掉残留的零字节 blob
find ~/.ollama/models/blobs -type f -size 0 -delete

# 同时确认空间和 inode
df -h ~/.ollama
df -i ~/.ollama

Step 2:关掉 VPN,再带 debug 日志重跑

OLLAMA_DEBUG=1 ollama pull llama3.3:70b

带上 OLLAMA_DEBUG=1 后,Ollama 会打印每个 layer 的 URL 和字节范围。如果它卡在某个具体的 layer hash 上,记下这个 hash 供 Step 3 用。先关 VPN 能排掉最常见的诱因。

Step 3:测真正的下载链路(R2),不只是注册表

# 注册表应该秒回
curl -sI https://registry.ollama.ai/v2/ | head -1

# 跟随一个 manifest/blob 的重定向到 R2,并测吞吐
curl -sL -o /dev/null --max-time 60 -w 'speed=%{speed_download} B/s\nfinal=%{url_effective}\n' \
  "https://registry.ollama.ai/v2/library/llama3.3/blobs/<debug-里看到的-digest>"

如果 final= 落在 *.r2.cloudflarestorage.com 的 URL 上,而 speed 低于约 1 MB/s 或直接超时,瓶颈就在你到 R2 的链路上——转到原因 4(代理/VPN)或换一条网络。

Step 4:换干净网络,或修好代理路由

# 让两个主机都走代理,或者干脆让 Ollama 绕过代理
export NO_PROXY=registry.ollama.ai,.r2.cloudflarestorage.com
ollama pull llama3.3:70b

用手机热点是验证”公司网络才是元凶”的最快办法。

Step 5:把 OLLAMA_MODELS 移到本地快速存储

# 写进 ~/.bashrc 或 ~/.zshrc —— 用本地 NVMe 路径,别用 NAS
export OLLAMA_MODELS=/path/to/local/ssd/ollama

# 重启服务让它读到新路径
# (macOS 应用:退出后重新打开;Linux:sudo systemctl restart ollama)
ollama pull llama3.3:70b

Step 6:先用一个小模型证明整条链路没问题

ollama pull llama3.2:3b
ollama run llama3.2:3b "say hello"

如果一个 2 GB 的模型能正常下完并回话,说明你的安装、磁盘和注册表鉴权都没问题——70B 卡住纯粹是网络耗时问题,重点查原因 1 和原因 4。

怎么确认已经修好

# 1. 模型已注册
ollama list | grep llama3.3

# 2. 没有残留的 partial 分片
find ~/.ollama/models/blobs -name '*-partial-*'   # 应该什么都不输出

# 3. 真的能加载并生成
ollama run llama3.3:70b "reply with the single word: ready"

ollama list 里有干净的条目,再加上一个真实生成的 token,说明 blob 和 manifest 都写成功了。

预防建议

  • 下载大于 10 GB 的模型前先关掉 VPN(或把 registry.ollama.ai*.r2.cloudflarestorage.com 从 VPN 里 split-tunnel 排除)。
  • 至少预留 1.2 倍模型大小的空间;大下载前同时检查 df -hdf -i ~/.ollama
  • 在企业代理后面,设 HTTPS_PROXY(绝不要用 HTTP_PROXY),并把注册表和 R2 CDN 都加进白名单。
  • OLLAMA_MODELS 放在本地 NVMe 上,永远别放网络共享。
  • ~/.ollama(Windows 上是 %USERPROFILE%\.ollama)加进杀毒排除项。
  • 任何超过 20 GB 的 pull 都带上 OLLAMA_DEBUG=1,这样能精确看到卡在哪个 layer。
  • 任何一次中断后,重试前先跑 find ~/.ollama/models/blobs -name '*-partial-*' -delete,避免陷入校验循环。

常见问答 (FAQ)

Q: 网络断了之后 Ollama 是续传还是从零重下? A: 续传。截至 v0.30.x,Ollama 会保存可续传的分片文件(sha256-<digest>-partial-*),下次 pull 时跳过已完成的 blob,并从断点继续未完成的 layer。坑在于损坏:如果某个分片只刷了一半、校验不过,这个 layer 会被丢弃并重下。只删 *-partial-* 文件(别删整个 blob)能获得最干净的续传。

Q: 进度条为什么会往回跑、总大小还变小? A: 一次 pull 最多并行 16 个分片,显示的百分比是聚合值。当某个分片校验失败或 TCP 流断开时,它的字节会被丢弃重下,于是聚合值下降。这虽然烦人但属于预期行为,不是损坏——让它自己恢复就行。

Q: 在家能下,到公司网络就卡,差别在哪? A: 几乎都是 Cloudflare R2 重定向。你的代理放行了 registry.ollama.ai(所以 manifest 能下),却拦住或限速了真正存字节的 *.r2.cloudflarestorage.com。把两个主机都放行,或者在家下完再把 models/ 目录拷进去。

Q: 能在另一台机器预先下好再拷过来吗? A: 可以。把整个 ~/.ollama/models/ 目录——blobs/manifests/ 都要——拷到目标机器,跑 ollama list 模型就出现了,不会再走网络。各系统路径不同(Linux 系统安装用 /usr/share/ollama/.ollama/models)。

Q: 下到 100% 了,但 ollama list 里没有这个模型,为什么? A: 所有 blob 都落盘了,但最后写 manifests/ 那步失败了,通常是临门一脚时空间不足或权限问题。检查 ~/.ollama/models/manifests/ 里有没有对应条目;如果没有,腾空间、修权限,然后重新 pull(已完成的 blob 会复用)。

Q: 怎么拉指定的量化版本而不是默认的? A: 用 tag 语法,例如 ollama pull llama3.3:70b-instruct-q4_K_M。完整 tag 列表(Q4_K_M、Q5_K_M、Q8_0 等)在模型库页面 https://ollama.com/library/llama3.3/tags。量化越小下载越快,在不稳定链路上失败也越少。

相关阅读

标签: #local-llm #ollama #排查