0 前言
官方教程:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/03_envs/run_rl_training.html
Isaacsim+Isaaclab安装:https://blog.csdn.net/m0_47719040/article/details/146389391?spm=1001.2014.3001.5502
在前面的教程中我们已经学习了如何定义强化学习任务环境、并将其注册到gym中。以及使用智能体与环境交互。本节将在此基础上学习如何使用强化学习来训练智能体完成指定任务。
虽然envs.ManagerBasedRLEnv
是按照gymnasium.Env
的接口规范的,但并不是一个完全的gym环境。
- 数据输入/输出类型不同
- 标准gym库:使用Numpy数组(np.ndarray)
- Isaaclab:使用Pytorch张量(torch.Tensor)
- 数据维度不同
- Isaaclab:Isaaclab是向量化环境,所有数据的第一维度为并行环境数量( [ n u m _ e n v s , o b s _ d i m ] [num\_envs,obs\_dim] [num_envs,obs_dim])。
- 标准gym:仅处理单个环境( [ o b s _ d i m ] [obs\_dim] [obs_dim])
主流RL库的接口要求对比
库名称 | 期望的观测类型 | 动作输入类型 | 并行环境支持方式 | 设备要求 |
---|---|---|---|---|
Stable-Baselines3 | np.ndarray 列表 | np.ndarray 列表 | SubprocVecEnv 多进程 | CPU |
RL-Games | torch.Tensor | torch.Tensor | 原生批量处理 | GPU |
RSL-RL | torch.Tensor | torch.Tensor | 完全GPU流水线 | GPU |
SKRL | torch.Tensor | torch.Tensor | 原生支持 | GPU/CPU |
由于每个库都各不相同,所以Isaaclab给出了一种接口适配解决方案。即Isaaclab中的isaaclab_rl库,该库给出了对应不同主流RL库的包装器(RL-Games Wrapper、RSL-RL Wrapper、SKRL Wrapper、Stable-Baselines3 Wrapper)。官方文档:https://isaac-sim.github.io/IsaacLab/main/source/api/lab_rl/isaaclab_rl.html,设计目标:
- 数据转换:在PyTorch张量和NumPy数组之间自动转换
- 设备管理:确保数据在CPU和GPU之间正确传输
- 接口兼容:将向量化环境转换为各库所需的格式(如SB3的VecEnv)
教程对应的脚本为train.py
在scripts/reinforcement_learning/sb3
目录下。
运行该程序:
- 进入安装 isaac lab 时创建的conda虚拟环境
- 在该环境下进入 isaac sim文件夹中运行
source setup_conda_env.sh
- 终端中输入
./isaaclab.sh -p scripts/reinforcement_learning/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 32
运行你的代码,会基于工作流RL环境进行训练。
2 包装流程
本教程的重点是创建环境并使用Stable-Baselines3 Wrapper进行包装。代码中包装器的应用顺序直接影响数据流处理方式,典型层次结构如下:
graph LRA[原始Isaac环境] --> B[gymnasium.wrappers.RecordVideo]B --> C[wrappers.sb3.Sb3VecEnvWrapper]C --> D[stable_baselines3.common.vec_env.VecNormalize]
1、RecordVideo 包装器
- 核心功能:
- 视频录制:定期截取环境状态生成训练过程视频
- 触发机制:基于步数间隔或自定义条件启动录制
- 关键参数配置
env = gym.wrappers.RecordVideo(env,video_folder="logs/videos",step_trigger=lambda step: step % 5000 == 0, # 每5000步录制一次video_length=300, # 每次录制300帧disable_logger=True # 禁用默认日志避免冲突
)
- 性能影响
- 显存占用:开启渲染时增加约10%显存使用
- 计算开销:帧捕获引入约5%的步进时间延迟
2、Sb3VecEnvWrapper 包装器
- 接口适配需求
- 数据类型转换:torch.Tensor ↔ np.ndarray
- 设备管理:GPU张量 → CPU内存的异步传输
- 批量处理:将向量化环境拆分为VecEnv期望的列表格式
- 关键代码实现
class Sb3VecEnvWrapper(VecEnvWrapper):def __init__(self, env):super().__init__(env)# 设备自动检测self.device = env.unwrapped.device# 创建 pinned memory 缓冲区加速传输self._obs_buffer = torch.empty((env.num_envs,) + env.obs_space.shape, dtype=torch.float32, pin_memory=True)def reset(self):obs = self.env.reset()self._obs_buffer.copy_(obs, non_blocking=True)return self._obs_buffer.cpu().numpy()def step_async(self, actions):# 转换NumPy数组为Tensor并发送到设备self.actions = torch.as_tensor(actions, device=self.device)def step_wait(self):obs, rewards, dones, infos = self.env.step(self.actions)self._obs_buffer.copy_(obs, non_blocking=True)return (self._obs_buffer.cpu().numpy(),rewards.cpu().numpy(),dones.cpu().numpy(),self._process_infos(infos))
3、VecNormalize 包装器
-
数据标准化
- 观测归一化:将不同量纲的观测特征缩放到[-1,1]范围
- 奖励缩放:防止梯度爆炸,提升训练稳定性
-
关键参数配置
env = VecNormalize(env,norm_obs=True, # 启用观测标准化norm_reward=True, # 启用奖励标准化clip_obs=10.0, # 观测裁剪范围[-10,10]clip_reward=10.0, # 奖励裁剪范围gamma=0.99 # 用于奖励标准化的折扣因子
)
3 代码执行
scripts/reinforcement_learning/sb3/train.py
从 Stable-Baselines3 训练一个 PPO 网络来解决车杆平衡问题。
非可视化环境下训练
./isaaclab.sh -p scripts/reinforcement_learning/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64 --headless
可视化训练
./isaaclab.sh -p scripts/reinforcement_learning/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64
记录训练期间的视频并做可视化训练
./isaaclab.sh -p scripts/reinforcement_learning/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64 --video
在新窗口中输入下述代码可以查看日志
./isaaclab.sh -p -m tensorboard.main --logdir logs/sb3/Isaac-Cartpole-v0
可以查看训练后的结果
# execute from the root directory of the repository
./isaaclab.sh -p scripts/reinforcement_learning/sb3/play.py --task Isaac-Cartpole-v0 --num_envs 32 --use_last_checkpoint
后续将会对train.py
代码做更详细的解释