转载需注明出处:https://www.codelast.com/

之前我写了一篇强化学习框架 rlpyt简介。通常,刚接触一个框架,在安装好它之后,一般都是要先把它的一个最简单的demo跑起来看看会不会有什么问题。所以在本文中继续讲一下安装以及试运行的过程。

安装
安装其实很简单,在 rlpyt 的GitHub主页上已经写得非常清楚。这里重复一遍:
 拷贝代码到本地

git clone https://github.com/astooke/rlpyt.git

 使用Anaconda安装 rlpyt

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),从而选择对应的配置文件。
另外:
(1).yml 文件里的 Python版本定义的是 3.7,如果习惯用 3.6,改成3.6也可以。
(2)macos_cpu.yml 里的PyTorch没有定义版本,可以指定成 1.2。
文章来源: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)

如果你用的是CentOS 6,这个问题是因为:自0.4.1开始,PyTorch的二进制文件不再支持CentOS 6。
可以从源代码编译PyTorch:https://github.com/pytorch/pytorch#from-source,或升级到CentOS 7。
补充一句,查看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_train
    runner.train()
  File "/home/codelast/rlpyt/rlpyt/runners/minibatch_rl.py", line 229, in train
    n_itr = self.startup()
  File "/home/codelast/rlpyt/rlpyt/runners/minibatch_rl.py", line 75, in startup
    rank=rank,
  File "/home/codelast/rlpyt/rlpyt/algos/dqn/dqn.py", line 81, in initialize
    self.initialize_replay_buffer(examples, batch_spec)
  File "/home/codelast/rlpyt/rlpyt/algos/dqn/dqn.py", line 134, in initialize_replay_buffer
    self.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_example
    return build_array(example, leading_dims, share_memory)
  File "/home/codelast/rlpyt/rlpyt/utils/buffer.py", line 29, in build_array
    return constructor(shape=leading_dims + a.shape, dtype=a.dtype)
MemoryError: Unable to allocate array with shape (1000003, 1, 104, 80) and data type uint8
那么是因为你机器上的内存不足以跑这个example。根据上面打印出来的错误,找到 buffer.py 的对应 method:

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!
 

[原创] 强化学习框架 rlpyt 安装及试跑
Tagged on:         

发表评论

电子邮件地址不会被公开。 必填项已用*标注