Rasa3源码分析系列1:Custom Graph Components

752 阅读5分钟

系列的第一章节,我们聊一聊Rasa3自定义的图组件的源码。Rasa3提出了将对话系统pipline统一为有向无环图(DAG)的架构,在此架构的基础上,用户可以采用Rasa提供的多种多样的NLU和Policy的组件,也可以自定义图组件。先来看看官方文档是怎么说的。

如何实现一个自定义图组件

要自定义图形组件并和rasa适配,它必须满足以下要求:

  • 必须实现GraphComponent interface
  • 必须使用已使用的模型配置进行注册
  • 必须在配置文件中使用
  • 它必须使用类型注释。Rasa使用类型注释来验证您的模型配置。不允许转发引用

Graph Components

Rasa使用传入的模型配置来构建有向无环图。此图描述了模型配置中组件之间的依赖关系以及数据在它们之间的流动方式。这有两个主要好处:

  • Rasa可以使用计算图来优化模型的执行。例如,有效缓存训练步骤和并行独立的执行步骤。
  • Rasa可以灵活地表示不同的模型体系结构。只要图保持非循环,Rasa理论上可以基于模型配置将任何数据传递给任何图组件,而不必将底层软件架构与所使用的模型架构联系起来。

当将模型配置转换为计算图时,Policies和NLU组件将成为该图中的节点。虽然模型配置中的策略和NLU组件之间存在区别,但当它们被放置在图中时,这种区别就会被抽象掉。在这一点上,Policies和NLU组件变成了抽象的图组件。在实践中,这由GraphComponent接口表示:Policies和NLU组件都必须从该接口继承,才能与Rasa的图兼容并可执行。

image.png

Graph Component Interface

下面一起来看源码,首先,我们定位到engine/graph.py,如果你想实现一个自定义的NLU或者Policies组件,那么必须实现Graph Component接口,接口实现了ABC类,是所有图组件的接口。

class GraphComponent(ABC):
    """
    所有图组件的接口
    """

下面让我们具体看一下,该接口实现了哪些方法:

required_packages

@classmethod
def required_components(cls) -> List[Type]:
    return []

很简单,就是定义该组件之前需要包含的组件。

create

@classmethod
@abstractmethod
def create(
        cls,
        config: Dict[Text, Any],
        model_storage: ModelStorage,
        resource: Resource,
        execution_context: ExecutionContext
) -> GraphComponent:
    ...

create方法用于在训练期间实例化图组件,并且必须重写。Rasa在调用方法时传递以下参数:

  • config:组件的默认配置与模型配置文件中图组件的配置合并后的配置
  • model_storage:可以使用它来持久化和加允许您唯一地标识图形组件在模型存储中的位置。载图组件
  • resource:标识图组件在model storage中的位置,即代表一个持久化组件
  • execution_context:这提供了有关当前执行模式的附加信息
    • model_id:推理过程中使用的模型的唯一标识符,此参数在训练期间为None
    • should_add_diagnostic_data:如果为True,则应在实际预测的基础上向图组件的预测添加额外的诊断元数据
    • is_finetuning:如果为True,则可以使用微调来训练图组件
    • graph_schema: graph schema描述用于训练助手或用它进行预测的计算图
    • node_name:node_name是graph schema中的唯一标识符,由被调用的图组件完成

load

@classmethod
def load(
        cls,
        config: Dict[Text, Any],
        model_storage: ModelStorage,
        resource: Resource,
        execution_context: ExecutionContext,
        **kwargs: Any
) -> GraphComponent:
    return cls.create(config, model_storage, resource, execution_context)

load方法用于在推理过程中实例化图组件。此方法的默认实现调用您的create方法。如果图组件将数据作为训练的一部分持久化,建议覆盖此项。参数与create方法一致。

get_default_config

@staticmethod
def get_default_config() -> Dict[Text, Any]:
    return {}

方法get_default_config返回图组件的默认配置。默认实现返回一个空字典,这意味着图组件没有任何配置。Rasa将在运行时使用配置文件更新默认配置

support_languages

@staticmethod
def supported_languages() -> Optional[List[Text]]:
    return None

supported_languages方法指定图组件支持哪些语言。Rasa将使用模型配置文件中的键language来验证图组件是否适用于指定的语言。如果图组件返回None(这是默认实现),则表示图组件支持所有不属于not_supported_languages的语言

not_supported_languages

@staticmethod
def not_supported_languages() -> Optional[List[Text]]:
    return None

not_supported_languages方法指定图组件不支持的语言。Rasa将使用模型配置文件中的键language来验证图组件是否可以与指定的语言一起使用。如果图组件返回None(这是默认实现),则表明支持supported_languages中指定的所有语言

required_packages

@staticmethod
def required_packages() -> List[Text]:
    return []

required_packages方法指示需要安装哪些额外的Python包才能使用此图组件。如果在运行时找不到所需的库,Rasa将在执行过程中报错。默认情况下,此方法返回一个空列表,这意味着您的图组件没有任何额外的依赖项。

结语

到此为止,GraphComponent接口的源码内容都看完了,在本章节我们只需要初步了解有向无环图的设计,和组件在创建和加载过程中的依赖即可。欢迎大家一起学习,如有问题和批评,欢迎在评论区中探讨。