介绍
在本章中,我们将深入探讨Hugging Face生态系统的世界,这一平台是机器学习领域的先锋,为最先进的ML模型提供支持。Hugging Face已经成为实践者和研究人员的首选资源,提供了易于使用的库、前沿的ML模型、便捷的模型分享平台以及强大的社区支持。重要的是,Hugging Face提供了多个框架(如TensorFlow、PyTorch等)的库支持。然而,几乎所有的功能都优先支持PyTorch。本章通过全面的分析,旨在帮助读者深入理解Hugging Face生态系统及其各个组成部分,并展示如何利用其功能构建基于PyTorch的Transformer模型。
章节结构
本章包含以下内容:
- 系统资源
- Hugging Face概述及其组成
- 数据集
- 模型
- 在Hugging Face上分享你的模型
- 空间(Spaces)
目标
本章的目标是深入理解Hugging Face生态系统的核心功能和特性,特别是聚焦于transformers、datasets和tokenizers库。你将通过实际的示例学习这些库的使用。本章还将引导你完成开源模型的训练和微调过程,帮助你了解如何在Hugging Face平台上分享你的微调模型。此外,本章将详细介绍如何微调基于stable-diffusion的Dreambooth模型,并通过实际操作展示如何有效地在Hugging Face上分享该模型。通过这一学习过程,你将掌握利用这些先进工具进行项目开发的技能和知识。
系统资源
有关环境设置的详细说明,请参考以下链接:
环境设置说明
激活虚拟环境:
conda activate transformer_learn
为了继续进行本章中的编程任务,请安装以下必要的包:
pip3 install transformers
pip3 install datasets
pip3 install git+https://github.com/huggingface/diffusers
pip3 install accelerate
pip3 install ftfy
pip3 install tensorboard
pip3 install Jinja2
Hugging Face概述
Hugging Face生态系统(huggingface.co/)是一个全面的资源和工具套件,支持最先进深度学习模型的开发、实现和部署。它成立于2016年,旨在通过提供易于使用的工具,帮助更广泛的社区实现人工智能的民主化。具体来说,Hugging Face以其开源的transformer库而闻名,该库已经成为BERT、GPT等基于Transformer的模型的事实标准包。此外,HuggingFace.co还是一个充满活力的社区,社区已经上传了超过15万个模型。
图2.1展示了Hugging Face的用户界面。该界面提供了适用于广泛机器学习任务的数据集和模型,包括多模态、计算机视觉、音频、表格数据和强化学习等领域。此外,界面还允许用户更深入地探索特定子领域。
Hugging Face的关键组件
Hugging Face生态系统由六个主要组件组成,共同构建了一个全面的机器学习平台。表2.1展示了Hugging Face生态系统的关键元素:
序号 | 名称 | 描述 |
---|---|---|
1 | Transformer库 | 一个开源库,提供广泛的预训练模型(超过190个)。 |
2 | 数据集库 | 拥有超过24,000个可直接使用的机器学习数据集。 |
3 | Tokenizer库 | 灵活的库,处理NLP文本数据的预处理和分词。 |
4 | ML集成 | 支持与多个框架的集成(如PyTorch、TensorFlow和JAX/Flax)。所有模型都支持PyTorch,其他框架则有限支持。 |
5 | 推理API | 使用户可以通过几行代码从Hugging Face部署模型。总体而言,支持小到大规模项目的生产就绪模型部署。 |
6 | Hugging Face Spaces | 用户可以在一个用户友好的环境中构建Web应用程序、托管演示并与社区协作。 |
表2.1:Hugging Face的关键组件
接下来,让我们深入了解这些主要组件。
Tokenizers(分词器)
分词器将原始文本转换为小单位(字符、单词、子词),这些单位是NLP处理的基本单元。表2.2展示了分词的主要示例。Hugging Face Tokenizer提供了多个预训练的分词算法,并提供了训练自定义分词器算法的机制。
分词示例
分词级别 | 示例 |
---|---|
字符级别 | ['T', 'h', 'e', ' ', 't', 'o', 'k', 'e', 'n', 'i', 'z', 'e', 'r', 's'] |
单词级别 | ['The', 'Tokenizers'] |
子词级别 | ['the', 'token', '##izer', '##s'] |
表2.2:分词过程
创建自定义分词器
在某些情况下,如在处理医疗等特定领域的专业术语时,您可能需要开发一个自定义分词器。本节将指导您如何创建一个量身定制的分词器,以满足您的特定需求。
训练
以下代码演示了如何:
- 使用您的数据集训练一个分词器;
- 将训练好的分词器保存为JSON文件;
- 使用训练好的分词器进行推理。
请根据您的文件路径修改第4行,提供您计算机上文本文件的路径。附带的文档包含tokenizer_train.txt
文件;不过,您也可以根据自己的使用案例,使用任何文本训练分词器。此外,修改第13行,提供您机器的路径:
from tokenizers import Tokenizer, models, pre_tokenizers, trainers
'''训练'''
# 从文件中读取数据集。txt文件可以在本书的GitHub仓库中找到
with open("/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/datasets/tokenizer_train.txt", "r") as file:
dataset = [line.strip() for line in file.readlines()]
# 初始化BPE分词器。Byte Pair Encoding (BPE) 是一种子词分词技术。
tokenizer = Tokenizer(models.BPE())
# 设置预处理器以将输入拆分为单词
tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()
# 在数据集上训练BPE分词器
trainer = trainers.BpeTrainer(special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])
tokenizer.train_from_iterator(dataset, trainer=trainer)
# 保存训练好的分词器
tokenizer.save("/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/model/tokenizer.json")
推理
现在,让我们使用我们定制的分词器来进行推理。在以下代码中,PreTrainedTokenizerFast
提供了加载预训练分词器的机制:
'''推理'''
from transformers import PreTrainedTokenizerFast
# 加载训练好的分词器
fast_tokenizer = PreTrainedTokenizerFast(tokenizer_file="/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/model/tokenizer.json")
# 输入文本
text = "The Tokenizers"
# 使用分词器对文本进行编码
encoded = tokenizer.encode(text)
# 打印分词后的文本
print(encoded.tokens)
输出:
['T', 'h', 'e', 'T', 'o', 'ken', 'iz', 'ers']
可视化:
from tokenizers.tools import EncodingVisualizer
# 可视化分词过程
visualizer = EncodingVisualizer(fast_tokenizer._tokenizer)
visualizer(text="The Tokenizers")
输出:
图2.2展示了短语 "The Tokenizers" 的分词输出。我们可以看到,分词过程将文本分为8个token,如下所示:
使用Hugging Face的预训练分词器
在以下代码中,我们使用了预训练的分词器 bert-base-uncased
。对于一般的语言处理任务,预训练分词器通常比自定义分词器更有效:
from transformers import BertTokenizer
# 加载预训练的BERT分词器
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
# 对文本进行分词
print(tokenizer.tokenize("The tokenizers"))
输出:
['the', 'token', '##izer', '##s']
当我们将自定义分词器的分词结果(['T', 'h', 'e', 'T', 'o', 'ken', 'iz', 'ers']
)与预训练的 BertTokenizer
的分词结果(['the', 'token', '##izer', '##s']
)进行比较时,可以明显看出,BertTokenizer
的效果要好得多。这是因为我们仅用几行代码训练了自定义分词器。要生产一个最佳的分词器,必须提供足够的训练数据。然而,当我们在需要大量领域特定词汇的专业领域工作时,创建自定义分词器仍然非常有用。
数据集 (Datasets)
Datasets
是一个强大的库,它简化了机器学习中数据集的下载、预处理和管理过程。以下是 Datasets
库的一些显著特点:
- 预加载数据集:它提供了大量的数据集,覆盖多个机器学习任务领域,包括计算机视觉、音频处理、自然语言处理 (NLP)、强化学习等。
- 高效的数据处理与易用性:该库底层使用了 Apache Arrow(一种列式内存数据格式),能够高效地处理和存储数据。此外,它还支持数据版本控制(有助于可复现性),并提供了一个用户界面,帮助快速查看数据集。
- 与 Hugging Face Transformer 和 PyTorch 的集成:
Datasets
库与 Hugging Face 的 Transformer 库兼容,并且可以无缝集成到 PyTorch 框架中。
使用 Hugging Face 数据集
准备数据:在以下示例中,我们下载了 IMDb 数据集并打印了其中的一行数据。正如你在第3行看到的,只需要一行代码就能下载数据集:
from datasets import load_dataset
# 加载 IMDb 电影评论数据集
imdb_dataset = load_dataset("imdb")
# 加载预训练模型和分词器
# 从数据集中选择一条示例文本
sample_text = imdb_dataset["test"][0]["text"]
print(sample_text)
输出:
I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded…..
使用 IMDb 数据集进行情感分析,我们将使用 IMDb 数据集进行情感分析:
from transformers import AutoModelForSequenceClassification, pipeline
from transformers import AutoTokenizer
model_name = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
# 创建情感分析流水线
sentiment_analysis_pipeline = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
# 从数据集中选择一条示例文本
sample_text = imdb_dataset["test"][0]["text"]
# 对示例文本进行情感分析
result = sentiment_analysis_pipeline(sample_text)
# 打印结果
print("Sample Text:", sample_text)
print("Sentiment Analysis Result:", result)
输出:
Sentiment Analysis Result: [{'label': 'NEGATIVE', 'score': 0.999616265296936}]
分析: 这是一个令人兴奋的发展!仅用不到20行代码,我们就能完成端到端的情感分析。你可以根据自己的具体需求定制上述代码。在这段代码中,我们使用了预训练模型 distilbert-base-uncased-finetuned-sst-2-english
,该模型用于分词和推理。这个模型使用了不区分大小写的英语词汇,并且在斯坦福情感树库 (SST-2) 数据集上进行了情感分析任务的微调。需要特别注意的是,在进行推理时,建议使用与模型相同的模型进行分词。
在 PyTorch 中使用 Hugging Face 数据集
直接将 Hugging Face 数据集传递给 DataLoader:在以下代码中,我们使用 torch
格式加载数据集。这将把数据转换为 PyTorch 的 Tensor 格式:
from datasets import load_dataset
from torch.utils.data import DataLoader, Dataset
import torch
# 加载 Hugging Face 数据集(以 IMDb 电影评论数据集为例)
imdb_dataset = load_dataset("imdb").with_format("torch")
查看加载的数据集:我们可以使用 DatasetInfo
查看数据集的信息:
from datasets import DatasetInfo
print(DatasetInfo(imdb_dataset))
输出:
DatasetInfo(description=DatasetDict({
train: Dataset({
features: ['text', 'label'],
num_rows: 25000
})
test: Dataset({
features: ['text', 'label'],
num_rows: 25000
})
unsupervised: Dataset({
features: ['text', 'label'],
num_rows: 50000
}))
分析: imdb_dataset
包含 train
、test
和 unsupervised
三个部分。此外,每一行都包含 text
和 label
两个部分。接下来,让我们创建 DataLoader
:
from torch.utils.data import DataLoader, Dataset
train_loader = DataLoader(imdb_dataset['train'], batch_size=8, shuffle=True)
test_loader = DataLoader(imdb_dataset['test'], batch_size=8, shuffle=False)
附带的 Notebook 文件中包含了我们创建 CustomDataset
类的实现方法。
模型
在 Hugging Face 上,有超过 150,000 个模型可用于各种机器学习任务。在之前的示例中,我们讨论了如何使用预训练的 Transformer 模型对 IMDb 数据集进行情感分析。
本节将重点讨论基于稳定扩散(stable diffusion)的 Dreambooth 实现的微调。Dreambooth 是一个文本到图像的扩散模型,它根据提供的文本输入生成图像。通常,文本到图像的模型可以根据提示生成图像,例如“一个人在攀登珠穆朗玛峰”。然而,如果你希望模型生成一幅你攀登珠穆朗玛峰的图像,可以使用 Dreambooth 微调模型,只需要几张你的图片。一旦模型微调完成,它就能够生成任何包含你进行某项活动的图像。这使得 Dreambooth 成为一种有效的以主题为驱动的图像生成工具。
环境设置
请激活你的 Conda 环境,并在终端中输入以下命令。根据提示输入必要的参数。
accelerate config
accelerate config
命令通常用于设置 Accelerate 库的默认参数,例如精度模式(例如混合精度或全精度)、梯度累积设置以及其他相关参数。在执行任何 PyTorch 脚本代码之前,必须先运行此命令,以确保 Accelerate 库正确配置。
训练
确保从 GitHub 下载 train_dreambooth.py
并将其保存在计算机上。你可以通过以下链接获取该文件:GitHub - Dreambooth Example。
请在终端中运行以下命令,这将开始训练 Dreambooth 模型:
export MODEL_NAME="CompVis/stable-diffusion-v1-4"
export INSTANCE_DIR="/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/datasets/dreambooth/photo"
export OUTPUT_DIR="/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/datasets/dreambooth/model"
accelerate launch train_dreambooth.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--instance_data_dir=$INSTANCE_DIR \
--output_dir=$OUTPUT_DIR \
--instance_prompt="a photo of sks boy" \
--resolution=512 \
--train_batch_size=1 \
--gradient_accumulation_steps=1 \
--learning_rate=5e-6 \
--lr_scheduler="constant" \
--lr_warmup_steps=0 \
--max_train_steps=1000
为了更好地理解上面提到的参数,我们将详细探讨它们的含义。
参数说明
- MODEL_NAME:指定基础模型的名称。在这个例子中,我们使用的是稳定扩散模型(
stable-diffusion-v1-4
)。 - INSTANCE_DIR:指定用于微调模型的照片位置。我们建议使用 5-10 张 PNG 格式的图片。我在微调中使用了这三张照片。你可以使用任何主题的照片,包括猫、花朵、你自己等。然而,带有清晰面部和透明背景的照片效果较好。
通过微调模型,我们可以使其生成符合我们需求的图像,尤其是在特定领域或自定义任务中。
第三个变量是 OUTPUT_DIR,它指定了微调模型将被保存的目录。在运行代码之前,请确保该目录为空。
instance_prompt 参数是一个关键标识符,在推理过程中是必需的。在提供的代码中,instance_prompt
被设置为“a photo of sks boy”。请确保为训练过程提供适当的标识符,因为在推理时它将用于准确的图像生成。
模型的总训练时间可能会根据你的计算机规格和加速配置有所不同。通常,整个训练过程需要 30 分钟到 1 小时。以我为例,我在配备 M2 Max 处理器和 32GB RAM 的 Mac 上进行训练,整个过程花费了 45 分钟。
推理
你已经成功创建了 Dreambooth 模型。接下来,让我们使用该模型,通过提供不同的提示词来生成图像:
from diffusers import StableDiffusionPipeline
import torch
model_id = "/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/datasets/dreambooth/model/"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16).to("mps")
prompt = "a photo of sks boy riding horse"
image = pipe(prompt, num_inference_steps=500, guidance_scale=7.5).images[0]
image.save("/Users/premtimsina/Documents/bpbbook/chapter2_huggingFace/datasets/dreambooth/photo/boy_ridding_horse.png")
解释:
- 在代码的第 4 行,我们将张量转换为
mps
格式,这是因为在 Mac 系统上运行代码时需要此格式。然而,如果你是在 GPU 上运行代码,应该将张量转换为cuda
格式。 - 确保张量的格式正确非常重要,否则在执行代码时可能会出现错误。如果遇到问题,请仔细检查张量的格式,并根据需要做出调整。
- 此外,请注意,在第 6 行,提示词以“a photo of sks boy”开头。我们在训练过程中为此提供了这个标识符,在推理过程中,你的标识符应该始终以此为开头。
图 2.4 展示了由自定义 DreamBooth 模型生成的图像。我们的模型生成的图像看起来相当不错,面部特征似乎匹配。如果你想生成高质量的图像,可以通过实验和优化训练参数来实现。
以下是推理生成的一些图像示例:
这太棒了!只需几行代码,我们就能创建一个根据指定主题生成图像的文本到图像生成器。
在 Hugging Face 上分享你的模型
在这一部分,我们将介绍如何将你的模型分享到 Hugging Face,并通过 Gradle 创建一个空间。关于这一过程的详细说明可以在随附的笔记本中找到。模型成功共享后,它将在你的 Hugging Face 账户中显示如下。
模型
下图展示了 Huggingface.co 上的 dreambooth_boy 模型,您可以在其中输入一个提示词,并根据所给的提示词生成相应的图像,如图所示:
Spaces
以下截图展示了我们的 Dreambooth-boy 模型对应的 Space。Hugging Face Spaces 提供了一种简便的方法来开发基于您模型的应用程序。具体来说,您可以执行以下任务:
- 部署您的模型
- 托管 Jupyter notebooks
- 使用 Gradio 设计用户友好的界面
- 使用 Streamlit 创建交互式 Web 应用程序
- 与协作者共享您的 Space,让多人共同开发同一个应用
总结
在本章中,我们详细探讨了 Hugging Face 生态系统,这一在机器学习领域具有重要地位的工具。我们重点介绍了其核心组件——Transformers、Datasets 和 Tokenizers 库,并展示了如何在实际场景中应用这些工具。我们还学习了如何为特定任务微调模型,并将其分享到 Hugging Face 平台,使其能够为他人所用。通过这段学习旅程,我们对如何在各种项目中使用这些先进技术有了实践性的理解,特别是如何将 Dreambooth 模型调整为个性化的用途。
Hugging Face 生态系统作为一个多功能、全面的资源,在 AI 领域,尤其是在 Transformer 基础模型方面,具有突出的优势。它提供了多种功能,从创建自定义 Tokenizer 到利用预训练模型。通过探索其能力,我们为您提供了知识和技能,使您能够充分利用 Hugging Face 的创新工具,拓展机器学习的广阔可能性。通过本章内容,您已经为深入 AI 世界做好了准备,并将 Hugging Face 生态系统作为未来项目的坚实基础。