Hugging Face Transformers 库
bash pip install transformers
### 选择深度学习框架
Transformers 背后需要依赖 PyTorch、TensorFlow 或 Flax。最常用的是 PyTorch,你可以根据实际情况安装:
```bash
# PyTorch(推荐)
pip install torch
# 或者安装 TensorFlow
pip install tensorflow
如果你希望支持多种框架,可以单独安装,也可以在安装时指定附加项:
pip install transformers[torch]
pip install transformers[tf-cpu]
其他常用依赖
为了后续数据处理和模型训练,还经常用到 datasets 和 tokenizers 库,它们也会被 transformers 自动依赖:
pip install datasets tokenizers
安装完成后,可以在 Python 中验证:
import transformers
print(transformers.__version__)
核心组件:模型、分词器与配置
Transformers 库的设计围绕着三个核心抽象类:PreTrainedModel、PreTrainedTokenizer 和 PretrainedConfig。理解它们能让你快速上手任何模型。
配置(Config)
配置对象存储了模型的超参数,比如层数、隐藏单元维度、注意力头数等。你可以直接加载预训练模型的配置:
from transformers import BertConfig
config = BertConfig.from_pretrained("bert-base-uncased")
print(config)
你也可以修改其中的参数,然后创建随机初始化的模型(不加载预训练权重):
my_config = BertConfig(hidden_size=512, num_hidden_layers=8)
model = BertModel(my_config)
分词器(Tokenizer)
分词器负责将原始文本转换为模型可以接受的输入张量,主要包括分词、添加特殊标记、转换为 ID、生成注意力掩码等步骤。所有分词器都继承自 PreTrainedTokenizer 基类。
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
text = "Hugging Face is creating a tool that democratizes AI."
tokens = tokenizer.tokenize(text)
print(tokens)
# ['hugging', 'face', 'is', 'creating', 'a', 'tool', 'that', 'democrat', '##izes', 'ai', '.']
input_ids = tokenizer.encode(text, add_special_tokens=True)
print(input_ids)
# [101, 17662, 12172, 2003, ...]
对于生成任务(如 GPT 系列),分词器还会支持填充到最大长度、生成注意力掩码等:
encoded = tokenizer(text, padding="max_length", truncation=True, max_length=20, return_tensors="pt")
print(encoded.keys())
# dict_keys(['input_ids', 'token_type_ids', 'attention_mask'])
模型(Model)
模型是核心计算单元。大部分模型都有对应的预训练版本,通过 from_pretrained 加载预训练权重:
from transformers import BertModel
model = BertModel.from_pretrained("bert-base-uncased")
outputs = model(**encoded)
print(outputs.last_hidden_state.shape)
# torch.Size([1, 20, 768])
对于不同的任务头部,Transformers 提供了带特定输出头的模型类。例如,对于序列分类,有 BertForSequenceClassification;对于问答,有 BertForQuestionAnswering 等。这些类都直接支持从预训练权重加载,并会在顶层添加合适的线性层。
模型推理:Pipeline 极简接口
如果你只是想快速体验一个模型的效果,pipeline() 函数是最快的方式。它封装了模型加载、分词、推理和后处理全过程。
文本情感分析
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
result = classifier("I love using Hugging Face Transformers!")
print(result)
# [{'label': 'POSITIVE', 'score': 0.9998}]
默认情况下,pipeline 会选择一个预训练模型(通常是 DistilBERT 或 RoBERTa 的小版本)。你也可以通过 model 参数指定其他模型:
classifier = pipeline("sentiment-analysis", model="cardiffnlp/twitter-roberta-base-sentiment-latest")
零样本分类
零样本分类允许不提供任何标注数据的情况下进行分类:
classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
result = classifier(
"A new breakthrough in COVID-19 treatment announced",
candidate_labels=["health", "sports", "politics", "technology"],
)
print(result["labels"])
# ['health', 'technology', 'politics', 'sports']
文本生成
使用 GPT 类模型进行补全式生成:
generator = pipeline("text-generation", model="gpt2")
result = generator("In the future, AI will", max_length=50, num_return_sequences=1)
print(result[0]["generated_text"])
其他常见 Pipeline
| 任务类型 | Pipeline 标识 | 示例模型 |
|---|---|---|
| 命名实体识别 | "ner" |
dbmdz/bert-large-cased-finetuned-conll03-english |
| 自动语音识别 | "automatic-speech-recognition" |
openai/whisper-small |
| 文本摘要 | "summarization" |
facebook/bart-large-cnn |
| 翻译 | "translation_xx_to_yy" |
Helsinki-NLP/opus-mt-en-de |
| 图像分类 | "image-classification" |
google/vit-base-patch16-224 |
| 问答 | "question-answering" |
distilbert-base-cased-distilled-squad |
Pipeline 会针对不同任务自动选择合适的默认模型,也允许你传入 tokenizer 和 model 进行自定义。
手动使用模型和分词器
虽然 Pipeline 很方便,但实际开发中往往需要更细粒度的控制。手动使用模型和分词器可以灵活地处理数据流、自定义后处理。
编码输入
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained("nlptown/bert-base-multilingual-uncased-sentiment")
model = AutoModelForSequenceClassification.from_pretrained("nlptown/bert-base-multilingual-uncased-sentiment")
使用 AutoTokenizer 和 AutoModel 可以根据模型名称自动推断正确的分词器和模型类,是推荐的做法。
编码单条或多条文本:
texts = ["I am very happy!", "This product is disappointing."]
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
前向传播
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
outputs 是一个包含各种张量的命名元组,不同模型会提供不同的属性(比如 last_hidden_state, pooler_output 等)。对于分类模型,通常直接使用 logits。
后处理
将 logits 转换为概率分布:
import torch.nn.functional as F
probs = F.softmax(logits, dim=-1)
ratings = torch.argmax(probs, dim=-1)
# 该模型输出1-5星评分,需要加1转换为1~5
print(ratings + 1)
如果模型是中文情感分类,可能需要查看分词器的 id2label 属性来获取类别名称:
predicted_class = torch.argmax(logits, dim=-1).item()
label = model.config.id2label[predicted_class]
print(label)
微调模型:Trainer API
在实际项目中,我们经常需要在自己的数据集上微调预训练模型。Transformers 提供了 Trainer 类来简化训练循环。
数据准备
使用 datasets 库加载或构建数据集:
from datasets import load_dataset
dataset = load_dataset("imdb")
print(dataset)
定义分词函数,将文本转换为模型可接受的格式:
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
加载模型
针对二分类情感分析,使用 AutoModelForSequenceClassification,并设置标签数量:
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
定义训练参数
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
save_strategy="epoch",
num_train_epochs=3,
per_device_train_batch_size=16,
per_device_eval_batch_size=64,
logging_dir="./logs",
learning_rate=2e-5,
weight_decay=0.01,
)
创建 Trainer 并开始训练
from transformers import Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"].shuffle(seed=42).select(range(2000)), # 示例只用 2000 条
eval_dataset=tokenized_datasets["test"].shuffle(seed=42).select(range(500)),
tokenizer=tokenizer,
)
trainer.train()
训练完成后,模型权重的保存与加载:
model.save_pretrained("./my_finetuned_model")
tokenizer.save_pretrained("./my_finetuned_model")
重新加载:
model = AutoModelForSequenceClassification.from_pretrained("./my_finetuned_model")
tokenizer = AutoTokenizer.from_pretrained("./my_finetuned_model")
进阶技巧与注意事项
使用 GPU 加速
将模型移动到 GPU 上只需一行:
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
在 pipeline 中可以通过 device 参数指定:
generator = pipeline("text-generation", model="gpt2", device=0)
梯度累积与混合精度
在 TrainingArguments 中开启混合精度训练可以节省显存并加速:
training_args = TrainingArguments(
fp16=True, # 需要支持半精度的 GPU
gradient_accumulation_steps=4,
)
自定义模型输出处理
有时我们需要取出隐藏状态用于可视化或进一步计算,可以在前向传播时设置 output_hidden_states=True:
outputs = model(input_ids=encoded["input_ids"], output_hidden_states=True)
hidden_states = outputs.hidden_states # 元组,每层一个张量