如何做到史上最快的基于CPU的通用强化学习环境并行模拟器?

共 4471字,需浏览 9分钟

 ·

2021-11-15 14:49

↑ 点击蓝字 关注极市平台

作者丨Trinkle@知乎(已授权)
来源丨https://zhuanlan.zhihu.com/p/431543858
编辑丨极市平台

极市导读

 

一个基于C++的、高效的、通用的RL并行环境模拟器EnvPool,并且能兼容已有的gym/dm_env API。根据现有测试结果,能在正常的笔记本上比python subprocess快个3倍,在256核的CPU上能全吃满,跑出一百万FPS。 >>加入极市CV技术交流群,走在计算机视觉的最前沿

这不是标题党谢谢,这是我暑假做的项目)

TL; DR: EnvPool是一个基于C++的、高效的、通用的RL并行环境(俗称vector env)模拟器,并且能兼容已有的gym/dm_env API。根据现有测试结果,能在正常的笔记本上比python subprocess快个3倍,并且在服务器上加速比也很高(核越多越高),在256核的CPU上能全吃满,跑出一百万FPS,比subprocess快十几倍,比之前最快的异步模拟器 Sample Factory(https://github.com/alex-petrenko/sample-factory/)还快个一倍多两倍(有的时候甚至同步版EnvPool跑的都比Sample Factory快)!

现在已经在GitHub开源了!欢迎批评以及各种评测(虽然还有很多东西没从内部版checkout出来……在做了在做了……咕咕咕)

https://github.com/sail-sg/envpool

使用的话……原来SubprocVecEnv怎么用,EnvPool也可以一样用,当然还有一些高端用法后面会慢慢说

为啥要做这个项目

首先玩过RL的人应该都知道,如果把1个env和1个agent交互的过程变成n个env和1个agent交互,那么训练速度会大大提高(如果调参调的好的话),计算资源利用率也会提高,这样就可以几分钟train出来一个不错的AI而不是原来的几小时甚至几天。(其实这也是 tianshou (https://github.com/thu-ml/tianshou)立项原因之一)

其次是目前主流的环境并行解决方案是python for-loop和python subprocess+share memory。虽然很方便写,但是……太慢了。for-loop慢是很正常的,subprocess慢是因为几个原因,一个是process的切换需要context switching,导致overhead比较大,第二个是python有GIL,三是数据传输也有额外开销,四是python有点慢(所以正常的环境为了确保性能都是C++写的)

那么我们为啥不能直接在C++这一层把并行给做了呢?对外只暴露batch的接口

然后有人要说了,为啥不分布式呢?ray其实也做了这个而且看起来挺灵活。但是根据测试,ray的计算资源利用率不太行,通常加速比是负数(,这样会花很多冤枉钱在训练上面

然后有人要说了,为啥不GPU用CUDA做呢?其实有项目已经做这个方面的优化了比如 Brax / Isaac-gym,但是GPU的话其实不够通用,要重写整个env代码,意味着不能很好兼容生态以及不能用一些受商业保护的代码。所以现在他们只重写了几个类似mujoco的env,虽然能达到几千万FPS但毕竟不能适用于所有RL环境。

Braxhttps://github.com/google/brax

 Isaac-gym:https://developer.nvidia.com/isaac-gym

然后有人要说了,为啥之前没人做这个C++层面并行的idea?其实是有的,只不过没做好。举几个例子是openai的 gym3 procgen 也是这么做的,但是我当时顺便测了下速发现他们 实 在 不 行。看这里有个讨论:https://github.com/thu-ml/tianshou/issues/409

 gym3 https://github.com/openai/gym3

procgenhttps://github.com/openai/procgen

(一个小插曲:我还在写EnvPool的时候,678月连着放了Brax/Isaac-gym/WarpDrive,虽然都是通过GPU进行加速,但是感觉非常慌,害怕连这种代码量巨大的项目也要卷……不过看起来是我多虑了)

(还有一个小插曲:某天看到票圈里面有个人说,花了三个月时间做Atari实验一共用了60万RMB,说应该把Atari剔除出RL benchmark。那我负责喊666然后顺便可以推销一波EnvPool,能省40万的话我要的也不多,就40万吧(雾

那么EnvPool性能究竟如何?

首先先解释一下EnvPool是如何区分同步step和异步step的。实际上在内部实现的时候这两种直接被看做是同一种方法,简单来讲举个例子,有8个env(num_envs=8)但是我每次设置只返回其中4个的结果(batch_size=4),每次step的时候把剩下的env放在background继续跑,这就是异步step;同步step就是num_envs == batch_size,每次等全部step好再返回。理论上这种异步step能够有效提高CPU利用率(事实确实如此)

之前画的图,内部版的API是numenv/waitnum,和num_envs/batch_size一个意思

然后直接上图

昨天和今天刚跑出来的。

首先EnvPool可以很方便的定义是同步版(每次step所有env,和vector_env一样)还是异步版(每次异步step指定env),这里面可以认为Sample Factory和EnvPool (async/numa) 是一组都是异步step,剩下的都是同步step。公平起见这里来算下每一组的倍数:

Highest FPSLaptop (12)TPU-VM (96)Apollo (96)DGX-A100 (256)
For-loop8.37x46.09x39.28x108.43x
Subprocess2.24x4.10x8.14x5.91x
EnvPool (sync)1x1x1x1x
Sample Factory1.87x1.83x1.56x1.32x
EnvPool (async)1x1x1x1x

为了不伤害Subprocess的自尊心,我这里就不拿async EnvPool和它比了。NUMA太优秀了就先一边站着。

Atari on TPUv3 96 core
Atari on Nvidia DGX-A100 256 core

值得一提的是Sample Factory是异步实现的env.step,但是和EnvPool同步版的性能却差不多,更加证明了python-level parallalization是多么不行)

其实还有vizdoom的benchmark结果的,但是还没从内部版checkout到开源版本上面,到时候会更的!

那么……生态呢?

开源项目必须得在生态营造的地方下功夫才不至于会死。

首先是安装,使用 pip install envpool 就能在linux机子上安装成功(需要python版本3.7以上)(时间太赶还要上课做作业暂时先没考虑别的操作系统了……)

其次是用法,使用

env_gym = envpool.make_gym("Pong-v5", ...)
env_dm = envpool.make_dm("Pong-v5", ...)

# obs/act shape
observation_space = env_gym.observation_space
action_space = env_gym.action_space

就能轻松得到一个gym.Env或者dm_env,在同步模式下API是和已有的标准API完全一致,当然也可以只step/reset部分env,只需要多传一个参数就行:

while True:
act = policy(obs)
obs, rew, done, info = env.step(act, env_id)
env_id = info["env_id"]

(这其实已经是异步step了,如果每次env_id都只有一部分的话)

以及在设计新版EnvPool的时候,我们还考虑了结构化数据(比如nested observation/action)、multi-player env、以及二者融合的情况,接口都预留好了;

以及对于潜在的contributor而言,只需要在C++一侧按照envpool/core/env.h的API把环境接好,然后实例化注册一下就能成功用上EnvPool的加速。

对于开源项目最重要的测试和文档,现在已经搭了一套比较成熟的CI pipeline进行C++和Python两方面的测试,并且文档已经就位了:


里面有各种API解释和各种可配置参数。以及顺带提供了一些examples在envpool/examples at master · sail-sg/envpool(https://github.com/sail-sg/envpool/tree/master/examples),理论上可以直接跑的(虽然确实还比较少但是……我不想掉头发,会做的会做的 咕咕咕咕)

最后日常不要脸求star,再放一遍链接

https://github.com/sail-sg/envpool


如果觉得有用,就请分享到朋友圈吧!

△点击卡片关注极市平台,获取最新CV干货

公众号后台回复“CVPR21检测”获取CVPR2021目标检测论文下载~


极市干货
神经网络:视觉神经网络模型优秀开源工作:timm库使用方法和最新代码解读
技术综述:综述:神经网络中 Normalization 的发展历程CNN轻量化模型及其设计原则综述
算法技巧(trick):8点PyTorch提速技巧汇总图像分类算法优化技巧


CV技术社群邀请函 #

△长按添加极市小助手
添加极市小助手微信(ID : cvmart4)

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)


即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群


每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~



觉得有用麻烦给个在看啦~  
浏览 58
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报