Hub Python 库文档

上传文件到 Hub

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

上传文件到 Hub

分享文件和工作是 Hub 的重要方面。huggingface_hub 提供了多种将文件上传到 Hub 的选项。你可以独立使用这些功能,也可以将它们集成到你的库中,让用户更方便地与 Hub 交互。本指南将向你展示如何推送文件:

  • 不使用 Git。
  • 使用 Git LFS 上传非常大的文件。
  • 使用 commit 上下文管理器。
  • 使用 push_to_hub() 函数。

每当你想要上传文件到 Hub 时,都需要登录到你的 Hugging Face 账户。有关身份验证的更多详细信息,请查看此部分

上传文件

使用 create_repo() 创建仓库后,你可以使用 upload_file() 将文件上传到你的仓库。

指定要上传的文件路径、要将文件上传到仓库中的位置以及要添加文件的仓库名称。根据你的仓库类型,你可以选择将仓库类型设置为 datasetmodelspace

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.upload_file(
...     path_or_fileobj="/path/to/local/folder/README.md",
...     path_in_repo="README.md",
...     repo_id="username/test-dataset",
...     repo_type="dataset",
... )

上传文件夹

使用 upload_folder() 函数将本地文件夹上传到现有仓库。指定要上传的本地文件夹路径、要将文件夹上传到仓库中的位置以及要添加文件夹的仓库名称。根据你的仓库类型,你可以选择将仓库类型设置为 datasetmodelspace

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# Upload all the content from the local folder to your remote Space.
# By default, files are uploaded at the root of the repo
>>> api.upload_folder(
...     folder_path="/path/to/local/space",
...     repo_id="username/my-cool-space",
...     repo_type="space",
... )

默认情况下,会考虑 .gitignore 文件来确定哪些文件应该提交,哪些不应该。默认情况下,我们检查提交中是否存在 .gitignore 文件,如果不存在,我们检查 Hub 上是否存在。请注意,只有根目录中存在的 .gitignore 文件才会被使用。我们不会检查子目录中的 .gitignore 文件。

如果你不想使用硬编码的 .gitignore 文件,你可以使用 allow_patternsignore_patterns 参数来过滤要上传的文件。这些参数接受单个模式或模式列表。模式是此处文档中描述的标准通配符(globbing 模式)。如果同时提供了 allow_patternsignore_patterns,则两者都适用。

除了 .gitignore 文件和允许/忽略模式之外,任何子目录中存在的 .git/ 文件夹都将被忽略。

>>> api.upload_folder(
...     folder_path="/path/to/local/folder",
...     path_in_repo="my-dataset/train", # Upload to a specific folder
...     repo_id="username/test-dataset",
...     repo_type="dataset",
...     ignore_patterns="**/logs/*.txt", # Ignore all text logs
... )

你还可以使用 delete_patterns 参数来指定要在同一提交中从仓库中删除的文件。如果你想在推送文件之前清理远程文件夹,并且不知道哪些文件已经存在,这可能会很有用。

以下示例将本地 ./logs 文件夹上传到远程 /experiment/logs/ 文件夹。只上传 txt 文件,但在此之前,仓库中所有以前的日志都将被删除。所有这些都在一个提交中完成。

>>> api.upload_folder(
...     folder_path="/path/to/local/folder/logs",
...     repo_id="username/trained-model",
...     path_in_repo="experiment/logs/",
...     allow_patterns="*.txt", # Upload all local text files
...     delete_patterns="*.txt", # Delete all remote text files before
... )

从 CLI 上传

你可以使用终端的 hf upload 命令直接将文件上传到 Hub。它在内部使用与上述 upload_file()upload_folder() 相同的辅助函数。

你可以上传单个文件或整个文件夹

# Usage:  hf upload [repo_id] [local_path] [path_in_repo]
>>> hf upload Wauplin/my-cool-model ./models/model.safetensors model.safetensors
https://huggingface.co/Wauplin/my-cool-model/blob/main/model.safetensors

>>> hf upload Wauplin/my-cool-model ./models .
https://huggingface.co/Wauplin/my-cool-model/tree/main

local_pathpath_in_repo 是可选的,可以隐式推断。如果未设置 local_path,该工具将检查本地文件夹或文件是否与 repo_id 同名。如果是,其内容将被上传。否则,将引发异常,要求用户显式设置 local_path。在任何情况下,如果未设置 path_in_repo,文件将上传到仓库的根目录。

有关 CLI 上传命令的更多详细信息,请参阅 CLI 指南

上传大型文件夹

在大多数情况下,upload_folder() 方法和 hf upload 命令应该是将文件上传到 Hub 的首选解决方案。它们确保只会进行一次提交,处理大量用例,并在出错时明确地失败。然而,在处理大量数据时,你通常会更喜欢一种有弹性的流程,即使它会导致更多的提交或需要更多的 CPU 使用量。upload_large_folder() 方法正是本着这种精神实现的。

  • 它是可恢复的:上传过程分为许多小任务(哈希文件、预上传文件和提交文件)。每次任务完成后,结果都会本地缓存到你要上传的文件夹内的 ./cache/huggingface 文件夹中。通过这种方式,中断后重新启动过程将恢复所有已完成的任务。
  • 它是多线程的:如果你的机器允许,哈希大型文件和预上传文件会大大受益于多线程。
  • 它对错误具有弹性:已添加高层次的重试机制,以无限期地重试每个独立任务,直到它通过(无论是 OSError、ConnectionError、PermissionError 等)。这个机制是双刃剑。如果发生瞬时错误,进程将继续并重试。如果发生永久性错误(例如权限被拒绝),它将无限期地重试,而不会解决根本原因。

如果你想了解 upload_large_folder 在底层是如何实现的更多技术细节,请查看 upload_large_folder() 包参考。

以下是如何在脚本中使用 upload_large_folder()。该方法的签名与 upload_folder() 非常相似

>>> api.upload_large_folder(
...     repo_id="HuggingFaceM4/Docmatix",
...     repo_type="dataset",
...     folder_path="/path/to/local/docmatix",
... )

你将在终端中看到以下输出

Repo created: https://huggingface.co/datasets/HuggingFaceM4/Docmatix
Found 5 candidate files to upload
Recovering from metadata files: 100%|█████████████████████████████████████| 5/5 [00:00<00:00, 542.66it/s]

---------- 2024-07-22 17:23:17 (0:00:00) ----------
Files:   hashed 5/5 (5.0G/5.0G) | pre-uploaded: 0/5 (0.0/5.0G) | committed: 0/5 (0.0/5.0G) | ignored: 0
Workers: hashing: 0 | get upload mode: 0 | pre-uploading: 5 | committing: 0 | waiting: 11
---------------------------------------------------

首先,如果仓库之前不存在,则创建仓库。然后,扫描本地文件夹以查找要上传的文件。对于每个文件,我们尝试恢复元数据信息(从之前中断的上传中)。从那里,它能够启动工作程序并每 1 分钟打印一次更新状态。在这里,我们可以看到 5 个文件已经哈希但尚未预上传。5 个工作程序正在预上传文件,而其他 11 个正在等待任务。

还提供了命令行。你可以在终端中定义工作程序数量和详细程度

hf upload-large-folder HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix --num-workers=16

对于大型上传,你必须显式设置 repo_type="model"--repo-type=model。通常,此信息在所有其他 HfApi 方法中都是隐式的。这是为了避免将数据上传到错误类型的仓库。如果发生这种情况,你将不得不重新上传所有内容。

虽然 upload_large_folder 在上传大型文件夹方面更加健壮,但它的功能比 upload_folder() 更受限制。实际上:

  • 你无法设置自定义的 path_in_repo。如果要上传到子文件夹,则需要在本地设置适当的结构。
  • 由于创建了多个提交,你无法设置自定义的 commit_messagecommit_description
  • 你无法在上传时从仓库中删除。请先进行单独的提交。
  • 你无法直接创建 PR。请先创建 PR(通过 UI 或使用 create_pull_request()),然后通过传递 revision 进行提交。

大型上传的提示和技巧

在处理仓库中的大量数据时,需要注意一些限制。考虑到数据流传输所需的时间,如果在过程结束时上传/推送失败或在 hf.co 上或在本地工作时遇到降级体验,可能会非常令人恼火。

请查看我们的 仓库限制和建议 指南,了解在 Hub 上构建仓库的最佳实践。接下来,我们将介绍一些实用技巧,让你的上传过程尽可能顺畅。

  • 从小处着手:我们建议从少量数据开始测试你的上传脚本。当失败只花费很少时间时,迭代脚本会更容易。
  • 预期失败:流式传输大量数据是一项挑战。你不知道会发生什么,但最好始终考虑至少会失败一次——无论是因为你的机器、你的连接还是我们的服务器。例如,如果你计划上传大量文件,最好在本地跟踪你已经上传了哪些文件,然后再上传下一批。你可以确保已经提交的 LFS 文件永远不会被重复上传,但客户端检查仍然可以节省一些时间。这就是 upload_large_folder() 为你所做的。
  • 使用 hf_xet:这利用了 Hub 的新存储后端,是用 Rust 编写的,目前正在向用户推出。要使用 hf_xet 上传,你的仓库必须启用 Xet 存储后端。它现在正在推出,所以请加入候补名单,尽快加入!
  • 使用 hf_transfer:这是一个基于 Rust 的,旨在加快带宽非常高的机器上的上传速度(上传 LFS 文件)。要使用 hf_transfer
    1. 安装 huggingface_hub 时指定 hf_transfer 额外依赖(即,pip install huggingface_hub[hf_transfer])。
    2. HF_HUB_ENABLE_HF_TRANSFER=1 设置为环境变量。

hf_transfer 是一个用于上传 LFS 文件的超级用户工具!它经过测试,已达到生产就绪状态,但它未来的适用性较差,并且缺少用户友好的功能,例如高级错误处理或代理。有关更多详细信息,请查看此部分

请注意,hf_xethf_transfer 工具是互斥的。前者用于将文件上传到启用 Xet 的仓库,而后者将 LFS 文件上传到常规仓库。

高级功能

在大多数情况下,你只需要 upload_file()upload_folder() 即可将文件上传到 Hub。但是,huggingface_hub 具有更高级的功能,可以使操作更简单。让我们看看它们!

更快的上传

通过 hf_xet 利用更快的上传,它是 xet-core 库的 Python 绑定,可实现基于块的重复数据删除,从而加快上传和下载速度。hf_xethuggingface_hub 无缝集成,但使用 Rust xet-core 库和 Xet 存储而不是 LFS。

截至 2025 年 5 月 23 日,启用 Xet 的存储库已成为所有新的 Hugging Face Hub 用户和组织的默认设置。如果您的用户或组织是在此日期之前创建的,您可能需要在存储库上启用 Xet,才能让 hf_xet 实际上传到 Xet 后端。加入候补名单,让 Xet 成为您所有存储库的默认设置。另请注意,虽然 hf_xet 适用于内存中的字节或字节数组数据,但对 BinaryIO 流的支持仍在进行中。

hf_xet 使用 Xet 存储系统,它将文件分解成不可变的块,将这些块的集合(称为块或 xorbs)远程存储,并在请求时检索它们以重新组装文件。上传时,在确认用户有权写入此仓库后,hf_xet 将扫描文件,将其分解成块并将这些块收集到 xorbs 中(并在已知块之间进行重复数据删除),然后将这些 xorbs 上传到 Xet 内容寻址服务 (CAS),该服务将验证 xorbs 的完整性,注册 xorb 元数据以及 LFS SHA256 哈希(以支持查找/下载),并将 xorbs 写入远程存储。

要启用它,只需安装最新版本的 huggingface_hub

pip install -U "huggingface_hub"

huggingface_hub 0.32.0 开始,这将同时安装 hf_xet

所有其他 huggingface_hub API 将继续无需任何修改即可工作。要了解有关 Xet 存储和 hf_xet 优势的更多信息,请参阅此部分

集群/分布式文件系统上传注意事项

从集群上传时,上传的文件通常位于分布式或网络文件系统(NFS、EBS、Lustre、Fsx 等)上。Xet 存储将分块这些文件并将其写入本地块(也称为 xorbs),一旦块完成,就会上传它们。为了在从分布式文件系统上传时获得更好的性能,请确保将 HF_XET_CACHE 设置为本地磁盘上的目录(例如本地 NVMe 或 SSD 磁盘)。Xet 缓存的默认位置在 HF_HOME 下(~/.cache/huggingface/xet),并且此位置通常也位于分布式文件系统上。

非阻塞上传

在某些情况下,你可能希望在不阻塞主线程的情况下推送数据。这对于在继续训练的同时上传日志和工件特别有用。为此,你可以在 upload_file()upload_folder() 中使用 run_as_future 参数。这将返回一个 concurrent.futures.Future 对象,你可以使用它来检查上传状态。

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> future = api.upload_folder( # Upload in the background (non-blocking action)
...     repo_id="username/my-model",
...     folder_path="checkpoints-001",
...     run_as_future=True,
... )
>>> future
Future(...)
>>> future.done()
False
>>> future.result() # Wait for the upload to complete (blocking action)
...

使用 run_as_future=True 时,后台作业将排队。这意味着你保证作业将按正确的顺序执行。

尽管后台作业主要用于上传数据/创建提交,但你可以使用 run_as_future() 队列任何你喜欢的方法。例如,你可以使用它创建仓库,然后将数据上传到后台。上传方法中内置的 run_as_future 参数只是它的别名。

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.run_as_future(api.create_repo, "username/my-model", exists_ok=True)
Future(...)
>>> api.upload_file(
...     repo_id="username/my-model",
...     path_in_repo="file.txt",
...     path_or_fileobj=b"file content",
...     run_as_future=True,
... )
Future(...)

分块上传文件夹

upload_folder() 可以轻松地将整个文件夹上传到 Hub。但是,对于大型文件夹(数千个文件或数百 GB),我们建议使用 upload_large_folder(),它将上传拆分为多个提交。有关更多详细信息,请参阅上传大型文件夹部分。

计划性上传

Hugging Face Hub 可以轻松保存和版本化数据。但是,当更新同一个文件数千次时,存在一些限制。例如,你可能希望保存训练过程的日志或已部署 Space 的用户反馈。在这些情况下,将数据作为数据集上传到 Hub 是有意义的,但可能很难正确执行。主要原因是你不希望版本化数据的每次更新,因为这会使 Git 仓库无法使用。CommitScheduler 类提供了此问题的解决方案。

其思想是运行一个后台作业,定期将本地文件夹推送到 Hub。假设你有一个 Gradio Space,它以文本作为输入并生成其两种翻译。然后,用户可以选择他们喜欢的翻译。对于每次运行,你都希望保存输入、输出和用户偏好,以分析结果。这是一个使用 CommitScheduler 的完美用例;你希望将数据保存到 Hub(可能是数百万条用户反馈),但你不需要实时保存每个用户的输入。相反,你可以将数据本地保存到 JSON 文件中,然后每 10 分钟上传一次。例如:

>>> import json
>>> import uuid
>>> from pathlib import Path
>>> import gradio as gr
>>> from huggingface_hub import CommitScheduler

# Define the file where to save the data. Use UUID to make sure not to overwrite existing data from a previous run.
>>> feedback_file = Path("user_feedback/") / f"data_{uuid.uuid4()}.json"
>>> feedback_folder = feedback_file.parent

# Schedule regular uploads. Remote repo and local folder are created if they don't already exist.
>>> scheduler = CommitScheduler(
...     repo_id="report-translation-feedback",
...     repo_type="dataset",
...     folder_path=feedback_folder,
...     path_in_repo="data",
...     every=10,
... )

# Define the function that will be called when the user submits its feedback (to be called in Gradio)
>>> def save_feedback(input_text:str, output_1: str, output_2:str, user_choice: int) -> None:
...     """
...     Append input/outputs and user feedback to a JSON Lines file using a thread lock to avoid concurrent writes from different users.
...     """
...     with scheduler.lock:
...         with feedback_file.open("a") as f:
...             f.write(json.dumps({"input": input_text, "output_1": output_1, "output_2": output_2, "user_choice": user_choice}))
...             f.write("\n")

# Start Gradio
>>> with gr.Blocks() as demo:
>>>     ... # define Gradio demo + use `save_feedback`
>>> demo.launch()

就这样!用户输入/输出和反馈将作为数据集在 Hub 上可用。通过使用唯一的 JSON 文件名,可以保证不会覆盖先前运行的数据或同时推送到同一存储库的其他 Spaces/副本的数据。

有关 CommitScheduler 的更多详细信息,你需要了解以下内容:

  • 仅追加: 假定你将仅向文件夹添加内容。你必须仅向现有文件追加数据或创建新文件。删除或覆盖文件可能会损坏你的存储库。
  • Git 历史记录:调度器将每 every 分钟提交一次文件夹。为避免过多地污染 Git 仓库,建议将最小间隔设置为 5 分钟。此外,调度器旨在避免空提交。如果在文件夹中未检测到新内容,则会丢弃计划的提交。
  • 错误: 调度器作为后台线程运行。它在你实例化类时启动并永不停止。特别是,如果在上传期间发生错误(例如:连接问题),调度器将静默忽略它并在下一个计划提交时重试。
  • 线程安全: 在大多数情况下,可以安全地假设你可以写入文件而无需担心锁文件。当你向文件夹写入内容时,如果调度器正在上传,它不会崩溃或损坏。实际上,可能会发生并发问题对于高负载应用程序。在这种情况下,我们建议使用 scheduler.lock 锁来确保线程安全。锁仅在调度器扫描文件夹以查找更改时被阻塞,而不是在上传数据时。你可以放心地假设它不会影响你的 Space 上的用户体验。

Space 持久化演示

将数据从 Space 持久化到 Hub 上的数据集是 CommitScheduler 的主要用例。根据用例,你可能希望以不同的方式组织数据。数据结构必须对并发用户和重新启动具有鲁棒性,这通常意味着生成 UUID。除了鲁棒性之外,你还应该以可由 🤗 Datasets 库读取的格式上传数据,以便以后重用。我们创建了一个Space,演示了如何保存几种不同的数据格式(你可能需要根据自己的特定需求进行调整)。

自定义上传

CommitScheduler 假定你的数据是仅追加的,并且应该“按原样”上传。但是,你可能希望自定义数据上传方式。你可以通过创建一个继承自 CommitScheduler 的类并覆盖 push_to_hub 方法来做到这一点(你可以随意以任何方式覆盖它)。你保证它将在后台线程中每 every 分钟调用一次。你不必担心并发和错误,但你必须小心其他方面,例如推送空提交或重复数据。

在下面的(简化)示例中,我们覆盖 push_to_hub 以将所有 PNG 文件压缩到一个存档中,以避免 Hub 上的仓库过载

class ZipScheduler(CommitScheduler):
    def push_to_hub(self):
        # 1. List PNG files
          png_files = list(self.folder_path.glob("*.png"))
          if len(png_files) == 0:
              return None  # return early if nothing to commit

        # 2. Zip png files in a single archive
        with tempfile.TemporaryDirectory() as tmpdir:
            archive_path = Path(tmpdir) / "train.zip"
            with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zip:
                for png_file in png_files:
                    zip.write(filename=png_file, arcname=png_file.name)

            # 3. Upload archive
            self.api.upload_file(..., path_or_fileobj=archive_path)

        # 4. Delete local png files to avoid re-uploading them later
        for png_file in png_files:
            png_file.unlink()

当你覆盖 push_to_hub 时,你可以访问 CommitScheduler 的属性,特别是

  • HfApi 客户端:api
  • 文件夹参数:folder_pathpath_in_repo
  • 仓库参数:repo_idrepo_typerevision
  • 线程锁:lock

有关自定义调度器的更多示例,请查看我们的演示 Space,其中包含根据您的用例的不同实现。

create_commit

upload_file()upload_folder() 函数是高级 API,通常使用起来很方便。如果你不需要在较低级别工作,我们建议你首先尝试这些函数。但是,如果你想在提交级别工作,可以直接使用 create_commit() 函数。

create_commit() 支持三种类型的操作:

  • CommitOperationAdd 将文件上传到 Hub。如果文件已存在,则文件内容将被覆盖。此操作接受两个参数:

    • path_in_repo:要上传文件的仓库路径。
    • path_or_fileobj:本地文件路径或文件对象。这是要上传到 Hub 的文件内容。
  • CommitOperationDelete 从仓库中删除文件或文件夹。此操作接受 path_in_repo 作为参数。

  • CommitOperationCopy 在仓库中复制文件。此操作接受三个参数:

    • src_path_in_repo:要复制的文件的仓库路径。
    • path_in_repo:文件应复制到的仓库路径。
    • src_revision:可选 - 如果要从不同的分支/修订版本复制文件,则为要复制的文件的修订版本。

例如,如果你想上传两个文件并删除 Hub 仓库中的一个文件:

  1. 使用适当的 CommitOperation 来添加或删除文件以及删除文件夹
>>> from huggingface_hub import HfApi, CommitOperationAdd, CommitOperationDelete
>>> api = HfApi()
>>> operations = [
...     CommitOperationAdd(path_in_repo="LICENSE.md", path_or_fileobj="~/repo/LICENSE.md"),
...     CommitOperationAdd(path_in_repo="weights.h5", path_or_fileobj="~/repo/weights-final.h5"),
...     CommitOperationDelete(path_in_repo="old-weights.h5"),
...     CommitOperationDelete(path_in_repo="logs/"),
...     CommitOperationCopy(src_path_in_repo="image.png", path_in_repo="duplicate_image.png"),
... ]
  1. 将你的操作传递给 create_commit()
>>> api.create_commit(
...     repo_id="lysandre/test-model",
...     operations=operations,
...     commit_message="Upload my model weights and license",
... )

除了 upload_file()upload_folder() 之外,以下函数也使用了 create_commit()

有关更详细的信息,请参阅 HfApi 参考。

提交前预上传 LFS 文件

在某些情况下,你可能希望在进行提交调用之前将大型文件上传到 S3。例如,如果你正在以内存中生成的多个分片提交数据集,则需要逐个上传分片以避免内存不足问题。一个解决方案是将每个分片作为单独的提交上传到仓库。虽然此解决方案完全有效,但它的缺点是可能会通过生成数十个提交来弄乱 Git 历史记录。为了解决此问题,你可以将文件逐个上传到 S3,然后最后创建一个单独的提交。这可以使用 preupload_lfs_files()create_commit() 结合使用来实现。

这是一种高级用户方法。在绝大多数情况下,直接使用 upload_file()upload_folder()create_commit(),而不是处理预上传文件的底层逻辑,是首选方式。preupload_lfs_files() 的主要缺点是,在实际提交之前,上传的文件无法在 Hub 上的仓库中访问。如果您有疑问,请随时在我们的 Discord 或 GitHub issue 中与我们联系。

以下是一个说明如何预上传文件的简单示例

>>> from huggingface_hub import CommitOperationAdd, preupload_lfs_files, create_commit, create_repo

>>> repo_id = create_repo("test_preupload").repo_id

>>> operations = [] # List of all `CommitOperationAdd` objects that will be generated
>>> for i in range(5):
...     content = ... # generate binary content
...     addition = CommitOperationAdd(path_in_repo=f"shard_{i}_of_5.bin", path_or_fileobj=content)
...     preupload_lfs_files(repo_id, additions=[addition])
...     operations.append(addition)

>>> # Create commit
>>> create_commit(repo_id, operations=operations, commit_message="Commit all shards")

首先,我们逐个创建 CommitOperationAdd 对象。在实际示例中,这些对象将包含生成的碎片。每个文件在生成下一个文件之前都会上传。在 preupload_lfs_files() 步骤中,CommitOperationAdd 对象将被修改。你只能将其直接传递给 create_commit()。对象的主要更新是二进制内容已从其中移除,这意味着如果你不存储对它的另一个引用,它将被垃圾回收。这是预期的,因为我们不想将已上传的内容保留在内存中。最后,我们通过将所有操作传递给 create_commit() 来创建提交。你可以传递尚未处理的其他操作(添加、删除或复制),它们将得到正确处理。

(旧版)使用 Git LFS 上传文件

上述所有方法都使用 Hub 的 API 来上传文件。这是上传文件到 Hub 的推荐方式。但是,我们也提供了 Repository,一个围绕 Git 工具的包装器,用于管理本地仓库。

尽管 Repository 并未正式弃用,但我们建议改用上述基于 HTTP 的方法。有关此建议的更多详细信息,请参阅 本指南,其中解释了基于 HTTP 和基于 Git 的方法之间的核心区别。

Git LFS 会自动处理大于 10MB 的文件。但是对于非常大的文件(>5GB),你需要为 Git LFS 安装自定义传输代理

hf lfs-enable-largefiles

你应为每个包含非常大文件的仓库安装此项。安装后,你就能推送大于 5GB 的文件了。

提交上下文管理器

commit 上下文管理器处理四个最常见的 Git 命令:pull、add、commit 和 push。git-lfs 自动跟踪任何大于 10MB 的文件。在以下示例中,commit 上下文管理器:

  1. text-files 仓库拉取。
  2. 添加对 file.txt 的更改。
  3. 提交更改。
  4. 将更改推送到 text-files 仓库。
>>> from huggingface_hub import Repository
>>> with Repository(local_dir="text-files", clone_from="<user>/text-files").commit(commit_message="My first file :)"):
...     with open("file.txt", "w+") as f:
...         f.write(json.dumps({"hey": 8}))

以下是另一个使用 commit 上下文管理器保存和上传文件到仓库的示例

>>> import torch
>>> model = torch.nn.Transformer()
>>> with Repository("torch-model", clone_from="<user>/torch-model", token=True).commit(commit_message="My cool model :)"):
...     torch.save(model.state_dict(), "model.pt")

如果你想异步推送提交,请将 blocking=False。非阻塞行为在你希望在提交被推送的同时继续运行脚本时很有用。

>>> with repo.commit(commit_message="My cool model :)", blocking=False)

你可以使用 command_queue 方法检查推送状态

>>> last_command = repo.command_queue[-1]
>>> last_command.status

请参阅下表了解可能的 statuses

状态 描述
-1 正在推送。
0 推送已成功完成。
非零 发生错误。

blocking=False 时,命令会被跟踪,你的脚本只有在所有推送完成后才会退出,即使脚本中发生其他错误。一些其他用于检查推送状态的有用命令包括:

# Inspect an error.
>>> last_command.stderr

# Check whether a push is completed or ongoing.
>>> last_command.is_done

# Check whether a push command has errored.
>>> last_command.failed

push_to_hub

Repository 类有一个 push_to_hub() 函数,用于添加文件、进行提交并将它们推送到仓库。与 commit 上下文管理器不同,你需要先从仓库中拉取,然后才能调用 push_to_hub()

例如,如果你已经从 Hub 克隆了仓库,则可以从本地目录初始化 repo

>>> from huggingface_hub import Repository
>>> repo = Repository(local_dir="path/to/local/repo")

使用 git_pull() 更新你的本地克隆,然后将文件推送到 Hub

>>> repo.git_pull()
>>> repo.push_to_hub(commit_message="Commit my-awesome-file to the Hub")

但是,如果你尚未准备好推送文件,可以使用 git_add()git_commit() 仅添加和提交文件

>>> repo.git_add("path/to/file")
>>> repo.git_commit(commit_message="add my first model config file :)")

当你准备好后,使用 git_push() 将文件推送到你的仓库

>>> repo.git_push()
< > 在 GitHub 上更新