外部环境与应用#
在许多情况下,RLlib“驱动”RL环境并没有意义。例如,当你在一个具有自身执行循环的复杂模拟器(如游戏引擎或机器人模拟器)中训练策略时。一种自然且用户友好的方法是反转这种设置,即——不是让RLlib“驱动”环境——而是让模拟器中的智能体完全控制自己的驱动。一个由RLlib支持的外部服务将可用于查询单个动作或接受批量样本数据。该服务将负责训练策略的任务,但不会对模拟器的步进频率或频率施加任何限制。
具有客户端推理的外部应用:外部模拟器(例如游戏引擎)通过一个TCP兼容的自定义EnvRunner连接到RLlib(作为服务器运行)。模拟器会不时地向服务器发送数据批次,并接收权重更新。为了获得更好的性能,动作是在客户端本地计算的。#
RLlib为此目的提供了一个名为RLlink的外部消息传递协议,并且可以选择自定义您的EnvRunner类,以便通过RLlink与一个或多个客户端进行通信。这里有一个基于TCP的EnvRunner实现的示例,它使用了RLlink:可在【这里】找到。它还包含一个用于测试的Dummy(CartPole)客户端,并且可以作为您的外部应用程序或模拟器应如何使用RLlink协议的模板。
注意
外部应用程序支持仍在RLlib的新API堆栈上进行中。Ray团队正在为自定义EnvRunner实现(除了已有的基于TCP的实现)以及各种客户端非Python的RLlib适配器(例如,针对流行的游戏引擎和其他模拟软件)提供更多示例。
RLlink协议#
RLlink是一个简单、有状态的协议,旨在实现强化学习(RL)服务器(例如RLlib)与充当环境模拟器的外部客户端之间的通信。该协议能够无缝交换RL特定数据,如剧集、配置和模型权重,同时促进在线策略训练工作流。
主要特点#
有状态设计:协议通过消息交换序列(例如,请求-响应对,如
GET_CONFIG->SET_CONFIG)来维护一些状态。严格的请求-响应设计:协议严格遵循(客户端)请求 -> (服务器)响应的模式。由于需要让客户端模拟器在其自身的执行循环中运行,服务器端避免向客户端发送任何未经请求的消息。
RL特定功能:为RL工作流量身定制,包括剧集处理、模型权重更新和配置管理。
灵活的采样:支持在线和离线数据收集模式。
JSON:为了便于调试和加速迭代,RLlink的早期版本完全基于JSON,未加密且不安全。
消息结构#
RLlink消息包含一个头部和一个主体
头部:8字节长度字段,指示主体的长度,例如,长度为16的主体编码为
00000016(因此,消息总长度)。主体:JSON编码的内容,包含一个
type字段,指示消息类型。
示例消息:PING和EPISODES_AND_GET_STATE#
以下是PING消息的一个完整简单示例。请注意,8字节的头部编码了后续主体的长度为16,后面是带有必需“type”字段的消息主体。
00000016{"type": "PING"}
客户端应在建立新连接后发送PING消息。服务器随后响应:
00000016{"type": "PONG"}
以下是客户端发送给服务器的EPISODES_AND_GET_STATE消息示例,该消息包含一批样本数据。通过同一条消息,客户端请求服务器发送更新的模型权重。
{
"type": "EPISODES_AND_GET_STATE",
"episodes": [
{
"obs": [[...]], // List of observations
"actions": [...], // List of actions
"rewards": [...], // List of rewards
"is_terminated": false,
"is_truncated": false
}
],
"env_steps": 128
}
所有消息类型概述#
请求:客户端 → 服务器#
``PING``
示例:
{"type": "PING"}目的:用于建立通信的初始握手。
预期响应:
{"type": "PONG"}。
``GET_CONFIG``
示例:
{"type": "GET_CONFIG"}目的:请求相关配置(例如,单条
EPISODES_AND_GET_STATE消息需要收集多少个时间步;见下文)。预期响应:
{"type": "SET_CONFIG", "env_steps_per_sample": 500, "force_on_policy": true}。
``EPISODES_AND_GET_STATE``
示例:此处有消息示例
目的:将
EPISODES和GET_STATE合并为单个请求。这对于在数据收集后需要对模型权重进行在线(同步)更新的工作流很有用。主体
episodes:JSON对象(字典)列表,每个对象包含必需的键“obs”(剧集中观察值列表)、“actions”(剧集中动作列表)、“rewards”(剧集中奖励列表)、“is_terminated”(布尔值)和“is_truncated”(布尔值)。请注意,“obs”列表比“actions”和“rewards”列表多一个元素,因为包含初始的“reset”观察值。weights_seq_no:模型权重的序列号,用于确保同步。
预期响应:
{"type": "SET_STATE", "weights_seq_no": 123, "mlir_file": ".. [base64 编码的 包含 模型的 二进制 .mlir 文件的 字符串] .."}。
响应:服务器 → 客户端#
``PONG``
示例:
{"type": "PONG"}目的:对
PING请求的确认,以验证连接性。
``SET_STATE``
示例:
{"type": "SET_STATE", "weights_seq_no": 123, "onnx_file": "... [base64 编码的 ONNX 文件] ..."}目的:向客户端提供当前状态(例如,模型权重)。
主体
onnx_file:Base64编码的压缩ONNX模型文件。weights_seq_no:模型权重的序列号,用于确保同步。
``SET_CONFIG``
目的:将相关配置详细信息发送给客户端。
主体
env_steps_per_sample:单条EPISODES_AND_GET_STATE消息收集的总环境步数。force_on_policy:是否强制执行在线采样。如果为true,客户端在发送EPISODES_AND_GET_STATE消息后,应等待SET_STATE响应,然后再继续收集下一轮样本。
工作流示例#
初始握手
客户端发送
PING。服务器用
PONG响应。
配置请求
客户端发送
GET_CONFIG。服务器用
SET_CONFIG响应。
训练(在线策略)
客户端收集在线策略数据并发送
EPISODES_AND_GET_STATE。服务器处理剧集并用
SET_STATE响应。
注意
此协议是我们为开发一个广泛采用的外部客户端与远程RL服务通信协议所做的初步尝试。随着协议的成熟,预计会有许多更改、增强和升级,包括增加安全层和压缩。但目前,它为将外部环境与RL框架集成提供了一个轻量级、简单但功能强大的接口。
示例:外部客户端连接到基于TCP的EnvRunner#
基于TCP的EnvRunner实现的RLlink示例可在【这里】找到。有关完整的端到端示例,请参见【这里】。
您可以随意修改自定义EnvRunner的基础逻辑,例如,您可以实现一个基于共享内存的通信层(而不是基于TCP的)。