多语言模型推理¶
在 🤗 Transformers 中有多种多语言模型,它们的推理使用方式与单语言模型有所不同。但并不是所有的多语言模型使用方式都不同。例如,像 google-bert/bert-base-multilingual-uncased 这样的模型可以像单语言模型一样使用。本指南将向你展示如何使用那些推理使用方式不同的多语言模型。
XLM¶
XLM 有十个不同的检查点,其中只有一个单语言模型。剩下的九个模型检查点可以分为两类:使用语言嵌入的检查点和不使用语言嵌入的检查点。
XLM 使用语言嵌入¶
以下 XLM 模型在推理时使用语言嵌入来指定所使用的语言:
FacebookAI/xlm-mlm-ende-1024(掩码语言建模,英德)FacebookAI/xlm-mlm-enfr-1024(掩码语言建模,英法)FacebookAI/xlm-mlm-enro-1024(掩码语言建模,英罗)FacebookAI/xlm-mlm-xnli15-1024(掩码语言建模,XNLI 语言)FacebookAI/xlm-mlm-tlm-xnli15-1024(掩码语言建模 + 翻译,XNLI 语言)FacebookAI/xlm-clm-enfr-1024(因果语言建模,英法)FacebookAI/xlm-clm-ende-1024(因果语言建模,英德)
语言嵌入表示为与传递给模型的 input_ids 形状相同的张量。这些张量中的值取决于所使用的语言,并通过分词器的 lang2id 和 id2lang 属性识别。
在这个例子中,加载 FacebookAI/xlm-clm-enfr-1024 检查点(因果语言建模,英法):
import torch
from transformers import XLMTokenizer, XLMWithLMHeadModel
tokenizer = XLMTokenizer.from_pretrained("FacebookAI/xlm-clm-enfr-1024")
model = XLMWithLMHeadModel.from_pretrained("FacebookAI/xlm-clm-enfr-1024")
分词器的 lang2id 属性显示了该模型支持的语言及其 ID:
print(tokenizer.lang2id)
# 输出: {'en': 0, 'fr': 1}
接下来,创建一个示例输入:
input_ids = torch.tensor([tokenizer.encode("Wikipedia was used to")]) # 批量大小为 1
将语言 ID 设置为 "en",并用它定义语言嵌入。语言嵌入是一个填充了 0 的张量,因为 0 是英语的语言 ID。这个张量的大小应与 input_ids 相同。
language_id = tokenizer.lang2id["en"] # 0
langs = torch.tensor([language_id] * input_ids.shape[1]) # torch.tensor([0, 0, 0, ..., 0])
# 将其重塑为 (批量大小, 序列长度)
langs = langs.view(1, -1) # 现在形状为 [1, 序列长度](我们有一个批量大小为 1)
现在你可以将 input_ids 和语言嵌入传递给模型:
outputs = model(input_ids, langs=langs)
run_generation.py 脚本可以使用 xlm-clm 检查点生成带有语言嵌入的文本。
XLM 不使用语言嵌入¶
以下 XLM 模型在推理时不需要语言嵌入:
FacebookAI/xlm-mlm-17-1280(掩码语言建模,17 种语言)FacebookAI/xlm-mlm-100-1280(掩码语言建模,100 种语言)
这些模型用于通用句子表示,不同于之前的 XLM 检查点。
BERT¶
以下 BERT 模型可用于多语言任务:
google-bert/bert-base-multilingual-uncased(掩码语言建模 + 下一句预测,102 种语言)google-bert/bert-base-multilingual-cased(掩码语言建模 + 下一句预测,104 种语言)
这些模型在推理时不需要语言嵌入。它们应该能够从上下文中识别语言并相应地推理。
XLM-RoBERTa¶
以下 XLM-RoBERTa 模型可用于多语言任务:
FacebookAI/xlm-roberta-base(掩码语言建模,100 种语言)FacebookAI/xlm-roberta-large(掩码语言建模,100 种语言)
XLM-RoBERTa 在 100 种语言的 2.5TB 新创建和清理的 CommonCrawl 数据上进行了训练。在分类、序列标注和问答等下游任务上,它相比之前发布的多语言模型如 mBERT 或 XLM 提供了显著的改进。
M2M100¶
以下 M2M100 模型可用于多语言翻译:
facebook/m2m100_418M(翻译)facebook/m2m100_1.2B(翻译)
在这个例子中,加载 facebook/m2m100_418M 检查点将中文翻译成英文。你可以在分词器中设置源语言:
from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer
en_text = "Do not meddle in the affairs of wizards, for they are subtle and quick to anger."
chinese_text = "不要插手巫師的事務, 因為他們是微妙的, 很快就會發怒."
tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M", src_lang="zh")
model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M")
对文本进行分词:
encoded_zh = tokenizer(chinese_text, return_tensors="pt")
M2M100 强制目标语言 ID 作为生成的第一个标记以翻译为目标语言。在 generate 方法中将 forced_bos_token_id 设置为 en 以翻译成英文:
generated_tokens = model.generate(**encoded_zh, forced_bos_token_id=tokenizer.get_lang_id("en"))
tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
# 输出: 'Do not interfere with the matters of the witches, because they are delicate and will soon be angry.'
MBart¶
以下 MBart 模型可用于多语言翻译:
facebook/mbart-large-50-one-to-many-mmt(一到多的多语言机器翻译,50 种语言)facebook/mbart-large-50-many-to-many-mmt(多到多的多语言机器翻译,50 种语言)facebook/mbart-large-50-many-to-one-mmt(多到一的多语言机器翻译,50 种语言)facebook/mbart-large-50(多语言翻译,50 种语言)facebook/mbart-large-cc25
在这个例子中,加载 facebook/mbart-large-50-many-to-many-mmt 检查点将芬兰语翻译成英文。你可以在分词器中设置源语言:
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
en_text = "Do not meddle in the affairs of wizards, for they are subtle and quick to anger."
fi_text = "Älä sekaannu velhojen asioihin, sillä ne ovat hienovaraisia ja nopeasti vihaisia."
tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-50-many-to-many-mmt", src_lang="fi_FI")
model = AutoModelForSeq2SeqLM.from_pretrained("facebook/mbart-large-50-many-to-many-mmt")
对文本进行分词:
encoded_en = tokenizer(en_text, return_tensors="pt")
MBart 强制目标语言 ID 作为生成的第一个标记以翻译为目标语言。在 generate 方法中将 forced_bos_token_id 设置为 en 以翻译成英文:
generated_tokens = model.generate(**encoded_en, forced_bos_token_id=tokenizer.lang_code_to_id["en_XX"])
tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
# 输出: "Don't interfere with the wizard's affairs, because they are subtle, will soon get angry."
如果你使用的是 facebook/mbart-large-50-many-to-one-mmt 检查点,则不需要强制目标语言 ID 作为生成的第一个标记,其他使用方式相同。