Rasa NLU 组件的生命周期

本文将详细介绍 Rasa NLU 组件(component)的生命周期。


兼容性说明:

本文介绍的 Rasa NLU 知识都是基于 v0.13.2, 不同版本之间可能会有差异。但结构变动的不大,因此本文介绍的知识在后续版本,甚至 v1.x 依然有效。


先介绍一个组件的生命周期:1. 训练阶段 2. 推理阶段

训练阶段

实例化

训练阶段,所有的组件都是 rasa_nlu.model.Trainer 这个类通过读取配置文件中的 pipeline 字段,逐一调用组件对应的类,将其实例化后,按照定义的顺序构造一个列表对象,这个对象我们后续称为 pipeline

训练流程

Trainer 会在做一系列 pipeline 的配置正确性检查后,调用每个组件的 train 方法。train 方法至少要接受训练数据 (一个 rasa_nlu.training_data.training_data.TrainingData 类的对象) 和模型配置 (一个 RasaNLUModelConfig 类的对象),除此之外 train 方法还可能会接收上游传递过来的 context 字典,里面会有各种上游组件传递给下游的变量,比如分词结果、特征提取结果等。模型根据自己的需要选择使用其中的零至多个变量。train 方法在完成训练任务后,可以在最后返回个字典,这个字典将会和现有的 context 字典合并 (覆盖旧值,如果重复)。这个新的 context 字典将会用于下游组件的训练。

持久化流程

模型训练完毕后,需要持久化成文件写入文件系统。在 Trainer 完成所有组件的训练后,Trainer 会先将训练数据持久化到模型输出目录,然后依次调用 pipeline 中各组件的 persist 方法。persist 方法需要接受两个参数:一个是按照模型在pipeline中的顺序和名字构成文件名,另一个是模型输出目录的路径。persist 方法需要在完成持久化之后输出一个字典,这个字典中将包含加载这个模型的参数文件的相对位置(相对模型输出目录),如果没有需要持久化的文件要存储,也可以返回 None。Trainer 会记录所有的模型 metadata 数据,这些 metadata 将会用于后续从文件系统加载该模型组件。在所有的组件都持久化完成后, Trainer 将合并训练数据、pipeline 以及各个组件的 metadata 作为模型的 metadata 写入模型目录。

推理阶段

实例化

推理阶段,模型需要从文件系统中载入并实例化好以做好推理的准备。在训练阶段的章节里,我们提到了 Trainer 会把所有的 metadata 写入模型目录,这个 metadata 数据包含了将模型运行的一切细节。DataRouter 根据请求中的 project 和 model 参数,从本地文件系统或者云存储系统查找模型文件。在找到模型后,会读取里面的 metadata,从 metadata 构建 Interpreter。

构建 Interpreter 的过程,会按照 metadata 中 pipeline 的顺序,先后实例化各个组件,然后依次用组件的 metadata模型目录路径模型的配置 作为参数调用每个组件的 load 方法。至此,组件的 load 方法有足够的信息,可以从文件系统载入相关的参数然后将组件组装成可以推理的状态。

推理流程

在 pipeline 中的每个组件都加载完毕后,模型就可以做推理的工作了。Interpreter 会把用户的请求数据解析成一个 rasa_nlu.training_data.message.Message 对象,然后将 message 对象依次传递给 pipeline 中的每一个组件实例,每个组件实例都可以在 message 对象上读取和添加相关的属性,将相关信息依次传递到下游,每个组件通过调用 message 对象的 set 方法的方式,完成推理结果的输出。

结构化输出

Rasa NLU 的输出的默认结果类似如下:

1
{"intent": {"name": None, "confidence": 0.0}, "entities": []}

Rasa NLU 会用从 message 对象上提取输出结果并和默认模板合并(前者覆盖后者)。默认情况下,只有通过 set 方法设置的属性才能从 message 输出。