Fairseq M2M-100 多语言分词指南:tok.sh 原理、安装与 BLEU 评估复现
【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq
M2M-100 是 Fairseq 中面向 100 种语言互译的多语言序列到序列模型,而不同语系在形态学、书写系统上差异巨大,单一分词策略无法兼顾所有语言。本文以 examples/m2m_100/tokenizers/README.md 为主线,深入讲解 Fairseq 官方为 M2M-100 提供的tok.sh分词器:其按语言分派不同分词后端的实现原理、依赖安装步骤,以及如何在fairseq-generate输出后用它完成与论文一致的 tokenize 后处理与 sacreBLEU 评估。读完本文,你将能在本地完整复现 M2M-100 论文的分词与评测流程。
1. 为什么 M2M-100 需要"按语言"分词
M2M-100 覆盖 100 种语言,涵盖罗马字母书写语言、中文/日文/韩文(CJK)、泰语、缅甸语、阿拉伯语、印度诸语言(印地语、尼泊尔语、僧伽罗语)等。这些语言在分词层面面临完全不同的问题:
- 大多数欧洲语言、拉丁系语言可以用 Moses 通用 tokenizer 处理;
- 中文、日文、泰文等语言词与词之间没有空格,需要专门的分词器;
- 韩语(朝鲜语)需要形态分析器(MeCab)做词素切分;
- 罗马尼亚语需要先做特殊规范化(如去除变音符号)再分词;
- 阿拉伯语需要专门的形态归一化工具;
- 印地语、尼泊尔语、僧伽罗语等印度语言需要 IndicNLP 库进行归一化与切分。
因此,tok.sh的定位是一个"分语言路由"的统一入口:根据目标语言代码,把输入文本管道化地交给对应的第三方工具处理,从而复现论文中的分词与 BLEU 评测结果。
2. tok.sh:统一入口与语言分派逻辑
仓库中的主脚本位于 examples/m2m_100/tok.sh,它从标准输入读取文本,按第一个参数(语言代码)选择不同处理流水线:
lg=$1 MOSES=$INSTALL_PATH/mosesdecoder REPLACE_UNICODE_PUNCT=$MOSES/scripts/tokenizer/replace-unicode-punctuation.perl NORM_PUNC=$MOSES/scripts/tokenizer/normalize-punctuation.perl REM_NON_PRINT_CHAR=$MOSES/scripts/tokenizer/remove-non-printing-char.perl TOKENIZER=$MOSES/scripts/tokenizer/tokenizer.perl各语言的处理分支如下:
| 语言代码 | 处理方式 | 依赖工具 |
|---|---|---|
zh(中文) | replace-unicode-punctuation→normalize-punctuation→remove-non-printing-char→tokenize_zh.py | Moses + sacrebleu |
th(泰语) | tokenize_thai.py | pythainlp |
ja(日语) | 去空白后由 KyTea 切分(seg_ja.sh) | KyTea |
ko(韩语) | MeCab-O wakati词素切分(seg_ko.sh) | MeCab + mecab-ko-dic |
ro(罗马尼亚语) | Moses 标准化管道 +normalise-romanian.py+remove-diacritics.py+ Moses tokenizer | Moses + wmt16-scripts |
my(缅甸语) | seg_my.py(来自 WAT2020 语料库脚本) | Python3 |
ar(阿拉伯语) | tokenizer_ar.sh(QCRI 归一化 + MADA/ARAMORPH) | QCRI 阿拉伯语工具 |
ne/si/hi(印度语言) | tokenize_indic.py $lg | indic-nlp-library + indic_nlp_resources |
| 其他语言 | Moses 通用流水线:replace-unicode-punctuation→normalize-punctuation→remove-non-printing-char→tokenizer.perl -no-escape -threads 8 | Moses |
以中文分支为例:
if [ "$lg" = "zh" ]; then cat - | $REPLACE_UNICODE_PUNCT | $NORM_PUNC -l $lg | $REM_NON_PRINT_CHAR | python $CHINESE_TOKENIZER而 tokenize_zh.py 的实现极简——直接调用 sacrebleu 内置的中文分词:
import fileinput import sacrebleu for line in fileinput.input(): print(sacrebleu.tokenize_zh(line))泰语 tokenize_thai.py 则借助 pythainlp 的word_tokenize逐行分词,并以空格连接:
from pythainlp import word_tokenize for line in sys.stdin: print(" ".join(word_tokenize(line.strip())))印度语言 tokenize_indic.py 先通过IndicNormalizerFactory对文本做归一化(remove_nuktas=False, nasals_mode="do_nothing"),再用trivial_tokenize完成切分:
factory = IndicNormalizerFactory() normalizer = factory.get_normalizer( sys.argv[1], remove_nuktas=False, nasals_mode="do_nothing" ) for line in sys.stdin: normalized_line = normalizer.normalize(line.strip()) tokenized_line = " ".join(trivial_tokenize(normalized_line, sys.argv[1])) print(tokenized_line)日语与韩语各自封装成独立的 shell 脚本。日语 seg_ja.sh 先将文本中的空白字符全部删除,再交给 KyTea 输出无标签切分结果:
cat - | tr -d "[:blank:]" | kytea -notags韩语 seg_ko.sh 则通过 MeCab 的-O wakati模式输出以空格分隔的词素序列:
cat - | mecab -O wakati阿拉伯语 tokenizer_ar.sh 需要用户预先安装 QCRI 的阿拉伯语归一化工具,并在脚本中填写SVMTOOL、GOMOSESGO、QCRI_ARABIC_NORMALIZER三个环境路径后,才会执行 MADA/ARAMORPH 归一化流水线;脚本中默认保留了一段提示信息用于引导安装,未配置时会直接退出。
3. 依赖安装:install_dependecies.sh 做了什么
除阿拉伯语外,其余语言所需的工具均可通过 examples/m2m_100/install_dependecies.sh 一键安装。该脚本将所有第三方工具克隆/下载到tokenizers/thirdparty目录,具体包含:
- Mosesdecoder:
git clone后固定 checkout 到03578921cc1a03402这个 commit(注释说明是为处理'与"的处理差异),提供replace-unicode-punctuation.perl、normalize-punctuation.perl、remove-non-printing-char.perl、tokenizer.perl等核心脚本; - wmt16-scripts:提供罗马尼亚语专用的
normalise-romanian.py与remove-diacritics.py; - KyTea:日文分词器,
autoreconf -i && ./configure --prefix=pwd`` 后make && make install本地安装; - MeCab(韩语版):下载
mecab-0.996-ko-0.9.2.tar.gz与mecab-ko-dic-2.1.1-20180720.tar.gz,编译安装,并通过mecabrc指向韩语词典目录; - indic_nlp_resources:印度语言归一化所需的资源数据;
- seg_my.py:从 WAT2020 缅甸语数据包中提取,并自动将脚本从 Python2 语法转换为 Python3(
unichr→chr、sys.std注释化); - pip 包:
pythainlp、sacrebleu、indic-nlp-library。
阿拉伯语因依赖 MADA/ARAMORPH 等第三方许可工具,需要单独按照 QCRI 提供的说明安装(即tokenizers/README.md中给出的http://alt.qcri.org/tools/arabic-normalizer/指引),并在 tokenizer_ar.sh 中更新环境变量后使用。
4. 复现论文结果:从模型输出到 BLEU
4.1 完整评估流水线
tokenizers/README.md给出了与论文一致的三步评估流程。首先需要已通过fairseq-generate生成翻译结果,其标准命令(参见 examples/m2m_100/README.md)形如:
fairseq-generate \ data_bin \ --batch-size 1 \ --path 12b_last_chk_4_gpus.pt \ --fixed-dictionary model_dict.128k.txt \ -s de -t fr \ --remove-bpe 'sentencepiece' \ --beam 5 \ --task translation_multi_simple_epoch \ --lang-pairs language_pairs.txt \ --decoder-langtok --encoder-langtok src \ --gen-subset test \ --fp16 \ --dataset-impl mmap \ --distributed-world-size 1 --distributed-no-spawn \ --pipeline-model-parallel \ --pipeline-chunks 1 \ --pipeline-encoder-balance '[1,15,10]' \ --pipeline-encoder-devices '[0,1,0]' \ --pipeline-decoder-balance '[3,11,11,1]' \ --pipeline-decoder-devices '[0,2,3,0]' > gen_out然后执行分词后处理(示例以法语为目标语言):
tgt_lang=... reference_translation=... cat generation_output | grep -P "^H" | sort -V | cut -f 3- | sh tok.sh $tgt_lang > hyp cat $reference_translation | sh tok.sh $tgt_lang > ref sacrebleu -tok 'none' ref < hyp各步骤含义:
grep -P "^H":提取fairseq-generate输出中以H-开头的假设(hypothesis)行;sort -V:按版本号自然排序,保证假设与参考句按索引对应;cut -f 3-:去掉行首的H-<id>\t<score>前缀,只保留翻译文本;sh tok.sh $tgt_lang:按目标语言对假设/参考句做论文一致的分词;sacrebleu -tok 'none':因为分词已由tok.sh完成,BLEU 计算时不再做额外 tokenization。
在 examples/m2m_100/README.md 中同样记录了这套流程的实际调用:
cd ${fairseq}/examples/m2m_100 cat ${fairseq}/gen_out | grep -P "^H" | sort -V | cut -f 3- | sh tok.sh fr > hyp cat ${fairseq}/raw_input.de-fr.fr | sh tok.sh fr > refsacrebleu -tok 'none' ref < hyp4.2 一个重要的前置约束
examples/m2m_100/README.md明确提醒:所有评测数据集在进入 SPM(SentencePiece)数据预处理之前,必须先做 detokenize 处理(例如 TED 数据集需要使用 Moses 的 detokenizer)。这是因为 M2M-100 的数据管线先做文本级分词/反分词,再统一套用 SPM 子词切分;评测阶段再通过tok.sh恢复与论文一致的分词粒度,以保证 BLEU 分数可直接对比。
5. 实战要点小结
- 运行
tok.sh前务必先执行 examples/m2m_100/install_dependecies.sh(在examples/m2m_100目录下),并确认tokenizers/thirdparty已就绪; tok.sh以标准输入为文本来源、以$1语言代码为路由键,适合与cat、grep、cut等管道命令自由组合;- 评测 BLEU 时必须使用
sacrebleu -tok 'none',避免二次分词导致分数失真; - 阿拉伯语(
ar)是唯一需要手工安装外部工具的语种,未配置前tokenizer_ar.sh会提示安装指引并退出; - 参考句与假设句必须使用同一目标语言的同一套分词管道,否则 BLEU 计算在 token 对齐层面会出现偏差。
通过上述步骤,你可以用与 M2M-100 论文完全一致的分词口径,在本地复现任意 100 语言方向上的 BLEU 评测,并以此为基础进行后续实验对照。
【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考