雷锋网 AI 科技评论按:在过去的几十年中,智能会话系统已经发生了显著的变化,从关键字识别交互式语音应答(IVR)系统到跨平台智能个人助理,都在慢慢成为日常生活中不可或缺的一部分。在这样的背景环境下,我们需要一个直观、灵活和全面的研发平台,用来帮助我们进行新算法评估、快速原型创建以及可靠地部署会话 AI 智能体。
因此,Uber AI 发布了名为「柏拉图研究会话系统」(Plato Research Dialogue System)的开源人工智能平台,来解决这个问题。雷锋网 AI 科技评论将其文章整理编译如下。
Plato 是一个用于构建、训练和部署会话 AI 智能体的平台。它能够使我们在会话 AI 中进行最先进的研究,快速创建原型和演示系统,以及更便捷的采集会话数据。而且该系统有「简洁」和「易于理解」的特点,并与现有的深度学习和与现有深度学习框架和贝叶斯优化框架(用于模型调优)集成,可减少编写代码的需要。因此不论是经验丰富的研究人员还是会话 AI 背景有限的兴趣爱好者,都能够轻松掌握其使用方法。
同时,我们也在平台拓展性方面做出了许多努力,如一般研究或特定用例所用工具,包括 Olympus,PyDial,ParlAI,Virtual Human Toolkit,Rasa,DeepPavlov,ConvLab 等。在评估是否利用这些工具时,我们发现许多用户需要熟悉特定于平台的源代码,关注特定的用例。这既不灵活也无法可靠地支持其他用户使用,并且有时还需要使用许可证。
Plato 则能够解决这些问题,并旨在构建、训练和部署会话 AI 智能体。它支持通过语音、文本或结构化信息(会话行为)进行交互,并且每个会话智能体可以与人类用户、其他会话智能体(在多智能体设置中)或数据进行交互。最重要的是,Plato 可以为每个会话智能体组件合并现有的预训练模型,并且每个组件都可以在线(在交互期间)或离线(从数据)进行训练。
从概念上讲,会话智能体需要经过各种步骤才能处理它接收的输入信息(例如,「今天天气如何?」)并产生恰当的输出(「有风但不太冷」)。主要步骤对应于标准体系结构的主要组件(见图 1):
语音识别(将语音转录为文本)
语言理解(从该文本中提取意义)
状态跟踪(迄今为止所说和所做工作的汇总信息)
API 调用(搜索数据库,查询 API 等)
会话策略(生成智能体响应的抽象含义)
语言生成(将抽象意义转换为文本)
语音合成(将文本转换为语音)
我们使 Plato 的设计尽可能模块化且具有灵活性,它支持传统的和自定义的会话 AI 架构。更重要的是,它支持多方交互,其中的多个智能体可能具有不同的角色,可以相互交互,同时进行训练,并解决分布式问题。
下面的图 1 和图 2 描绘了与人类用户和模拟用户交互时 Plato 会话智能体架构的示例。与模拟用户交互是研究社区中用于快速开始学习的常见做法(即在与人类交互之前学习一些基本行为)。每个单独的组件都可以用任意机器学习库(例如,Ludwig,TensorFlow 或 PyTorch)进行在线或离线的训练。因为 Plato 是一个通用框架,Uber 的开源深度学习工具箱 Ludwig 是一个很好的选择,因为 Ludwig 不需要编写代码并且与 Plato 完全兼容。
图 1:Plato 的模块化架构有助于组件的在线或离线训练,可以通过自定义或预先训练的模型进行替换。(图中的灰色组件不是核心柏拉图组件)
图 2:使用模拟用户而不是人类用户,如图 1 所示,我们可以预先训练柏拉图各组件的统计模型。然后,这些可以用于创建原型会话智能体,该智能体可以与人类用户交互以收集更多自然数据,这些数据随后可用于训练更好的统计模型。(图中的灰色组件不是柏拉图核心组件)
除了单智能体交互之外,Plato 还支持多智能体会话,其中多个柏拉图智能体可以相互交互并相互学习。具体来说,柏拉图将产生会话智能体,确保输入和输出(每个智能体听到和说出的内容)被恰当地传递给每个智能体,并跟踪会话。
这种设置可以促进多智能体学习的研究,其中智能体需要学习如何生成语言以执行任务,以及在多方交互的子领域中进行研究(会话状态跟踪、会话轮控制等等)。会话原则定义了每个智能体可以理解的内容(实体或含义的本体,例如:价格、位置、偏好、烹饪类型等)以及它可以做什么(询问更多信息、提供一些信息、调用 API 等)。智能体可以通过语音、文本或结构化信息(会话行为)进行通信,并且每个智能体都有自己的配置。下面的图 3 描述了这种架构,概述了两个智能体和各种组件之间的通信:
图 3:Plato 的架构允许对多个智能体进行并行训练,每个智能体可能具有不同的角色和目标,并且可以促进多方交互和多智能体学习等领域的研究。(图中的灰色组件不是核心柏拉图组件)
最后,Plato 通过图中所示的通用智能体体系结构支持自定义体系结构(例如:将 NLU 拆分为多个独立组件)和联合训练的组件(例如:文本到会话状态、文本到文本或任何其他组合)。如图 4 所示:
图 4:Plato 的通用智能体体系结构支持广泛的自定义,包括联合组件、语音到语音组件和文本到文本组件,所有这些组件都可以串行或并行执行。
此模式脱离了标准会话智能体体系结构,支持任何类型的体系结构(例如:使用联合组件、文本到文本或语音到语音组件或任何其他设置),并允许将现有或预先训练有素的模型加载进 Plato 中。
用户只需为模块提供 Python 类名和包路径,以及模型的初始化参数,或将自己的组件载入 Plato 中,就可以自行定义这个体系结构。用户简单的按照应该执行的顺序将模块列出之后,Plato 就可以负责其余部分了,包括:包装输入/输出、链接模块和处理会话。Plato 支持模块的串行和并行执行。
Plato 还通过组合结构的贝叶斯优化(BOCS)为会话 AI 架构或单个模块参数的贝叶斯优化提供支持。
版本 Plato(v.1.1)不需要实际安装,因为它允许用户修改部分代码或扩展现有用例以获得更大的灵活性。但是,Plato 确实依赖于某些外部库,需要安装这些库。可以按照以下两个步骤完成此过程:
注意:Plato 是用 Python 3 开发的。
1. 克隆存储库:
git clone
git@github.com:uber-research/plato-research-dialogue-system.git
2. 安装要求:
MacOS:
brew install portaudio
pip install -r requirements.txt
Ubuntu / Debian:
sudo apt-get install python3-pyaudio
pip install -r requirements.tx
Windows:
pip install -r requirements.txt
为了支持语音,则必须安装 PyAudio,它具有开发人员机器上可能不存在的许多依赖项。如果上述步骤不成功,PyAudio 安装错误这篇文章(https://stackoverflow.com/questions/5921947/pyaudio-installation-error-command-gcc-failed-with-exit-status-1)包含了有关如何获取这些依赖项并安装 PyAudio 的说明。
其他常见安装问题的解决方案可在 Commonsues.md.
3. 运行:
有关配置文件以及如何运行 Plato 的快速介绍,请参见下文。
运行 Plato 会话智能体
要运行 Plato 会话智能体,用户必须使用相应的配置文件运行以下命令(请参阅示例/ simulate_agenda.yaml 以获取示例配置文件,其中包含有关环境和要创建的智能体的许多设置以及他们的组件):
python runPlatoRDS.py -config <PATH TO yaml CONFIG FILE>
下面列出了一些示例模式和配置:
1)运行单个会话智能体
使用 Cambridge Restaurants 域中基于议程的用户模拟器运行模拟:
python runPlatoRDS.py -config examples / config / simulate_agenda.yaml
使用 Cambridge Restaurants 域中基于议程的模拟器运行基于文本的交互:
python runPlatoRDS.py -config examples / config / simulate_text.yaml
使用 Cambridge Restaurants 域中基于议程的模拟器运行基于语音的交互:
python runPlatoRDS.py -config examples / config / simulate_speech.yaml
2)运行多个会话智能体
柏拉图的主要功能之一是允许两个智能体互相交互。每个智能体可以具有不同的角色(例如,系统和用户)、不同的目标,并接收不同的奖励信号。例如,要在基准剑桥餐厅域上运行多个 Plato 智能体,我们运行以下命令来训练智能体的会话策略并对其进行测试:
训练阶段
python runPlatoRDS.py -config 示例/ config / CamRest_MA_train.yaml
测试阶段
python runPlatoRDS.py -config 示例/ config / CamRest_MA_test.yaml
3)运行通用 Plato 会话智能体
本文中的大多数讨论和示例都围绕传统的会话智能体体系结构展开。然而,Plato 不需要坚守这条规则,它的通用智能体支持任何范围的自定义模块,包括:将自然语言理解分解成许多组件、将多个组件并行运行以及只有一个文本到文本模型等等。
通用智能体允许用户将其自定义模块作为 Python 类对象加载。对于配置文件中列出的每个模块,Plato 将使用给定的路径和参数实例化该类模型。然后在每次会话期间,通用智能体将按顺序调用每个模块(按照其配置文件中提供的顺序),并将当前模块的输出传递给列表中的下一个模块,最后通用智能体将返回最后一个模块的输出。
以下是在通用模块模式下运行单个 Plato 智能体或多个 Plato 智能体的两个示例。
单一通用智能体,用于实现自定义体系结构或使用现有的预先训练的统计模型:
python runPlatoRDS.py -config 示例/ config / simulate_agenda_generic.yaml
多个通用智能体,与上述相同,但适用于多个智能体(假设该智能体已使用 Examples / config / CamRest_MA_train.yaml 训练过会话策略):
python runPlatoRDS.py -config examples / config / MultiAgent_test_generic.yaml
数据训练
Plato 支持使用任何深度学习框架在线(在交互期间)或离线(从数据)方式训练智能体的内部组件。实际上,只要符合 Plato 接口输入/输出的类型,任何模型都可以加载到 Plato 中。例如:目标模型是自定义 NLU,它只需要具有 Plato 的 NLU 抽象类,实现必要的功能,并将数据打包/解压到自定义模型中即可。
Plato 内部经验数据追踪
为了便于在线学习、调试和评估,Plato 在一个称为会话情节记录器的结构中跟踪其内部经验数据,包含有关先前的会话状态、采取的行动、当前会话状态、收到的话语信息和产生的话语信息、收到的奖励以及一些其他结构,如:一个可用于跟踪上述类别无法收集的任何其他内容的自定义字段。
在会话结束或按照指定时间间隔结束时,每个会话智能体将调用其内部组件的 train()函数,将会话经验数据作为训练数据传递;然后每个组件都会选择训练所需的信息部分。
要使用在 Plato 中实现的学习算法,任何外部数据(如 DSTC2 数据)都需要被解析为 Plato 类型的经验数据,以便这些外部数据可以由训练中相应的组件进行加载和使用。或者用户可以解析数据,并在 Plato 之外训练他们的模型;然后在需要将这些数据用于 Plato 智能体时简单地加载训练模型。
在线/离线训练
在线训练的过程就跟用户希望将所训练每个组件配置中的「Train」标志转换为「True」一样简单。而以数据进行训练的离线训练中,用户只需加载他们从数据集中解析的经验数据。我们将使用 DSTC2 数据集作为 Plato 离线训练的一个例子,该数据集可以从「第二会话状态跟踪挑战网站」(http://camdial.org/~mh521/dstc/downloads/dstc2_traindev.tar.gz)中获得。
该 runDSTC2DataParser.py 脚本将解析 DSTC2 数据,并将其保存为 Plato 的经验数据。然后,它将加载该经验数据并训练受监督的策略:
python runDSTC2DataParser.py -data_path
<PATH_TO_DSTC2_DATA> / dstc2_traindev / data /
可以使用以下配置文件测试经过训练的策略:
python runPlatoRDS.py -config
Examples/ config / simulate_agenda_supervised.yaml
注意:用户可以将经验数据从过去的交互或从数据加载到 Plato,然后通过强化学习或其他学习方法继续训练他们的模型。
Ludwig 是一个由 Uber 发布的开源深度学习框架,它允许用户在不编写任何代码的情况下训练模型。用户只需将其数据解析为 CSV 文件,创建 Ludwig 配置文件,然后在终端中简单执行运行命令即可。用 YAML 编写的 Ludwig 配置文件描述了神经网络的架构,其中包含在 CSV 文件中使用到的功能以及其他参数。
在上一节中,runDSTC2DataParser.py 脚本实际上生成了一些 CSV 文件,可用于训练自然语言理解和生成,可在以下位置找到:Data/data。作为一个例子,我们将看到如何训练系统端自然语言生成器。为此,用户需要编写 yaml 配置文件,类似于下面所示。
Input_features:
name:nlg_input
type:sequence
encoder:rnn
cell_type:lstm
Output_features:
name:nlg_output
type:sequence
decoder:generator
cell_type:lstm
training:
epochs:20
learning_rate:0.001
dropout:0.2
并训练他们的模型:
ludwig experiment –model_definition_file
Examples/config/ludwig_nlg_train.yaml –data_csv
Data/data/DSTC2_NLG_sys.csv –output_directory Models/CamRestNLG/Sys/
接下来是在 Plato 中加载模型。用户应该转到 simulate_agenda_nlg.yaml 配置文件,并在必要时更新 Ludwig 模型的路径:
...
NLG:
nlg:CamRest
model_path:<PATH_TO_YOUR_LUDWIG_MODEL>/model
...
并测试该模型的工作原理:
python runPlatoRDS.py -config
Examples / config / simulate_agenda_nlg.yaml
请记住,Ludwig 每次调用时都会创建一个新的 experiment_run_i 目录,因此用户需要确保 Plato 配置文件中的模型路径是最新的。
Ludwig 还提供了一种在线训练模型的方法,因此在实践中,用户只需要编写非常少的代码来构建、训练和评估 Plato 中新的深度学习组件。
为了给面向任务的应用程序(如插槽填充)构建会话智能体,用户需要一个项目数据库和一个描述其域的本体。Plato 提供了一个脚本来自动执行此过程。
例如,假设用户想要为在线花店构建会话智能体,在 CSV 文件中包含以下项目:
物品 ID,类型,颜色,价格,场合
1,玫瑰,红色,1,任何
2,玫瑰,白色,2,周年纪念
3,玫瑰,黄色,2,庆祝
4,莉莉,白色,5,任何
5,兰花,粉红色,30,任何
6,大丽花,蓝色,15,任何
用户只需调用 createSQLiteDB.py 即可自动生成 DB SQL 文件和 JSON 本体文件。用户可以在配置文件中指定信息、请求和系统可请求的插槽,如下所示:
-
GENERAL:
csv_file_name:Data / data / flowershop.csv
db_table_name:
estore db_file_path:Ontology / Ontologies / flowershop.db
ontology_file_path:Ontology / Ontologies / flowershop.json
ONTOLOGY(本体):
informable_slots:[类型,价格,场合]
requestable_slots:[价格,颜色]
system_requestable_slots:[价格,场合]
注意:ONTOLOGY 部分是可选的。如果 ONTOLOGY 未被提供,脚本将假定所有插槽都是信息性的、可请求的和系统可请求的。
并运行脚本:
python createSQLiteDB.py -config
Examples / config / create_flowershop_DB.yaml
A flowershop-rules.json 和 a flowershop-dbase.db 可以在 Domain/Domains 中找到。我们现在可以简单地使用虚拟组件运行 Plato 并与简单智能体进行交互作为完整性检查:
python runPlatoRDS.py -config
Examples / config / flowershop_text.yaml
根据其功能,我们有两种方法可以创建新模块。如果模块采用了执行 NLU 或会话策略的新方法实现,那么用户应该编写一个自相应抽象类的类。
但是,如果一个模块不适合单个智能体基本组件之一,例如:它执行命名实体识别或从文本预测会话行为,那么用户必须编写一个直接从 ConversationalModule 得到的类,然后这个类只由通用智能体使用。
自抽象类
用户需要创建一个自相应 Plato 抽象类的新类,并实现抽象类定义的接口以及他们希望的任何其他功能。此类应具有唯一名称(例如「myNLG」),用于在解析配置文件时将其与其他选项区分开来。在此版本中,除非用户使用通用智能体,否则需要手动添加解析配置文件的一些条件(例如:会话智能体、会话管理器等)。
构建新模块
要构造新模块,用户必须将其代码添加到从会话模块得到的新类中。然后他们可以通过在配置中提供适当的包路径、类名和参数,用通用智能体来加载模块。
…
MODULE_i:
package:myPackage.myModule
Class:myModule
arguments:
model_path:Models/myModule/parameters/
…
…
用户负责确保新模块能够适当地处理前面模块的输出,并且新模块的输出可以按照其通用配置文件中的规定,由其他模块恰当地使用。
由 Uber AI 研发的项目 Plato 被用于促进 SIGDial 2019 的工作,即同时训练两个通过自生成语言相互交流的会话智能体。在这项工作中,我们可以利用 Plato 轻松对这两个会话智能体进行训练,使它们中一个能实现餐馆信息询问,而另一个则可以提供该问题回答的信息。并且随着时间的推移,他们的谈话将变得越来越自然。
我们相信,Plato 能够在 Ludwig、TensorFlow、PyTorch、Keras 以及其他开源项目的深度学习框架中更加无缝地进行会话智能体的训练,从而改进学术和行业应用中的会话 AI 技术。
原文链接:
https://eng.uber.com/plato-research-dialogue-system/
GitHub 地址:
https://github.com/uber-research/plato-research-dialogue-system
更详细的使用方法:
https://uber-research.github.io/plato-research-dialogue-system/
雷锋网 AI 科技评论