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 上传

您可以使用终端中的 huggingface-cli upload 命令直接将文件上传到 Hub。在内部,它使用与上述 upload_file()upload_folder() 助手相同的方法。

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

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

>>> huggingface-cli 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() 方法和 huggingface-cli 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
---------------------------------------------------

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

还提供了命令行。您可以在终端中定义 worker 的数量和详细程度

huggingface-cli 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 提交到 PR。

大型上传的技巧和窍门

在仓库中处理大量数据时,需要注意一些限制。考虑到流式传输数据所需的时间,在流程结束时上传/推送失败或遇到降级的体验(无论是在 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 extra(即,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 进行的更快上传,hf_xetxet-core 库的 Python 绑定,该库支持基于块的重复数据删除,从而实现更快的上传和下载。hf_xethuggingface_hub 无缝集成,但使用 Rust xet-core 库和 Xet 存储而不是 LFS。

Xet 存储目前正在向 Hugging Face Hub 用户推出,因此可能需要为您的仓库启用 xet 上传,hf_xet 才能实际上传到 Xet 后端。加入候补名单以尽快加入!此外,今天的 hf_xet 仅适用于文件系统上的文件,因此不能与类文件对象(字节数组、缓冲区)一起使用。

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

要启用它,请在安装 huggingface_hub 时指定 hf_xet extra

pip install -U huggingface_hub[hf_xet]

所有其他 huggingface_hub API 将继续工作,无需任何修改。要了解有关 Xet 存储和 hf_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 上的 Dataset 是 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_id, repo_type, revision
  • 线程锁: 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 问题中 ping 我们。

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

>>> 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 安装自定义传输代理

huggingface-cli lfs-enable-largefiles

您应该为每个包含非常大的文件的存储库安装此代理。安装后,您将能够推送大于 5GB 的文件。

commit 上下文管理器

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

有关可能的状态,请参阅下表

状态 描述
-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 上更新