前言

在下面的步骤中,我们将看看分享预训练模型到🤗 Hub的最简单方法。有一些工具和实用程序可以帮助我们在Hub上轻松地分享和更新模型,我们将在下面进行探索。

我们鼓励所有训练模型的用户通过分享它们来为社区做出贡献——即使是在非常特定的数据集上训练的模型,分享它们也能帮助其他人,节省他们的时间和计算资源,并提供有用的训练成果。反过来,你也可以从其他人的工作中受益!

创建新模型仓库有三种方法:

  • 使用 push_to_hub API
  • 使用 huggingface_hub Python 库
  • 使用网页界面

一旦你创建了一个仓库,你可以通过 git 和 git-lfs 向其上传文件。在接下来的部分,我们将引导你创建模型仓库并上传文件到这些仓库。

src link: https://huggingface.co/learn/nlp-course/chapter4/3

Operating System: Ubuntu 22.04.4 LTS

参考文档

  1. NLP Course - Sharing pretrained models

使用 push_to_hub API

上传文件到 Hub 最简单的方法是利用 push_to_hub API。

在继续之前,你需要生成一个认证令牌,这样 huggingface_hub API 才知道你是谁,以及你拥有写入权限的命名空间。确保你处于已安装 transformers 的环境中(参见设置)。如果你在笔记本中,你可以使用以下函数进行登录:

1
2
3
from huggingface_hub import notebook_login

notebook_login()

在终端中,你可以运行:

1
huggingface-cli login

在这两种情况下,系统都会提示您输入用户名和密码,这些信息与您登录Hub时使用的信息相同。如果您还没有Hub个人资料,您应该在这里创建一个。

太好了!现在您的身份验证令牌已存储在缓存文件夹中。让我们创建一些仓库吧!

如果您已经使用Trainer API训练了一个模型,将模型上传到Hub最简单的方法是在定义TrainingArguments时设置push_to_hub=True:

1
2
3
4
5
from transformers import TrainingArguments

training_args = TrainingArguments(
"bert-finetuned-mrpc", save_strategy="epoch", push_to_hub=True
)

当您调用trainer.train()时,Trainer会在每次保存模型时(这里每个epoch)将您的模型上传到Hub,并存放在您的命名空间下的一个仓库中。该仓库的名称将与您选择的输出目录(这里是bert-finetuned-mrpc)相同,但您可以通过设置hub_model_id = "a_different_name"来选择一个不同的名称。

要将您的模型上传到您是其成员的组织,只需使用hub_model_id = "my_organization/my_repo_name"进行传递即可。

训练完成后,您应该执行一次最终的trainer.push_to_hub(),以上传您模型的最后一个版本。它还会生成一个模型卡,其中包含所有相关的元数据,报告使用的超参数和评估结果!以下是在此类模型卡中可能找到的内容示例:

在更低的层面上,可以直接通过模型的push_to_hub()方法访问模型Hub,包括模型、分词器和配置对象。此方法负责创建仓库以及将模型和分词器文件直接推送到仓库,无需像我们下面将看到的API那样进行手动处理。

为了了解其工作原理,让我们首先初始化一个模型和一个分词器:

1
2
3
4
5
6
from transformers import AutoModelForMaskedLM, AutoTokenizer

checkpoint = "camembert-base"

model = AutoModelForMaskedLM.from_pretrained(checkpoint)
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

您可以自由地对这些进行任何操作——向分词器添加标记,训练模型,对其进行微调。一旦您对结果模型、权重和分词器感到满意,您可以直接利用模型对象上可用的push_to_hub()方法:

1
model.push_to_hub("dummy-model")

这将在您的个人资料中创建一个名为 dummy-model 的新仓库,并使用您的模型文件填充它。对分词器也执行相同的操作,以便现在所有文件都可用在这个仓库中:

1
tokenizer.push_to_hub("dummy-model")

如果您属于某个组织,只需指定 organization 参数即可上传到该组织的命名空间:

1
tokenizer.push_to_hub("dummy-model", organization="huggingface")

如果您希望使用特定的 Hugging Face 令牌,您也可以自由地将其指定给 push_to_hub() 方法:

1
tokenizer.push_to_hub("dummy-model", organization="huggingface", use_auth_token="<TOKEN>")

现在前往模型中心查找您新上传的模型:https://huggingface.co/user-or-organization/dummy-model。

点击“文件和版本”标签,您应该会看到如下屏幕截图中的文件:

正如您所看到的,push_to_hub() 方法接受多个参数,使得可以上传到特定的仓库或组织命名空间,或者使用不同的 API 令牌。我们建议您查看 🤗 Transformers 文档中直接提供的方法规范,以了解有哪些可能性。

push_to_hub() 方法由 huggingface_hub Python 包支持,该包为 Hugging Face Hub 提供了一个直接的 API。它被集成在 🤗 Transformers 和其他几个机器学习库中,如 allenlp。虽然我们在本章中关注的是 🤗 Transformers 的集成,但将其集成到您自己的代码或库中是非常简单的。

跳到最后一个部分,了解如何将文件上传到您新创建的仓库!

使用 huggingface_hub Python 库

huggingface_hub Python 库是一个提供模型和数据集中心工具集的包。它提供了简单的方法和类,用于常见的任务,如获取中心上仓库的信息和管理它们。它提供了简单的 API,这些 API 在 git 之上工作,以管理这些仓库的内容,并将 Hub 集成到您的项目和库中。

与使用 push_to_hub API 类似,这也需要您将 API 令牌保存在缓存中。为了做到这一点,您需要使用上一节中提到的 CLI 中的 login 命令(同样,如果在 Google Colab 中运行,请确保在这些命令前加上 ! 字符):

1
huggingface-cli login

huggingface_hub 包提供了几种方法和类,这对我们的目的非常有用。首先,有一些方法可以管理仓库的创建、删除等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from huggingface_hub import (
# User management
login,
logout,
whoami,

# Repository creation and management
create_repo,
delete_repo,
update_repo_visibility,

# And some methods to retrieve/change information about the content
list_models,
list_datasets,
list_metrics,
list_repo_files,
upload_file,
delete_file,
)

此外,它还提供了非常强大的 Repository 类来管理本地仓库。在接下来的几个部分中,我们将探索这些方法和那个类,以了解如何利用它们。

create_repo 方法可用于在中心创建新仓库:

1
2
3
from huggingface_hub import create_repo

create_repo("dummy-model")

这将在您的命名空间中创建名为 dummy-model 的仓库。如果您愿意,您可以使用 organization 参数指定该仓库应属于哪个组织:

1
2
3
from huggingface_hub import create_repo

create_repo("dummy-model", organization="huggingface")

这将创建一个名为 dummy-model 的仓库,假设您属于该组织。其他可能有用的参数包括:

  • private,用于指定仓库是否应对其他人可见。
  • token,如果您想用给定的令牌覆盖缓存中的令牌。
  • repo_type,如果您想创建一个数据集或空间而不是模型。接受的值有 “dataset” 和 “space”。

一旦创建了仓库,我们应该向其中添加文件!跳到下一节,看看如何处理这个问题。

使用网页界面

网页界面提供了在 Hub 中直接管理仓库的工具。使用这个界面,您可以轻松创建仓库,添加文件(甚至是大型文件!),探索模型,可视化差异,以及更多功能。

要创建一个新仓库,请访问 huggingface.co/new:

首先,指定仓库的所有者:这可以是你或你所属的任何一个组织。如果你选择一个组织,该模型将出现在组织的页面上,并且该组织的每个成员都将有权限为该仓库做出贡献。

接下来,输入你的模型名称。这同时也将是仓库的名称。最后,你可以指定你的模型是公开的还是私有的。私有模型对公众是不可见的。

创建你的模型仓库后,你应该会看到一个类似这样的页面:

这是你的模型将被托管的地方。要开始填充内容,你可以直接从网页界面添加一个 README 文件。

README 文件使用 Markdown 格式——随意发挥吧!本章的第三部分专门介绍如何构建模型卡。模型卡对于提升你模型的价值至关重要,因为这是你告诉他人你的模型能做什么的地方。

如果你查看“文件和版本”标签,你会看到那里还没有很多文件——只有你刚刚创建的 README.md 文件和用于跟踪大文件的 .gitattributes 文件。

接下来,我们将了解如何添加一些新文件。

上传模型文件

Hugging Face Hub 上管理文件的系统基于 git 用于常规文件,以及 git-lfs(即 Git 大文件存储)用于更大的文件。

在下一节中,我们将介绍三种不同的方法将文件上传到 Hub:通过 huggingface_hub 和通过 git 命令。

upload_file 方法

使用 upload_file 方法不需要在你的系统上安装 git 和 git-lfs。它使用 HTTP POST 请求直接将文件推送到 🤗 Hub。这种方法的一个限制是它不能处理大于 5GB 的文件。如果您的文件大于 5GB,请按照下面详细说明的另外两种方法操作。

API 可以按照以下方式使用:

1
2
3
4
5
6
7
from huggingface_hub import upload_file

upload_file(
"<path_to_file>/config.json",
path_in_repo="config.json",
repo_id="<namespace>/dummy-model",
)

这将上传位于 <path_to_file> 的文件 config.json 到仓库的根目录下,作为 dummy-model 仓库的 config.json。其他可能有用的参数包括:

  • token,如果你想要用给定的 token 覆盖存储在你缓存中的 token。
  • repo_type,如果你想要上传到数据集或空间而不是模型。接受的值有 “dataset” 和 “space”。

仓库类

仓库类以类似于 git 的方式管理本地仓库。它抽象了人们可能在使用 git 时遇到的大部分痛点,以提供我们所需要的功能。

使用这个类需要安装 git 和 git-lfs,所以在开始之前,请确保你已经安装了 git-lfs(安装说明请参见这里)并进行了设置。

为了开始使用我们刚刚创建的仓库,我们可以通过克隆远程仓库将其初始化到本地文件夹中:

1
2
3
from huggingface_hub import Repository

repo = Repository("<path_to_dummy_folder>", clone_from="<namespace>/dummy-model")

这在我们的工作目录中创建了文件夹 <path_to_dummy_folder>。这个文件夹只包含 .gitattributes 文件,因为这是通过 create_repo 实例化仓库时创建的唯一文件。

从这一点开始,我们可以利用几个传统的 git 方法:

1
2
3
4
5
repo.git_pull()
repo.git_add()
repo.git_commit()
repo.git_push()
repo.git_tag()

还有其他的!我们建议查看这里可用的 Repository 文档,以了解所有可用方法的总览。

目前,我们有一个模型和一个分词器,我们想要推送到 hub。我们已经成功克隆了仓库,因此我们可以将文件保存在该仓库中。

我们首先确保我们的本地克隆是最新的,方法是拉取最新的更改:

1
repo.git_pull()

一旦完成,我们保存模型和分词器文件:

1
2
model.save_pretrained("<path_to_dummy_folder>")
tokenizer.save_pretrained("<path_to_dummy_folder>")

现在 <path_to_dummy_folder> 包含了所有的模型和分词器文件。我们遵循通常的 git 工作流程,将文件添加到暂存区,提交它们,然后将它们推送到 hub:

1
2
3
repo.git_add()
repo.git_commit("Add model and tokenizer files")
repo.git_push()

恭喜!你刚刚在 hub 上推送了你的第一个文件。

基于 git 的方法

这是上传文件的最基本方法:我们将直接使用 git 和 git-lfs。之前的 方法抽象了大部分困难,但以下方法有一些注意事项,所以我们将遵循一个更复杂的使用案例。

使用这个类需要安装 git 和 git-lfs,所以在开始之前,请确保你已经安装了 git-lfs(安装说明请参见这里)并进行了设置。

首先初始化 git-lfs:

1
git lfs install
1
2
Updated git hooks.
Git LFS initialized.

一旦完成,第一步是克隆你的模型仓库:

1
git clone https://huggingface.co/<namespace>/<your-model-id>

我的用户名是 lysandre,我使用的模型名是 dummy,所以对我来说,命令最终看起来像下面这样:

1
git clone https://huggingface.co/lysandre/dummy

现在我的工作目录中有一个名为 dummy 的文件夹。我可以 cd 进入该文件夹并查看内容:

1
cd dummy && ls
1
README.md

如果你刚刚使用 Hugging Face Hub 的 create_repo 方法创建了你的仓库,这个文件夹应该只包含一个隐藏的 .gitattributes 文件。如果你按照上一节的说明使用网页界面创建了一个仓库,这个文件夹应该包含一个单独的 README.md 文件以及一个隐藏的 .gitattributes 文件,如这里所示。

添加一个常规大小的文件,比如配置文件、词汇文件,或者基本上任何几兆字节的文件,都是像在任何基于 git 的系统中那样完成的。然而,更大的文件必须通过 git-lfs 注册,以便将它们推送到 huggingface.co

让我们回到 Python 一会儿,生成我们想要提交到我们的 dummy 仓库的模型和分词器:

1
2
3
4
5
6
7
8
9
10
11
from transformers import AutoModelForMaskedLM, AutoTokenizer

checkpoint = "camembert-base"

model = AutoModelForMaskedLM.from_pretrained(checkpoint)
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

# Do whatever with the model, train it, fine-tune it...

model.save_pretrained("<path_to_dummy_folder>")
tokenizer.save_pretrained("<path_to_dummy_folder>")

现在我们已经保存了一些模型和分词器工件,让我们再次查看 dummy 文件夹:

1
ls
1
config.json  pytorch_model.bin  README.md  sentencepiece.bpe.model  special_tokens_map.json tokenizer_config.json  tokenizer.json

如果你查看文件大小(例如,使用 ls -lh),你应该会看到模型状态字典文件(pytorch_model.bin)是唯一一个超过 400 MB 的异常值。

✏️ 当从网页界面创建仓库时,.gitattributes 文件会自动设置,将具有某些扩展名(如 .bin 和 .h5)的文件视为大文件,git-lfs 将跟踪它们,而您无需进行任何必要的设置。

我们现在可以像通常使用传统 Git 仓库一样继续操作。我们可以使用 git add 命令将所有文件添加到 Git 的暂存环境:

1
git add .

然后我们可以查看当前暂存的文件:

1
git status
1
2
3
4
5
6
7
8
9
10
11
12
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: .gitattributes
new file: config.json
new file: pytorch_model.bin
new file: sentencepiece.bpe.model
new file: special_tokens_map.json
new file: tokenizer.json
new file: tokenizer_config.json

同样,我们可以使用 git-lfs 的 status 命令来确保它正在跟踪正确的文件:

1
git lfs status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
On branch main
Objects to be pushed to origin/main:


Objects to be committed:

config.json (Git: bc20ff2)
pytorch_model.bin (LFS: 35686c2)
sentencepiece.bpe.model (LFS: 988bc5a)
special_tokens_map.json (Git: cb23931)
tokenizer.json (Git: 851ff3e)
tokenizer_config.json (Git: f0f7783)

Objects not staged for commit:

我们可以看到,除了 pytorch_model.bin 和 sentencepiece.bpe.model 文件由 LFS 处理外,所有文件都由 Git 处理。太好了!

让我们继续最后一步,提交并将文件推送到 huggingface.co 远程仓库:

1
git commit -m "First model version"
1
2
3
4
5
6
7
8
9
[main b08aab1] First model version
7 files changed, 29027 insertions(+)
6 files changed, 36 insertions(+)
create mode 100644 config.json
create mode 100644 pytorch_model.bin
create mode 100644 sentencepiece.bpe.model
create mode 100644 special_tokens_map.json
create mode 100644 tokenizer.json
create mode 100644 tokenizer_config.json

推送可能需要一些时间,具体取决于你的互联网连接速度和文件的大小:

1
git push
1
2
3
4
5
6
7
8
9
Uploading LFS objects: 100% (1/1), 433 MB | 1.3 MB/s, done.
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 288.27 KiB | 6.27 MiB/s, done.
Total 9 (delta 1), reused 0 (delta 0), pack-reused 0
To https://huggingface.co/lysandre/dummy
891b41d..b08aab1 main -> main

如果我们在完成后查看模型仓库,我们可以看到所有最近添加的文件:

用户界面允许你浏览模型文件和提交,并查看每次提交引入的差异:

结语

第二百二十二篇博文写完,开心!!!!

今天,也是充满希望的一天。