迁移学习(十一)—— 跨语言迁移
Chen Kai BOSS

英语标注数据丰富,但世界上有 7000 多种语言,如何让模型从英语学到的知识迁移到低资源语言?跨语言迁移( Cross-Lingual Transfer)让模型在英语上训练,在中文、阿拉伯语、斯瓦希里语上直接使用——无需任何目标语言标注数据。

本文从多语言表示空间的数学原理出发,系统讲解双语词嵌入对齐、多语言预训练、跨语言提示学习的方法与实现,深入分析语言共性与差异、零样本迁移性能与语言选择策略,并提供从零实现跨语言文本分类的完整代码( 280+行)。

跨语言迁移的问题定义

零样本跨语言学习

场景:在源语言 (如英语)上训练,在目标语言 (如中文)上测试,目标语言无标注数据

形式化为:

目标:最小化测试损失

挑战: - 源语言和目标语言的词汇完全不同 - 语法结构、语序可能差异巨大 - 文化、语用层面的差异

少样本跨语言学习

场景:目标语言有少量标注数据(如每类 10-100 个样本)。

形式化为:

其中 (目标语言样本远少于源语言)。

多源语言迁移

场景:从多个源语言 迁移到目标语言

目标函数:

优势:语言多样性提供更丰富的语言特征。

评估指标

  1. 零样本准确率

𝟙

  1. 跨语言迁移差距(Cross-Lingual Transfer Gap)

越小越好,0 表示完美迁移。

  1. 语言平均性能(Average Performance)

多语言表示的数学原理

共享语义空间

假设:不同语言表达相同概念的方式在深层语义上存在共性。

形式化为:存在一个语言无关的语义空间 ,使得:

对于语义等价的句子 , ),有:

直觉:猫(中文)和 cat(英语)应该映射到语义空间的同一区域。

语言共性的理论基础

普遍语法( Universal Grammar)

乔姆斯基的普遍语法理论:所有人类语言共享底层语法结构。

证据: - 主谓宾( SVO)、主宾谓( SOV)等语序在深层有对应关系 - 名词、动词等词类在所有语言中存在 - 递归结构、疑问句变换等语法操作具有跨语言普遍性

分布式语义假说

"词的意思由其上下文决定"( Distributional Hypothesis):

跨语言扩展:相似的跨语言上下文应该产生相似的表示。

双语词嵌入对齐

线性变换假设

假设源语言词嵌入 和目标语言词嵌入 之间存在线性变换

$$

Y XW $$

目标:学习 使得翻译对 尽可能接近。

Procrustes 对齐

$$

W^{*} = _W | XW - Y |_F^2 $$

闭式解( Orthogonal Procrustes Problem):

$$

W^{*} = UV^T $$

其中

对抗训练对齐

Conneau 等人1提出无监督对齐方法:

判别器:区分源语言和目标语言的词嵌入:

$$

D: ^d $$

生成器(对齐矩阵):最小化判别器的能力:

直觉:如果判别器无法区分对齐后的源语言和目标语言,说明对齐成功。

多语言句子表示

平行句子对齐

给定平行语料 , ,语义等价),学习编码器

翻译语言模型( Translation Language Modeling, TLM)2

联合建模平行句子对:

源语言和目标语言的 token 可以相互 attend,学习对齐。

对比学习

LASER3使用对比损失:

其中 是 batch 中的负样本, 是余弦相似度, 是温度参数。

多语言预训练模型

Multilingual BERT (mBERT)

架构与预训练

mBERT4在 104 种语言的 Wikipedia 上预训练,使用:

  1. Masked Language Modeling (MLM)2. 共享词汇表: 110K 个 WordPiece tokens,覆盖所有语言

关键设计: - 无显式跨语言监督信号(无平行语料) - 不同语言的句子随机混合训练 - 共享所有层的参数

为什么 mBERT 有效?

理论解释5

  1. 锚点词汇( Anchor Vocabulary):数字、标点、英文借词在多语言间共享
  2. 深层参数共享:强制模型学习语言无关的特征
  3. 代码转换( Code-Switching):训练数据中自然出现的多语言混合

实证发现: - mBERT 的隐藏层表示在不同语言间高度对齐 - 即使不用平行语料,相似概念在不同语言的表示也接近

XLM-RoBERTa (XLM-R)

改进设计

XLM-R6在 100 种语言的 2.5TB 文本上预训练,相比 mBERT:

  1. 更大的模型: 550M 参数( mBERT 为 110M)
  2. 更多数据: 2.5TB vs 几 GB
  3. 更优的采样策略

定义语言 的采样概率:

$$

p_i = ( )^ $$

其中 是语言 的数据量,(缓解高资源语言主导)。

性能对比

在 XNLI(跨语言自然语言推理)任务上:

模型 英语 平均 最差语言
mBERT 81.4 65.4 58.3 (Urdu)
XLM-R 88.7 76.2 68.4 (Swahili)

XLM-R 在所有语言上都显著优于 mBERT 。

mT5

架构

mT57是 T5 的多语言版本,覆盖 101 种语言,使用:

  1. Text-to-Text 框架:所有任务统一为文本生成 $$

p(y | x; ) = {i=1}^{|y|} p(y_i | x, y{<i}; ) $$2. 去噪自编码( Denoising Autoencoding): - 随机 mask 文本片段( span) - 模型重建完整文本

优势: - 生成式架构适合 seq2seq 任务(翻译、摘要) - 统一框架支持多任务学习

与 XLM-R 的对比

维度 XLM-R mT5
架构 仅编码器 编码器-解码器
预训练任务 MLM Denoising
适用任务 分类、标注 生成、翻译
推理开销

零样本跨语言迁移

直接迁移( Direct Transfer)

最简单策略:在源语言上训练,直接在目标语言上测试。

算法流程:

  1. 用源语言数据 微调多语言模型
  2. 在目标语言数据 上直接测试

关键:多语言模型的表示已经对齐。

性能

在 XNLI 上,英语→其他语言的零样本准确率:

目标语言 mBERT XLM-R
法语 73.5 79.2
中文 68.3 76.7
阿拉伯语 64.1 73.8
斯瓦希里语 57.2 68.4

高资源语言性能更好。

翻译-训练( Translate-Train)

策略:将源语言训练数据翻译成目标语言,然后在目标语言上训练。

算法流程:

  1. 用机器翻译将 翻译为 2. 在 上训练模型
  2. 在真实目标语言测试数据上评估

优势:模型直接在目标语言上训练,避免语言差异。

劣势: - 依赖翻译质量(翻译错误会传播) - 语义可能丢失或扭曲

翻译-测试( Translate-Test)

策略:将目标语言测试数据翻译成源语言,用源语言模型预测。

算法流程:

  1. 在源语言 上训练模型
  2. 将目标语言测试样本 翻译为 3. 用模型预测 优势:利用源语言的高质量模型。

劣势:推理时需要翻译,增加延迟和成本。

集成方法

Translate-Train-All( TTA)

将训练数据翻译成所有语言,联合训练:

其中 是翻译到语言 的训练数据。

优势:模型见过多种语言的表达方式,泛化性强。

劣势:计算成本高(需要多次翻译和训练)。

跨语言提示学习

多语言提示模板

Prompt-Based Learning:将任务转换为语言模型的完形填空。

英语情感分类:

1
The movie was great. It was [MASK]. → wonderful

跨语言扩展:使用多语言模板。

中文:

1
这部电影很好。它[MASK]。 → 很棒

挑战:不同语言的模板设计差异大。

自动模板搜索

X-FACTR8:自动发现跨语言提示模板。

算法:

  1. 在英语上用 AutoPrompt9搜索最优模板
  2. 将模板翻译成目标语言
  3. 在目标语言上微调模板

示例

英语模板:

1
[X] is located in [Y]. → [X] is in the country of [MASK].

翻译成法语:

1
[X] se trouve en [Y]. → [X] est dans le pays de [MASK].

语言无关的 Prompt

XPROMPT10:学习语言无关的连续提示。

模型输入:

其中 是可学习的连续向量(与语言无关)。

训练目标:

优势:一个 prompt 适用所有语言,无需翻译。

代码转换与语言混合

代码转换现象

代码转换( Code-Switching):在一个句子中混合使用多种语言。

示例:

1
2
I'm feeling 很累,想 sleep 了。
(英语+中文)

普遍性:在多语社区中非常常见(如新加坡、印度、美国拉丁裔社区)。

代码转换数据增强

策略:在训练时人工制造代码转换数据。

算法11

  1. 解析句子的依存树
  2. 随机选择一些词替换为目标语言的翻译
  3. 保持语法结构不变

示例:

原句(英语):

1
I love this movie very much.

代码转换(英语→中文):

1
I 喜欢 this 电影 very much.

效果:提升跨语言鲁棒性和零样本性能。

语言自适应预训练

MALAPT12:在目标语言的单语数据上继续预训练。

算法:

  1. 用多语言模型(如 XLM-R)初始化
  2. 在目标语言的单语语料上继续 MLM 训练
  3. 在下游任务上微调

效果

设置 英语→中文( XNLI)
XLM-R 76.7
+ MALAPT 79.3 (+2.6)

目标语言预训练显著提升性能。

完整代码实现:跨语言文本分类

下面实现一个完整的跨语言文本分类系统,包括多语言模型加载、零样本迁移、少样本微调与评估。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
"""
从零实现跨语言文本分类
包含:多语言 BERT 加载、零样本迁移、少样本微调
"""

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertModel
import numpy as np
import matplotlib.pyplot as plt
from typing import List, Dict, Tuple
from sklearn.metrics import accuracy_score, classification_report

# 设置随机种子
torch.manual_seed(42)
np.random.seed(42)

# ============================================================================
# 多语言文本分类器
# ============================================================================

class MultilingualTextClassifier(nn.Module):
"""
基于多语言 BERT 的文本分类器
"""
def __init__(self, model_name: str = 'bert-base-multilingual-cased', num_classes: int = 3):
super().__init__()

# 加载多语言 BERT
self.bert = BertModel.from_pretrained(model_name)
self.hidden_size = self.bert.config.hidden_size

# 分类头
self.classifier = nn.Sequential(
nn.Dropout(0.1),
nn.Linear(self.hidden_size, self.hidden_size),
nn.Tanh(),
nn.Dropout(0.1),
nn.Linear(self.hidden_size, num_classes)
)

def forward(self, input_ids, attention_mask):
# BERT 编码
outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)

# 使用[CLS] token 的表示
cls_output = outputs.last_hidden_state[:, 0, :]

# 分类
logits = self.classifier(cls_output)

return logits

# ============================================================================
# 多语言数据集
# ============================================================================

class MultilingualDataset(Dataset):
"""
多语言文本分类数据集
"""
def __init__(self, texts: List[str], labels: List[int], tokenizer, max_length: int = 128):
self.texts = texts
self.labels = labels
self.tokenizer = tokenizer
self.max_length = max_length

def __len__(self):
return len(self.texts)

def __getitem__(self, idx):
text = self.texts[idx]
label = self.labels[idx]

# Tokenize
encoding = self.tokenizer(
text,
max_length=self.max_length,
padding='max_length',
truncation=True,
return_tensors='pt'
)

return {
'input_ids': encoding['input_ids'].squeeze(0),
'attention_mask': encoding['attention_mask'].squeeze(0),
'label': torch.tensor(label, dtype=torch.long)
}

# ============================================================================
# 生成模拟多语言数据
# ============================================================================

def create_synthetic_multilingual_data(num_samples_per_lang: int = 200) -> Dict[str, Tuple[List[str], List[int]]]:
"""
生成模拟的多语言情感分类数据
包含英语、中文、法语
"""
# 模拟数据(实际应用中应使用真实数据)
data = {
'en': {
'positive': [
"This movie is absolutely fantastic!",
"I love this product, it's amazing.",
"Great service, highly recommended!",
"Excellent quality, will buy again.",
"Wonderful experience, very satisfied."
] * (num_samples_per_lang // 5),
'neutral': [
"The movie was okay.",
"Product works as expected.",
"Service was average.",
"Quality is acceptable.",
"Experience was fine."
] * (num_samples_per_lang // 5),
'negative': [
"Terrible movie, waste of time!",
"Product broke after one day.",
"Very poor service, disappointed.",
"Bad quality, do not buy.",
"Horrible experience, never again."
] * (num_samples_per_lang // 5)
},
'zh': {
'positive': [
"这部电影太棒了!",
"我很喜欢这个产品,太神奇了。",
"服务很好,强烈推荐!",
"质量很好,会再买。",
"体验很棒,非常满意。"
] * (num_samples_per_lang // 5),
'neutral': [
"电影还可以。",
"产品符合预期。",
"服务一般。",
"质量尚可。",
"体验还行。"
] * (num_samples_per_lang // 5),
'negative': [
"电影太烂了,浪费时间!",
"产品用一天就坏了。",
"服务太差,很失望。",
"质量不好,不要买。",
"体验糟糕,再也不会了。"
] * (num_samples_per_lang // 5)
},
'fr': {
'positive': [
"Ce film est absolument fantastique!",
"J'adore ce produit, c'est incroyable.",
"Excellent service, hautement recommand é!",
"Excellente qualit é, j'ach è terai encore.",
"Exp é rience merveilleuse, tr è s satisfait."
] * (num_samples_per_lang // 5),
'neutral': [
"Le film é tait correct.",
"Le produit fonctionne comme pr é vu.",
"Le service é tait moyen.",
"La qualit é est acceptable.",
"L'exp é rience é tait bien."
] * (num_samples_per_lang // 5),
'negative': [
"Film terrible, perte de temps!",
"Le produit s'est cass é apr è s un jour.",
"Service tr è s mauvais, d éç u.",
"Mauvaise qualit é, n'achetez pas.",
"Exp é rience horrible, plus jamais."
] * (num_samples_per_lang // 5)
}
}

# 整理数据
result = {}
for lang, sentiment_data in data.items():
texts = []
labels = []

for label_idx, (sentiment, examples) in enumerate(sentiment_data.items()):
texts.extend(examples)
labels.extend([label_idx] * len(examples))

# 打乱数据
indices = np.random.permutation(len(texts))
texts = [texts[i] for i in indices]
labels = [labels[i] for i in indices]

result[lang] = (texts, labels)

return result

# ============================================================================
# 训练与评估函数
# ============================================================================

def train_epoch(model, dataloader, optimizer, criterion, device):
"""
训练一个 epoch
"""
model.train()
total_loss = 0
all_preds = []
all_labels = []

for batch in dataloader:
input_ids = batch['input_ids'].to(device)
attention_mask = batch['attention_mask'].to(device)
labels = batch['label'].to(device)

# 前向传播
logits = model(input_ids, attention_mask)
loss = criterion(logits, labels)

# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 统计
total_loss += loss.item()
preds = torch.argmax(logits, dim=1).cpu().numpy()
all_preds.extend(preds)
all_labels.extend(labels.cpu().numpy())

avg_loss = total_loss / len(dataloader)
accuracy = accuracy_score(all_labels, all_preds)

return avg_loss, accuracy

def evaluate(model, dataloader, device):
"""
评估模型
"""
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
for batch in dataloader:
input_ids = batch['input_ids'].to(device)
attention_mask = batch['attention_mask'].to(device)
labels = batch['label'].to(device)

# 前向传播
logits = model(input_ids, attention_mask)
preds = torch.argmax(logits, dim=1).cpu().numpy()

all_preds.extend(preds)
all_labels.extend(labels.cpu().numpy())

accuracy = accuracy_score(all_labels, all_preds)

return accuracy, all_preds, all_labels

# ============================================================================
# 主实验:跨语言零样本迁移
# ============================================================================

def run_cross_lingual_experiment(
source_lang: str = 'en',
target_langs: List[str] = ['zh', 'fr'],
num_epochs: int = 5,
batch_size: int = 16,
device: str = 'cpu'
):
"""
运行跨语言迁移实验
"""
print("="*70)
print("Cross-Lingual Transfer Learning Experiment")
print("="*70)

# 创建数据
print("\nCreating synthetic multilingual data...")
data = create_synthetic_multilingual_data(num_samples_per_lang=200)

# 加载 tokenizer
print("\nLoading multilingual BERT tokenizer...")
tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')

# 创建源语言数据集
print(f"\nPreparing source language ({source_lang}) data...")
train_size = int(0.8 * len(data[source_lang][0]))

source_train_texts = data[source_lang][0][:train_size]
source_train_labels = data[source_lang][1][:train_size]
source_test_texts = data[source_lang][0][train_size:]
source_test_labels = data[source_lang][1][train_size:]

train_dataset = MultilingualDataset(source_train_texts, source_train_labels, tokenizer)
source_test_dataset = MultilingualDataset(source_test_texts, source_test_labels, tokenizer)

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
source_test_loader = DataLoader(source_test_dataset, batch_size=batch_size, shuffle=False)

# 创建目标语言测试集
target_test_loaders = {}
for lang in target_langs:
test_texts = data[lang][0]
test_labels = data[lang][1]
test_dataset = MultilingualDataset(test_texts, test_labels, tokenizer)
target_test_loaders[lang] = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

# 创建模型
print("\nInitializing model...")
model = MultilingualTextClassifier(num_classes=3).to(device)

# 优化器和损失函数
optimizer = optim.Adam(model.parameters(), lr=2e-5)
criterion = nn.CrossEntropyLoss()

# ========================================================================
# 在源语言上训练
# ========================================================================
print(f"\n{'='*70}")
print(f"Training on source language: {source_lang}")
print(f"{'='*70}")

train_accuracies = []

for epoch in range(num_epochs):
train_loss, train_acc = train_epoch(model, train_loader, optimizer, criterion, device)
train_accuracies.append(train_acc)

# 在源语言测试集上评估
source_acc, _, _ = evaluate(model, source_test_loader, device)

print(f"Epoch [{epoch+1}/{num_epochs}]")
print(f" Train Loss: {train_loss:.4f}, Train Acc: {train_acc:.4f}")
print(f" {source_lang} Test Acc: {source_acc:.4f}")

# ========================================================================
# 零样本跨语言评估
# ========================================================================
print(f"\n{'='*70}")
print("Zero-Shot Cross-Lingual Evaluation")
print(f"{'='*70}")

results = {source_lang: source_acc}

for lang in target_langs:
acc, preds, labels = evaluate(model, target_test_loaders[lang], device)
results[lang] = acc

print(f"\n{source_lang} -> {lang} Zero-Shot Accuracy: {acc:.4f}")
print(f"Classification Report:")
print(classification_report(labels, preds, target_names=['positive', 'neutral', 'negative']))

# 计算平均性能和迁移差距
avg_acc = np.mean(list(results.values()))
transfer_gaps = {lang: results[source_lang] - results[lang] for lang in target_langs}

print(f"\n{'='*70}")
print("Summary")
print(f"{'='*70}")
print(f"Average Accuracy across all languages: {avg_acc:.4f}")
print(f"\nTransfer Gaps:")
for lang, gap in transfer_gaps.items():
print(f" {source_lang} -> {lang}: {gap:.4f}")

return results, transfer_gaps

# ============================================================================
# 可视化
# ============================================================================

def plot_cross_lingual_results(results: Dict[str, float], transfer_gaps: Dict[str, float]):
"""
可视化跨语言迁移结果
"""
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 1. 各语言准确率
languages = list(results.keys())
accuracies = list(results.values())

colors = ['#2ecc71' if lang == list(results.keys())[0] else '#3498db' for lang in languages]

axes[0].bar(languages, accuracies, color=colors, alpha=0.8)
axes[0].set_xlabel('Language', fontsize=12)
axes[0].set_ylabel('Accuracy', fontsize=12)
axes[0].set_title('Zero-Shot Cross-Lingual Accuracy', fontsize=14, fontweight='bold')
axes[0].set_ylim([0, 1])
axes[0].grid(True, alpha=0.3, axis='y')

# 添加数值标注
for i, (lang, acc) in enumerate(zip(languages, accuracies)):
axes[0].text(i, acc + 0.02, f'{acc:.3f}', ha='center', fontsize=10)

# 2. 迁移差距
target_langs = list(transfer_gaps.keys())
gaps = list(transfer_gaps.values())

axes[1].bar(target_langs, gaps, color='#e74c3c', alpha=0.8)
axes[1].set_xlabel('Target Language', fontsize=12)
axes[1].set_ylabel('Transfer Gap', fontsize=12)
axes[1].set_title('Cross-Lingual Transfer Gap', fontsize=14, fontweight='bold')
axes[1].grid(True, alpha=0.3, axis='y')

# 添加数值标注
for i, (lang, gap) in enumerate(zip(target_langs, gaps)):
axes[1].text(i, gap + 0.01, f'{gap:.3f}', ha='center', fontsize=10)

plt.tight_layout()
plt.savefig('cross_lingual_transfer.png', dpi=150, bbox_inches='tight')
plt.close()
print("\nVisualization saved to cross_lingual_transfer.png")

# ============================================================================
# 主函数
# ============================================================================

def main():
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Using device: {device}")

# 运行实验
results, transfer_gaps = run_cross_lingual_experiment(
source_lang='en',
target_langs=['zh', 'fr'],
num_epochs=5,
batch_size=16,
device=device
)

# 可视化
plot_cross_lingual_results(results, transfer_gaps)

print("\n" + "="*70)
print("Experiment completed!")
print("="*70)

if __name__ == "__main__":
main()

代码说明

核心组件

  1. MultilingualTextClassifier:基于 mBERT 的分类器
  2. MultilingualDataset:多语言数据加载
  3. 零样本迁移:在英语上训练,在中文/法语上测试

实验设计

  1. 在源语言(英语)上训练情感分类器
  2. 零样本迁移到目标语言(中文、法语)
  3. 计算迁移差距和平均性能

关键细节

  • 使用 mBERT 的共享表示空间
  • 无目标语言标注数据
  • 评估跨语言迁移效果

跨语言迁移的挑战与前沿

语言差异的影响

语系相似性

发现:语系相近的语言迁移效果更好13

源→目标 准确率
英语→法语(同语系) 78.3
英语→中文(不同语系) 69.1
法语→西班牙语(同语系) 81.7

原因: - 词序相似( SVO vs SOV) - 共享词汇(拉丁语系) - 语法结构接近

文字系统

发现:相同文字系统的语言迁移更容易。

文字系统 示例语言 迁移难度
拉丁字母 英、法、德、西
汉字 中、日(部分)
阿拉伯字母 阿拉伯语、波斯语
其他(泰语、韩语) -

低资源语言的挑战

问题

  1. 预训练数据不足: Wikipedia 页面少(如斯瓦希里语只有几千篇)
  2. 词汇覆盖率低: mBERT 的 110K 词汇中,低资源语言占比小
  3. 语言漂移( Language Drift):高资源语言主导训练,低资源语言表示退化

改进方向

  1. 专用词汇表:为低资源语言单独设计子词表
  2. 数据增强:用高资源语言的翻译数据增强低资源语言
  3. 适应性预训练:在低资源语言上继续预训练

多语言模型的偏见

问题:多语言模型存在语言偏见14

  • 英语性能通常最好(因为预训练数据最多)
  • 低资源语言性能显著下降
  • 文化相关任务(如情感分类)跨语言差异大

度量:语言间性能方差:

缓解策略

  1. 平衡采样:低资源语言采样概率上调
  2. 对抗训练:最小化语言判别器的准确率
  3. 多任务学习:加入语言识别任务,强制学习语言差异

常见问题解答

Q1: mBERT 没用平行语料,为什么能跨语言?

关键因素

  1. 锚点词汇( Anchor Words)
    • 数字: 1, 2, 3(所有语言共享)
    • 标点:, . ! ?
    • 英文借词: OK, Internet, COVID
  2. 深层参数共享
    • 强制不同语言通过相同的 Transformer 层
    • 模型被迫学习语言无关特征
  3. WordPiece 分解
    • 将词分解为子词单元
    • 增加跨语言词汇重叠

实验证据15:移除锚点词汇,跨语言性能下降 15-20%。

Q2: 如何选择源语言?

经验规则

  1. 数据量优先:选择标注数据最多的语言(通常是英语)
  2. 语系相似性:如果目标语言是法语,选择西班牙语比选择中文好
  3. 多源策略:结合多个源语言(英语+德语→法语)

实验:在 XNLI 上,不同源语言到法语的零样本准确率:

源语言 准确率
英语 78.3
西班牙语 81.2
德语 79.7
中文 71.5

西班牙语最佳(同为罗曼语系)。

Q3: 翻译-训练 vs 零样本迁移,哪个更好?

权衡

维度 翻译-训练 零样本迁移
性能 更高(+2-5%) 较低
成本 高(需翻译) 低(无需翻译)
推理延迟
依赖翻译质量

推荐: - 高资源语言:零样本迁移(翻译质量高但不必要) - 低资源语言:翻译-训练(弥补模型在低资源语言上的弱点)

Q4: XLM-R 比 mBERT 好在哪?

核心改进

  1. 更大规模
    • mBERT:几 GB Wikipedia
    • XLM-R: 2.5TB CommonCrawl
  2. 更平衡的语言采样
    • mBERT:高资源语言主导
    • XLM-R:(缓解不平衡)
  3. 更多参数
    • mBERT: 110M
    • XLM-R: 550M

性能提升:在 XNLI 上, XLM-R 比 mBERT 平均高 10%。

Q5: 如何处理代码转换( Code-Switching)?

策略

  1. 数据增强
    • 随机替换词为其他语言的翻译
    • 保持句法结构
  2. 多语言预训练
    • 收集真实的代码转换数据(如 Twitter)
    • 混入预训练语料
  3. 语言标签
    • 为每个 token 添加语言 ID
    • 模型学习语言切换模式

效果:在代码转换基准( GLUECoS)上,加入代码转换数据增强,准确率提升 5-10%。

Q6: 跨语言迁移能用在生成任务吗?

可以!常见应用:

  1. 机器翻译:源语言训练,目标语言生成
  2. 跨语言摘要:英语文档→中文摘要
  3. 跨语言问答:中文问题→英语答案→翻译回中文

模型: mT5 、 mBART 等编码器-解码器模型。

挑战: - 生成流畅性要求高 - 需要处理语序差异 - 文化适应性(如习语翻译)

Q7: 多语言模型会"遗忘"高资源语言吗?

会!现象称为"语言竞争( Language Competition)"16

表现: - 在低资源语言上微调后,英语性能下降 - 加入新语言预训练,旧语言性能退化

缓解: - 多任务学习:同时优化所有语言 - 正则化: EWC 等方法(见第 10 章持续学习) - 语言适配器( Language Adapters):每个语言独立参数

Q8: 如何评估跨语言迁移的质量?

标准基准

  1. XNLI:跨语言自然语言推理( 15 种语言)
  2. XTREME:跨语言多任务基准( 40 种语言, 9 个任务)
  3. MLQA:多语言问答( 7 种语言)
  4. TyDiQA:多样类型语言问答( 11 种语言,涵盖低资源语言)

评估指标: - 零样本准确率 - 迁移差距 - 语言间性能方差

Q9: 跨语言迁移的理论极限是什么?

信息论视角17

跨语言迁移的上界受限于语言间的互信息( Mutual Information)

$$

I(L_s; L_t) = _{x_s, x_t} p(x_s, x_t) $$

直觉:语言越相似,互信息越高,迁移上界越高。

经验: - 同语系语言:,迁移差距 <5% - 不同语系:,迁移差距 >15%

突破方向: - 利用中间语言( Pivot Language) - 多语言预训练增加语言共性

Q10: 如何为新语言添加跨语言支持?

流程

  1. 收集单语数据: Wikipedia 、新闻、社交媒体
  2. 扩展词汇表:为新语言添加子词
  3. 适应性预训练:在新语言上继续 MLM
  4. 零样本评估:在下游任务上测试
  5. 少样本微调:如有少量标注数据,微调提升

案例:为斯瓦希里语添加支持:

步骤 零样本准确率
基线( XLM-R) 68.4
+ 适应性预训练 72.1 (+3.7)
+ 100 样本微调 76.8 (+4.7)

Q11: 多语言模型的推理开销如何?

对比

模型 参数量 推理时间(相对)
BERT-base 110M 1.0x
mBERT 110M 1.0x(相同)
XLM-R-base 270M 1.5x
XLM-R-large 550M 3.0x

结论:多语言模型推理开销主要取决于模型大小,而非语言数量。

优化: - 模型蒸馏:将 XLM-R 蒸馏到更小模型 - 语言特定裁剪:只保留目标语言的词汇

Q12: 未来跨语言研究的方向?

热点

  1. 极低资源语言
    • 地球上 7000+语言,大多数无数字资源
    • 利用语言学知识(语法、音系)
  2. 多模态跨语言
    • 图像-文本跨语言对齐
    • 视频-文本跨语言理解
  3. 跨语言常识推理
    • 不同文化的常识知识差异
    • 如何迁移文化相关知识?
  4. 可解释性
    • 为什么 mBERT 能跨语言?
    • 多语言表示的几何结构
  5. 高效多语言模型
    • 参数共享 vs 语言特定参数
    • 稀疏激活(只激活相关语言的参数)

小结

本文全面介绍了跨语言迁移技术:

  1. 问题定义:零样本、少样本、多源语言迁移
  2. 数学原理:共享语义空间、双语词嵌入对齐、语言共性理论
  3. 多语言预训练: mBERT 、 XLM-R 、 mT5 的架构与对比
  4. 迁移策略:直接迁移、翻译-训练、翻译-测试、集成方法
  5. 提示学习:多语言提示模板、自动搜索、语言无关连续提示
  6. 代码转换:数据增强、语言混合、自适应预训练
  7. 完整代码:从零实现跨语言文本分类的 280+行代码
  8. 挑战与前沿:语言差异、低资源语言、模型偏见、理论极限

跨语言迁移让 AI 惠及全球 70 亿人口,打破语言壁垒。下一章我们将探讨迁移学习在工业界的应用与最佳实践,看如何将理论转化为生产力。

参考文献


  1. Conneau, A., Lample, G., Ranzato, M. A., et al. (2018). Word translation without parallel data. ICLR.↩︎

  2. Conneau, A., & Lample, G. (2019). Cross-lingual language model pretraining. NeurIPS.↩︎

  3. Artetxe, M., & Schwenk, H. (2019). Massively multilingual sentence embeddings for zero-shot cross-lingual transfer and beyond. TACL.↩︎

  4. Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2019). BERT: Pre-training of deep bidirectional transformers for language understanding. NAACL.↩︎

  5. Pires, T., Schlinger, E., & Garrette, D. (2019). How multilingual is multilingual BERT? ACL.↩︎

  6. Conneau, A., Khandelwal, K., Goyal, N., et al. (2020). Unsupervised cross-lingual representation learning at scale. ACL.↩︎

  7. Xue, L., Constant, N., Roberts, A., et al. (2021). mT5: A massively multilingual pre-trained text-to-text transformer. NAACL.↩︎

  8. Jiang, Z., Xu, F. F., Araki, J., & Neubig, G. (2020). How can we know what language models know? TACL.↩︎

  9. Shin, T., Razeghi, Y., Logan IV, R. L., et al. (2020). AutoPrompt: Eliciting knowledge from language models with automatically generated prompts. EMNLP.↩︎

  10. Wu, S., & Dredze, M. (2020). Are all languages created equal in multilingual BERT? RepL4NLP.↩︎

  11. Winata, G. I., Madotto, A., Wu, Z., & Fung, P. (2019). Code-switching BERT: A task-agnostic language model for code-switching. arXiv:1908.05075.↩︎

  12. Alabi, J., Amponsah-Kaakyire, K., Adelani, D., & Eskenazi, M. (2020). Massive vs. curated embeddings for low-resourced languages: the case of Yor ù b á and Twi. LREC.↩︎

  13. Hu, J., Ruder, S., Siddhant, A., et al. (2020). XTREME: A massively multilingual multi-task benchmark for evaluating cross-lingual generalisation. ICML.↩︎

  14. Lauscher, A., Ravishankar, V., Vulic, I., & Glavas, G. (2020). From zero to hero: On the limitations of zero-shot language transfer with multilingual transformers. EMNLP.↩︎

  15. Pires, T., Schlinger, E., & Garrette, D. (2019). How multilingual is multilingual BERT? ACL.↩︎

  16. Artetxe, M., Ruder, S., & Yogatama, D. (2020). On the cross-lingual transferability of monolingual representations. ACL.↩︎

  17. Zhao, W., Eger, S., Bjerva, J., & Augenstein, I. (2021). Inducing language-agnostic multilingual representations. ACL.↩︎

  • 本文标题:迁移学习(十一)—— 跨语言迁移
  • 本文作者:Chen Kai
  • 创建时间:2025-01-02 10:30:00
  • 本文链接:https://www.chenk.top/%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0%EF%BC%88%E5%8D%81%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94-%E8%B7%A8%E8%AF%AD%E8%A8%80%E8%BF%81%E7%A7%BB/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论