ParlAI 中的 ConvAI2 任务全指南:PersonaChat 数据集、模型训练与交互评测实战
【免费下载链接】ParlAIA framework for training and evaluating AI models on a variety of openly available dialogue datasets.项目地址: https://gitcode.com/gh_mirrors/pa/ParlAI
本篇技术指南围绕 ParlAI 仓库中 projects/convai2/README.md 所记录的ConvAI2(NIPS 2018 竞赛)任务展开,系统梳理该闲聊(chit-chat)数据集的多种版本(self/self_revised/none/both)、Teacher 实现、数据构建流程,并给出查看数据、交互对话、训练与评测模型的完整命令。读者读完本文后,将能够在当前 ParlAI 仓库中直接使用--task convai2加载数据、运行预训练模型交互,并理解该任务用于评估"模型利用 persona 进行个性化对话能力"的设计意图。
一、任务背景:从 PersonaChat 到 NIPS 2018 ConvAI2 竞赛
ConvAI2 是 ParlAI 在 NIPS 2018 期间赞助并组织的一场对话 AI 竞赛,其官网为 convai.io。竞赛使用的数据集基于 PersonaChat 论文(arxiv 1801.07243)构建,属于**基于 persona 的闲聊(chit-chat)**任务:每段对话开始前,对话双方各被分配若干条your persona: ...描述,模型需要阅读这些 persona 信息并在此基础上与对方自然交谈。
原项目 README 明确指出,该竞赛代码目前已归档,ParlAI 主分支不再维护旧版竞赛代码;如需使用旧版交互脚本与 baseline 代码,可切换到归档标签:
git checkout convai2archive需要特别说明的是,数据集与 Teacher 部分并未随竞赛代码一起归档,它们始终保留在 ParlAI 主分支中,位于 parlai/tasks/convai2,可以通过--task convai2直接使用。本文后续内容以当前仓库主分支的实际代码为准,归档标签中的内容仅作背景说明。
二、快速开始:查看 ConvAI2 训练数据
在 ParlAI 中加载 ConvAI2 任务的最简单方式是使用display_data脚本,这与查看其他任务完全一致:
parlai display_data -t convai2 -dt train其中:
-t convai2:指定任务为 ConvAI2;-dt train:指定数据类别(datatype)为训练集,也可以换成valid或test。
实际输出的一条训练样本形如(节选自仓库内的示例数据 parlai/tasks/convai2/test/convai2_train.yml):
your persona: i like to remodel homes. your persona: i like to go hunting. your persona: i like to shoot a bow. your persona: my favorite holiday is halloween. hi , how are you doing ? i'm getting ready to do some cheetah chasing to stay in shape .可以看到:每条样本的text以多行your persona:开头,随后是对话历史,而labels是下一句应答;同时每条样本还附带一组label_candidates(候选应答),用于支持排序(ranking)式训练与评测——这正是原 README 中所说的"额外添加了候选以支持基于排序损失的训练/评测"。
三、数据集版本与 Teacher 结构(源码级剖析)
原 README 提到,ConvAI2 数据集存在多个版本,可通过convai2:self、convai2:self_revised和convai2:none访问,分别对应 PersonaChat 论文中的 "original self persona"、"revised self persona" 和 "no persona"。
在源码层面,这些版本被实现为 parlai/tasks/convai2/agents.py 中的一组 Teacher 类,全部继承自FbDeprecatedDialogTeacher(读取经典 FbDialog 格式的.txt数据文件):
任务参数(-t) | Teacher 类 | 对应数据文件 | 说明 |
|---|---|---|---|
convai2 | DefaultTeacher(即SelfOriginalTeacher) | self_original | 默认设置,leaderboard 评测即使用该版本 |
convai2:self | SelfTeacher/SelfOriginalTeacher | self_original | 原始 self persona |
convai2:self_revised | SelfRevisedTeacher | self_revised | 修订后的 self persona |
convai2:none | NoneTeacher | none_original | 无 persona(对照实验用) |
convai2:both | BothTeacher | both_original | 从双方视角提供训练样本,供 self-chat / persona 加载使用 |
其中SelfTeacher只是SelfOriginalTeacher的别名(agents.py 第 78-79 行),DefaultTeacher同样直接继承自SelfOriginalTeacher(agents.py 第 199-200 行)。
3.1 是否携带 label candidates
源码注释(agents.py 第 20-27 行)明确说明:每个 Teacher 默认使用带 label candidates的数据集;如果需要不带候选的版本,使用如下任务标志:
--task convai2:{TEACHER_NAME}:no_cands其中TEACHER_NAME为None、SelfOriginal(或Self)、SelfRevised。以BothTeacher为例(agents.py 第 42-51 行),Teacher 会解析opt['task']的第三段是否为no_cands,从而决定拼接_no_cands后缀的数据文件路径。这在做"候选排序 vs 生成"两类模型对比时非常实用。
3.2 测试集处理逻辑
在_path函数中(agents.py 第 30-39 行)有一段值得注意的逻辑:官方测试集不对外公开,如果用户传入-dt test,系统会打印警告"WARNING: Test set not included. Setting datatype to valid."并自动回退到验证集。这是竞赛隐藏测试集的直接体现——提交评测由官方在隐藏测试集上进行(详见第五节)。
3.3 数据下载与版本管理
数据构建逻辑位于 parlai/tasks/convai2/build.py:
- 数据包:
convai2_fix_723.tgz,下载自http://parl.ai/downloads/convai2/,并带 SHA-256 校验值(build.py 第 14-20 行); - 内部版本号为
v5.0,若本地存在旧版本数据,会自动清理后重新下载(build.py 第 24-39 行); - 数据解压到
datapath/ConvAI2/目录下。
数据集规模可参考 parlai/zoo/bb3/model_card.md 中的汇总:PersonaChat 数据共约 18688 个 episode、131438 条 example,可通过parlai dd -t convai2快速浏览;仓库内置的小样本文件 parlai/tasks/convai2/test/convai2_train.yml 末尾同样标注了num_episodes: 17878、num_examples: 131438。
3.4 标准化 Teacher(NormalizedTeacher)
除原始版本外,任务还提供了一套"规范化"Teacher,用于统一文本格式:NormalizedTeacher、NormalizedBothTeacher、NormalizedTheirTeacher、NormalizedNoneTeacher。其核心逻辑NormalizedTeacherTrait(agents.py 第 94-167 行)提供两个命令行参数:
--your-persona-first(默认True):是否将your persona:置于partner's persona:之前,默认行为与BothTeacher保持一致;--max-num-turns(默认-1):每个 episode 只展示前 X 轮;-1表示展示整个 episode。
此外它会调用parlai.utils.strings.normalize_reply对 persona 句与普通话语进行统一规范化(如标点、大小写处理),保证不同版本数据格式一致。
3.5 世界(Worlds)实现
任务还提供了两个专用 World(parlai/tasks/convai2/worlds.py):
InteractiveWorld:支持--display-partner-persona(默认True)参数,对话结束后在终端打印对方扮演的 persona(worlds.py 第 57-96 行);SelfChatWorld:支持 self-chat(两个模型自己聊天)场景。
两者的 persona 来源一致:_load_personas会临时以convai2:both数据驱动一个FixedResponseAgent遍历整个数据集,提取其中的your persona:/partner's persona:语句,去重后构成 persona 池(worlds.py 第 24-54 行)。测试用例 tests/tasks/convai2/test_convai2_worlds.py 验证了InteractiveWorld在clone()(分布式/并行共享)时不会重复加载 persona 列表。
四、与模型交互对话
4.1 归档代码中的交互脚本
原 README 提供的交互方式基于竞赛归档代码,切换到convai2archive标签后可以使用:
python projects/convai2/interactive.py -mf models:convai2/kvmemnn/model也可以切换成 seq2seq 模型:
python projects/convai2/interactive.py -mf models:convai2/seq2seq/convai2_self_seq2seq_model -m legacy:seq2seq:0其中-mf(--model-file)指定模型文件,-m指定模型类。注意:这两个模型文件(models:convai2/kvmemnn/model、models:convai2/seq2seq/convai2_self_seq2seq_model)以及projects/convai2/interactive.py脚本都属于归档版本,当前主分支的projects/convai2目录下仅保留 README,因此运行上述命令前需要先git checkout convai2archive。
4.2 当前仓库的交互方式:使用 zoo 预训练模型
在当前主分支中,交互对话统一通过parlai interactive(或python parlai/scripts/interactive.py)完成。仓库中已提供多个在 ConvAI2 上微调过的预训练模型,可直接体验:
parlai interactive -m transformer/polyencoder \ -mf zoo:pretrained_transformers/model_poly/model \ --encode-candidate-vecs true \ --eval-candidates fixed \ --fixed-candidates-path data/models/pretrained_transformers/convai_trainset_cands.txt该命令来自 parlai/zoo/pretrained_transformers/README.md:使用在 Reddit 上预训练、并在 ConvAI2 上微调的 Poly-Encoder 模型,配合官方提供的训练集候选文件(convai_trainset_cands.txt)进行固定候选交互。parlai/zoo/model_list.py 中的模型条目(第 400-427 行)同样给出了简化版入口:
parlai interactive -mf zoo:pretrained_transformers/model_poly/model -t convai2其示例对话输出为:
Enter Your Message: your persona: i love to drink fancy tea.\nyour persona: i have a big library at home.\nyour persona: i'm a museum tour guide.\nhi how are you doing ? [Polyencoder]: i am alright . i am back from the library . Enter Your Message: oh, what do you do for a living? [Polyencoder]: i work at the museum downtown . i love it there . Enter Your Message: what is your favorite drink? [Polyencoder]: i am more of a tea guy . i get my tea from china .注意 README 中的一句重要提示:该模型期望输入与训练数据分布一致的文本,即开头必须包含多行your persona: ...,否则模型可能答非所问。这正是 ConvAI2 任务"persona 驱动"特性的体现。
其他可用的 ConvAI2 微调模型还包括:
DodecaDialogue ConvAI2 微调模型(
zoo:dodecadialogue/convai2_ft/model,image_seq2seq架构),可配合 beam 搜索交互:parlai interactive -mf zoo:dodecadialogue/convai2_ft/model -t convai2 \ --inference beam --beam-size 3 --beam-min-length 10 --beam-block-ngram 3 --beam-context-block-ngram 3Unlikelihood 对话模型(如
zoo:dialogue_unlikelihood/rep_convai2_ctxt_and_label/model),针对上下文/标签重复做了 unlikelihood 训练,其下载与版本信息见 parlai/zoo/dialogue_unlikelihood/rep_convai2_label.py 等文件:python parlai/scripts/interactive.py -mf zoo:dialogue_unlikelihood/rep_convai2_ctxt_and_label/model -m projects.dialogue_unlikelihood.agents:RepetitionUnlikelihoodAgent
五、训练模型:从归档 baseline 到当前主流模型
5.1 归档版本中的 baseline
原 README 提到,任务提供了若干 baseline 训练/交互脚本,位于projects/convai2/baselines/目录(例如baselines/seq2seq/train.py与baselines/seq2seq/interact.py,后者基于 ParlAI 的 parlai/agents/seq2seq 实现)。这些脚本同样属于convai2archive标签,当前主分支中已移除。
5.2 当前仓库中的 ConvAI2 微调示例
在主分支中,训练 ConvAI2 模型的推荐路径是"在大型预训练模型上微调"。以 Poly-Encoder 为例(见 parlai/zoo/model_list.py 第 198-220 行):
parlai train_model \ --init-model zoo:pretrained_transformers/poly_model_huge_reddit/model \ -t convai2 \ --model transformer/polyencoder --batchsize 256 --eval-batchsize 10 \ --warmup_updates 100 --lr-scheduler-patience 0 --lr-scheduler-decay 0.4 \ -lr 5e-05 --data-parallel True --history-size 20 --label-truncate 72 \ --text-truncate 360 --num-epochs 8.0 --max_train_time 200000 -veps 0.5 \ -vme 8000 --validation-metric accuracy --validation-metric-mode max \ --save-after-valid True --log_every_n_secs 20 --candidates batch --fp16 True \ --dict-tokenizer bpe --dict-lower True --optimizer adamax --output-scaling 0.06 \ --variant xlm --reduction-type mean --share-encoders False \ --learn-positional-embeddings True --n-layers 12 --n-heads 12 --ffn-size 3072 \ --attention-dropout 0.1 --relu-dropout 0.0 --dropout 0.1 --n-positions 1024 \ --embedding-size 768 --activation gelu --embeddings-scale False --n-segments 2 \ --learn-embeddings True --polyencoder-type codes --poly-n-codes 64 \ --poly-attention-type basic --dict-endtoken __start__ \ --model-file <YOUR MODEL FILE>关键参数说明:
--init-model:以 Reddit 预训练的 Poly-Encoder 为初始化权重,这是达到高精度的关键;-t convai2:训练数据使用默认的convai2:self(original self persona)版本;--history-size 20:保留 20 轮对话历史(persona 行也算入历史);--text-truncate 360/--label-truncate 72:输入与标签的最大 token 长度;--candidates batch:训练时使用 batch 内候选做排序学习;--validation-metric accuracy --validation-metric-mode max:以验证集 accuracy 为早停指标。
依据 parlai/zoo/model_list.py 中的记录,类似配置训练出的 Poly-Encoder 在 ConvAI2 验证集上的报告结果约为{'exs': 7801, 'accuracy': 0.8942, 'f1': 0.9065, 'hits@1': 0.894, 'hits@5': 0.99, ...};parlai/zoo/pretrained_transformers/README.md 也注明该模型在 ConvAI2 valid 集上 hits@1/20 达 89+,且足以支撑 10 万候选的实时交互。需要注意的是,这些数字来自仓库记录(可能因随机性略有浮动),并非本文的评测结论。
训练好的模型同样用parlai eval_model做离线评测:
parlai eval_model -mf zoo:pretrained_transformers/model_poly/model -t convai2 --eval-candidates inline六、提交评测与 Leaderboard 机制(历史流程)
原 README 详细描述了竞赛期间的提交流程,虽然该流程随竞赛结束已不再开放,但它解释了 ConvAI2 任务的评测设计,对理解任务仍有价值:
- 提交方式:参赛者创建一个私有仓库,仓库结构类似
baselines/目录,包含与希望评测的每个指标对应的eval_XXX.py文件; - 评测函数复用:这些
eval_XXX.py从竞赛代码目录导入官方评测函数。例如baselines/seq2seq/eval_f1.py先为模型设置好参数,再导入并运行基础eval_f1.py中的评测逻辑; - 官方评测:官方在隐藏测试集(格式与公开的验证集一致)上运行自动评测并更新 leaderboard;
- 提交频率:每月最多提交一次;
- 人工评测:提交系统在 9 月 30 日锁定后,官方对排名靠前的模型运行人工评测。
这也解释了前文提到的"测试集自动回退到验证集"的源码行为——测试集数据从未随仓库下发,以保证评测公平性。
七、数据集版本设计的实验意义:self vs none
原 README 特别强调了一个实验设计要点:
可以使用
none模式与self模式做对比,检验模型是否真正利用了 persona 信息来提升对话表现;self是任务的默认设置,leaderboard 评测使用self_original。
具体而言:
convai2:self(默认):对话开始时提供双方各自的 persona(original self persona);convai2:self_revised:使用修订版 persona(对话双方可以互相看到对方 persona 的修订表述);convai2:none:不提供任何 persona,作为对照(ablative)条件。
一个合理的实验设计是:分别用-t convai2和-t convai2:none训练两个同架构模型,对比其验证指标,从而量化 persona 信息带来的增益。由于none版本与self版本共享几乎相同的对话内容(仅去掉 persona 行),这种对比相对干净。
另外,与原 PersonaChat 数据集相比,ConvAI2 做了三处关键改动(原 README 明确说明):
- 预处理方式不同(modified preprocessing);
- 生成了全新的隐藏测试集;
- 新增了从双方视角(both speakers)的训练样本以及额外候选,以支持基于排序损失的训练与评测。
关于第三点,"双方视角"在源码中的对应物就是BothTeacher(数据文件both_original),它同时被 worlds.py 的_load_personas用来抽取 persona 池,从而支撑interactive与self-chat两类世界。
原 README 还提到,为原始(非竞赛)PersonaChat 任务准备的模型通常可以较容易地迁移到本任务,相关示例见 projects/personachat 项目目录。
八、实战小贴士
- 快速确认数据可用:运行
parlai display_data -t convai2 -dt valid,若输出正常则说明convai2_fix_723.tgz已成功下载并解压到datapath/ConvAI2/; - 跑 Teacher 自检:任务内置了自动化 Teacher 测试,覆盖
DefaultTeacher、NormalizedTeacher、BothTeacher、NoneTeacher、SelfRevisedTeacher等(见 parlai/tasks/convai2/test.py),可借助 ParlAI 的AutoTeacherTest机制回归验证数据加载是否正常; - 关注任务元信息:parlai/tasks/convai2/README.md 标注了任务的 Tag(
#ConvAI2、#All、#ChitChat)与许可协议CC 4.0 BY,在数据合规使用场景下请留意该条款; - 区分"归档代码"与"当前代码":涉及
projects/convai2/interactive.py、baselines/及models:convai2/...模型的操作请先切换到convai2archive标签;当前分支请统一使用parlai interactive/parlai train_model/parlai eval_model,并优先选用zoo:pretrained_transformers/...、zoo:dodecadialogue/convai2_ft/model、zoo:dialogue_unlikelihood/...等仍受维护的模型入口。
九、总结
ConvAI2 是 ParlAI 生态中极具代表性的"persona 化闲聊"任务:它以 PersonaChat 为蓝本,通过self/self_revised/none三组数据版本支持对 persona 利用能力的对照实验,通过both版本与 label candidates 支持排序式训练,并通过隐藏测试集与官方评测脚本支撑了 NIPS 2018 竞赛。在当前仓库中,数据加载、Teacher 扩展、交互与 self-chat World、模型微调与评测均已沉淀为稳定可用的代码路径——本文所述命令均可直接复制运行,是理解与复现该任务的可靠起点。
【免费下载链接】ParlAIA framework for training and evaluating AI models on a variety of openly available dialogue datasets.项目地址: https://gitcode.com/gh_mirrors/pa/ParlAI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考