将文件上传到 Hub
共享您的文件和工作是 Hub 的一个重要方面。huggingface_hub
提供了多个将文件上传到 Hub 的选项。您可以独立使用这些功能,也可以将其集成到您的库中,从而方便您的用户与 Hub 交互。本指南将向您展示如何推送文件
- 无需使用 Git。
- 使用 Git LFS 上传非常大的文件。
- 使用
commit
上下文管理器。 - 使用 push_to_hub() 函数。
无论何时要将文件上传到 Hub,您都需要登录您的 Hugging Face 帐户。有关身份验证的更多详细信息,请查看 此部分。
上传文件
使用 create_repo() 创建存储库后,您可以使用 upload_file() 将文件上传到您的存储库。
指定要上传的文件的路径、您希望在存储库中的哪个位置上传文件以及要向其添加文件的存储库的名称。根据您的存储库类型,您可以选择将存储库类型设置为 dataset
、model
或 space
。
>>> 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() 函数将本地文件夹上传到现有仓库。指定要上传的本地文件夹路径,您希望在仓库中的哪个位置上传文件夹,以及您要将文件夹添加到哪个仓库的名称。根据您的仓库类型,您可以选择将仓库类型设置为 dataset
、model
或 space
。
>>> 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_patterns
和 ignore_patterns
参数来过滤要上传的文件。这些参数可以接受单个模式或模式列表。模式是标准通配符(glob 模式),如 此处 所述。如果同时提供 allow_patterns
和 ignore_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_path
和 path_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
---------------------------------------------------
首先,如果仓库以前不存在,则会创建它。然后,扫描本地文件夹以查找要上传的文件。对于每个文件,我们尝试恢复元数据信息(来自先前中断的上传)。从那里,它能够启动工作程序并在每 1 分钟打印更新状态。在这里,我们可以看到 5 个文件已被散列但尚未预上传。5 个工作程序正在预上传文件,而其他 11 个工作程序正在等待任务。
还提供了一个命令行。您可以在终端中定义工作程序的数量和详细程度。
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_message
和commit_description
,因为创建了多个提交。 - 您无法在上传时从仓库中删除。请先进行单独的提交。
- 您无法直接创建 PR。请先创建 PR(从 UI 或使用 create_pull_request()),然后通过传递
revision
提交到它。
大型上传的提示和技巧
在处理仓库中的大量数据时,需要了解一些限制。考虑到流式传输数据所需的时间,在流程结束时导致上传/推送失败或遇到性能下降(无论是在 hf.co 上还是在本地工作时),都可能非常令人恼火。
查看我们的 仓库限制和建议 指南,了解有关如何在 Hub 上构建仓库的最佳实践。让我们继续了解一些使上传过程尽可能顺畅的实用技巧。
- 从小开始:我们建议从少量数据开始测试您的上传脚本。当失败只需花费很少时间时,迭代脚本会更容易。
- 预期失败:流式传输大量数据具有挑战性。您不知道会发生什么,但最好始终考虑某些事情至少会失败一次——无论它是由您的机器、您的连接还是我们的服务器造成的。例如,如果您计划上传大量文件,最好在上传下一批文件之前在本地跟踪已上传的文件。您可以确保已提交的 LFS 文件永远不会被重复上传两次,但客户端检查仍然可以节省一些时间。这就是 upload_large_folder() 为您做的事情。
- 使用
hf_transfer
:这是一个基于 Rust 的 库,旨在加快带宽非常高的机器上的上传速度。要使用hf_transfer
- 在安装
huggingface_hub
时指定hf_transfer
附加组件(即pip install huggingface_hub[hf_transfer]
)。 - 将
HF_HUB_ENABLE_HF_TRANSFER=1
作为环境变量设置。
- 在安装
hf_transfer
是一款高级用户工具!它经过测试且已准备好投入生产,但它缺乏用户友好的功能,例如高级错误处理或代理。有关更多详细信息,请查看此 部分。
高级功能
在大多数情况下,您只需要使用 upload_file() 和 upload_folder() 即可将文件上传到 Hub。但是,huggingface_hub
拥有更多高级功能来简化操作。让我们一起来看看吧!
非阻塞上传
在某些情况下,您希望在不阻塞主线程的情况下推送数据。这在上传日志和工件的同时继续训练时特别有用。为此,您可以在 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),这仍然可能具有挑战性。如果您的文件夹包含大量文件,您可能希望将其分成多个提交进行上传。如果您在上传过程中遇到错误或连接问题,则无需从头开始恢复流程。
要将文件夹分成多个提交进行上传,只需将 multi_commits=True
作为参数传递。在后台,huggingface_hub
将列出要上传/删除的文件,并将它们分成多个提交。“策略”(即如何拆分提交)基于要上传的文件数量和大小。Hub 上有一个 PR 用于推送所有提交。PR 准备就绪后,提交将被压缩成单个提交。如果在完成之前流程中断,您可以重新运行脚本以恢复上传。创建的 PR 将被自动检测,并且上传将从中断处恢复。建议传递 multi_commits_verbose=True
以更好地了解上传及其进度。
下面的示例将把 checkpoints 文件夹上传到数据集,并分成多个提交。上传完成后,将在 Hub 上创建一个 PR 并自动合并。如果您希望 PR 保持打开状态并手动审查,则可以传递 create_pr=True
。
>>> upload_folder(
... folder_path="local/checkpoints",
... repo_id="username/my-dataset",
... repo_type="dataset",
... multi_commits=True,
... multi_commits_verbose=True,
... )
如果您希望更好地控制上传策略(即创建的提交),可以查看低级 plan_multi_commits() 和 create_commits_on_pr() 方法。
multi_commits
仍然是一个实验性功能。其 API 和行为可能会在将来更改,恕不另行通知。
定时上传
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 文件名,您可以保证不会覆盖先前运行的数据或来自其他 Space/副本同时推送到同一存储库的数据。
有关 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_path
和path_in_repo
- 存储库参数:
repo_id
、repo_type
、revision
- 线程锁:
lock
有关自定义调度程序的更多示例,请查看我们的 演示空间,其中包含根据您的用例的不同实现。
创建提交
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 存储库中删除一个文件
- 使用适当的
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"),
... ]
- 将您的操作传递给 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()
- delete_file() 从 Hub 上的存储库中删除单个文件。
- delete_folder() 从 Hub 上的存储库中删除整个文件夹。
- metadata_update() 更新存储库的元数据。
有关更详细的信息,请查看 HfApi 参考。
在提交之前预上传 LFS 文件
在某些情况下,您可能希望在发出提交调用 **之前** 将大型文件上传到 S3。例如,如果您正在提交一个在内存中生成的多个分片中的数据集,则需要逐个上传分片以避免内存不足问题。一种解决方案是将每个分片作为存储库上的单独提交进行上传。虽然完全有效,但此解决方案的缺点是可能会通过生成数十个提交来弄乱 git 历史记录。为了克服这个问题,您可以将文件逐个上传到 S3,然后在最后创建一个提交。这可以使用 preupload_lfs_files() 与 create_commit() 结合使用来实现。
这是一种高级用户方法。在绝大多数情况下,直接使用 upload_file()、upload_folder() 或 create_commit() 而不是处理预上传文件的低级逻辑是最佳选择。preupload_lfs_files() 的主要警告是,在实际进行提交之前,上传的文件在 Hub 上的存储库中不可访问。如果您有任何疑问,请随时在我们的 Discord 或 GitHub 问题中联系我们。
这是一个说明如何预上传文件的简单示例
>>> 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
上下文管理器处理四个最常见的 Git 命令:拉取、添加、提交和推送。git-lfs
自动跟踪任何大于 10MB 的文件。在以下示例中,commit
上下文管理器
- 从
text-files
存储库中拉取。 - 添加对
file.txt
所做的更改。 - 提交更改。
- 将更改推送到
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()