首页
/ Transformers 多语言模型推理指南:XLM 语言嵌入、M2M100 与 MBart 多语翻译实战

Transformers 多语言模型推理指南:XLM 语言嵌入、M2M100 与 MBart 多语翻译实战

2026-09-04 23:56:55作者:齐添朝

本文基于 Transformers 仓库官方的多语言模型文档(docs/source/ar/multilingual.md),系统讲解在 Transformers 中如何正确调用 XLM、BERT、XLM-RoBERTa、M2M100、MBart 五类多语言模型进行推理:哪些模型可以直接按单语模型方式使用,哪些模型必须显式传入语言嵌入或源语言参数,并结合仓库源码剖析 langs 张量、lang2idforced_bos_token_id 等关键机制的底层实现,帮助你在跨语言 NLP 任务中避开"忘记指定语言"这一类隐蔽的推理错误。

多语言模型:哪些可以直接用,哪些需要特殊处理

Transformers 中包含大量多语言模型,但它们的推理用法并不统一。文档明确指出:并不是所有多语言模型的用法都不同。部分模型(如 google-bert/bert-base-multilingual-uncased)的调用方式与单语模型完全一致;而另一些模型(如需要语言嵌入的 XLM、需要指定源语言的多语翻译模型)则必须遵循额外的调用约定。本指南聚焦后者。

按调用方式,可以把多语言模型分为三类:

  1. 无需任何语言信息的模型:BERT 多语版本、XLM-RoBERTa、不要求语言嵌入的 XLM MLM 大模型;
  2. 需要显式传入语言嵌入(language embeddings)的模型:多数 XLM 因果/掩码语言模型;
  3. 需要指定源语言、并在生成时强制目标语言 BOS 的翻译模型:M2M100、MBart。

XLM 系列模型总览

XLM 共有十种预训练副本,其中仅一种是单语模型。其余九种可划分为两大类:

  • 使用语言嵌入的副本:推理时必须传入与输入形状相同的 langs 张量;
  • 不使用语言嵌入的副本FacebookAI/xlm-mlm-17-1280(17 语言 MLM)与 FacebookAI/xlm-mlm-100-1280(100 语言 MLM),用于通用的句子表示,不需要语言信息。

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 因果语言建模 英-德

语言嵌入的底层实现:langs 张量与 lang_embeddings

语言嵌入被表示为一个与 input_ids 形状完全相同的张量,其取值由语言决定,并通过分词器的 lang2idid2lang 两个映射字典确定。这两个属性在 XLMTokenizer 实现 中作为可选构造参数传入,并在加载预训练词表时自动设置;若传入的 lang 参数不在 lang2id 映射中,分词器会直接抛出错误,提示检查语言是否受支持(参见 tokenization_xlm.py)。

模型侧的实现可以在 modeling_xlm.py 中确认:当配置满足 n_langs > 1 and use_lang_emb 时,XLMModel 会创建 self.lang_embeddings = nn.Embedding(self.n_langs, self.dim)。在前向传播中(modeling_xlm.py):

  • langs 张量的形状必须断言为 (batch_size, sequence_length),否则触发 assert 失败;
  • 若启用了增量缓存(past_key_values),只取 langs 的最后 _slen 列;
  • 最终执行 tensor = tensor + self.lang_embeddings(langs),即将语言嵌入逐元素加到词嵌入上——这就是为什么 langs 中每个位置都填充同一语言 ID 也能生效,因为语言信息是叠加在每个 token 嵌入上的。

完整示例:加载 xlm-clm-enfr-1024 并传入语言嵌入

以因果语言建模副本 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 查看该模型支持的语言及其编号:

>>> print(tokenizer.lang2id)
{'en': 0, 'fr': 1}

创建输入序列(batch size 为 1):

>>> input_ids = torch.tensor([tokenizer.encode("Wikipedia was used to")])  # batch size of 1

将语言 ID 取为 "en" 对应的编号(0),构造与 input_ids 同形状、全部填充该值的 langs 张量:

>>> language_id = tokenizer.lang2id["en"]  # 0
>>> langs = torch.tensor([language_id] * input_ids.shape[1])  # torch.tensor([0, 0, 0, ..., 0])

>>> # 重塑为 (batch_size, sequence_length)
>>> langs = langs.view(1, -1)  # 形状变为 [1, sequence_length](batch size 为 1)

input_ids 与语言嵌入一起传入模型:

>>> outputs = model(input_ids, langs=langs)

要点回顾:langs 的形状必须严格等于 input_ids 的形状,这是源码中 assert langs.size() == (bs, slen) 强制保证的;对于 batch 推理,每个样本对应一行,各自填充该样本语言对应的 lang2id 值即可。

此外,仓库中的文本生成示例脚本 run_generation.py 支持在生成时指定 XLM 语言:其 argparse 定义 提供了 --xlm_language 参数(Optional language when used with the XLM model.),并在交互模式下提示用户从 tokenizer 可用语言列表中选择(run_generation.py)。运行前需先安装该目录的依赖 examples/pytorch/text-generation/requirements.txt

不使用语言嵌入的 XLM 模型

  • FacebookAI/xlm-mlm-17-1280(掩码语言建模,17 语言)
  • FacebookAI/xlm-mlm-100-1280(掩码语言建模,100 语言)

这两个副本用于通用的句子表示(sentence representation),与前面需要显式语言嵌入的 XLM 副本不同,它们在推理时不需要 langs 参数。

BERT 多语模型:从上下文推断语言

以下 BERT 模型可用于多语言任务:

  • google-bert/bert-base-multilingual-uncased(掩码语言建模 + 下一句预测,102 种语言)
  • google-bert/bert-base-multilingual-cased(掩码语言建模 + 下一句预测,104 种语言)

这两类模型在推理时不要求语言嵌入:语言必须由上下文决定,模型自行推断。也就是说,你可以完全按标准 BERT 的方式调用它们,只需确保输入文本在词表覆盖范围内(如阿拉伯语、中文等非拉丁文字,建议先确认所用副本的 tokenizer 词表支持情况)。

XLM-RoBERTa:面向 100 种语言的双向编码模型

以下 XLM-RoBERTa 模型可用于多语言任务:

  • FacebookAI/xlm-roberta-base(掩码语言建模,100 种语言)
  • FacebookAI/xlm-roberta-large(掩码语言建模,100 种语言)

XLM-RoBERTa 基于 2.5 TB 的 CommonCrawl 新数据、经优化后的 100 种语料训练,在分类、序列标注、问答等下游任务上,相较 mBERT、XLM 等早期多语言模型有明显收益。由于它是掩码语言建模架构且无需语言嵌入,加载后与标准 BERT 式调用一致(AutoTokenizer / AutoModel 或直接使用对应类),无需传递任何语言参数。

M2M100:100 语言互译与 src_lang 的正确设定

以下 M2M100 模型可用于多语翻译:

  • facebook/m2m100_418M(翻译)
  • facebook/m2m100_1.2B(翻译)

源码机制:源语言标记如何加入输入

要正确翻译,关键是理解 M2M100 分词器的内部约定。在 tokenization_m2m_100.py 中,set_src_lang_special_tokens 方法会将编码后的输入重写为 X [eos, src_lang_code] 的结构(即无 prefix,suffix 为 [eos, 源语言码])——这正是 文档注释 所述 input_ids(编码器)的形状约定。src_lang 属性带有 setter(tokenization_m2m_100.py),任何对 tokenizer.src_lang = "zh" 的赋值都会触发特殊 token 的重置。默认源语言为 "en"tokenization_m2m_100.py)。

目标语言则通过 forced_bos_token_id 在生成阶段强制:M2M100 要求第一个生成 token 即目标语言的语言码 token。仓库中翻译 pipeline 的输入构建逻辑 _build_translation_inputs 会自动执行 inputs["forced_bos_token_id"] = tgt_lang_id,并且要求 src_langtgt_lang 均不为空,否则抛出 ValueError——这为手动调用 model.generate 时的参数约定提供了权威参照。

完整示例:中译英

facebook/m2m100_418M 为例,将中文文本翻译为英文。源语言通过在加载分词器时用 src_lang 指定:

>>> 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")

将文本切分为 token:

>>> encoded_zh = tokenizer(chinese_text, return_tensors="pt")

generate 中用 forced_bos_token_id 强制目标语言为英文,tokenizer.get_lang_id("en") 负责把语言码解析为 token ID(实现见 tokenization_m2m_100.py):

>>> 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.'

注意 skip_special_tokens=True 会跳过开头的目标语言码 token 与结尾特殊 token,输出为干净的译文。

MBart:50 语言翻译与 lang_code_to_id

以下 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

源码机制:fairseq 语言码表与语言码后缀

MBart 分词器在初始化时基于 FAIRSEQ_LANGUAGE_CODES 构建语言码到 token ID 的映射(tokenization_mbart.py):

self.lang_code_to_id = {
    lang_code: self.convert_tokens_to_ids(lang_code) for lang_code in FAIRSEQ_LANGUAGE_CODES
}

这与 M2M100 的 get_lang_id 作用相同,但语言码命名不同:MBart 使用 fairseq 风格带区域后缀的代码(如 "fi_FI""en_XX"),而 M2M100 使用 ISO 简码(如 "fi""en")。同样地,src_lang setter 会在赋值时重置源语言特殊 token(tokenization_mbart.py),默认源语言为 "en_XX"tokenization_mbart.py);其 _build_translation_inputs 也会像 M2M100 一样把 forced_bos_token_id 设为目标语言 ID,作为 generate 调用约定的实现依据。

完整示例:芬兰语译英文

facebook/mbart-large-50-many-to-many-mmt 为例,将芬兰语文本翻译为英文。源语言 src_lang="fi_FI" 在加载分词器时指定(注意使用 Auto 类亦可,因为 MBart 已注册自动映射):

>>> 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")

将文本切分为 token:

>>> encoded_en = tokenizer(en_text, return_tensors="pt")

generate 中把 forced_bos_token_id 设为 "en_XX" 对应的 ID,强制输出为英文(注意这里使用的是 lang_code_to_id 字典而非 get_lang_id 方法,因为 MBart 分词器暴露的是前者):

>>> 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 作为首生成 token——该副本被训练为统一输出单一目标语言;除此之外用法完全相同。

三类模型的调用约定速查

模型 需要语言信息 传入方式 关键源码
BERT multilingual / XLM-RoBERTa 无需参数,语言从上下文推断
XLM(MLM/CLM 双语副本) model(input_ids, langs=langs)langs 形状同 input_ids,取值来自 tokenizer.lang2id modeling_xlm.py
XLM xlm-mlm-17/100-1280 常规 MLM 调用
M2M100 分词器 src_lang(ISO 简码)+ generate(forced_bos_token_id=tokenizer.get_lang_id(...)) tokenization_m2m_100.py
MBart(非 many-to-one) 分词器 src_lang(fairseq 码如 fi_FI)+ generate(forced_bos_token_id=tokenizer.lang_code_to_id["en_XX"]) tokenization_mbart.py
MBart many-to-one-mmt 部分 只需 src_lang,无需 forced_bos_token_id

常见陷阱与注意事项

  1. langs 形状错误:XLM 前向中 assert langs.size() == (bs, slen) 会因形状不匹配直接失败。单条输入务必 langs.view(1, -1),batch 推理时每行填充对应样本的语言 ID。
  2. 语言码格式混淆:M2M100 用 "en""zh" 这类 ISO 简码;MBart 用 "en_XX""fi_FI" 这类 fairseq 风格码。跨模型迁移示例代码时,语言码不能照抄。
  3. 忘记 forced_bos_token_id:M2M100 与多数 MBart 副本若不在 generate 时强制目标语言首 token,模型可能输出错误的目标语言(或不确定输出);many-to-one-mmt 副本除外。
  4. 默认源语言:M2M100 与 MBart 分词器在未显式指定 src_lang 时默认 "en" / "en_XX",翻译非英语源语言时必须显式设置。
  5. 词表覆盖:使用 BERT 多语副本处理阿拉伯语、中文等文字时,先确认对应 tokenizer 的词表支持情况,避免大量 <unk> 影响表示质量。

总结

Transformers 中的多语言模型并非"一套调用走天下":BERT 多语与 XLM-RoBERTa 可以按常规方式直接推理;XLM 双语副本要求把语言 ID 编码成与 input_ids 同形状的 langs 张量并加到词嵌入上;M2M100 与 MBart 则需要在分词器层指定 src_lang、在 generate 层用 forced_bos_token_id 锁定目标语言。理解 modeling_xlm.pytokenization_m2m_100.pytokenization_mbart.py 中的这些实现细节后,你可以准确地把任意 XLM/M2M100/MBart 预训练权重接入自己的多语言推理或翻译流程。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384