fairseq 中的 XStoryCloze 多语言数据集:从 StoryCloze 专业翻译到零样本/少样本评测实践
【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq
XStoryCloze 是 FAIR(Fundamental Artificial Intelligence Research)在论文 Few-shot Learning with Multilingual Generative Language Models(EMNLP 2022) 中随 XGLM 多语言生成式语言模型一同发布的多语言评测数据集,由英文 StoryCloze 数据集(Spring 2016 版)验证集的专业翻译扩展至 10 种语言。本文将基于 examples/xglm/XStoryCloze.md 及其配套的 examples/xglm/README.md、examples/xglm/model_card.md,完整介绍该数据集的构成、语言覆盖、数据划分方案,并结合 fairseq 仓库源码讲解如何将其用于多语言模型的零样本(zero-shot)与少样本(few-shot)能力评测。
数据集背景与定位
XStoryCloze 的核心内容是对英文 StoryCloze 数据集验证集(Spring 2016 版本)的专业翻译。原始英文 StoryCloze 通过 罗切斯特大学官方渠道 申请获取,而 XStoryCloze 则由 FAIR 团队将其中每个故事样例翻译成 10 种语言,形成一份专门用于衡量多语言语言模型零样本与少样本学习能力的评测基准。
从 examples/xglm/model_card.md 的评测数据说明可以看到,XStoryCloze 与 XNLI、XCOPA、XWinograd、PAWS-X 一起构成了 XGLM 模型零样本/少样本评估的核心数据集组合,用于检验模型在"从自然语言描述和少量示例中学习任务"这一能力上的跨语言表现。因此,XStoryCloze 的价值不仅在于其本身是一个多语言故事补全评测集,更在于它是 XGLM 论文主张的"多语言少样本学习"能力的直接证据来源。
语言覆盖:10 种类型学上多样的语言
XStoryCloze 覆盖以下 10 种语言:
ru(俄语)、zh(简体中文)、es(拉丁美洲西班牙语)、ar(阿拉伯语)、hi(印地语)、id(印度尼西亚语)、te(泰卢固语)、sw(斯瓦希里语)、eu(巴斯克语)、my(缅甸语)
这 10 种语言在类型学上差异显著,横跨多个语系与文字系统,能够有效检验模型在不同书写系统(西里尔字母、汉字、阿拉伯字母、天城文、缅甸文等)下的跨语言迁移能力。英文原文(en)本身不包含在翻译文件内,需要单独申请获取,再按本文下述划分方案对齐使用。
数据划分:每语言 360/1510 的训练-测试切分
根据 examples/xglm/XStoryCloze.md 的说明,数据集按语言分别切分为 train 与 test 两个部分:
| 划分 | 样例数 |
|---|---|
| train | 360 |
| test(原文档中称为 test / eval) | 1510 |
配套的 examples/xglm/README.md 给出了更完整的逐语言统计表,10 种语言(ar、es、eu、hi、id、my、ru、sw、te、zh)的 Train size 均为 360,Eval size 均为 1511(即 1510 个故事样例外加 1 行 TSV 表头):
| 语言 | ar | es | eu | hi | id | my | ru | sw | te | zh |
|---|---|---|---|---|---|---|---|---|---|---|
| Train size | 360 | 360 | 360 | 360 | 360 | 360 | 360 | 360 | 360 | 360 |
| Eval size | 1511 | 1511 | 1511 | 1511 | 1511 | 1511 | 1511 | 1511 | 1511 | 1511 |
需要注意的是,不同语言的文件之间保持逐行对齐(line-by-line alignment):同一行号在不同语言文件中对应的是同一个故事样例的翻译版本。这一设计保证了跨语言评测时可以使用完全相同的样例索引与标签,方便进行逐语言的公平对比。
获取英文 StoryCloze 并复现数据划分
由于翻译数据基于英文验证集生成,若要获得完整的 en 对照数据(例如做零样本评测时对比英文与多语言效果),需要先申请原始英文 StoryCloze 数据集,然后按照 XStoryCloze 相同的划分方案切分英文数据。原始文档给出了直接可用的 shell 命令,其划分逻辑是:
- 取
spring2016.val.tsv的前 361 行作为训练集(其中包含 1 行 TSV 表头 + 360 个样例); - 取第 1 行作为 eval 文件表头,再追加尾部 1511 行作为 eval 集(1 行表头 + 1511 行内容,与上表 Eval size 一致)。
具体命令如下:
head -361 spring2016.val.tsv > spring2016.val.en.tsv.split_20_80_train.tsv head -1 spring2016.val.tsv > spring2016.val.en.tsv.split_20_80_eval.tsv # TSV header tail -1511 spring2016.val.tsv >> spring2016.val.en.tsv.split_20_80_eval.tsv命令执行后,你将得到与 XStoryCloze 各语言文件完全对齐的英文训练/测试划分,可以用于构建en对照评测集。
评测方式:基于 XGLM 的零样本/少样本评估
XStoryCloze 的设计目标正是评测零样本与少样本学习能力(examples/xglm/XStoryCloze.md 中明确指出 "This dataset is intended to be used for evaluating the zero- and few-shot learning capabilities of multilingual language models")。在 fairseq 仓库中,评测 XGLM 类多语言模型的标准流程由 examples/xglm/README.md 给出,核心 API 是TransformerLanguageModel.from_pretrained与lm.score。
预训练数据格式与换行处理
XGLM 模型的预训练数据以"段落用单换行分隔、文档用双换行分隔"的格式组织。fairseq 的预处理会把换行符替换为句末符号</s>,因此模型在预训练期间从未见过\n字符。这意味着在少样本推理前,必须对输入执行同样的换行替换预处理,否则会与预训练分布不一致、拉低评测效果。原始文档给出如下示例:
from fairseq.models.transformer_lm import TransformerLanguageModel model_dir = 'path_to_decompressed_tar_gz_dir' lm = TransformerLanguageModel.from_pretrained(model_dir, bpe='sentencepiece') text = """First paragraph of the first document. Second paragraph of the first document. First paragraph of the second document. """ tokens = lm.score(text, replace_newlines_with_eos=True)['tokens'] assert '\n' not in lm.decode(tokens) # no newlines were encoded从源码实现看,score方法定义在 fairseq/hub_utils.py:
def score(self, sentences, replace_newline_with_eos=False, **kwargs): ... def encode(sentence): if replace_newline_with_eos: return torch.cat([self.encode(line) for line in sentence.splitlines()]) else: return self.encode(sentence) # NOTE: this doesn't support translation tasks currently tokenized_sentences = [encode(sentence) for sentence in sentences] return [hypos[0] for hypos in self.generate(tokenized_sentences, score_reference=True, **kwargs)]可以看到,当replace_newline_with_eos=True时,输入文本按行splitlines()切分,每行独立编码后再沿 token 维度拼接——由于 fairseq 的编码器(SentencePiece)会把行尾处理为</s>,最终 token 序列中不会残留\n。score内部通过generate(..., score_reference=True)走 SequenceScorer 对参考文本逐位置打分,返回的positional_scores即每个 token 的对数概率。TransformerLanguageModel本体则定义在 fairseq/models/transformer_lm.py,其hub_models中内置了多种已发布 LM 的加载入口。
零样本 COPA 评测范式(可直接迁移到 XStoryCloze)
examples/xglm/README.md 以 COPA(Choice of Plausible Alternatives)为例演示了完整的零样本评测流程。虽然评测对象是 COPA,但该方法论可以直接套用到 XStoryCloze 上:XStoryCloze 同样基于故事补全任务,评测时对每个故事的候选结尾计算语言模型对数概率并取较优者。示例数据(英文、中文、印地语/海地语克里奥尔语样本)定义如下:
data_samples = { 'en': [ { "premise": "I wanted to conserve energy.", "choice1": "I swept the floor in the unoccupied room.", "choice2": "I shut off the light in the unoccupied room.", "question": "effect", "label": "1" }, ... ], 'zh': [...], 'hi': [...] }评测代码使用三种语言共享的{premise}\n{choice1}、{premise}\n{choice2}非语言提示(non-verbal prompts)模板:
from fairseq.models.transformer_lm import TransformerLanguageModel model_dir = 'path_to_decompressed_tar_gz_dir' lm = TransformerLanguageModel.from_pretrained(model_dir, bpe='sentencepiece') lm = lm.eval() lm = lm.half() lm = lm.cuda() def get_logprobs(prompt): import re prompt = re.sub('\n+' , '\n', prompt) # collapse repeated newlines, which indicate separate documents return lm.score(prompt, replace_newlines_with_eos=True)['positional_scores'] # Zero-shot evaluation for the Choice of Plausible Alternatives (COPA) task. # A return value of 0 indicates that the first alternative is more plausible, # while 1 indicates that the second alternative is more plausible. def COPA_eval(prompt, alternative1, alternative2): lprob1 = get_logprobs(prompt + "\n" + alternative1).sum() lprob2 = get_logprobs(prompt + "\n" + alternative2).sum() return 0 if lprob1 > lprob2 else 1 for lang in ['en', 'zh', 'hi']: for idx, example in enumerate(data_samples[lang]): predict = COPA_eval(example["premise"], example["choice1"], example["choice2"]) print(f'{lang}-{idx}', predict, example['label'])期望输出为全部预测正确:
en-0 1 1 en-1 0 0 zh-0 1 1 zh-1 0 0 hi-0 1 1 hi-1 0 0这段流程中的几个关键点同样适用于 XStoryCloze 评测:
re.sub('\n+', '\n', prompt):折叠连续换行,因为双换行在预训练数据中表示文档分隔;replace_newlines_with_eos=True:保持与预训练预处理一致,详见上文源码分析;- 逐 token 对数概率求和:
lm.score(...)['positional_scores'].sum()作为候选文本的似然估计,取似然更高的候选项作为模型预测; - 少样本扩展:只需在 prompt 前拼接若干带标签示例(few-shot exemplars)即可从零样本切换为少样本评测,这正是 XStoryCloze 设计意图所覆盖的场景。
此外,若不需要逐位置分数而希望快速批量打分,也可以使用 fairseq 自带的 fairseq_cli/eval_lm.py,其内部通过 fairseq/sequence_scorer.py 中的SequenceScorer对参考序列打分,与lm.score走的是同一条评分链路(scorer.generate(models, sample)),返回的positional_scores可直接汇总为困惑度或对数似然。
许可证
XStoryCloze 在CC BY-SA 4.0许可下开源,与原始英文 StoryCloze 采用相同的许可证(examples/xglm/XStoryCloze.md)。使用该数据集时请遵守相应的署名与相同方式共享要求。
引用
如果你在研究或工作中使用了 XStoryCloze,请按如下方式引用(BibTeX 见 examples/xglm/XStoryCloze.md):
@article{DBLP:journals/corr/abs-2112-10668, author = {Xi Victoria Lin and Todor Mihaylov and Mikel Artetxe and Tianlu Wang and Shuohui Chen and Daniel Simig and Myle Ott and Naman Goyal and Shruti Bhosale and Jingfei Du and Ramakanth Pasunuru and Sam Shleifer and Punit Singh Koura and Vishrav Chaudhary and Brian O'Horo and Jeff Wang and Luke Zettlemoyer and Zornitsa Kozareva and Mona T. Diab and Veselin Stoyanov and Xian Li}, title = {Few-shot Learning with Multilingual Language Models}, journal = {CoRR}, volume = {abs/2112.10668}, year = {2021}, url = {https://arxiv.org/abs/2112.10668}, eprinttype = {arXiv}, eprint = {2112.10668}, timestamp = {Tue, 04 Jan 2022 15:59:27 +0100}, biburl = {https://dblp.org/rec/journals/corr/abs-2112-10668.bib}, bibsource = {dblp computer science bibliography, https://dblp.org} }总结
XStoryCloze 为多语言少样本学习研究提供了一个高质量、跨语言对齐的评测基准:10 种类型学多样的语言、每语言 360 条训练/1510 条测试样例、与英文 StoryCloze 保持逐行对齐,且附带了可直接复现的英文数据划分命令。结合 fairseq 仓库中TransformerLanguageModel.score(fairseq/hub_utils.py)的换行处理实现与 examples/xglm/README.md 给出的零样本评测范式,研究者可以快速搭建一套用于衡量多语言语言模型跨语言常识推理与少样本学习能力的标准评估流程。更多配套说明可进一步阅读 examples/xglm/model_card.md 与 examples/xglm/README.md。
【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考