ML-Agents 在 Windows/Mac 上使用 Docker 进行训练与推理的完整指南
【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址: https://gitcode.com/gh_mirrors/ml/ml-agents
本篇技术指南面向希望在 Windows 与 macOS 上使用 Docker 运行 Unity ML-Agents 训练与推理的用户。通过容器化方案,你可以完全跳过在本机手动安装 Python 与 TensorFlow 的环节,同时利用Xvfb实现无显示器、无 GPU 的虚拟渲染,让训练环境与宿主系统彻底隔离。读完本文,你将掌握"以特定标志构建 Linux 版 Unity 环境 → 构建 Docker 镜像 → 挂载数据卷并运行训练容器 → 优雅停止并保存训练状态"的完整实战流程。
为什么用 Docker 运行 ML-Agents
对于 Windows 和 Mac 用户来说,本地搭建 ML-Agents 训练环境通常需要手动安装 Python、依赖库与 TensorFlow,版本冲突与路径配置问题层出不穷。仓库 本地化文档 与 英文原版文档 提供了基于 Docker 的替代方案:
- 宿主零安装:Python 与 TensorFlow 全部封装在容器镜像内,主机无需安装任何 ML-Agents 依赖;
- 环境隔离:Docker 容器运行在与宿主机隔离的环境中,通过**挂载目录(bind mount)**共享训练配置、Unity 可执行文件与训练产出的模型图(graph)等数据;
- 纯 CPU 计算:当前方案强制 TensorFlow 与 Unity 只使用 CPU 计算,不依赖 GPU;
- 虚拟渲染:使用
Xvfb进行虚拟渲染。Xvfb允许ML-Agents(或其他应用)在没有任何显示器甚至没有 GPU 的机器上进行离屏渲染——这意味着运行 ML-Agents 的机器不要求配备 GPU 或物理显示器,但也意味着包含相机视觉观测(camera-based visual observations)的复杂环境可能会更慢。
注意:英文原版文档已标注Deprecated(已弃用),官方团队不再使用该指南,但保留它供参考。因此本文内容属于"可用但非官方主力路径"的社区/历史方案,请结合你的 Unity 与 ML-Agents 版本酌情使用。
需求与环境准备
必备组件
| 组件 | 说明 |
|---|---|
| Docker | 从 Docker 官网 下载安装,确保 Docker 引擎(daemon)正常运行 |
| Unity Linux Build Support 组件 | 使用 Unity Installer 安装 Unity 时必须勾选Linux Build Support组件 |
安装 Unity 时选中Linux Build Support组件是后续构建 Linux 版环境可执行文件的前提;Docker 引擎则负责后续镜像构建与容器运行。
共享目录:unity-volume
由于 Docker 容器运行在独立环境中,宿主机需要提供一个挂载目录用于共享以下数据:
- 训练器配置文件(trainer config file)
- Unity 可执行文件
- 课程学习文件(curriculum files,如使用 curriculum 训练)
- TensorFlow 训练产出的 graph 与模型
为方便使用,仓库根目录已预置一个空的 unity-volume 目录(当前仓库中该目录保持为空,等待放入你的构建产物),你也可以自由改用其他任何目录。本指南后续命令均假设使用unity-volume目录。
使用 Docker 的三大步骤总览
- 构建 Unity 环境:使用特定标志把 Unity 环境构建为 Linux 平台可执行文件;
- 构建 Docker 容器:在仓库根目录执行
docker build; - 运行容器:挂载
unity-volume并传入 ML-Agents 训练参数。
如果你还不熟悉如何为 ML-Agents 构建 Unity 环境,建议先阅读 Sample.md(3D Balance Ball 示例入门)。
第一步:构建 Linux 版 Unity 环境(可选)
如果你打算直接在 Unity编辑器中执行训练,可以跳过此步。
因为 Docker 容器通常与宿主机共享(Linux)内核,所以 Unity 环境必须构建为 Linux 平台。在 Unity 的 Build Settings 窗口中请选择:
- Target Platform设为
Linux - Architecture设为
x86_64
点击Build后,为环境命名(例如3DBall),并将输出目录设置为unity-volume。构建完成后,确认unity-volume下生成了:
- 可执行文件
<environment-name>.x86_64 - 数据目录
<environment-name>_Data/
第二步:构建 Docker 容器
先确认 Docker 引擎已在你的系统上运行,然后在仓库根目录执行:
docker build -t <image-name> .将<image-name>替换为你的镜像名称,例如balance.ball.v0.1。
仓库根目录下的 Dockerfile 揭示了该镜像的底层构成:
- 基础镜像为
nvidia/cuda:10.2-cudnn7-devel-ubuntu18.04(尽管运行阶段强制 CPU 计算,镜像基底仍源自 CUDA 镜像); - 安装了大量系统依赖,包括
xvfb、xorg、mesa-utils、libgl1-mesa-dev等图形/渲染相关库,这正是Xvfb虚拟渲染能力的来源; - 通过
git fetch拉取指定 SHA 的 ml-agents 源码后,执行pip install -e /ml-agents/ml-agents-envs与pip install -e /ml-agents/ml-agents以可编辑模式安装ml-agents-envs与ml-agents两个 Python 包。
第三步:运行 Docker 容器进行训练
在仓库根目录执行以下命令启动训练容器:
docker run --name <container-name> \ --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \ -p 5005:5005 \ <image-name>:latest \ --docker-target-name=unity-volume \ <trainer-config-file> \ --env=<environment-name> \ --train \ --run-id=<run-id>参数逐项说明
| 参数 | 含义与注意事项 |
|---|---|
<container-name> | 用于标识容器(便于中断或终止它)。可选;不设置时 Docker 会生成随机名。注意:每次运行镜像时容器名必须唯一 |
<image-name> | 构建容器时使用的镜像名,对应上一步docker build -t指定的名称 |
--mount type=bind,source=...,target=... | source指向宿主机存放 Unity 可执行文件的路径;target告诉 Docker 把该路径挂载为容器内名为该值的磁盘(目录) |
-p 5005:5005 | 将容器内 5005 端口映射到宿主机,供 Python 与 Unity 之间通过 gRPC 通信(ML-Agents 默认通信端口) |
--docker-target-name=unity-volume | 告诉 ML-Agents Python 包去哪个挂载盘读取 Unity 可执行文件并保存模型图。因此它的值必须与--mount的target一致。该参数属于旧版 ML-Agents 的参数形式,在新版本中已不再需要,改为在--env中直接指定容器内可执行文件路径(见下文"新版本写法") |
<trainer-config-file> | 训练器配置文件名,会被透传给mlagents-learn。建议把配置文件放入unity-volume,这样容器才能访问到该文件 |
--env=<environment-name> | (可选)若用 Linux 可执行文件训练,此值为可执行文件名;若在 Unity 编辑器中训练,则不要传该参数,当屏幕显示"Start training by pressing the Play button in the Unity Editor"时点击 |
--train | 表示执行训练(而非仅推理) |
--run-id=<run-id> | 为每次实验打上唯一标识,用于区分实验结果与产出目录 |
其中trainer-config-file、train、run-id都是透传给mlagents-learn的 ML-Agents 参数,与直接在本机执行mlagents-learn的用法一致(可参考 Learning-Environment-Executable.md 中的mlagents-learn <trainer-config-file> --env=<env_name> --run-id=<run-identifier>调用方式)。
实战示例:训练 3DBall
以下命令使用名为3DBall的环境可执行文件进行训练:
docker run --name 3DBallContainer.first.trial \ --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \ -p 5005:5005 \ balance.ball.v0.1:latest 3DBall \ --docker-target-name=unity-volume \ trainer_config.yaml \ --env=3DBall \ --train \ --run-id=3dball_first_trial与之配套的 3DBall 训练器配置文件可以直接参考仓库中的 config/ppo/3DBall.yaml,其核心配置如下(放入unity-volume后即可被容器读取):
behaviors: 3DBall: trainer_type: ppo hyperparameters: batch_size: 64 buffer_size: 12000 learning_rate: 0.0003 beta: 0.001 epsilon: 0.2 lambd: 0.99 num_epoch: 3 learning_rate_schedule: linear network_settings: normalize: true hidden_units: 128 num_layers: 2 vis_encode_type: simple reward_signals: extrinsic: gamma: 0.99 strength: 1.0 keep_checkpoints: 5 max_steps: 500000 time_horizon: 1000 summary_freq: 12000新版本写法说明
英文原版文档(Using-Docker.md)展示了更新版本的命令形态,二者差异主要在路径表达上:
docker run -it --name <container-name> \ --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \ -p 5005:5005 \ -p 6006:6006 \ <image-name>:latest \ <trainer-config-file> \ --env=<environment-name> \ --train \ --run-id=<run-id>其对应的 3DBall 示例为:
docker run -it --name 3DBallContainer.first.trial \ --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \ -p 5005:5005 \ -p 6006:6006 \ balance.ball.v0.1:latest 3DBall \ /unity-volume/trainer_config.yaml \ --env=/unity-volume/3DBall \ --train \ --run-id=3dball_first_trial新旧版本的差异点:
- 新版不再有
--docker-target-name参数,而是直接在--env=/unity-volume/3DBall中给出容器内的完整可执行文件路径; - 新版增加了
-p 6006:6006端口映射,用于在宿主机浏览器访问容器内 TensorBoard; - 旧版把
3DBall放在镜像名之后作为环境名参数传入,新版则统一通过--env指定。
在容器内运行 TensorBoard 监控训练
英文原版文档提供了在容器内启动 TensorBoard 的方法,训练过程中可通过宿主机浏览器访问http://localhost:6006实时查看训练曲线(前提是运行时已映射6006端口):
docker exec -it <container-name> tensorboard --logdir /unity-volume/results --host 0.0.0.0沿用前面的 3DBall 示例:
docker exec -it 3DBallContainer.first.trial tensorboard --logdir /unity-volume/results --host 0.0.0.0TensorBoard 的详细用法可参见 Using-Tensorboard.md。
停止容器并保存训练状态
当训练进度令你满意时,可以通过以下方式停止容器并保存状态:
- 在终端中按下
Ctrl+C(Mac 使用⌘+C);或 - 执行命令:
docker kill --signal=SIGINT <container-name><container-name>是之前docker run命令中指定的容器名。如果当时未指定,Docker 会随机生成名字,可通过docker container ls查看。使用SIGINT信号而非强制SIGKILL的目的是让训练进程有机会把模型权重与检查点(checkpoint)写入挂载盘unity-volume,从而保留训练进度,便于后续--resume续训或导出推理模型。
注意事项与常见坑
- 视觉观测环境更慢:由于强制 CPU 计算且依赖
Xvfb虚拟渲染,包含相机视觉观测的"富环境"(如视觉 3DBall、FoodCollector)训练速度会明显下降,请合理规划训练步数(如max_steps)与时间; - 增加容器内存:使用 Docker 训练含视觉观测的环境时,可能需要提高 Docker 分配给容器的默认内存上限(例如 Docker for Mac 的 Advanced 设置中可以调整内存分配);
- 容器名唯一:同一镜像每次
docker run都必须使用不同的<container-name>,重复使用会报冲突,可先用docker container ls检查已有容器; - 配置文件路径:训练器配置文件必须放在挂载盘内(如
unity-volume)容器才能读取,否则会出现文件找不到的错误; - 挂载机制细节:如需深入了解 bind mount 的挂载语义,可参考 Docker 官方文档中关于 bind mounts 的说明。
总结
通过 Docker 运行 ML-Agents,本质上是把"Unity 环境构建为 Linux 可执行文件 + 挂载共享目录 + 容器内运行 mlagents-learn"三步串联起来。仓库中的 Dockerfile 完整定义了镜像内的 CUDA 基底、Xvfb渲染依赖与 ml-agents Python 包安装流程;unity-volume 目录则充当宿主机与容器之间的数据交换枢纽;而训练参数本身(如 config/ppo/3DBall.yaml)与直接在本机运行mlagents-learn完全一致,只是文件需要放入挂载盘。掌握这一流程后,你可以在任何装有 Docker 的 Windows/Mac 机器上复现完整的 ML-Agents 训练管线。
【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址: https://gitcode.com/gh_mirrors/ml/ml-agents
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考