Transformer 是一种使用注意力机制处理数据的机器学习模型架构。许多模型都基于这种架构,例如 GPT、BERT、T5 和 Llama。其中许多模型彼此相似。虽然你可以使用 PyTorch 或 TensorFlow 在 Python 中构建自己的模型,但 Hugging Face 发布了一个库,可以更轻松地创建这些模型,并提供了许多你可以使用的预训练模型。该库的名字并不重要,就是 `transformers`。在本文中,你将学习如何使用这个库。
通过我的书籍《Hugging Face Transformers中的NLP》,快速启动您的项目。它提供了带有工作代码的自学教程。
让我们开始吧。

Transformers 库温和入门
照片由 sdl sanjaya 拍摄。部分权利保留。
什么是 Transformer 库?
Transformer 库是一个 Python 库,为处理不同的 Transformer 模型提供了统一的接口。它并非详尽无遗,但定义了许多知名的开源模型,如 GPT、BERT、T5 和 Llama。虽然它不是许多这些模型的官方库,但它们的架构是相同的。这个库的优点在于它统一了不同模型的接口。例如,你知道 BERT 和 T5 都可以生成文本;你不需要了解它们之间的架构差异,但仍然可以通过相同的函数调用来使用它们。
Hugging Face Hub 是一个机器学习资源库,包括预训练模型。作为模型的使用者,你可以在自己的项目中使用它们,而无需了解其背后的机制。如果你想使用模型,例如 GPT,你可以在 Hub 中找到模型的名称并在 Transformer 库中使用它。该库将下载模型,弄清楚它正在使用哪种架构,然后创建模型并加载权重,所有这些都在一行代码中完成。

Hugging Face Hub
Transformer 库使你无需成为机器学习模型专家,就能轻松地在项目中使用 Transformer 模型。
安装
安装非常简单。你可以使用 pip 来安装该库
1 |
pip install transformers |
这将安装该库及其所有依赖项。支持的模型通常使用三个框架构建:PyTorch、TensorFlow 和 JAX/Flax。调用该库时,你可以选择使用其中一个。大多数模型默认使用 PyTorch。
这足以开始一个项目,例如在自己的数据上创建和训练新模型。但是,Hugging Face Hub 上的一些预训练模型要求你拥有 Hugging Face 帐户。你可以免费注册一个。此外,有些模型是“受限”的,这意味着你需要请求访问权限才能使用它们。从 Transformer 库使用这些模型需要你使用访问令牌进行身份验证。
要注册 Hugging Face 帐户,请访问网站 https://hugging-face.cn/join。拥有帐户后,你就可以创建访问令牌。你可以通过访问 访问令牌页面 来完成此操作。获得令牌后,请务必记住它,因为它在创建时仅显示一次。

注册帐户

创建访问令牌以与 Transformer 库一起使用
使用该库
该库非常易于使用。让我们看看如何使用它来加载预训练模型。
1 2 3 4 5 6 7 8 9 10 11 12 |
import torch from transformers import AutoTokenizer, AutoModelForCausalLM model_id = "bert-base-uncased" tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained(model_id) input_ids = tokenizer("Hello, world!", return_tensors="pt") with torch.no_grad(): outputs = model(**input_ids) output_tokens = outputs.logits.argmax(dim=-1) output_text = tokenizer.decode(output_tokens[0], skip_special_tokens=True) print(output_text) |
这并不是使用 Transformer 库的最简洁的代码,但它展示了主要思想。它创建了一个将输入文本转换为整数令牌的分词器,然后创建了一个处理这些令牌并返回输出的模型。
所有预训练模型都由模型 ID 标识。当你创建一个预训练模型所需的分词器时,它会与预训练模型的配置进行检查以实例化正确的分类器对象,模型也是如此。因此,你只需使用 `AutoTokenizer` 和 `AutoModel`,而不是特定的类,例如 `BertTokenizer` 和 `BertModel`。了解 Transformer 模型通常如何工作,你应该期望核心模型接受输入令牌并输出 logit 张量。因此,你在上面使用 `argmax` 将 logits 转换为令牌 ID,并使用分词器的 `decode` 方法将 ID 转换为字符串。
但是,如果你想使用受限模型并执行上述代码,则必须提供访问令牌。设置访问令牌的方法是使用一些环境变量。你可以在文档中找到所有对 Transformer 库重要的环境变量;最重要的几个是:
HF_TOKEN
:访问令牌。HF_HOME
:用于存储缓存模型的目录。
你应该在运行脚本之前将它们设置为环境变量,或者像下面这样操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import os os.environ["HF_TOKEN"] = "hf_YourTokenHere" os.environ["HF_HOME"] = "~/.cache/huggingface" from transformers import AutoTokenizer, AutoModelForCausalLM model_id = "meta-llama/Llama-3.2-1B" tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained(model_id) input_ids = tokenizer("Hello, world!", return_tensors="pt") with torch.no_grad(): outputs = model(**input_ids) output_tokens = outputs.logits.argmax(dim=-1) output_text = tokenizer.decode(output_tokens[0], skip_special_tokens=True) print(output_text) |
请注意,环境变量应在导入 Transformer 库之前设置为 `os.environ`。上面使用的模型 `meta-llama/Llama-3.2-1B` 是一个受限模型的示例,你需要请求访问权限并通过访问令牌进行身份验证才能使用它。
Pipeline 和任务
如果预训练模型可以帮助你完成文本生成任务,你为什么还要关心分词器和 logit 输出等细节呢?因此,`transformers` 库提供了一个 `pipeline` 函数来执行不同的任务,同时隐藏了所有这些细节。下面是一个使用 `pipeline` 函数执行情感分析任务的示例:
1 2 3 4 5 6 |
from transformers import pipeline model_id = "distilbert-base-uncased-finetuned-sst-2-english" classifier = pipeline("sentiment-analysis", model=model_id) result = classifier("Machine Learning Mastery is a great website for learning machine learning.") print(result) |
`pipeline` 函数将创建模型和分词器,用预训练的权重加载它们,并执行你指定的任务。所有这些都在一行代码中完成。你无需关心不同组件如何协同工作。
`pipeline` 函数的第一个参数是任务名称。该库支持的任务很少,其中一些与图像和音频处理有关。在文本处理领域最常见的任务是:
text-generation
:以自动补全方式生成文本。这可能是最常用的任务。sentiment-analysis
:情感分析,通常用于预测给定文本的“积极”或“消极”情感。`text-classification` 任务与此任务相同。zero-shot-classification
:零样本分类。也就是说,向模型提供一个句子和一组标签,让模型预测最能描述该句子的标签。question-answering
:问答。这不应与 `text-generation` 任务混淆,后者可以回答开放式问题。此任务根据提供的上下文为给定问题生成答案。
你可以仅使用任务名称来启动 pipeline。所有任务都有默认模型。如果你希望使用不同的模型,可以指定模型 ID,如上面的示例所示。
如果你有兴趣,可以检查 pipeline 对象以查看它正在使用哪种模型。例如,上面的 `classifier` 对象使用 `DistilBertForSequenceClassification` 模型。你可以使用以下方法进行检查:
1 2 3 |
... print(classifier.model) print(classifier.tokenizer) |
输出将是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
DistilBertForSequenceClassification( (distilbert): DistilBertModel( (embeddings): Embeddings( (word_embeddings): Embedding(30522, 768, padding_idx=0) (position_embeddings): Embedding(512, 768) (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True) (dropout): Dropout(p=0.1, inplace=False) ) (transformer): Transformer( (layer): ModuleList( (0-5): 6 x TransformerBlock( (attention): DistilBertSdpaAttention( (dropout): Dropout(p=0.1, inplace=False) (q_lin): Linear(in_features=768, out_features=768, bias=True) (k_lin): Linear(in_features=768, out_features=768, bias=True) (v_lin): Linear(in_features=768, out_features=768, bias=True) (out_lin): Linear(in_features=768, out_features=768, bias=True) ) (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True) (ffn): FFN( (dropout): Dropout(p=0.1, inplace=False) (lin1): Linear(in_features=768, out_features=3072, bias=True) (lin2): Linear(in_features=3072, out_features=768, bias=True) (activation): GELUActivation() ) (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True) ) ) ) ) (pre_classifier): Linear(in_features=768, out_features=768, bias=True) (classifier): Linear(in_features=768, out_features=2, bias=True) (dropout): Dropout(p=0.2, inplace=False) ) DistilBertTokenizerFast(name_or_path='distilbert-base-uncased-finetuned-sst-2-english', vocab_size=30522, model_max_length=512, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True, added_tokens_decoder={ 0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True), 100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True), 101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True), 102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True), 103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True), } ) |
从上面的输出可以看出,模型是 `DistilBertForSequenceClassification`,分词器是 `DistilBertTokenizerFast`。你确实可以使用以下代码直接创建模型和分词器:
1 2 3 4 5 |
from transformers import DistilBertForSequenceClassification, DistilBertTokenizerFast model_id = "distilbert-base-uncased-finetuned-sst-2-english" model = DistilBertForSequenceClassification.from_pretrained(model_id) tokenizer = DistilBertTokenizerFast.from_pretrained(model_id) |
但是,你需要自己处理输入文本并运行模型。在这方面,pipeline 函数是一种便利。
进一步阅读
以下是一些你可能觉得有用的文章:
- Transformers 库文档: https://hugging-face.cn/docs/transformers/en/index
- Hugging Face 模型中心: https://hugging-face.cn/models
- Pipeline 文档: https://hugging-face.cn/docs/transformers/v4.49.0/en/main_classes/pipelines
总结
在本文中,你学习了如何使用 Transformer 库加载预训练模型并使用它来执行任务。特别是,你学习了:
- 如何使用 Transformer 库创建模型并用它来执行任务。
- 使用 `pipeline` 函数来处理预训练模型的不同任务。
- 如何检查 pipeline 对象以查看它正在使用哪种模型。
暂无评论。