开头...
写这个文章的目的让更多关注,想要搞,正在搞对话管理(dialogue manager,后面简称DM)的同学尽力少踩坑,至于已经在坑里,甚至从坑里爬起来的人那么来多拍拍砖,甚是欢迎!
基本概念
这个是经典的语音智能交互的图,可以看到DM的位置,在nlu之后,nlg之前,输入是context和语义表示,输出是当前context下需要执行的action
这里就已经牵扯到很多问题了,语义表示究竟是啥,context里面存什么东西,action是个枚举吗等等等等...这里就不展开了,后面的零零碎碎会有些回答
试着把满足一个用户的诉求(任务),当成是一个流程图流转的过程。图上有很多节点,甚至回路,从开始节点如果能流转到终结节点,那么这个任务就被完成了。
但是通过每个节点是有代价的,比如需要填上一些信息等,那么我们把这样的代价称为阻力。
用户的输入就是克服这个阻力的动力,用户说的话会转换成语义表示,里面包含的信息越多,那么动力就越强,一次对话流转的节点有可能就很多
比如:
我要去杭州 => 出发地? => 时间? => 坐席? => 确认支付?
vs
我要买一张明天上午10点从北京去杭州的高铁二等座的票 => 出发地OK => 时间OK => 坐席OK => 确认支付?
action在这里并不仅仅是个“字符串的枚举值”,可能还会附带一些参数或数据,用于展示等
举个栗子
看完所处的位置和输入输出,那么看个"简单"例子,有个直观的感受
例子里表述的就是一个语音导航的交互流程,用户提出诉求,然后筛选得到精确结果,最后启动导航
例子中不同的颜色代表了对话的一些“类型”(这些类型并不是什么标准的定义,仅仅是为了区别角色的变化)
- 蓝色,机器发起询问,向人收集信息,直到满足一个阶段的要求(比如满足了请求API的前提)
- 红色,主导权从机器转向了人,人可以在某个范围内自由发出指令(比如筛选/过滤结果)
- 紫色,人向机器发出了直接改变任务流程的“命令”
- 绿色,机器主导发起确认
这样的流程与颜色的前后顺序并不形成模式,列出不同的颜色是为了说明,a) 一个对话的流程往往很复杂,每个阶段都有很多分支可以走;b) 虽然复杂,但是也有一些明显的“模式”可以别捕捉,比如:收集用户信息,确认等
(如果看得仔细,可以发现,第一句话和最后一句话都是“导航”,但是处于完全不同的上下文,最终执行的action会不一样,这里究竟是“上下文无关的NLU”+“DM根据sematic控制action”,还是“上下文相关的NLU” + “DM做简单的sematic到action的映射”...见仁见智,个人推荐前者,欢迎拍砖)
实际上...
实际上,DM的职责会比想象中的多一些,杂一些
比如:多semantic信息的筛选,rank
这个问题挺现实的,想让一个NLU完成业务的所有语义理解,还是稍微勉强了一些,那么如果面对多个语义输入,总得有个地方做汇聚,那么DM有context,有客户端的info等,是个不错的聚合/筛选的地方
比如:请求第三方服务
第三方服务返回的结果可能会让整个对话朝不同的方向发展(请求成功往下走,请求失败又是另外一条路),如果请求第三方服务作为DM的职责之一,那么会带来很大便利
等等...
(负担更多的职责是有利有弊的,这个需要做权衡)
表示方式
DM的表示方式有那么几种,各有自己的优缺点。需要注意的是这里只是“表示方式”,无关如何实现(规则方法或者模型方法)
面临的挑战
讲到这里,其实也就是引出了一些DM的一些挑战(坑)
我就不一一展开了,重点就是场景的打断与恢复
我觉得这个能力是衡量一个对话管理系统好坏的很关键的点。
有些情况下用户的偏离是无意的,比如:ASR或者NLU的错误导致的偏离,使得系统感知到用户要跳出当前场景
有些情况下用户的偏离是有意的,比如:买火车票的时候,忽然想查个目的地的天气等
(如果把火车票中查天气作为场景的一个分支那么会带来更高复杂性)
场景的打断与恢复
篇幅有限我就不详细展开了,上图列出的是一个最简单的做法,实际上还有非常多的细节和优化点
实现方案
OK,那么来看看实现方式。
很多人包括我自己,想到DM的时候,第一时间联想到的就是MDP,POMDP,Reinforcement learning,甚至一些巨复杂的end2end的“高大上”算法...然后就随后带来一堆堆的问题。
模型化困难重重
1 . 训练数据在哪里?标注的成本巨高,连“生语料”的来源都是问题...,就算使用RL这样的无监督算法,那你总得有个agent让他学吧,但如果你把agent弄好了,你就已经有了个rule base对话逻辑了...
2 . PD大笔一挥把交互改了怎么办?痛不欲生,训练语料要么修正要么重新弄,agent也是一样一样的
3 . 如何将服务API及其返回状态融入模型?有些paper确实考虑到了DM的action调用API的事情,恶心的地方是,如果模型的输出的action才决定了,那么API返回请求失败或者没有数据这件事情模型不处理归谁处理呢?所以还要写一个模型的后处理程序?如果成功了怎么办,失败了怎么办?(当然可以让一轮对话调用多次模型,模型返回的是内部action,然后再转换为外部action,这个就不展开了)
...
回到起点
如果仔细想,要解决这个问题,需要想清楚挺多事情的
1 . 在DM这个任务上,为什么需要或者为什么不需要模型?模型的优势和劣势在哪里?
模型无非是想用数据驱动(代价)的方式得到泛化能力(收益)
那么需要弄清楚的是,很多paper并不是单纯的DM任务,其实夹杂了NLU甚至ASR容错等任务,所以他们才用模型,换句话说,其实很多paper标题是DM,其实解决的是NLU + DM的问题,这样的前提下,那么模型的泛化能力起了非常重要的作用。如果你面临是和paper上一样的问题,那么去试试,如果你的情况和paper里面不一样,NLU你已经做好了,仅仅想做DM,那么理清思路,重新出发
2 . 如何规避劣势,发挥优势
做新场景,冷启动,哪来数据,那么能否先获取数据,再逐步往模型进发?如果是这样的思路,能否先rule base,然后再模型化
有个圈子比较难绕出去的是,既然有了rule base DM,而且我们大PD的设计是确定性的,不是概率性的,为啥还要模型呢?这个模型所谓的泛化究竟泛化的是啥?其实就是DM模型化的收益是什么
DM模型化的收益
1 . 优化交互逻辑(主要)。是是是,我们的大PD是很资深,但是和用户的实际使用总是有差别的,模型化把所有的路径都概率化,以一个低概率把机会留给一些“意想不到”的路径(exploration),人走多了自然就是一条“正确”的路,特别是业务存在多场景自由切换的情况下
2 . 千人千面(比较虚)。如果能做到根据不同用户的习惯给出不同的流转方式,那简直太(niu)厉(bi)害(da)了(le)
最后收一下就是,冷启动阶段,先用规则方法打造一个DM,快速上线并满足业务需求,收集数据之后再转换成模型
说了挺多了,有点啰嗦,写得有点累...就匆匆收尾吧