翻译¶
翻译是将一段文本从一种语言转换为另一种语言的过程。它是可以表述为序列到序列(sequence-to-sequence)问题的几种任务之一,这是一个强大的框架,用于从输入返回某些输出,如翻译或总结。翻译系统通常用于不同语言文本之间的翻译,但也可以用于语音或两者之间的某种组合,如文本到语音或语音到文本。
本指南将向您展示如何:
- 在 OPUS Books 数据集的英语-法语子集上微调 T5,以将英语文本翻译成法语。
- 使用您微调的模型进行推理。
要查看与该任务兼容的所有架构和检查点,建议查看 任务页面。
在开始之前,请确保已安装所有必要的库:
pip install transformers datasets evaluate sacrebleu
我们鼓励您登录您的 Hugging Face 账户,以便您可以上传并与社区分享您的模型。当提示时,输入您的令牌以登录:
from huggingface_hub import notebook_login
notebook_login()
加载 OPUS Books 数据集¶
首先从 🤗 Datasets 库中加载 OPUS Books 数据集的英语-法语子集:
from datasets import load_dataset
books = load_dataset("opus_books", "en-fr")
使用 train_test_split 方法将数据集分为训练集和测试集:
books = books["train"].train_test_split(test_size=0.2)
然后查看一个示例:
books["train"][0]
from transformers import AutoTokenizer
checkpoint = "google-t5/t5-small"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
您要创建的预处理函数需要:
- 在输入前添加提示,以便 T5 知道这是翻译任务。一些能够执行多种 NLP 任务的模型需要特定任务的提示。
- 在
text_target参数中设置目标语言(法语),以确保分词器正确处理目标文本。如果不设置text_target,分词器会将目标文本作为英语处理。 - 截断序列,使其不超过
max_length参数设置的最大长度。
source_lang = "en"
target_lang = "fr"
prefix = "translate English to French: "
def preprocess_function(examples):
inputs = [prefix + example[source_lang] for example in examples["translation"]]
targets = [example[target_lang] for example in examples["translation"]]
model_inputs = tokenizer(inputs, text_target=targets, max_length=128, truncation=True)
return model_inputs
要应用预处理函数到整个数据集,使用 🤗 Datasets 的 map 方法。您可以通过设置 batched=True 来加速 map 函数,以便一次处理数据集的多个元素:
tokenized_books = books.map(preprocess_function, batched=True)
现在使用 DataCollatorForSeq2Seq 创建一个示例批次。在整理过程中,动态填充 句子到批次中最长的长度更高效,而不是将整个数据集填充到最大长度。
Pytorch¶
from transformers import DataCollatorForSeq2Seq
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint)
TensorFlow¶
from transformers import DataCollatorForSeq2Seq
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf")
import evaluate
metric = evaluate.load("sacrebleu")
然后创建一个函数,将您的预测和标签传递给 compute 以计算 SacreBLEU 分数:
import numpy as np
def postprocess_text(preds, labels):
preds = [pred.strip() for pred in preds]
labels = [[label.strip()] for label in labels]
return preds, labels
def compute_metrics(eval_preds):
preds, labels = eval_preds
if isinstance(preds, tuple):
preds = preds[0]
decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True)
labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)
decoded_preds, decoded_labels = postprocess_text(decoded_preds, decoded_labels)
result = metric.compute(predictions=decoded_preds, references=decoded_labels)
result = {"bleu": result["score"]}
prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id) for pred in preds]
result["gen_len"] = np.mean(prediction_lens)
result = {k: round(v, 4) for k, v in result.items()}
return result
您的 compute_metrics 函数现在准备好了,您将在设置训练时返回到它。
训练¶
Pytorch¶
如果您不熟悉使用 Trainer 微调模型,请查看这里的 basic tutorial here!
您现在可以开始训练您的模型了!加载 T5 与 AutoModelForSeq2SeqLM:
from transformers import AutoModelForSeq2SeqLM, Seq2SeqTrainingArguments, Seq2SeqTrainer
model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint)
此时,只剩下三个步骤:
- 在 Seq2SeqTrainingArguments 中定义您的训练超参数。唯一必需的参数是
output_dir,它指定了保存模型的位置。您可以通过设置push_to_hub=True将模型推送到 Hub(您需要登录 Hugging Face 才能上传您的模型)。在每个 epoch 结束时,Trainer 将评估 SacreBLEU 指标并保存训练检查点。 - 将训练参数传递给 Seq2SeqTrainer,同时传递模型、数据集、分词器、数据整理器和
compute_metrics函数。 - 调用 train() 以微调您的模型。
training_args = Seq2SeqTrainingArguments(
output_dir="my_awesome_opus_books_model",
eval_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
weight_decay=0.01,
save_total_limit=3,
num_train_epochs=2,
predict_with_generate=True,
fp16=True, # change to bf16=True for XPU
push_to_hub=True,
)
trainer = Seq2SeqTrainer(
model=model,
args=training_args,
train_dataset=tokenized_books["train"],
eval_dataset=tokenized_books["test"],
processing_class=tokenizer,
data_collator=data_collator,
compute_metrics=compute_metrics,
)
trainer.train()
训练完成后,使用 push_to_hub() 方法将您的模型分享到 Hub,以便每个人都可以使用您的模型:
trainer.push_to_hub()
from transformers import AdamWeightDecay
optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01)
然后您可以加载 T5 与 TFAutoModelForSeq2SeqLM:
from transformers import TFAutoModelForSeq2SeqLM
model = TFAutoModelForSeq2SeqLM.from_pretrained(checkpoint)
使用 prepare_tf_dataset() 将您的数据集转换为 tf.data.Dataset 格式:
tf_train_set = model.prepare_tf_dataset(
tokenized_books["train"],
shuffle=True,
batch_size=16,
collate_fn=data_collator,
)
tf_test_set = model.prepare_tf_dataset(
tokenized_books["test"],
shuffle=False,
batch_size=16,
collate_fn=data_collator,
)
使用 compile 配置模型以进行训练。请注意,Transformers 模型都有一个默认的任务相关损失函数,所以您不需要指定一个,除非您想这样做:
import tensorflow as tf
model.compile(optimizer=optimizer) # No loss argument!
在开始训练之前,最后两件事是计算 SacreBLEU 指标和提供一种将您的模型推送到 Hub 的方法。这两者都通过使用 Keras callbacks 完成。
将您的 compute_metrics 函数传递给 KerasMetricCallback:
from transformers.keras_callbacks import KerasMetricCallback
metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set)
在 PushToHubCallback 中指定要推送模型和分词器的位置:
from transformers.keras_callbacks import PushToHubCallback
push_to_hub_callback = PushToHubCallback(
output_dir="my_awesome_opus_books_model",
tokenizer=tokenizer,
)
然后将您的回调捆绑在一起:
callbacks = [metric_callback, push_to_hub_callback]
最后,您已经准备好开始训练您的模型了!调用 fit 并传入您的训练和验证数据集、epoch 数量和回调以微调模型:
model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks)
训练完成后,您的模型将自动上传到 Hub,以便每个人都可以使用它!
要深入了解如何微调翻译模型,请查看相应的 PyTorch notebook 或 TensorFlow notebook。
推理¶
太好了,现在您已经微调了一个模型,可以使用它进行推理了!
想出一些您想要翻译成另一种语言的文本。对于 T5,您需要根据您正在处理的任务在输入前添加前缀。对于从英语到法语的翻译,您应该像下面这样添加前缀:
text = "translate English to French: Legumes share resources with nitrogen-fixing bacteria."
尝试您微调的模型进行推理的最简单方法是使用 pipeline()。使用您的模型实例化一个 pipeline 用于翻译,并将您的文本传递给它:
from transformers import pipeline
translator = pipeline("translation_en_to_fr", model="username/my_awesome_opus_books_model")
translator(text)
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_opus_books_model")
inputs = tokenizer(text, return_tensors="pt").input_ids
使用 generate() 方法创建翻译。有关不同文本生成策略和生成控制的更多信息,请查看 Text Generation API。
from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained("username/my_awesome_opus_books_model")
outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95)
将生成的 token ids 解码回文本:
tokenizer.decode(outputs[0], skip_special_tokens=True)
TensorFlow¶
对文本进行分词并返回 input_ids 作为 TensorFlow 张量:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_opus_books_model")
inputs = tokenizer(text, return_tensors="tf").input_ids
使用 ~transformers.generation_tf_utils.TFGenerationMixin.generate 方法创建翻译。有关不同文本生成策略和生成控制的更多信息,请查看 Text Generation API。
from transformers import TFAutoModelForSeq2SeqLM
model = TFAutoModelForSeq2SeqLM.from_pretrained("username/my_awesome_opus_books_model")
outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95)
将生成的 token ids 解码回文本:
tokenizer.decode(outputs[0], skip_special_tokens=True)