Update: 2018/12/17
我们对中文使用基于字符的标记化,对所有其他语言使用 WordPiece 标记化。两种模型都应该开箱即用,不需要修改任何代码。
模型
目前有两种多语言模型可供选择。我们不打算发布更多单语言模型,但我们可能会在未来发布这两种版本的BERT-Large版本:
多语言 Cased 模型修复了许多语言的规范化问题,因此建议使用非拉丁字母表的语言(对于大多数使用拉丁字母的语言,通常表现的比较好)。 使用此模型时,请确保将–do_lower_case = false传递给run_pretraining.py和其他脚本。
请参阅多语言模型支持的语言列表。多语言模型确实包含中文(和英文),但如果您的 Fine-tuning 数据仅限中文,中文模型可能会产生更好的结果。
结果
为了评估不同的系统,我们使用 XNLI 数据集数据集,它是 MultiNLI 的一个版本,其中开发集和测试集已经由人类翻译成15种语言。请注意,训练集是机器翻译的(我们使用的是XNLI提供的翻译,而不是Google NMT)。
系统 | 英文 | 中文 |
---|---|---|
XNLI Baseline - Translate Train | 73.7 | 67.0 |
XNLI Baseline - Translate Test | 73.7 | 68.3 |
BERT - Translate Train Cased | 81.9 | 76.6 |
BERT - Translate Train Uncased | 81.4 | 74.2 |
BERT - Translate Test Uncased | 81.4 | 70.1 |
BERT - Zero Shot Uncased | 81.4 | 63.8 |
前两行是 XNLI 论文的基线,最后四行是我们使用BERT的结果。
Translate Train 意味着 MultiNLI 训练集是用英语机器翻译成外语的。所以训练和评估都是用外语完成的。遗憾的是,训练是使用机器翻译的数据完成的,因此无法量化是由于机器翻译的质量还是预训练模型的质量欠佳导致了较低的准确度(与英语相比)。
Translate Test 意味着 XNLI 测试集是用外语机器翻译成英语的。 所以训练和评估都是用英语完成的。但是,测试是使用机器翻译的英文完成的,因此准确性取决于机器翻译系统的质量。
Zero Shot 意味着多语言 BERT系统在英语MultiNLI上进行了微调,然后在外语XNLI测试中进行了评估。在这种情况下,在预训练或微调中根本不涉及机器翻译。
对于资源较多的语言(英文,中文等),多语言模型比单语言模型表现来得差。以下是用多语言BERT-Base和单语言中文BERT-Base训练中文模型的比较(单语言模型大概好3%):
系统 | 中文 |
---|---|
XNLI Baseline | 67.0 |
BERT Multilingual Model | 74.2 |
BERT Chinese-only Model | 77.2 |
Fine-tuning 例子
多语言模型不需要任何特殊考虑或API更改。 我们在 tokenization.py 中更新了 BasicTokenizer 以支持中文字符标记化,但是,我们并没有改变标记化API。
为了测试新模型,我们在 run_classifier.py 添加了对 XNLI 数据集的支持。 这是 MultiNLI 的15种语言版本,其中开发/测试集已经过人工翻译,训练集经过机器翻译。
要运行我们 fine-tuning 过的代码,请下载 XNLI 开发/测试集和XNLI 机器翻译的训练集,然后将两个 .zip 文件解压缩到目录 $ XNLI_DIR 中。run_classifier.py 中语言默认为中文,因此如果要运行其他语言,请修改 XnliProcessor。
这是一个大型数据集,因此训练将需要几个小时的GPU(或在Cloud TPU上大约30分钟)。 要快速运行实验以进行调试,只需将num_train_epochs 设置为小值(如0.1)即可。
export BERT_BASE_DIR=/path/to/bert/chinese_L-12_H-768_A-12 # or multilingual_L-12_H-768_A-12
export XNLI_DIR=/path/to/xnli
python run_classifier.py \
--task_name=XNLI \
--do_train=true \
--do_eval=true \
--data_dir=$XNLI_DIR \
--vocab_file=$BERT_BASE_DIR/vocab.txt \
--bert_config_file=$BERT_BASE_DIR/bert_config.json \
--init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
--max_seq_length=128 \
--train_batch_size=32 \
--learning_rate=5e-5 \
--num_train_epochs=2.0 \
--output_dir=/tmp/xnli_output/
如果使用单语言中文的模型,结果看起来应该是这样:
***** Eval results *****
eval_accuracy = 0.774116
eval_loss = 0.83554
global_step = 24543
loss = 0.74603
标记化
对于标记化,我们使用110k共享的WordPiece词汇表。单词计数的加权方式与数据相同,因此低资源语言会被某些因素加权。我们故意不使用任何标记来表示输入语言(以便 zero-shot 训练可以工作)。
因为中文(日本汉字、韩国汉字)没有 whitespace,所以在应用 WordPiece 之前,我们在每个 CJK Unicode 范围内的每个字符周围添加空格。这意味着中文实际上是 character-tokenized 的。注意 CJK Unicode 仅仅包括中文字,不包括朝鲜谚文和日文平假片假名,这两者和其他语言一样使用 whitespace+WordPiece 来 tokenized。
对于其他语言,我们应用了与英语相同的处理方式:
我们理解口音标记在某些语言中具有重要意义,但是减少词汇量带来的好处弥补了这一点。通常,BERT的强大上下文模型应该弥补通过移除口音标记引入的任何歧义。
备注:whitespace:空格、\t、\n、\r、\f