查看关于 rlpyt 的更多文章请点击这里。
之前我写了一篇强化学习框架 rlpyt 的简介。通常,刚接触一个框架,在安装好它之后,一般都是要先把它的一个最简单的demo跑起来看看会不会有什么问题。所以在本文中继续讲一下安装以及试运行的过程。
▶ 安装
安装其实很简单,在 rlpyt 的GitHub主页上已经写得非常清楚。这里重复一遍:
✎ 拷贝代码到本地
git clone https://github.com/astooke/rlpyt.git
✎ 使用Anaconda安装 rlpyt(在这个过程中会安装其依赖的PyTorch)
cd rlpyt
conda env create -f linux_[cpu|cuda9|cuda10].yml
rlpyt 目录下有4个配置文件:linux_cpu.yml,linux_cuda10.yml,linux_cuda9.yml,macos_cpu.yml,取决于你要安装 rlpyt 的目标OS是什么系统,以及是否有GPU,以及CUDA的版本(使用 nvidia-smi 可以查看 CUDA Version),从而选择对应的配置文件。
另外:
✔ .yml 文件里的 Python版本定义的是 3.7,如果习惯用 3.6,改成3.6也可以。
✔ macos_cpu.yml 里的PyTorch没有定义版本,可以指定成 1.2。
✔ 如果执行 conda env create xxx 命令的时候提示“Segmentation fault”错误,可以先用 conda clean -a 命令清理,再重新执行一次应该就OK了。
文章来源:https://www.codelast.com/
▶ 试跑
✎ 切换到刚安装的Anaconda环境
source activate rlpyt
✎ 设置 PYTHONPATH 环境变量
export PYTHONPATH=path_to_rlpyt:$PYTHONPATH
其中,path_to_rlpyt 是git clone到本地的 rlpyt 的根目录路径。
文章来源:https://www.codelast.com/
✎ 选择一个最简单的例子来跑
examples/ 目录下有很多例子,它们是按复杂性来排序的,example_1.py 最简单,因此可以选择跑这个例子。注意 atari_dqn_async_*.py 这几个例子是要有GPU才能跑的,因为async模式只在有GPU的时候才有意义),所以如果你是在没有GPU的个人PC上跑的话,不要跑这几个async example。
cd examples/
python example_1.py
虽然 example_1 是最简单的例子,但偏偏跑它是最有可能失败的,有可能会遇到以下几个问题:
✔ glibc版本问题
ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/codelast/.anaconda/envs/rlpyt/lib/python3.6/site-packages/torch/lib/libshm.so)
补充一句,查看glibc的版本,可以用命令:ldd --version
文章来源:https://www.codelast.com/
✔ 内存不足问题
如果抛出以下错误:
Traceback (most recent call last):File "/home/codelast/rlpyt/examples/example_1.py", line 63, in <module>cuda_idx=args.cuda_idx,File "/home/codelast/rlpyt/examples/example_1.py", line 50, in build_and_trainrunner.train()File "/home/codelast/rlpyt/rlpyt/runners/minibatch_rl.py", line 229, in trainn_itr = self.startup()File "/home/codelast/rlpyt/rlpyt/runners/minibatch_rl.py", line 75, in startuprank=rank,File "/home/codelast/rlpyt/rlpyt/algos/dqn/dqn.py", line 81, in initializeself.initialize_replay_buffer(examples, batch_spec)File "/home/codelast/rlpyt/rlpyt/algos/dqn/dqn.py", line 134, in initialize_replay_bufferself.replay_buffer = ReplayCls(**replay_kwargs)File "/home/codelast/rlpyt/rlpyt/replays/frame.py", line 38, in __init__share_memory=self.async_) # [T+n_frames-1,B,H,W]File "/home/codelast/rlpyt/rlpyt/utils/buffer.py", line 17, in buffer_from_examplereturn build_array(example, leading_dims, share_memory)File "/home/codelast/rlpyt/rlpyt/utils/buffer.py", line 29, in build_arrayreturn constructor(shape=leading_dims + a.shape, dtype=a.dtype)MemoryError: Unable to allocate array with shape (1000003, 1, 104, 80) and data type uint8
def build_array(example, leading_dims, share_memory=False): a = np.asarray(example) if a.dtype == "object": raise TypeError("Buffer example value cannot cast as np.dtype==object.") constructor = np_mp_array if share_memory else np.zeros if not isinstance(leading_dims, (list, tuple)): leading_dims = (leading_dims,) return constructor(shape=leading_dims + a.shape, dtype=a.dtype)
通过设置断点,会发现在发生错误的时候,constructor 为 np.zeros,而 shape 为 (1000003, 1, 104, 80),因此,程序想要创建一个 size 为 1000003 * 1 * 104 * 80 的全零矩阵,type 为 uint8,因此,其占用的内存大小为 1000003 * 1 * 104 * 80 / 1024 / 1024 / 1024 = 7.75 GB,而一般的PC上可能根本就分配不出这么大的内存,于是挂了。如果你到一台物理内存有上百GB的机器上去跑可能就会发现毫无问题。
文章来源:https://www.codelast.com/
实际上,这里想要分配的内存超过了允许值,还和Linux系统的配置有关,即所谓的 memory over-commit 配置。memory over-commit意思是操作系统承诺给进程的内存大小超过了实际可用的内存,Linux其实是允许memory over-commit的。
不出意外的话在你的OS上:
cat /proc/sys/vm/overcommit_memory
输出的应该是0,即表示禁用了这个特性。如果你想干点危险的事情,可以打开这个特性:
echo 1 > /proc/sys/vm/overcommit_memory
然后就可以分配大于实际可用的内存给一个进程了。这样做在array是sparse的场景下会有一些用,但你最正确的做法是到内存够大的机器上去跑,而不是打开 memory over-commit!
文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤
转载需注明出处:codelast.com
感谢关注我的微信公众号(微信扫一扫):