拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DeepMind Lab Python 模块:从 Bazel 构建到 pip 安装的完整实战指南

DeepMind Lab Python 模块:从 Bazel 构建到 pip 安装的完整实战指南
  • 人工智能
  • 强化学习
  • 机器学习

【免费下载链接】lab

A customisable 3D platform for agent-based AI research

项目地址:https://gitcode.com/gh_mirrors/la/lab
点击查看免费下载

导读

DeepMind Lab 是一个面向智能体(agent)研究的可定制 3D 平台,其 Python 模块(deepmind_lab)是官方推荐的、在 Bazel 项目之外使用该环境的方式。本文以 python/pip_package/README.md 为骨架,完整讲解从依赖准备、Bazel 构建、打包成 wheel 到 pip 安装与验证的整条链路,并结合仓库内的打包脚本、setup.py、模块加载源码与测试用例,帮助你理解每个环节的底层原理。读完本文,你将能够独立构建并安装 DeepMind Lab 的 Python 包,创建环境对象、驱动智能体交互,并选择使用原生 Python API 或 DeepMind 通用dm_envAPI。

DeepMind Lab Python 模块是什么

DeepMind Lab 的 Python 模块是官方推荐的、在 Bazel 项目之外使用 DeepMind Lab 的方式。安装后,你可以在任意 Python 项目中以import deepmind_lab的方式创建和运行环境,使用的 API 与在 Bazel 项目内构建时完全一致。

从仓库源码可以看到模块的实际构成:

  • python/pip_package/init.py 中,deepmind_lab包通过imp.load_dynamic加载随包分发的动态库deepmind_lab.so,并把其中的Lab类暴露为模块的顶层符号:
    _deepmind_lab = imp.load_dynamic( __name__, pkg_resources.resource_filename(__name__, 'deepmind_lab.so')) Lab = _deepmind_lab.Lab # needed from within dmenv_module

    也就是说,pip 包的本质是"原生动态库 + Python 包装层"的捆绑分发。

  • python/pip_package/BUILD 中的build_pip_package是sh_binary目标,其data包含README.md、__init__.py、setup.py以及//:deepmind_lab.so,这正是打包阶段需要收集的核心文件清单。

构建与安装的整体流程

根据官方文档,完整流程分为四步:

  1. 安装项目依赖(External dependencies);
  2. 使用 Bazel 构建项目资产与二进制(build assets and binaries);
  3. 将资产与二进制捆绑成 Python 包(bundle into a Python package);
  4. 安装该包(install the package)。

如果你已经配置好依赖,可以直接使用下面的"短版本"命令(在仓库根目录执行):

git clone https://github.com/deepmind/lab.git && cd lab bazel build -c opt --python_version=PY2 //python/pip_package:build_pip_package ./bazel-bin/python/pip_package/build_pip_package /tmp/dmlab_pkg pip install /tmp/dmlab_pkg/deepmind_lab-1.0-py2-none-any.whl --force-reinstall

其中第三条命令运行打包脚本,将产物 wheel 输出到/tmp/dmlab_pkg;第四条命令把生成的.whl安装进当前 Python 环境。--force-reinstall的作用是覆盖已安装的旧版本(下文"卸载与重装"还会详细说明)。

依赖准备

外部依赖

首先请参考仓库根目录 README.md 中"External dependencies, prerequisites and porting notes"一节,安装缺失的系统依赖。在此基础上,构建 pip 包还需要:

  • pip、wheel 与 setuptools
  • virtualenv(可选,但官方推荐)

关于虚拟环境中的 NumPy 版本匹配

如果使用 virtualenv,可能需要在该隔离环境中用 pip 重新安装 NumPy。这里有一个关键约束:虚拟环境中 NumPy 的版本必须与构建 Python 模块时使用的 NumPy 版本兼容,且不能更旧。如果两者不一致,需要在WORKSPACE与python.BUILD文件中把 NumPy 版本改为与你 pip 包中一致的版本,详见 docs/users/build.md。

该文档进一步给出了如何查找运行时 NumPy 头文件路径的方法:

import numpy as np print(np.get_include())

从仓库的 python/pip_package/setup.py 可以看到包声明的运行时依赖为numpy >= 1.13.3与six >= 1.10.0,这构成了 NumPy 版本匹配的下限依据:

install_requires=[ 'numpy >= 1.13.3', 'six >= 1.10.0', ], extras_require={ 'dmenv_module': ['dm-env'], },

Python 2 与 Python 3 的选择

模块针对哪个 Python 版本 API 构建,由 Bazel 的--python_version标志决定:

  • Python 2:bazel build -c opt --python_version=PY2 //python/pip_package:build_pip_package
  • Python 3:bazel build -c opt --python_version=PY3 //python/pip_package:build_pip_package

针对 Python 3 构建时,通常还需要:

  • 使用virtualenv --python=python3创建虚拟环境;
  • 在运行打包脚本前设置export PYTHON_BIN_PATH="/usr/bin/python3",确保打包脚本调用的是与构建时一致的解释器。

生成的.whl文件名中会包含-py2-或-py3-字样,可用于区分构建目标。另外,自 Bazel 0.27 起,默认的 Python 版本为PY3。

从 python/pip_package/build_pip_package.sh 的源码可以看到PYTHON_BIN_PATH的实际处理逻辑:如果未设置该环境变量,脚本会依次尝试which python || which python3,并在路径无效时报错退出;最终调用${PYTHON_BIN_PATH} setup.py bdist_wheel生成 wheel。

构建资产与二进制

克隆仓库后,在lab目录下执行:

cd lab bazel build -c opt //python/pip_package:build_pip_package

如果构建失败,请确认:

  1. 已拉取最新代码;
  2. 已安装全部 DeepMind Lab 依赖(对照 README.md 的依赖清单逐一核对)。

需要特别注意的是:对 DeepMind Lab 的任何改动——包括新增游戏脚本(Lua level)、模型、纹理或 C/C++ 代码——都需要重新构建打包脚本并重新执行后续安装步骤。这是因为打包脚本会把构建产物连同 runfiles 一起收集进 wheel,旧产物不会自动更新。

打包资产与二进制

运行打包脚本生成分发文件:

./bazel-bin/python/pip_package/build_pip_package /tmp/dmlab_pkg

脚本必须从 DeepMind Lab 源码根目录运行,因为它依赖当前目录下的bazel-bin目录(脚本源码中有明确的检查:找不到bazel-bin时会提示Did you run from the root of the build tree?)。

从 python/pip_package/build_pip_package.sh 可以还原打包脚本的完整工作流程:

  1. 用mktemp创建临时目录;
  2. 将 Bazel 构建产物的 runfiles 复制进临时目录:新式结构(含org_deepmind_lab前缀)复制bazel-bin/python/pip_package/build_pip_package.runfiles/org_deepmind_lab,旧式结构则复制整个runfiles目录,并统一重命名为deepmind_lab;
  3. 依次拷贝README.md、setup.py,把__init__.py复制为包内的deepmind_lab/__init__.py,把 python/dmenv_module.py 复制为deepmind_lab/dmenv_module.py;
  4. 生成MANIFEST.in,把deepmind_lab目录下的所有文件登记进包清单;
  5. 调用setup.py bdist_wheel生成 wheel,并拷贝到目标目录DEST。

从runfiles的复制行为可以看出:wheel 中不仅包含 Python 包装代码,还包含 DeepMind Lab 的全部运行时资源(地图、游戏脚本、模型等),因此安装后无需额外下载数据文件即可直接运行关卡。

使用 virtualenv 安装

官方推荐的安装方式是 Virtualenv,它能把不同项目的依赖彼此隔离。以下步骤均在虚拟环境内进行。

创建并激活虚拟环境(在项目目录下执行):

cd ~/my_agent virtualenv agentenv source agentenv/bin/activate

如果希望虚拟环境复用系统级 Python 包(例如系统已装好的 NumPy),可以改用:

virtualenv --system-site-package agentenv

这样后续就不需要再在虚拟环境中安装 NumPy。

激活后,安装剩余依赖(若未使用--system-site-package):

(agentenv)$ pip install numpy

然后安装打包阶段生成的 wheel(/tmp/dmlab_pkg下):

(agentenv)$ pip install /tmp/dmlab_pkg/deepmind_lab-1.0-py2-none-any.whl

安装成功后,DeepMind Lab 就可以作为独立模块使用了。结束工作时用deactivate退出虚拟环境:

(agentenv)$ deactivate

验证安装:跑一个最小智能体

新建agent.py,内容如下:

import deepmind_lab import numpy as np # Create a new environment object. lab = deepmind_lab.Lab("demos/extra_entities", ['RGB_INTERLEAVED'], {'fps': '30', 'width': '80', 'height': '60'}) lab.reset(seed=1) # Execute 100 walk-forward steps and sum the returned rewards from each step. print(sum( [lab.step(np.array([0,0,0,1,0,0,0], dtype=np.intc)) for i in range(0, 100)]))

运行:

(agentenv)$ python agent.py

DeepMind Lab 会在控制台输出大量调试/诊断信息,但最后会打印一个奖励数值。对于示例中的demos/extra_entities关卡,该值应为4.0,因为出生点正前方有四个苹果,向前走会依次吃到它们。

这段代码对应原生 API 的核心用法:Lab构造环境(关卡名、观测列表、配置字典),reset(seed=1)固定随机种子以复现实验,step()接收一个np.intc类型的 7 维动作数组并返回单步奖励。你可以参考仓库中的 python/random_agent_simple.py(随机动作采样智能体)与 python/random_agent.py 了解更完整的 agent 循环写法。

卸载与重装

如果修改了被打包进 wheel 的文件,需要让新版本生效,有两种方式:

  1. 先卸载旧版本,再安装新版本;
  2. 安装时直接加--force-reinstall标志(即短版本命令中的做法)。

彻底卸载:

pip uninstall deepmind_lab

如果同时安装到了虚拟环境和系统级包,需要对两个环境各执行一次。

DeepMind Lab Python API 速览

独立安装的 Python 模块与 Bazel 项目内构建使用完全相同的 API,完整参考见 docs/users/python_api.md。这里摘录几个核心要点。

环境构造:deepmind_lab.Lab

import deepmind_lab observations = ['RGBD'] env = deepmind_lab.Lab('lt_chasm', observations, config={'width': '640', # screen size, in pixels 'height': '480', # screen size, in pixels 'botCount': '2'}, # lt_chasm option. renderer='hardware') # select renderer. env.reset()

构造函数的完整签名为Lab(level, observations, config={}, renderer='software', level_cache=None)。其中config字典以字符串键值对的形式提供额外设置,已识别的选项如下:

选项说明默认值
width观测帧的水平分辨率'320'
height观测帧的垂直分辨率'240'
fps每秒帧数'60'
levelDirectory关卡目录的可选路径(相对路径相对于game_scripts/levels)''
appendCommand注入内部 Quake 控制台的命令''
mixerSeed与喂给环境的每个 seed 组合,用于划分互不重叠的种子子集'0'

未被识别的选项会被透传给关卡的 init 函数(在 Lua 中对应api:init的kwargs.opts)。config的键值必须是字符串——python/tests/dmlab_module_test.py 中的testInitArgs用例验证了传 list 或非字符串值会分别抛出TypeError,传未知观测名会抛出ValueError。

渲染器与图形后端

renderer参数的可选值与构建时使用的--define graphics=<option>相关:

  • --define graphics=osmesa_or_egl(默认):renderer='software'使用 OSMesa 软件渲染;renderer='hardware'使用 EGL 渲染。
  • --define graphics=osmesa_or_glx:renderer='software'使用 OSMesa;renderer='hardware'使用 GLX。
  • --define graphics=sdl:渲染到原生窗口,此时observations中必须包含以'RGB'开头的观测才能正确渲染。

机器学习智能体通常使用无头渲染(EGL/GLX 或 OSMesa),不需要显示窗口。

环境对象的核心方法

  • reset(episode=-1, seed=None):重置环境以开始新回合;seed省略或为None时使用随机种子,mixerSeed会与每次传入的 seed 组合。
  • num_steps():返回距上次reset()以来的帧数。
  • is_running():环境是否仍在运行。
  • step(action, num_steps=1):执行动作推进若干帧。action必须是np.intc类型的 NumPy 数组,并遵循action_spec()的约定。
  • observation_spec():返回支持的所有观测的名称、dtype 与 shape 列表;若某维度在运行时才确定,该维度记为 0。
  • action_spec():返回动作数组各维度的 min/max 范围。以空房间测试关卡为例,包含LOOK_LEFT_RIGHT_PIXELS_PER_FRAME(-512~512)、LOOK_DOWN_UP_PIXELS_PER_FRAME(-512~512)、STRAFE_LEFT_RIGHT(-1~1)、MOVE_BACK_FORWARD(-1~1)、FIRE(0~1)、JUMP(0~1)、CROUCH(0~1)共 7 个维度。
  • observations():返回初始化时指定的观测,值为 NumPy 数组。
  • events():返回自上次reset()/step()以来发生的事件列表,每个事件是(名称,观测列表)元组。
  • close():关闭环境并释放底层 Quake III Arena 实例;关闭后仅允许调用is_running()。

以上方法均有对应的测试覆盖:例如 python/tests/dmlab_module_test.py 的testSpecs校验了观测/动作 spec 的名称集合,testVeloctyObservations验证了VEL.TRANS/VEL.ROT速度观测在前进、后退与侧视动作下的数值行为,testEvents验证了事件语义与回合终止逻辑,可作为你编写 agent 时对 API 行为预期的权威参考。

绑定 DeepMind 通用 dm_env API

除了原生 API,仓库还提供了一个适配器模块 python/dmenv_module.py,把 DeepMind Lab 暴露为 DeepMind 通用强化学习 APIdm_env下的dm_env.Environment。该适配器同样被打包进上述 pip 包,安装后可用如下方式导入:

from deepmind_lab import dmenv_module as dm_env_lab lab = dm_env_lab.Lab(level='lt_chasm', observation_names=['RGB'], config={})

dm_env 绑定所需的额外依赖通过 pip extra 安装:

pip install /tmp/dmlab_pkg/deepmind_lab-1.0-py2-none-any.whl[dmenv_module]

该 extra 在 setup.py 中声明为'dmenv_module': ['dm-env']。从 python/dmenv_module.py 的实现看,适配器做了如下映射:

  • 把 DeepMind Lab 原生action_spec()的每个动作维度转换为dm_env.specs.BoundedArray(int32、标量 shape),并用名字建立动作索引映射;
  • step()时按名字把dm_env的字典动作填充进原生动作数组,再转发给deepmind_lab.Lab.step();
  • 根据is_running()的结果返回dm_env.transition(...)或dm_env.termination(...),回合结束后下一次step()会自动触发reset()。

需要提醒的是:并非所有 DeepMind Lab 功能都能通过 dm_env API 暴露。例如,截至编写时,dm_env 的观测 spec 不允许动态 shape,而 DeepMind Lab 原生 API(见 third_party/rl_api/env_c_api.h)支持动态 shape——适配器在遇到包含 0 维(动态维度)的观测时会直接抛出NotImplementedError。因此,当你的实验依赖动态形状观测(如程序化生成的关卡)时,应优先使用原生deepmind_lab.LabAPI。

小结

至此,你已掌握 DeepMind Lab Python 模块的完整使用链路:理解 pip 包在仓库中的构成(原生.so+ 包装层 + runfiles 资源)、按官方流程从 Bazel 构建到 wheel 打包与 virtualenv 安装、用最小 agent 验证安装、掌握Lab环境的核心 API 与config配置参数,并能根据需求在原生 Python API 与dm_env适配器之间做出选择。如需更深入地定制关卡、观测与奖励,可继续阅读 docs/users/python_api.md 与 docs/developers/reference.md。

  • 人工智能
  • 强化学习
  • 机器学习

【免费下载链接】lab

A customisable 3D platform for agent-based AI research

项目地址:https://gitcode.com/gh_mirrors/la/lab
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表