ParlAI MultiLIGHT 任务实战:基于 LIGHT 的多角色群聊数据格式、Teacher 体系与模型评测指南
2026/9/24 13:58:30 网站建设 项目流程
  • NLP
  • 人工智能
  • 深度学习

【免费下载链接】ParlAI

A framework for training and evaluating AI models on a variety of openly available dialogue datasets.

项目地址:https://gitcode.com/gh_mirrors/pa/ParlAI
点击查看免费下载

MultiLIGHT 是 ParlAI 中一个面向三方异步角色扮演对话的多角色聊天任务(Multi-party chat),数据源自 LIGHT 环境,每个参与者被分配一个角色(character)进行扮演。本文将以 parlai/tasks/light_multiparty/README.md 为骨架,结合 agents.py、build.py 等源码与测试数据,系统讲解 MultiLIGHT 的数据格式、三类 Teacher 的用法与全部命令行参数、上下文构造原理、自定义评测指标,以及配套发布模型的评测命令。读完本文,你将能够直接运行parlai dd查看该数据集的任意 Teacher 输出,理解__SILENCE____START__等特殊标记的语义,并复现项目页中报告的困惑度(PPL)评测。

MultiLIGHT 数据集的渲染示例(projects/multilight/DatasetExample.png):三个角色在 LIGHT 环境中进行带地点、人物设定的异步对话。

一、任务背景:从双人对话走向多角色群聊

传统对话研究大多聚焦于两两(双人)对话,而 MultiLIGHT 要解决的是多于两个说话者共处一个场景的日常群聊问题。其数据在 LIGHT 环境中采集:每位参与者领到一个角色(如海盗船上的船长、年轻水手),围绕指定的地点与人物设定展开异步对话。任务列表 task_list.py 中对它的定义是:

  • idMultiLIGHT
  • tasklight_multiparty
  • tagsAllChitChat
  • description:Multi-party async conversation between 3 role-playing characters(3 个角色扮演人物之间的多方异步对话)

任务目录parlai/tasks/light_multiparty/下包含 4 类文件:README.md(任务说明)、__init__.pyagents.py(Teacher 核心实现)、test.py(自动化测试),以及test/目录下为每个 Teacher 生成的 train/valid/test 三段 YAML 样本数据。

该任务对应的论文为 MultiLIGHT 一文(项目页 projects/multilight/README.md 标注的 arXiv 编号为 2304.13835)。论文指出,多角色场景要求模型具备两项双人训练模型通常缺失的能力:

  1. 决定何时开口(deciding when to talk);
  2. 基于多个角色设定生成连贯话语(producing coherent utterances grounded on multiple characters)。

MultiLIGHT 数据集的发布,正是为了在群聊场景下带来显著的模型能力提升。

二、数据获取与底层格式

2.1 自动下载与版本校验

与多数 ParlAI 任务一致,数据由 Teacher 在初始化时自动触发下载,逻辑集中在 build.py:

  • 数据集名称:DATASET_NAME = 'parlai_multilight'(build.py);
  • 数据包:parlai_multilight.tar.gz,并带有 SHA1 校验值cbc20e4fa7a551c0efec4a4129e75335d3f3586797d6f767e320403079f4a6b2(build.py),确保下载内容完整可信;
  • 数据版本:'1.0',通过build_data.built(dpath, version)判断是否需要重新构建;若检测到旧版本会先清除再重新下载(build.py)。

因此,你无需手动下载任何文件,直接运行任务命令即可,数据会落盘到--datapath(默认data/)下的parlai_multilight/目录。

2.2 原始 JSONL 数据与字段结构

Teacher 读取的原始数据是 JSONL 文件(每行一个完整对话 episode),路径为<datapath>/parlai_multilight/{fold}.jsonl,其中 fold 由DatatypeHelper.fold(opt["datatype"])归一化得到(如trainvalidtest),见 agents.py。

每个对话 episode 的核心字段如下(可从测试样本 light_multiparty_train.yml 中直接观察到):

字段含义
characters参与对话的角色名列表,例如["young boy", "boat captain", "captain"]
messages[]按时间顺序排列的话语序列,每条含speakertimestamp
speaker/speaker_id当前话语的说话者姓名与其在characters中的 1-based 序号
location场景地点:name(如 Pirate Ship)与description(场景描述文本)
personas[]每个角色的name与其persona(角色设定描述)
quality_tier该 episode 的数据质量层级(1 高 / 2 低)
workers_quality_check[]每个说话者对应的 worker 质量层级,Teacher 会据此为每条话语计算speaker_worker_tier

2.3 数据质量分级:episode 与 speaker 双维度过滤

为了兼顾数据规模与质量,MultiLIGHT 在两个粒度上标注了质量层级(见 agents.py 的参数说明):

  • episode 层级--episode-quality-tiers):控制哪些对话作为训练样本;
  • speaker 层级--speaker-quality-tiers):控制哪些说话者产生的话语参与训练。

可用的层级为1(高质量)与2(低质量),两者默认值均为"1,2"(即默认全量使用)。注意:只有训练集划分带有质量层级标注,validtest划分仅包含 tier 1 数据_get_data_quality_tiers()(agents.py)会校验传入值,非 1/2 的层级直接触发断言错误。

setup_data中,episode 层级过滤在对话级别执行(conv["quality_tier"] not in self.episode_quality_tiers则跳过),而 speaker 层级过滤在 utterance 级别执行(通过conv['workers_quality_check'][speaker_id - 1]['worker_tier']取到当前说话者的质量层级),见 agents.py 与 agents.py。

三、Teacher 体系:三种任务设置的实现

任务目录下 agents.py 定义了完整的 Teacher 类层级。项目页 projects/multilight/README.md 明确指出本任务提供三种类型的 Teacher:两种聚焦话语/对话内容,一种聚焦预测下一说话者。

3.1 Teacher 类继承关系

DialogTeacher └── BaseTeacher(抽象基类,封装公共逻辑与全部参数) ├── AllSpeakersTeacher # 所有角色的全部话语 │ ├── SpeakerPredictionTeacher # 预测下一说话者 │ └── DefaultTeacher # 默认入口 = AllSpeakersTeacher └── SingleSpeakerTeacher(抽象) ├── FirstSpeakerTeacher # 角色 0(索引 0) ├── SecondSpeakerTeacher # 角色 1(索引 1) └── ThirdSpeakerTeacher # 角色 2(索引 2)

BaseTeacher__init__中完成数据构建(build(opt))、fold 归一化与 datafile 拼接,并一次性读取全部参数缓存为实例属性,随后调用DialogTeacher.__init__(agents.py)。它本身是抽象类,源码注释明确标注"Do NOT use directly!"。

3.2 AllSpeakersTeacher:训练模型生成任意角色的下一句话

AllSpeakersTeacher(agents.py)的任务设置是:给定截至当前轮次的历史上下文(含说话者标记),预测下一条话语,而不管下一轮由哪个角色开口。其idmultilight_dialogue_:all_speakers

它把setup_data产出的消息组装为text:由get_extra_context_before(可选的地点/人物设定)+full_context(历史话语)+get_extra_context_after(可选的时间步/当前说话者提示)用--utterance-delimiter拼接而成(agents.py)。同时按speaker_worker_tier过滤掉质量不达标的话语样本。

运行示例(来自项目页,parlai dd即 ParlAI 的 display_data 脚本,对应 display_data.py):

# 展示全部角色话语 Teacher,并在上下文中加入地点与人物设定 parlai dd -t light_multiparty --add-location-to-context true --add-personas-to-context true

观察测试样本 light_multiparty_train.yml 可以看到,text随轮次逐句累积,例如:

text: 'captain: Greetings to both of you. young boy: Hi Captains! It is so nice out on the ocean today! boat captain: Well I imagine this ship holds many secrets!' labels: - 'young boy: It does! I saw a ghost on it last night!'

每条样本都携带locationpersonasspeakerspeaker_idtimestepquality_tier等字段,供模型或上层代码使用。该划分的规模可在 yml 文件尾部看到:num_episodes: 293264num_examples: 293264(每个 episode 对应一个训练样本)。

3.3 SingleSpeakerTeacher:固定扮演单一角色 + 静默标记

SingleSpeakerTeacher(agents.py)只让模型扮演某一个固定角色(First/Second/Third 分别对应角色索引 0/1/2),回答"若轮到该角色发言,他会说什么"。当该轮实际由其他角色发言时,标签变为静默标记__SILENCE__,从而让模型同时学习"何时不开口"。

这是 MultiLIGHT 最独特的设置。关键实现点:

  • is_this_speaker_turn()通过get_utterance_speaker_id()判断当前话语的说话者是否为指定角色(agents.py);
  • 非本角色轮次时,generate_silence_label()生成形如young boy: __SILENCE__的标签(开启--include-speaker-in-label时带说话者前缀),见 agents.py;
  • 上下文只保留"自该角色上一轮发言以来的"增量片段(full_context[(last_speaker_trun + 1):]),避免把该角色自己的上一句话重复喂入(agents.py);
  • 每个 episode 的第一条样本仍会附带地点/人物等 extra context(agents.py),后续轮次则只给增量上下文;
  • 该 Teacher 特有的temp_history字段存放"时间步 + 当前说话者提示",用于在推理时追加提示而不污染完整历史(agents.py)。

运行示例:

# 让模型扮演第一个角色(索引 0),学习"何时发言、何时沉默" parlai dd -t light_multiparty:FirstSpeakerTeacher --add-location-to-context true --add-personas-to-context true

从测试样本 light_multiparty_FirstSpeakerTeacher_train.yml 可以看到典型的标签交替:

# 第一轮:轮到 young boy 发言 labels: - 'young boy: Hi Captains! It is so nice out on the ocean today!' episode_done: false # 第二轮:young boy 没说话,标签为静默标记 labels: - 'young boy: __SILENCE__'

注意这类 Teacher 的episode_done通常为false,因为同一对话的多轮会作为连续样本流式产出,直到对话结束才标记true

静默样本的随机丢弃(dropout)--silence-token-dropout可在训练时按概率丢弃静默样本,缓解"沉默"标签占比过高导致的类别不平衡。默认值为0(保留全部静默样本),取1则完全丢弃;源码在__init__中断言其必须落在[0, 1]区间(agents.py)。若因 dropout 跳过了某 episode 的开头,Teacher 会通过episode_needs_reset标志在下一轮重置 episode 边界(agents.py),保证数据流自洽。

3.4 SpeakerPredictionTeacher:预测下一轮由谁开口

SpeakerPredictionTeacher(agents.py)将任务重构为分类问题:给定历史上下文,预测下一个说话者是谁。其idSpeakerPrediction

实现要点:

  • 标签被改写为说话者名字,候选集label_candidates为全部角色名(get_speaker_names,即各persona['name']),见 agents.py;
  • 开启--include-speaker-in-label时,会先把标签中的说话者前缀剥离(并断言前缀与实际 speaker 一致,确保数据格式正确),再取纯话语文本作为"当前轮"内容(_label_text,agents.py);
  • 新增参数--add-current-turn(默认False):为true时把当前轮的话语内容也追加到上下文末尾,让模型在"看到这句话"的前提下预测其说话者(agents.py)。

运行示例:

# 预测下一轮说话者,候选为全部角色名 parlai dd -t light_multiparty:SpeakerPredictionTeacher --add-location-to-context true --add-personas-to-context true

四、Teacher 命令行参数全解

以下参数全部由 agents.py 中add_cmdline_args声明,按所属 Teacher 分组列出。除特殊标注外均为BaseTeacher通用参数:

参数类型默认值说明
--episode-quality-tiersstr"1,2"参与训练的 episode 质量层级(1 高 / 2 低),逗号分隔;valid/test 仅有 tier 1
--speaker-quality-tiersstr"1,2"参与训练的说话者质量层级,同上
--utterance-delimiterstr"\n"上下文中每条话语之间的分隔符,如'A: Hello\nB: Hi there'
--use-start-tokenboolFalse是否在对话开头放置开始标记,并把第一句话也作为训练样本
--start-tokenstr"__START__"对话开始标记的具体 token
--include-speaker-in-labelboolTrue标签是否带说话者前缀,如'Rachel: Hi'而非'Hi'
--include-speaker-in-contextboolTrue上下文是否带说话者前缀,如'Rachel: Hi'而非'Hi'
--add-speaker-to-context-endboolFalse是否把"当前说话者"追加到上下文末尾(源码 help 文本写作 Defaults to True,实际默认值为False,以代码为准)
--speaker-token-delimiterstr":"说话者名称与话语内容之间的分隔符
--include-timestep-in-contextboolFalse是否在每条历史话语前附带相对时间步
--add-current-timestep-to-contextboolFalse是否在上下文末尾追加当前轮的时间步
--add-personas-to-contextboolFalse是否把全部角色的扁平化人物设定前置到上下文
--add-location-to-contextboolFalse是否把场景地点描述前置到上下文

以下为SpeakerPredictionTeacher专属参数(agents.py):

参数类型默认值说明
--add-current-turnboolFalse是否把当前轮话语文本也包含进输入上下文

以下为SingleSpeakerTeacher系专属参数(agents.py):

参数类型默认值说明
--silence-tokenstr"__SILENCE__"表示"所选角色本轮未发言"的静默标记
--silence-token-dropoutfloat0静默样本丢弃概率,取值范围[0,1]0全部保留,1全部丢弃

五、上下文构造细节:人物、地点、时间步与说话者标记

5.1 扁平化标记(Persona / Location)

flatten_personasflatten_location把结构化的人物设定与地点描述转换为带起止标记的纯文本(agents.py):

__personas__ young boy: I am the son of the ship's captain. ... boat captain: I am the captain of the world's biggest boat. ... __end-personas__
__location__ Pirate Ship: A majestic, shimmering, black pirate ship sits upon the water. ... __end-location__

这两段文本通过get_extra_context_before前置到对话历史之前(agents.py),仅在对应开关(--add-personas-to-context/--add-location-to-context)为真时启用。注意:项目页中的示例命令均显式开启这两个开关,这是与论文一致的推荐配置——模型需要人物与场景信息才能生成 grounded 的话语。

5.2 相对时间步

原始 JSONL 中的timestamp是绝对时间戳,Teacher 会以每条对话第一条话语的时间为基准,将其转换为HH:MM:SS的相对时间(_format_timestep,agents.py),例如测试样本中的timestep: 00:00:0300:00:22。当--include-timestep-in-context开启时,说话者提示变为形如speaker <ts> :的格式(get_speaker_prompt,agents.py);--add-current-timestep-to-context则把当前轮的时间步追加到上下文末尾(get_extra_context_after,agents.py)。

5.3 对话开始处理

--use-start-tokenTrue时,每条对话在上下文最前端放置__START__,并把第一句话也作为一条训练样本(否则第一句话只被当作后续轮次的上下文而跳过),对应逻辑见 agents.py。

六、自定义评测指标

MultiLIGHT 的 Teacher 通过custom_evaluation提供了任务专属指标,无需额外脚本即可在评测时自动统计:

AllSpeakersTeacher(agents.py),仅在--include-speaker-in-label开启时生效:

  • speaker_acc:预测的说话者前缀与真实说话者的精确匹配准确率(ExactMatchMetric);
  • speech_f1:剔除说话者前缀后,话语正文部分的 unigram F1(F1Metric)。

模型输出按--speaker-token-delimiter(默认为:)切分:前半段视为预测的说话者,后半段视为话语正文;若输出中没有分隔符,则记为__NO_SPEAKER__以判定说话者预测错误。

SingleSpeakerTeacher(agents.py):

  • self_speaker_acc:模型"该说话/该沉默"二分类是否正确——通过判断输出文本中是否出现--silence-token实现;
  • self_speaker_precision/self_speaker_recall/self_speaker_f1:同一二分类任务经ConfusionMatrixMetric.compute_metrics(见 torch_classifier_agent.py)计算出的混淆矩阵派生指标,以"True"(即"应当发言")为正类。

七、预训练模型与评测命令

项目页 projects/multilight/README.md 发布了三个配套模型:

模型路径(zoo)说明
zoo:multilight/utterance_3B/model最优"纯话语"模型,在 LIGHT、LIGHT Wild 与 MultiLIGHT 上多任务训练,约 3B 参数;论文人类评测所用
zoo:multilight/utterance_400m/model同配置的小规模"纯话语"模型,约 400M 参数
zoo:multilight/speaker/model预测下一说话者的专用模型;论文人类评测所用

评测命令(数据集自动下载,无需额外准备):

parlai eval_model -mf zoo:multilight/utterance_3B/model \ --task light_multiparty \ --add-location-to-context true \ --add-personas-to-context true

两个话语模型在全部角色 Teacher 上的困惑度(PPL)如下(数据来自项目页):

话语模型PPL
zoo:multilight/utterance_3B/model13.25
zoo:multilight/utterance_400m/model15.08

注意:评测时务必保持与训练一致的上下文开关(--add-location-to-context--add-personas-to-context),因为模型已针对该输入格式微调;若关闭这些开关,输入分布变化会直接影响困惑度结果。

八、自动化测试验证

任务目录下的 test.py 基于 ParlAI 的AutoTeacherTest工具(见 testing.py)对 6 个 Teacher 做了端到端回归测试:

class TestDefaultTeacher(AutoTeacherTest): task = 'light_multiparty' class TestSpeakerPredictionTeacher(AutoTeacherTest): task = 'light_multiparty:SpeakerPredictionTeacher' class TestFirstSpeakerTeacher(AutoTeacherTest): task = 'light_multiparty:FirstSpeakerTeacher' class TestSecondSpeakerTeacher(AutoTeacherTest): task = 'light_multiparty:SecondSpeakerTeacher' class TestThirdSpeakerTeacher(AutoTeacherTest): task = 'light_multiparty:ThirdSpeakerTeacher'

运行方式:

python -m pytest tests/tasks/ -k light_multiparty -q

该测试会自动校验 Teacher 产出的消息字段(textlabelsepisode_doneid等)与test/目录下 YAML 快照的一致性。test/中为每个 Teacher 生成的*_train.yml*_valid.yml*_test.yml既是回归基准,也是理解各类 Teacher 输出格式最直接的样例(例如 light_multiparty_FirstSpeakerTeacher_train.yml 展示了__SILENCE__标签,light_multiparty_train.yml 展示了全角色话语的累积式上下文)。测试命名上TestSpeakersTeacherTestSpeakerPredictionTeacher指向同一任务字符串,从源码结构看这属于测试代码中的小笔误,不影响各 Teacher 本身的覆盖。

结语

MultiLIGHT 是 ParlAI 任务库中少数专门面向多角色群聊的数据集任务:AllSpeakersTeacher覆盖"生成任意角色下一句",SingleSpeakerTeacher(First/Second/Third)覆盖"固定扮演某角色并学会沉默",SpeakerPredictionTeacher覆盖"预测下一说话者"。配合--add-location-to-context--add-personas-to-context--include-timestep-in-context等开关,你可以灵活组合出多种上下文形态;--episode-quality-tiers/--speaker-quality-tiers则提供了数据质量控制手段。若需深入自定义,直接阅读 agents.py 并参考 projects/multilight/README.md 中发布的模型与评测配置即可。

  • NLP
  • 人工智能
  • 深度学习

【免费下载链接】ParlAI

A framework for training and evaluating AI models on a variety of openly available dialogue datasets.

项目地址:https://gitcode.com/gh_mirrors/pa/ParlAI
点击查看免费下载

相关推荐

上一篇:如何高效封装企业级组件?Geeker-Admin组件库设计指南
下一篇:Vue.js Modal配置与属性详解:掌握30+个自定义选项的高级用法

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询