Hub Python 库文档
上传文件到 Hub
并获得增强的文档体验
开始使用
上传文件到 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
参数来过滤要上传的文件。这些参数接受单个模式或模式列表。模式是此处文档中描述的标准通配符(globbing 模式)。如果同时提供了 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 上传
你可以使用终端的 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_path
和 path_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_message
和commit_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
:- 安装
huggingface_hub
时指定hf_transfer
额外依赖(即,pip install huggingface_hub[hf_transfer]
)。 - 将
HF_HUB_ENABLE_HF_TRANSFER=1
设置为环境变量。
- 安装
hf_transfer
是一个用于上传 LFS 文件的超级用户工具!它经过测试,已达到生产就绪状态,但它未来的适用性较差,并且缺少用户友好的功能,例如高级错误处理或代理。有关更多详细信息,请查看此部分。
请注意,hf_xet
和 hf_transfer
工具是互斥的。前者用于将文件上传到启用 Xet 的仓库,而后者将 LFS 文件上传到常规仓库。
高级功能
在大多数情况下,你只需要 upload_file() 和 upload_folder() 即可将文件上传到 Hub。但是,huggingface_hub
具有更高级的功能,可以使操作更简单。让我们看看它们!
更快的上传
通过 hf_xet
利用更快的上传,它是 xet-core
库的 Python 绑定,可实现基于块的重复数据删除,从而加快上传和下载速度。hf_xet
与 huggingface_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_path
和path_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 仓库中的一个文件:
- 使用适当的
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 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
上下文管理器:
- 从
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
请参阅下表了解可能的 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()