为什么我的模型无法部署到 Hugging Face Spaces(以及 Git LFS 实际的作用)

发布: (2026年1月11日 GMT+8 10:02)
15 分钟阅读
原文: Dev.to

Source: Dev.to

为什么我的模型无法部署到 Hugging Face Spaces,以及 Git LFS 实际上在做什么

在尝试把一个大型模型推送到 Hugging Face Spaces 时,我遇到了让人抓狂的错误信息。经过一番调查,我发现问题根源在于 Git Large File Storage (Git LFS) 的使用方式不当。下面我把整个排查过程、错误表现以及最终的解决方案整理成了一篇小文,供大家参考。


1. 现象:部署失败的错误信息

当我在本地运行 git push 把模型文件(约 1.2 GB)推送到仓库时,终端输出类似下面的内容:

error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
fatal: The remote end hung up unexpectedly

随后,在 Hugging Face Spaces 的部署日志里看到:

Traceback (most recent call last):
  File "/workspace/app.py", line 12, in <module>
    from transformers import AutoModel
...
OSError: [Errno 2] No such file or directory: 'model.bin'

简而言之,模型文件根本没有被正确上传,导致 Space 启动时找不到模型。


2. 为什么会出现这种情况?

2.1 Git LFS 的工作原理

  • Git LFS 并不把大文件直接存储在普通的 Git 对象库里,而是把它们替换成指向 LFS 服务器 的指针文件(.gitattributes 中会标记哪些文件走 LFS)。
  • 当你执行 git push 时,Git 会先把指针文件推送到普通的 Git 服务器,然后再把真实的大文件上传到 LFS 端点(在 Hugging Face 上是 https://huggingface.co/<repo>.git/info/lfs)。
  • 如果本地没有正确安装或配置 LFS,或者 LFS 上传过程被中断,指针文件会被提交上去,但实际的大文件根本没有被上传。

2.2 常见的误区

误区解释
只执行 git addgit commitgit push,认为 LFS 会自动生效必须先 安装 Git LFS 并运行 git lfs install,否则指针文件会被当作普通文本提交。
把模型文件直接放在仓库根目录,而不在 .gitattributes 中声明没有声明的话,Git 会把模型当作普通文件处理,导致仓库体积爆炸或推送被拒绝。
以为一次 git push 就能把所有大文件全部上传LFS 上传是 分块 进行的,网络不稳定时可能只上传了部分块,导致文件不完整。

3. 解决方案:一步步让模型成功部署

下面是我最终采用的完整流程,确保模型文件能够正确走 LFS 并在 Spaces 中被加载。

3.1 安装并初始化 Git LFS

# 如果系统里没有 LFS,先安装
# macOS (Homebrew)
brew install git-lfs

# Ubuntu/Debian
sudo apt-get install git-lfs

# Windows (Chocolatey)
choco install git-lfs

# 初始化(只需要在每台机器上执行一次)
git lfs install

注意git lfs install 会在全局或当前仓库的 .git/config 中写入钩子,确保后续的 git add 能自动把匹配的文件交给 LFS。

3.2 在 .gitattributes 中声明要走 LFS 的文件类型

在项目根目录创建(或编辑).gitattributes,加入类似下面的规则:

# 将所有模型权重文件走 LFS
*.bin filter=lfs diff=lfs merge=lfs -text
*.pt  filter=lfs diff=lfs merge=lfs -text
*.pth filter=lfs diff=lfs merge=lfs -text

这一步非常关键:没有这条规则,模型文件会被当作普通文件提交。

3.3 把模型文件重新添加到 Git(确保走 LFS)

如果之前已经提交过模型文件,需要先 撤回(reset)再重新添加:

# 让 Git 重新识别 LFS 规则
git rm --cached path/to/model.bin
git add path/to/model.bin
git commit -m "Add model.bin via Git LFS"

3.4 推送到 Hugging Face(包括 LFS 内容)

git push origin main

在推送过程中,你会看到类似的输出:

Uploading LFS objects:   0% (0/10), 0 B | 0 B/s
Uploading LFS objects: 100% (10/10), 1.2 GB | 12.3 MB/s, done.

如果网络不稳定导致中断,可以使用 git lfs push --all origin main 强制重新上传所有 LFS 对象。

3.5 在 Spaces 中验证模型是否可用

部署完成后,打开 Space 的 Settings → Files,确认模型文件已经显示为 LFS(文件大小会被正确显示)。随后在 app.py(或其他入口文件)里使用常规的 transformers 加载方式:

from transformers import AutoModel, AutoTokenizer

model = AutoModel.from_pretrained("./")
tokenizer = AutoTokenizer.from_pretrained("./")

如果一切正常,日志中不再出现 “No such file or directory” 的错误。


4. 小贴士:避免以后再次踩坑

  1. 始终在克隆新仓库后第一时间运行 git lfs install。即使你已经在本地装了 LFS,新的机器上也需要执行一次。
  2. .gitignore 里不要把模型文件排除,否则即使声明了 LFS,Git 也会直接忽略它们。
  3. 使用 git lfs ls-files 检查已被 LFS 管理的文件,确保没有遗漏。
  4. 如果模型体积超过 5 GB,Hugging Face 仍然支持,但需要在仓库设置里开启 “Large File Storage” 并可能需要付费计划。
  5. 网络不佳时,可以把 LFS 对象先上传到本地缓存(git lfs fetch --all),再在网络好时一次性推送。

5. 结语

这篇文章的核心信息是:模型部署失败往往不是 Hugging Face 本身的 bug,而是 Git LFS 配置不当导致的大文件没有真正被上传。只要按照上面的步骤——安装 LFS、声明文件类型、重新添加并推送——就能让模型顺利出现在 Spaces 中,后续的推理服务也会如期运行。

如果你在部署过程中仍然遇到奇怪的错误,建议先检查:

  • .gitattributes 是否生效(git check-attr filter path/to/file
  • LFS 对象是否完整(git lfs ls-files
  • Space 的日志里是否还有 “LFS pointer” 的提示

祝大家玩得开心,模型部署顺利! 🚀

Source:

我尝试了什么(以及为什么一直失败)

当我尝试推送仓库时,Git 返回了以下错误:

remote: -------------------------------------------------------------------------
remote: Your push was rejected because it contains files larger than 10 MiB.
remote: Please use https://git-lfs.github.com/ to store large files.
remote: See also: https://hf.co/docs/hub/repositories-getting-started#terminal
remote:
remote: Offending files:
remote:   - model.pkl (ref: refs/heads/main)
remote: -------------------------------------------------------------------------
To https://huggingface.co/spaces/chloezhoudev/minima
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://huggingface.co/spaces/chloezhoudev/minima'

我能看出 Git 在抱怨——model.pkl 太大了——但我并不真正明白这为什么会是个问题,或者 “Git LFS” 实际上意味着什么。我以前从未使用过它。

于是,我按照错误信息中的指示一步步尝试修复。

1️⃣ 安装并初始化 Git LFS

brew install git-lfs    # Install Git LFS (macOS via Homebrew)
git lfs install         # Initialise Git LFS and register Git hooks
git lfs version         # Confirm Git LFS installation

2️⃣ 跟踪模型文件并推送

git lfs track "model.pkl"
git add model.pkl
git commit -m "Track model file with Git LFS"
git push

推送再次失败——错误完全相同

3️⃣ 尝试从索引中移除该文件

git rm --cached model.pkl
git lfs track "model.pkl"
git commit -m "Store model file using Git LFS"
git push

同样的错误。 😅

4️⃣ 创建一个孤立分支

git checkout --orphan clean-main
git add .
git commit -m "Initial deployment with Git LFS model"
git branch -M main
git push -f origin main

这一次,推送终于成功了。

Source:

我最终对 Git 和 Git LFS 的认识

为什么 Git 一直拒绝我的推送?

Hugging Face 仓库会强制执行 pre‑receive hook,它会扫描 你本次推送的所有提交,如果 任何提交中包含大于 10 MiB 的文件,就会 拒绝推送

如果大文件以普通 Git blob 的形式存储在某个提交中,即使你随后为其添加了 LFS 跟踪,钩子仍会拒绝该推送。

Git LFS 实际上做了什么?

  • 普通 Git 将文件内容存为 blob 对象。每个你添加的文件(大致)会以原始大小保存在仓库历史中。对于二进制文件,这意味着每一次修改该文件的提交都会保存完整的数据。
  • Git LFS指针文件(极小的文本文件)取代大文件,并把真实的二进制数据存放在专用的 LFS 服务器上。当你 git add 一个符合 LFS 规则的文件时,Git LFS 会生成一个指针,将该指针交给 Git,并把实际文件上传到 LFS 存储。

为什么 git rm --cached 没有起作用?

git rm --cached model.pkl 只会把文件从当前工作树的 索引 中移除。大的 blob 已经存在于你尝试推送的之前的提交中,所以 pre‑receive hook 仍然会看到包含超大 blob 的提交并拒绝推送。

为什么创建孤立分支就能解决问题?

git checkout --orphan clean-main 开启了一个 全新的历史,没有任何之前的提交。随后在已经配置好 LFS 的情况下添加文件并只提交一次,仓库唯一的提交里只包含 LFS 指针,而不是大 blob。于是 pre‑receive hook 没有检测到超大 blob,推送得以通过。

关键要点

  1. 在大文件进入仓库历史之前必须先使用 LFS 进行跟踪。
    在大文件已经提交后再添加 LFS 跟踪并不会 retroactively 重写该提交。

  2. .gitattributes 文件决定 LFS 跟踪。
    Hugging Face Spaces 会自动添加类似以下内容的行:

    *.pkl filter=lfs diff=lfs merge=lfs -text

    这告诉 Git 将任何 *.pkl 文件视为 LFS 对象,前提是 在首次添加文件时已安装 LFS。

  3. 从索引中移除文件并不会把它从历史中抹掉。
    若要真正删除超大 blob,需要重写历史(例如使用 git filter-repo,或创建一个全新的孤立分支)。

  4. 孤立分支是快速获得干净状态的办法。
    当你有一个小项目并希望确保没有大 blob 时,在设置好 LFS 后创建孤立分支,可保证第一次提交是干净的。

TL;DR

  • 在添加任何大文件之前先安装 Git LFS
  • 确保 .gitattributes 中包含相应的模式。
  • 如果不小心提交了大文件,要么重写历史,要么创建新孤立分支并在启用 LFS 跟踪的情况下重新提交。

现在模型被高效存储,Space 部署不再报错,我也终于明白了 Git LFS 的作用以及孤立分支技巧为何有效。

关于 git rm — cached 怎么办?

⚠️ 重要

git rm --cached 只影响后续提交。它 不会 从现有的 Git 历史中删除文件。

  • 该命令会把文件从暂存区移除,并在后续提交中停止跟踪它,同时保持工作目录中的文件完整。
  • 但是,它并不会删除最初添加该大文件的那个提交。

因为原始提交仍然把 model.pkl 作为普通的 Git blob 保存,问题文件仍然存在于仓库历史中——于是 Hugging Face 仍然会拒绝推送。

有效的解决方案

创建一个没有历史记录的新分支(git checkout — orphan)解决了所有问题,因为它 从一张干净的白纸开始,根本没有任何提交。

  1. 创建孤立分支

    git checkout --orphan new-main
  2. 添加文件(已配置 Git LFS)

    git add .
    git commit -m "Add files with LFS"
  3. 将分支重命名为 main 并强制推送

    git branch -M main
    git push -f origin main

警告: 使用 --orphan,尤其是 git push -f,在有多个协作者使用同一分支时非常危险,因为这会替换分支的历史记录。就我而言,Space 仓库仅用于部署,所以这样做没问题,但在团队环境中需要格外小心。

💡 额外提示:Git LFS 已不再是唯一选择

Hugging Face 现在也推荐 git‑xet,这是一种专为大型机器学习制品设计的更新后端。

  • Git LFS 将大文件 移出 Git
  • git‑xet 重新思考 Git 对大型内容的整体存储方式。

经过所有调试后,模型终于部署成功并按预期工作。你可以在 此处 试用实时演示。

感谢阅读。 😊

Back to Blog

相关文章

阅读更多 »

你好,我是新人。

嗨!我又回到 STEM 的领域了。我也喜欢学习能源系统、科学、技术、工程和数学。其中一个项目是…