跳转到主要内容

Reverb是一个高效且易于使用的数据存储和传输系统,专为机器学习研究设计。

项目描述

Reverb

PyPI - Python Version PyPI version

Reverb 是一个高效且易于使用的机器学习研究用数据存储和传输系统。Reverb 主要用作分布式强化学习算法的经验回放系统,但该系统还支持多种数据结构表示,如FIFO、LIFO和优先队列。

目录

安装

请注意,Reverb 并未针对生产使用进行强化,虽然我们尽力保持系统正常运行,但系统可能会出现故障或段错误。

:warning: Reverb 目前仅支持基于 Linux 的操作系统。

安装 Reverb 的推荐方式是使用 pip。我们还提供了使用与发布相同的 Docker 镜像从源代码构建的说明。

TensorFlow 可以单独安装,也可以作为 pip 安装的一部分。将 TensorFlow 作为安装的一部分确保兼容性。

$ pip install dm-reverb[tensorflow]

# Without Tensorflow install and version dependency check.
$ pip install dm-reverb

夜间构建

PyPI version

$ pip install dm-reverb-nightly[tensorflow]

# Without Tensorflow install and version dependency check.
$ pip install dm-reverb-nightly

调试构建

从版本 0.6.0 开始,Reverb 的调试构建上传到 Google Cloud Storage。以下模式可以下载或直接通过 pip 安装构建。可以使用 gsutils 导航目录结构以确保文件存在,例如 gsutil ls gs://rl-infra-builds/dm_reverb/builds/dbg。要构建自己的调试二进制文件,请参阅构建说明

对于 python 3.8 和 3.9,请遵循以下模式

$ export reverb_version=0.8.0
# Python 3.9
$ export python_version=39
$ pip install https://storage.googleapis.com/rl-infra-builds/dm_reverb/builds/dbg/$reverb_version/dm_reverb-$reverb_version-cp$python_version-cp$python_version-manylinux2010_x86_64.whl

从源代码构建

本指南详细介绍了如何从源代码构建 Reverb。

Reverb 发布

由于某些底层库(如 protocabsl),Reverb 必须与 TensorFlow 的特定版本配合使用。如果使用 pip install dm-reverb[tensorflow] 安装 Reverb,则会安装正确的 TensorFlow 版本。下表列出了 Reverb 每个版本关联的 TensorFlow 版本以及一些感兴趣版本

  • 0.13.0 删除了对 Python 3.8 的支持。
  • 0.11.0 是第一个支持 Python 3.11 的版本。
  • 0.10.0 是最后一个支持 Python 3.7 的版本。
发布 分支 / 标签 TensorFlow 版本
夜间 master tf-nightly
0.14.0 v0.14.0 2.14.0
0.13.0 v0.13.0 2.14.0
0.12.0 v0.12.0 2.13.0
0.11.0 v0.11.0 2.12.0
0.10.0 v0.10.0 2.11.0
0.9.0 v0.9.0 2.10.0
0.8.0 v0.8.0 2.9.0
0.7.x v0.7.0 2.8.0

快速开始

启动 Reverb 服务器就像

import reverb

server = reverb.Server(tables=[
    reverb.Table(
        name='my_table',
        sampler=reverb.selectors.Uniform(),
        remover=reverb.selectors.Fifo(),
        max_size=100,
        rate_limiter=reverb.rate_limiters.MinSize(1)),
    ],
)

创建一个客户端以与服务器通信

client = reverb.Client(f'localhost:{server.port}')
print(client.server_info())

将一些数据写入表

# Creates a single item and data element [0, 1].
client.insert([0, 1], priorities={'my_table': 1.0})

项目可以引用多个数据元素

# Appends three data elements and inserts a single item which references all
# of them as {'a': [2, 3, 4], 'b': [12, 13, 14]}.
with client.trajectory_writer(num_keep_alive_refs=3) as writer:
  writer.append({'a': 2, 'b': 12})
  writer.append({'a': 3, 'b': 13})
  writer.append({'a': 4, 'b': 14})

  # Create an item referencing all the data.
  writer.create_item(
      table='my_table',
      priority=1.0,
      trajectory={
          'a': writer.history['a'][:],
          'b': writer.history['b'][:],
      })

  # Block until the item has been inserted and confirmed by the server.
  writer.flush()

我们可以通过采样来读取添加到 Reverb 中的项目

# client.sample() returns a generator.
print(list(client.sample('my_table', num_samples=2)))

继续阅读Reverb 教程进行交互式教程。

详细概述

经验回放已成为训练离策略强化学习策略的重要工具。它被深度Q网络(DQN)[链接]、软演员-评论家(SAC)[链接]、深度确定性策略梯度(DDPG)[链接]、Hindsight Experience Replay[链接]等算法所使用。然而,构建一个高效、易于使用且可扩展的回放系统可能具有挑战性。为了获得良好的性能,Reverb是用C++实现的,并且为了支持分布式使用,它提供了一个gRPC服务,用于添加、采样和更新表的内容。Python客户端以易于使用的方式公开了服务的全部功能。此外,还提供了原生TensorFlow操作,以便与TensorFlow和tf.data高效集成。

虽然Reverb最初是为离策略强化学习设计的,但其灵活性使其对在线策略强化学习——甚至(非)监督学习同样有用。有创意的用户甚至使用Reverb来存储和分发频繁更新的数据(例如模型权重),作为内存中轻量级的分布式文件系统替代品,其中每个表代表一个文件。

表格

Reverb的服务器由一个或多个表组成。表包含项目,每个项目引用一个或多个数据元素。表还定义了样本和移除选择策略、最大项目容量和速率限制器

多个项目可以引用相同的数据元素,即使这些项目存在于不同的表中。这是因为项目只包含对数据元素的引用(而不是数据的副本)。这也意味着只有当不存在包含对它引用的项目时,数据元素才会被删除。

例如,可以设置一个表作为优先经验回放(PER)用于转换(长度为2的序列),另一个表作为长度为3的序列的(FIFO)队列。在这种情况下,PER数据可以用于训练DQN,而FIFO数据可以用于训练环境的转换模型。

Using multiple tables

当满足以下两种条件之一时,项目将自动从表中删除:

  1. 插入新项目会导致表中的项目数量超过其最大容量。使用表的移除策略来确定要删除的项目。

  2. 项目被采样的次数超过了表速率限制器允许的最大次数。此类项目将被删除。

不再由任何项目引用的数据元素也将被删除。

用户可以完全控制如何从Reverb表中采样和删除数据。该行为主要由作为samplerremover提供给Tableitem-selection-strategies控制。结合rate_limitermax_times_sampled,可以实现广泛的行为。一些常用配置包括

均匀经验回放

维护一组最近插入的N=1000个项目。通过设置sampler=reverb.selectors.Uniform(),选择项目的概率对所有项目都是相同的。由于reverb.rate_limiters.MinSize(100),采样请求将阻塞,直到插入100个项目。通过设置remover=reverb.selectors.Fifo(),当需要删除项目时,将首先删除最旧的项目。

reverb.Table(
     name='my_uniform_experience_replay_buffer',
     sampler=reverb.selectors.Uniform(),
     remover=reverb.selectors.Fifo(),
     max_size=1000,
     rate_limiter=reverb.rate_limiters.MinSize(100),
)

使用均匀经验回放算法的示例包括SACDDPG

优先经验回放

一组最近插入的N=1000个项目。通过设置sampler=reverb.selectors.Prioritized(priority_exponent=0.8),选择项目的概率与项目的优先级成正比。

注意:有关在此实现中使用的优先经验回放算法的更多信息,请参阅Schaul, Tom, et al.

reverb.Table(
     name='my_prioritized_experience_replay_buffer',
     sampler=reverb.selectors.Prioritized(0.8),
     remover=reverb.selectors.Fifo(),
     max_size=1000,
     rate_limiter=reverb.rate_limiters.MinSize(100),
)

利用优先经验回放的算法示例包括DQN及其变体,以及分布式分布式确定性策略梯度

队列

最多包含N=1000个项目的集合,其中最早的项目在相同操作中被选中并移除。如果集合包含1000个项目,则插入调用被阻塞,直到它不再满;如果集合为空,则采样调用被阻塞,直到至少有一个项目。

reverb.Table(
    name='my_queue',
    sampler=reverb.selectors.Fifo(),
    remover=reverb.selectors.Fifo(),
    max_size=1000,
    max_times_sampled=1,
    rate_limiter=reverb.rate_limiters.Queue(size=1000),
)

# Or use the helper classmethod `.queue`.
reverb.Table.queue(name='my_queue', max_size=1000)

利用队列的算法示例包括IMPALA近端策略优化的异步实现。

项目选择策略

Reverb定义了几个选择器,可用于项目采样或删除

  • 均匀:在所有项目间均匀采样。
  • 优先级:根据存储的优先级进行采样。
  • FIFO:选择最老的数据。
  • LIFO:选择最新的数据。
  • 最小堆:选择优先级最低的数据。
  • 最大堆:选择优先级最高的数据。

这些策略中的任何一种都可以用于从表中选择或删除项目。这使用户能够创建最适合其需求的定制表。

速率限制

速率限制器允许用户在何时可以插入和/或从表中采样项目时强制执行条件。以下是Reverb当前可用的速率限制器列表

  • 最小大小:设置在可以进行采样之前必须存在于表中的最小项目数。
  • 采样到插入比率:设置通过阻塞插入和/或采样请求的插入到采样的平均比率。这对于控制在删除之前每个项目被采样的次数很有用。
  • 队列:在删除之前,项目将被采样一次。
  • 栈:在删除之前,项目将被采样一次。

分片

Reverb服务器之间互不了解,当将系统扩展到多服务器配置时,数据不会在超过一个节点之间复制。这使得Reverb不适合作为传统数据库,但它在可以接受一定数据损失的系统扩展方面具有优势。

可以通过简单地增加Reverb服务器数量来水平扩展分布式系统。当与gRPC兼容的负载均衡器结合使用时,可以将负载均衡目标的地址提供给Reverb客户端,操作将自动分布在不同节点上。您可以在相关方法和类的文档中找到具体行为的详细信息。

如果您的配置中没有负载均衡器或需要更多控制,则系统仍然可以以几乎相同的方式扩展。只需增加Reverb服务器数量,并为每个服务器创建单独的客户端。

检查点

Reverb支持检查点;Reverb服务器的状态和内容可以存储到永久存储中。在检查点过程中,Server将所有需要重建的数据和元数据序列化。在此过程中,Server将阻止所有传入的插入、采样、更新和删除请求。

使用Reverb Client的调用执行检查点

# client.checkpoint() returns the path the checkpoint was written to.
checkpoint_path = client.checkpoint()

从检查点恢复reverb.Server

# The checkpointer accepts the path of the root directory in which checkpoints
# are written. If we pass the root directory of the checkpoints written above
# then the new server will load the most recent checkpoint written from the old
# server.
checkpointer = reverb.platform.checkpointers_lib.DefaultCheckpointer(
  path=checkpoint_path.rsplit('/', 1)[0])

# The arguments passed to `tables=` must be the same as those used by the
# `Server` that wrote the checkpoint.
server = reverb.Server(tables=[...], checkpointer=checkpointer)

有关Reverb中检查点实现的详细信息,请参阅tfrecord_checkpointer.h

使用reverb_server启动Reverb(beta版)

使用pip安装dm-reverb将安装一个reverb_server脚本,该脚本接受其配置为textproto。例如

$ reverb_server --config="
port: 8000
tables: {
  table_name: \"my_table\"
  sampler: {
    fifo: true
  }
  remover: {
    fifo: true
  }
  max_size: 200 max_times_sampled: 5
  rate_limiter: {
    min_size_to_sample: 1
    samples_per_insert: 1
    min_diff: $(python3 -c "import sys; print(-sys.float_info.max)")
    max_diff: $(python3 -c "import sys; print(sys.float_info.max)")
  }
}"

rate_limiter配置与Python表达式MinSize(1)等效,请参阅rate_limiters.py

引用

如果您使用此代码,请引用Reverb论文作为

@misc{cassirer2021reverb,
      title={Reverb: A Framework For Experience Replay},
      author={Albin Cassirer and Gabriel Barth-Maron and Eugene Brevdo and Sabela Ramos and Toby Boyd and Thibault Sottiaux and Manuel Kroiss},
      year={2021},
      eprint={2102.04736},
      archivePrefix={arXiv},
      primaryClass={cs.LG}
}

项目详情


发布历史 发布通知 | RSS源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

此版本没有可用的源分发文件。请参阅生成分发存档的教程。

构建分发

由以下机构支持