本文是对著名对话机器人开源框架Rasa NLU classifier中最受欢迎的DIET Classifier的解析。Rasa是一套开源机器学习框架,用于构建基于上下文的AI小助手和聊天机器人。Rasa有两个主要模块:Rasa NLU 用于对用户消息内容的语义理解;Rasa Core 用于对话管理(Dialogue management)。本文主要针对Rasa NLU classifier 中的DIET Classifier做详细的说明。
本文更多关注算法,主要内容如下:
- Rasa NLU Classifier架构
- 主流技术支持情况
DIET Classifier架构
321
模型支持说明
DIET支持的Huggingface模型类型如下表:
模型类型 | 模型名称 | 默认加载的预训练模型 |
---|---|---|
BERT | bert | rasa/LaBSE ( bert-base-uncased ) |
GPT | gpt | openai-gpt |
GPT2 | gpt2 | gpt2 |
XLNet | xlnet | xlnet-base-cased |
DistilBERT | distilbert | distilbert-base-uncased |
RoBERTa | roberta | roberta-base |
对在HuggingFace 中上传的所有预训练模型(Huggingface模型列表),Rasa DIET可以支持满足以下条件的所有模型:
点击Huggingface模型列表->选中一个模型->点击进入模型页面->点击Files and version
- 检查 config.json 中的 model_type 是否列在上表的 模型名称 列中
- 检查文件 tf_model.h5 是否存在
- 模型使用默认tokenizer, config.json 中不包含支持自定义的 tokenizer_class
对满足上述条件的模型,通过2.1.3.3中描述的方式可开箱即用。
DIET支持Huggingface的配置样例
在Rasa2.0中,若想在DIET架构中使用Huggingface提供的预训练模型,除在rasa的config文件中指定使用DIETClassifier外,还需要配合使用对应的模块:
- HFTransformersNLP
主要参数:model_name: 预训练模型config.json 中的 model_type的值
model_weights: Huggingface模型列表提供的预训练模型名称
- LanguageModelTokenizer:确保训练数据token对应的token_id与预训练模型的token_id保持一致
- LanguageModelFeaturizer:生成经预训练模型转换后的特征向量,做为架构后续模块的输入。
1 | language: en |
- DIET样例代码包位置:examples/hf_demo
- DIET样例代码调用方式:项目根目录/main.py
- 涉及的源码改动:
如按 ‘样例代码调用方式’ 直接跑报错... set from_pt=true, 请修改: 项目根目录/rasa/nlu/utils/hugging_face/hf_transformers.py: class HFTransformersNLP中的def _load_model_instance中
1 | self.model = model_class_dict[self.model_name].from_pretrained(self.model_weights, cache_dir=self.cache_dir) |
改为
1 | self.model = model_class_dict[self.model_name].from_pretrained(self.model_weights, cache_dir=self.cache_dir, from_pt=True) |
DIET核心代码解析
rasa.nlu.model.Trainer.train:遍历pipeline所有components,对每个component调用component.train方法完成训练。在component遍历到DIETClassifier之前,HFTransformersNLP等组件已经提取好了DIETClassifier训练需要的特征。遍历至DIETClassifier后,DIETClassifier开始利用已经提取好的特征进入训练。
rasa.nlu.classifiers.DIETClassifier.train: 该方法主要完成三件事:
语料准备:通过DIETClassifier类中的方法preprocess_train_data,将训练数据和之前提取的特征整理成符合RasaModelData格式的model_data。RasaModelData格式为。。。。。之后将整理好的model_data按batch_size整理成data_generator供batch训练用。
指定模型:将DIETClassifier类的成员self.model通过初始化DIET类完成指定DIET模型训练。
DIET模型类继承自TransformerRasaModel类:自定义了
TransformerRasaModel继承自RasaModel:自定义了。。。 要求实现。。。
RasaModel继承自TmpKerasModel:通过重写tf.keras.Model中的train_step(), test_step(), predict_step(), save()和load()方法,实现自定义的Rasa模型.
- train_step()使用自定义的batch_loss并对该loss做了正则化。batch_loss需由其子类实现。
- predict_step()使用自定义的batch_predict()。需由其子类实现。
- save()只使用tf.keras.Model.save_weights()。
- load()生成模型结构后加载weights.
TmpKerasModel继承自tf.keras.models.Model:重写了tf.keras.models.Model的fit方法来使用自定义的数据适配器。将数据转写成CustomDataHandler后由其处理迭代 epoch 级别的
tf.data.Iterator
对象。
训练