翻译
翻译将一段文本从一种语言转换为另一种语言。它是可以被表述为序列到序列问题(sequence-to-sequence problem)的众多任务之一,序列到序列问题是一个强大的框架,用于从输入返回某些输出,例如翻译或摘要。翻译系统通常用于不同语言文本之间的翻译,但它也可以用于语音或介于两者之间的组合,如文本到语音或语音到文本。
本指南将向您展示如何
- 在T5上微调OPUS Books数据集的英语-法语子集,以将英语文本翻译成法语。
- 使用您微调的模型进行推理。
要查看与此任务兼容的所有架构和检查点,我们建议您查看任务页面。
在您开始之前,请确保您已安装所有必要的库
pip install transformers datasets evaluate sacrebleu
我们鼓励您登录您的 Hugging Face 帐户,以便您可以上传并与社区共享您的模型。当系统提示您时,请输入您的令牌以登录
>>> from huggingface_hub import notebook_login
>>> notebook_login()
加载 OPUS Books 数据集
首先从 🤗 数据集库加载 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]
{'id': '90560',
'translation': {'en': 'But this lofty plateau measured only a few fathoms, and soon we reentered Our Element.',
'fr': 'Mais ce plateau élevé ne mesurait que quelques toises, et bientôt nous fûmes rentrés dans notre élément.'}}
translation
:文本的英语和法语翻译。
预处理
下一步是加载 T5 标记器来处理英语-法语语言对。
>>> 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 创建一批示例。在整理期间,动态填充句子到批次中的最长长度,而不是将整个数据集填充到最大长度,这样效率更高。
>>> from transformers import DataCollatorForSeq2Seq
>>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint)
>>> from transformers import DataCollatorForSeq2Seq
>>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint, return_tensors="tf")
评估
在训练期间包含指标通常有助于评估模型的性能。您可以使用 🤗 Evaluate 库快速加载评估方法。对于此任务,加载 SacreBLEU 指标(有关如何加载和计算指标的更多信息,请参阅 🤗 Evaluate 快速入门)。
>>> 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
函数现在已经准备就绪,您将在设置训练时返回它。
训练
您现在可以开始训练您的模型了!使用 AutoModelForSeq2SeqLM 加载 T5。
>>> from transformers import AutoModelForSeq2SeqLM, Seq2SeqTrainingArguments, Seq2SeqTrainer
>>> model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint)
此时,只剩下三个步骤。
- 在 Seq2SeqTrainingArguments 中定义您的训练超参数。唯一必需的参数是
output_dir
,它指定保存模型的位置。您将通过设置push_to_hub=True
将此模型推送到 Hub(您需要登录 Hugging Face 才能上传您的模型)。在每个纪元结束时,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"],
... tokenizer=tokenizer,
... data_collator=data_collator,
... compute_metrics=compute_metrics,
... )
>>> trainer.train()
训练完成后,使用 push_to_hub() 方法将您的模型共享到 Hub,以便每个人都可以使用您的模型。
>>> trainer.push_to_hub()
如果您不熟悉使用 Keras 微调模型,请查看此处基本教程!
>>> from transformers import AdamWeightDecay
>>> optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01)
然后,您可以使用 TFAutoModelForSeq2SeqLM 加载 T5。
>>> 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 回调 来完成的。
将您的 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
来微调模型。
>>> model.fit(x=tf_train_set, validation_data=tf_test_set, epochs=3, callbacks=callbacks)
训练完成后,您的模型会自动上传到 Hub,以便每个人都可以使用它!
有关如何微调翻译模型的更深入的示例,请查看相应的 PyTorch 笔记本 或 TensorFlow 笔记本。
推理
很好,现在您已经微调了一个模型,您可以使用它进行推理!
想出一些您想翻译成另一种语言的文本。对于 T5,您需要根据要执行的任务在输入前添加提示。对于从英语到法语的翻译,您应该在输入前添加以下提示。
>>> text = "translate English to French: Legumes share resources with nitrogen-fixing bacteria."
尝试使用您微调的模型进行推理的最简单方法是在 pipeline() 中使用它。使用您的模型实例化一个用于翻译的 pipeline
,并将您的文本传递给它。
>>> from transformers import pipeline
# Change `xx` to the language of the input and `yy` to the language of the desired output.
# Examples: "en" for English, "fr" for French, "de" for German, "es" for Spanish, "zh" for Chinese, etc; translation_en_to_fr translates English to French
# You can view all the lists of languages here - https://huggingface.co/languages
>>> translator = pipeline("translation_xx_to_yy", model="username/my_awesome_opus_books_model")
>>> translator(text)
[{'translation_text': 'Legumes partagent des ressources avec des bactéries azotantes.'}]
如果您愿意,您也可以手动复制 pipeline
的结果。
标记文本并返回 input_ids
作为 PyTorch 张量。
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_opus_books_model")
>>> inputs = tokenizer(text, return_tensors="pt").input_ids
使用 generate() 方法创建翻译。有关控制生成的各种文本生成策略和参数的更多详细信息,请查看 文本生成 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)
将生成的标记 ID 解码回文本。
>>> tokenizer.decode(outputs[0], skip_special_tokens=True)
'Les lignées partagent des ressources avec des bactéries enfixant l'azote.'
标记文本并返回 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
方法创建翻译。有关控制生成的各种文本生成策略和参数的更多详细信息,请查看 文本生成 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)
将生成的标记 ID 解码回文本。
>>> tokenizer.decode(outputs[0], skip_special_tokens=True)
'Les lugumes partagent les ressources avec des bactéries fixatrices d'azote.'