配置文件系统¶
介绍¶
配置文件系统是机器学习算法工具中的一个重要组成部分,而强化学习的复杂性使得其配置领域任务相比其他机器学习任务更加复杂。为了解决这个问题,DI-engine 基于“约定优于配置”(CoC)的原则进行设计,并开发了一套基本原则和相关工具,包括:
Python 配置原则
配置编译原理
默认配置和用户配置
强化学习任务核心配置字段的分类
注意
To learn more about the Convention over Configuration principle, you can refer to a Chinese blog post 设计杂谈(0x02)——约定大于配置 .
基本原则¶
整体示意图如下:
Python 配置原则¶
由于大多数机器学习程序重视编程的灵活性和易用性,DI-engine 使用 Python 文件(特别是多级字典)作为默认配置文件,以兼容各种特殊需求。之前使用 yaml 和 json 的用户也可以轻松迁移到 Python 配置。然而,对于核心模块之外的部分,例如强化学习模拟环境中的通信接口,也可以使用原生配置,没有任何特殊限制。
配置编译原理¶
在整个训练程序中,DI-engine 使用诸如 compile_config 和 get_instance_cfg 等工具函数作为边界。在边界之前,用户可以通过使用默认配置、在代码中修改配置、从命令行输入配置等多种方式自定义所需的配置内容。然而,在边界之后,所有配置文件将被固定,不允许再进行更改。训练程序将根据当时的配置创建相应的功能模块和训练管道。这一规则被称为 Configuration Compilation Principles,其中边界之前的时期称为 configuration compilation generation period,边界之后的时期称为 configuration runtime usage period。此外,在工具函数中,最终生成的配置文件将被导出并存储在实验目录文件夹中(通常命名为 total_config.py),用户可以使用该文件检查配置文件设置的有效性,或直接使用该文件重现原始实验。
注意
通常,在完成实验后,相关信息会存储在以exp_name配置字段命名的路径文件夹中。其中,宏配置文件是total_config.py,格式转换后可以直接用于训练的配置文件是formatted_total_config.py。用户可以直接从该文件中导入相应的main_config和create_config,并将它们传递给训练入口函数以启动实验。
提示
为确保配置编译原则的有效性,建议用户不要在模块代码中使用诸如cfg.get('field_xxx', 'xxx')等操作,因为这可能违反编译原则,并且无法记录和跟踪相关修改。
默认配置和用户配置¶
另一方面,由于强化学习训练程序中的各种配置内容,如MDP建模设置、算法调优设置和训练系统效率设置,通常存在大量的可配置文件字段。然而,不同的配置字段有不同的使用频率,在大多数情况下,大多数配置字段不需要用户修改。因此,DI-engine引入了默认配置的概念,强化学习中的核心概念,如Policy、Env和Buffer,通常都有其默认配置(default config),其完整定义和解释可以在相应的类定义中找到。在使用DI-engine时,用户只需指定在当前情况下需要修改或添加的配置字段。在前面提到的边界函数中(如compile_config),默认配置和用户配置被编译并合并,形成最终的配置文件。具体的合并规则如下:
存在于默认配置中但不在用户配置中的字段将使用默认值。
用户配置中存在但默认配置中不存在的字段将使用用户指定的值。
默认配置和用户配置中都存在的字段将使用用户指定的值。
强化学习任务核心配置字段的类别¶
总体而言,DI-engine 中强化学习任务所需的配置字段主要可以分为两类:
第一类由训练管道中各种工作者/中间件共享的对象组成,例如算法策略(
Policy)、环境(Env)、奖励模型(Reward Model)、数据队列(Buffer)等。每个对象都有其默认配置。在整体配置文件中,它们彼此平行放置并保持扁平层次结构。每个对象的配置字段的含义可以在相应的类定义中找到,类变量config和类方法default_config指定了默认配置和调用方法。第二类包括在训练管道中执行各种任务的工作者/中间件,例如学习者(
Learner)、数据收集器(Collector)等。它们通常具有较少的相应参数,这些参数可以直接在训练入口函数中指定或附加到整体配置文件的全局区域。对于它们的具体实现没有特殊要求,代码应保持清晰且易于使用。
除了主配置 main_config 外,还有一个创建配置 create_config,用于快速创建训练入口点。这部分创建配置仅用于 serial_pipeline_xxx 系列的快速训练入口点,对于创建自定义训练入口函数的用户可以忽略。创建配置需要指定相应的类型名称(type)和导入模块所需的路径(import_names)。
注意
由于历史原因,Policy 领域中定义了许多子域,例如 learn、collect、eval、other 等。然而,在最新版本的 DI-engine(>=0.4.7)中,已取消对这些定义的强制依赖。现在,使用或不使用这些结构是可选的,只要配置字段与策略中相应的有效代码段对应即可。
其他工具¶
DI-engine 还提供了一些用于配置文件存储和格式化的相关工具。具体信息,请参考代码 ding/config 。
配置文件示例分析¶
这里有一个在DI-engine中的具体配置示例,用于在CartPole环境中训练DQN代理(快速入门文档中使用的示例)。具体的配置内容和相关字段解释如下:
from easydict import EasyDict
cartpole_dqn_config = dict(
exp_name='cartpole_dqn_seed0',
env=dict(
collector_env_num=8,
evaluator_env_num=5,
n_evaluator_episode=5,
stop_value=195,
),
policy=dict(
cuda=False,
model=dict(
obs_shape=4,
action_shape=2,
),
nstep=1,
discount_factor=0.97,
learn=dict(
update_per_collect=5,
batch_size=64,
learning_rate=0.001,
),
collect=dict(n_sample=8),
),
)
cartpole_dqn_config = EasyDict(cartpole_dqn_config)
main_config = cartpole_dqn_config
cartpole_dqn_create_config = dict(
env=dict(
type='cartpole',
import_names=['dizoo.classic_control.cartpole.envs.cartpole_env'],
),
env_manager=dict(type='base'),
policy=dict(type='dqn'),
)
cartpole_dqn_create_config = EasyDict(cartpole_dqn_create_config)
create_config = cartpole_dqn_create_config
if __name__ == "__main__":
# or you can enter `ding -m serial -c cartpole_dqn_config.py -s 0`
from ding.entry import serial_pipeline
serial_pipeline((main_config, create_config), seed=0)
整个配置文件可以分为两部分,main_config 和 create_config。主配置(main_config)包含三个部分:实验名称(exp_name)、环境(env)和策略(policy),它们分别指定了当前任务最相关且最常修改的配置字段。
创建配置指定了环境类型、环境管理器和策略的类型,以便下面的快速训练入口 serial_pipeline 可以直接运行此配置文件。如果您使用任务/中间件方法来自定义训练入口,可以直接加载此配置文件。