【楠】双 RTX 5090 工作站从零部署 Isaac Sim 6.0 与 Isaac Lab 全记录(含踩坑实录)
【楠】双 RTX 5090 工作站从零部署 Isaac Sim 6.0 与 Isaac Lab 全记录(含踩坑实录)
本文记录在一台双 RTX 5090(Blackwell 架构)工作站上,从零安装 NVIDIA Isaac Sim 6.0 + Isaac Lab,直到完整跑通强化学习训练与 3D 可视化的全过程。重点不在"成功的命令",而在中间踩到的一连串坑:依赖冲突、可视化方式变更、扩展超前引用、双卡渲染崩溃等。每个问题都给出了定位思路和最终解法,适合同样在 50 系新卡上折腾 Isaac Lab 的同学参考。
前言
Isaac Lab 是 NVIDIA 基于 Isaac Sim 的机器人学习框架,做强化学习(RL)、模仿学习的机器人仿真很常用。但在 RTX 50 系(Blackwell)这种新卡 + develop 滚动分支的组合下,官方文档的"标准流程"会遇到不少没写出来的暗坑。
本文环境的特殊性在于两点:一是 Blackwell 架构对 CUDA 版本有硬要求,二是双卡 + 滚动开发分支带来了若干非典型问题。下面按时间线复盘整个过程。
一、硬件与系统环境
先确认本机配置,这是后续所有决策的基础。
| 项目 | 配置 |
|---|---|
| GPU | 2 x NVIDIA GeForce RTX 5090(各 32GB 显存) |
| CPU | AMD Ryzen Threadripper PRO 7965WX(24 核 48 线程) |
| 内存 | 62GB |
| 系统盘 | 3.6TB NVMe(可用 3.4TB) |
| 操作系统 | Ubuntu 22.04.2 LTS |
| 内核 | 5.19.0-32-generic |
| 显卡驱动 | 595.71.05(CUDA 13.2) |
| Python | Anaconda(base 为 3.13) |
用 nvidia-smi 确认双卡与驱动:
nvidia-smi
关键信息:驱动 595.71.05、CUDA 13.2、两张 RTX 5090 各 32GB。这套配置远超 Isaac Sim 的推荐要求,是非常理想的训练平台。
二、官方要求与版本对应关系
查阅 Isaac Lab develop 文档和 Isaac Sim 系统要求后,整理出几个对本机的关键约束:
| 约束项 | 要求 | 本机情况 |
|---|---|---|
| Python 版本 | Isaac Sim 6.X 必须 3.12 | base 是 3.13,需新建环境 |
| Blackwell + CUDA | 新架构要求 CUDA >= 13 内核 | 驱动 595 即 CUDA 13.2,满足 |
| PyTorch 构建 | x86_64 Linux 推荐 cu128 | 后续验证可用 |
| GPU 类型 | 需带 RT Core,A100/H100 不支持 | RTX 5090 满足 |
| 驱动版本 | Linux 推荐 >= 580.95.05 | 595 满足 |
| Isaac Sim 版本 | 官方已放弃 5.1.0 及以下,推荐 6.0.0 | 安装 6.0.0 |
这里有一个容易踩的点:Python 不能用 base 的 3.13。Isaac Sim 6.0 是针对 3.12 编译的,必须新建一个独立的 3.12 环境。
整体安装流程如下:
三、创建环境与安装 Isaac Sim
按照官方推荐,用 conda 建独立的 3.12 环境,避免污染 base。
# 1. 新建独立的 python 3.12 环境
conda create -n isaaclab python=3.12 -y
conda activate isaaclab
pip install --upgrade pip
环境名直接叫 isaaclab,这点有讲究:Isaac Lab 的 isaaclab.sh 脚本里有自动检测 conda 环境名的逻辑,默认假设环境名就是 isaaclab,所以这样命名能无缝对接。
接着安装 Isaac Sim 6.0:
pip install "isaacsim[all,extscache]==6.0.0" \
--extra-index-url https://pypi.nvidia.com \
--pre
坑 1:pip 不认 --prerelease 参数
官方文档给的命令带 --prerelease=allow,但那是 uv 包管理器的参数,pip 不认识,会直接报错:
no such option: --prerelease
解法:pip 的等价参数是 --pre。它的作用是允许 pip 选取预发布版本的依赖(Isaac Sim 6.0 的部分依赖带 rc/beta 标记,不加会解析失败)。
四、验证 PyTorch 与 Blackwell 兼容性
安装 Isaac Sim 时,pip 会自动把 PyTorch 三件套一起装进来。安装完成后清单里能看到:
torch-2.10.0 torchvision-0.25.0 torchaudio-2.10.0
nvidia-cuda-runtime-cu12-12.8.90 ...
也就是 torch 2.10.0 + cu128 构建。
这里要澄清一个常见误区:很多人看到 Blackwell 要 CUDA 13,就以为 PyTorch 必须装 cu130。实际上,x86_64 Linux 的官方推荐就是 cu128(cu130 主要针对 DGX Spark / aarch64 那种强制 CUDA >= 13 的场景)。关键在于 CUDA 12.8 已经包含 Blackwell 的 sm_120 内核,而 595 驱动(CUDA 13.2)向后兼容 12.8 运行时。
所以装完先别急着换 cu130,先验证当前 cu128 能不能真正在 5090 上跑。
第一步,确认设备识别:
python -c "import torch; print('torch:', torch.__version__); print('cuda available:', torch.cuda.is_available()); print('device:', torch.cuda.get_device_name(0)); print('capability:', torch.cuda.get_device_capability(0))"
输出:
torch: 2.10.0+cu128
cuda available: True
device: NVIDIA GeForce RTX 5090
capability: (12, 0)
capability (12, 0) 就是 Blackwell 的 sm_120,识别正确。
第二步是决定性的,跑一个真实的 GPU 算子,确认 sm_120 内核确实存在(光识别到设备不够,得真能执行 kernel):
python -c "import torch; x=torch.randn(4000,4000,device='cuda'); print('matmul ok:', (x@x).sum().item())"
输出:
matmul ok: 290702.4375
能打印出数值,说明 cu128 的 sm_120 内核在 5090 上正常执行,无需换 cu130。如果这一步报 no kernel image is available for execution on the device,才需要覆盖成 cu130。
五、安装 Isaac Lab
torch 验证通过后,克隆 develop 分支并安装:
cd ~
git clone https://github.com/isaac-sim/IsaacLab.git --branch develop
cd IsaacLab
./isaaclab.sh --install
--install 会自动检测已激活的 conda 环境,把 Isaac Lab 各子包(isaaclab、isaaclab_rl、isaaclab_tasks 等)以可编辑模式装进当前环境,并编译扩展、安装一堆 RL 库(rsl_rl、rl_games、skrl 等),耗时几分钟。
坑 2:大量依赖冲突警告
安装过程中会刷出一大片版本冲突警告,例如:
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed.
isaacsim-core 6.0.0.0 requires torchaudio==2.10.0, which is not installed.
isaacsim-kernel 6.0.0.0 requires Pillow==12.1.1, but you have pillow 11.3.0 which is incompatible.
isaacsim-core 6.0.0.0 requires mujoco==3.5.0, but you have mujoco 3.8.1 which is incompatible.
rl-games 1.6.1 requires psutil<6.0.0,>=5.9.0, but you have psutil 7.2.2 which is incompatible.
...
这是 pip 安装 Isaac Lab develop 的典型现象:RL 生态的库(viser、rerun-sdk、rl_games、moviepy)和 NVIDIA 用 == 钉死的版本互相打架。pip 的解析器是"尽力而为",装后一个包时不会回头校验前面的约束。
关键经验:不要盲目把这十几个包逐一钉回去。 因为有些约束本身互相矛盾,例如 psutil 这一项,rl-games 要 <6.0.0、isaacsim 要 ==5.9.8,根本不可能同时满足。硬钉会引发新一轮反复横跳。正确做法是先看哪些冲突真的影响运行,大部分 == 警告实际能跑。
唯一确定必须补的是 torchaudio 缺失(isaacsim-core 硬依赖):
pip install torchaudio==2.10.0 --index-url https://download.pytorch.org/whl/cu128
补完后,用最直接的方式验证核心链路是否打通:
python -c "import isaacsim; print('isaacsim import ok')"
首次运行会弹出 NVIDIA Omniverse 许可协议(EULA),输入 yes 接受。看到:
isaacsim import ok
就说明核心链路完全打通了。剩下那些 == 版本警告没有阻断导入,先放着,等真在某功能上报错了再定点处理。
另外 --install 结尾那条警告也是正常的,无需理会:
[WARN] Could not find the isaac-sim directory: /home/aa/IsaacLab/_isaac_sim.
pip 安装方式下没有 _isaac_sim 软链目录(那是二进制安装才有的),Isaac Lab 通过 Python 包直接找 isaacsim,不影响运行。
六、headless 训练验证
环境装好后,先用最能代表实际用途的方式验证:无头(headless)强化学习训练。这种方式不开窗口、纯 GPU 跑,最不容易出显示相关的幺蛾子。
./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py \
--task=Isaac-Ant-v0 --headless
它会创建 4096 个并行环境训练一只四足 Ant 机器人学走路,日志逐轮滚动:
################################################################################
Learning iteration 50/1000
Total steps: 6684672
Steps per second: 307704
Mean reward: 42.68
Metrics/success_rate: 0.9078
Iteration time: 0.43s
关键指标:
- Steps per second: 307704 每秒 30 万步,这是 5090 的实力
- Mean reward: 42.68 从负数涨上来,RL 在正常学习
- success_rate: 0.9078 50 轮就 90% 成功率,收敛又快又好
看到 reward 逐轮上升,说明仿真 + GPU 并行 + RL 训练整条链路完全可用。
七、可视化的坑:从看不到窗口到跑通 GUI
headless 跑通后,自然想看 3D 画面。但接下来连踩三个坑,这部分是本文重点。
坑 3:develop 默认不开窗口,–headless 已废弃
最初一直看不到窗口。排查发现,Kit 日志里写着:
"experienceName":"isaaclab.python.headless"
也就是程序加载的是 headless 体验配置,根本不创建窗口。
查 app_launcher.py 源码后真相大白:develop 分支改了可视化的控制方式。
- 旧版:默认开窗口,加
--headless关窗口 - develop 新版:默认就是 headless(不开窗口),要看 GUI 必须显式加
--viz
--viz 的可选值有五个:kit、newton、rerun、viser、none。其中 kit 就是完整的 Isaac Sim 3D 窗口。
正确命令(注意结尾的 --viz kit):
./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py \
--task=Isaac-Ant-v0 --num_envs 64 --viz kit
这里顺带提醒一个低级但常见的错误:CLI 参数都是双横杠(--task 不是 -task),且别用反斜杠折行粘贴,否则换行符会被带进命令导致解析报错。
坑 4:GUI 启动报扩展依赖解析失败
加了 --viz kit 后,启动直接崩溃:
[Error] [omni.ext.plugin] Failed to resolve extension dependencies. Failure hints:
* No versions of isaacsim.core.experimental.primdata that satisfies:
isaaclab.python-3.0.0 depends on isaacsim.core.experimental.primdata version *
- Available packages ... (none found)
Synced registries:
- kit/default : found 0 packages (couldn't connect or empty)
报错里有"连不上仓库",很容易误以为是网络问题。但深入排查后发现根因完全不同。
排查过程:
# 检查本地有哪些 core.experimental 扩展
find .../isaacsim/exts -maxdepth 1 -type d -iname "isaacsim.core.experimental*"
结果本地只有 objects / prims / materials / utils 四个,唯独没有 primdata。再查 isaacsim-core 6.0.0 这个 pip 包的文件清单,确认 primdata 扩展本体根本没被打包。
真正的根因:这是 Isaac Lab develop 分支的超前引用。 develop(滚动更新)的 GUI 配置文件引用了 isaacsim.core.experimental.primdata 这个扩展,但它在已发布的 Isaac Sim 6.0.0 里还不存在(应该是 NVIDIA 内部把 prims 拆分出 primdata 的改动,已进 IsaacLab develop,但还没进 isaacsim 的发布包)。
所以这不是网络问题,翻墙重装也下不到一个上游根本没发布的扩展;也不是版本错配,因为对应的稳定 release 分支(release/3.0.0-beta2)的 kit 文件同样引用 primdata。
解法是用差集法一次性找出所有"被引用但本地不存在"的扩展。思路:列出 GUI kit 文件引用的全部扩展,与本地已安装扩展目录做差集。
SP=.../site-packages/isaacsim
KIT=~/IsaacLab/apps/isaaclab.python.kit
# 本地已安装扩展
{ ls -1 $SP/exts/; ls -1 $SP/extscache/ | sed -E 's/-[0-9].*$//'; } | sort -u > /tmp/installed.txt
# kit 文件引用的扩展
grep -oE '^\s*"[a-zA-Z0-9._]+"\s*=' "$KIT" | grep -oE '"[a-zA-Z0-9._]+"' | tr -d '"' | sort -u > /tmp/deps.txt
# 差集:引用了但本地没有的
comm -23 /tmp/deps.txt /tmp/installed.txt
差集结果里,isaaclab* 开头的是误报(它们装在 ~/IsaacLab/source/ 下,不在扫描目录),真正缺失的是三个 isaacsim 扩展:
isaacsim.core.experimental.primdataisaacsim.robot.wheeled_robots.nodesisaacsim.sensors.experimental.rtx
在 ~/IsaacLab/apps/isaaclab.python.kit 中把这三行注释掉(改前先备份):
"isaacsim.core.experimental.objects" = {}
# "isaacsim.core.experimental.primdata" = {} # 6.0.0 发布包中不存在,注释以修复 --viz kit
"isaacsim.core.experimental.prims" = {}
...
# "isaacsim.robot.wheeled_robots.nodes" = {} # 同上
...
# "isaacsim.sensors.experimental.rtx" = {} # 同上
primdata 是从 prims 拆出来的,而 prims 本地有,所以去掉 primdata 这行后 GUI 会回退用 prims,完全能跑。
注意:更新 develop 后这个文件可能被覆盖,需要重做这步。建议把这几行注释固化成脚本,每次 git pull 后跑一遍。
坑 5:双卡 RTX 渲染导致窗口黑屏退出
解决扩展问题后,GUI 窗口终于弹出来了,但是一片黑,而且很快进程就退出了。
排查发现进程已经结束(GPU 占用回落、训练进程消失)。查看带时间戳的 Kit 详细日志,发现它停在 RTX 渲染管线初始化的最后一步:
[rtx.scenedb] [MBVH]: Creating scene acceleration structures for context 0, device mask: 0x3
device mask: 0x3 是二进制 11,意味着 RTX 渲染器同时往两张 GPU 上初始化加速结构,然后就崩溃退出。
这与本机的一个硬件问题直接相关(详见下一节):第二张卡 GPU1 的 PCIe 链路只协商到 x4,且 IOMMU 开启导致 P2P 带宽异常。RTX 渲染器尝试用双卡(deviceMask 0x3)建场景加速结构时,因为那块跛脚的 GPU1 而崩溃。headless 训练不走 RTX 渲染,所以一直没事;GUI 一开 RTX 就踩到这个坑。
解法:强制只用满血的 GPU0 渲染。
CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py \
--task=Isaac-Ant-v0 --num_envs 64 --viz kit
CUDA_VISIBLE_DEVICES=0 让进程只看得到 GPU0,RTX 的 device mask 就变成 0x1(单卡),绕开 GPU1。这次窗口正常出画面,Ant 在 3D 场景里训练。
首次 GUI 启动的设置弹窗怎么选
首次启动 Kit 会弹几个设置对话框,推荐选法:
| 弹窗 | 选项 | 推荐 | 理由 |
|---|---|---|---|
| USD/Fabric 后端 | USD / Fabric CPU / Fabric GPU | Fabric GPU | 数据全程留在 GPU,匹配 GPU 并行仿真,最快 |
| reset simulation on stop | enable / disable | enable(默认) | 不影响脚本训练,只在手动点 Stop 时触发 |
| 渲染质量 | 各档位 | 任意高档 | 5090 渲染 64 个 Ant 毫无压力 |
关于那片 PhysX 红色报错
GUI 模式下会刷出大量这样的红色报错:
PhysX error: PxArticulationReducedCoordinate::setRootLinearVelocity():
it is illegal to call this method if PxSceneFlag::eENABLE_DIRECT_GPU_API is enabled!
这不是致命错误,可以无视。 证据是它报完这些之后照样打印 Completed setting up the environment 并正常开始训练。原因是 Isaac Lab 在 reset 机器人时调用了 CPU 端的 setRootLinearVelocity 接口,而 GPU 直接管线(eENABLE_DIRECT_GPU_API,大规模并行训练的关键)下 PhysX 会拒绝这个 CPU 写入并刷屏报错,但训练数据流走的是 GPU 路径,所以能继续。这是 develop 分支 GUI 模式的已知瑕疵。
八、附带发现:双卡 PCIe 带宽不对等
在排查过程中,Isaac Sim 启动日志里出现了一条值得深究的警告:
Device 0 PCIe link current width 16 and device 1 PCIe link current width 4 don't match.
CUDA peer-to-peer observed bandwidth: 14.0 GB/s.
GPU1 跑在 x4 而不是 x16,P2P 带宽只有 14 GB/s(正常 x16 应上百)。这个问题虽然不影响单卡使用,但会拖累双卡分布式训练,顺手排查了根因。
用 nvidia-smi 确认链路状态:
nvidia-smi --query-gpu=index,name,pci.bus_id,pcie.link.gen.current,pcie.link.gen.max,pcie.link.width.current,pcie.link.width.max --format=csv
输出:
0, RTX 5090, 0000:41:00.0, 5, 5, 16, 16 (满血 Gen5 x16)
1, RTX 5090, 0000:42:00.0, 1, 5, 4, 16 (降到 Gen1 x4)
再用 lspci 查链路能力(需 root),对比两卡的上游 CPU 根端口:
sudo lspci -vv -s 42:00.0 | grep -iE "LnkCap:|LnkSta:"
关键在于看 LnkCap(硬件能力)而非 LnkSta(当前状态)。逐级排查后发现:
GPU1 上游根端口 40:03.1 的 LnkCap: Width x4 (这个端口硬件上限就是 x4)
同组其它端口 40:03.x 的 LnkCap: x4 / x2 / x1 / x1 / x4 / x4
对比 GPU0 上游根端口 40:01.1 的 LnkCap: Width x16 (满血)
40:03.x 这组根端口被拆成了 x4 + x2 + x1 + x1 + x4 + x4 这样的碎片,这是典型的 PCIe bifurcation(通道拆分) 特征:一条 CPU 的 x16 物理链路在 BIOS 里被拆分了,GPU1 插的那条槽只分到一个 x4 段。
结论与修复方向:
- 这是 BIOS lane 拆分或主板插槽布局问题,不是显卡损坏(GPU1 自身 LnkCap 是 x16)
- 软件层面无法修复,PCIe lane 分配在开机时就由固件协商死了
- 修法:进 BIOS 把该槽的 lane 从拆分模式改为 x16/Auto,或把 GPU1 换到 CPU 直连的 x16 物理槽,并考虑在 BIOS 关闭 IOMMU 以改善 P2P
- Threadripper PRO 7965WX 有 128 条 PCIe 5.0 lane,带宽绝对够,纯粹是分配配置问题
在修好之前,单卡训练(默认 GPU0)与单卡 GUI 渲染完全不受影响。
九、完整训练与回放
最后跑一次完整训练(1000 轮)确认全程稳定:
Learning iteration 999/1000
Total steps: 2048000
Mean reward: 50.66
Metrics/success_rate: 1.0000
Training time: 707.22 seconds
[INFO]: SimulationContext cleared
[780.472s] Simulation App Shutting Down
结果:success_rate 1.0000,Ant 完全学会走路,1000 轮约 12 分钟(带 GUI + 单卡),干净退出。
想回放训练好的策略,用 play.py 加载最新 checkpoint:
CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/play.py \
--task=Isaac-Ant-v0 --num_envs 32 --viz kit
十、性能对比与使用建议
GUI 模式和 headless 模式的性能差异很大,这是必须理解的取舍:
| 模式 | Steps/s | 说明 |
|---|---|---|
| headless(4096 env,双卡可见) | 约 307000 | 不渲染,纯训练,最快 |
| –viz kit(64 env,单卡) | 约 3000 | RTX 实时渲染吃算力 + 单卡 |
两者差约 100 倍,这是正常的,原因有二:一是 GUI 开了 RTX 实时渲染,二是为绕开 GPU1 渲染崩溃只用了单卡。
因此实际使用的正确分工:
- 训练模型:用
--headless,几分钟练好,不看画面 - 调试 / 看行为 / 录视频:加
--viz kit,环境数调小(如--num_envs 16到64),牺牲速度换画面
十一、踩坑总结
把本文遇到的坑汇总成一张速查表:
| 编号 | 问题 | 根因 | 解法 |
|---|---|---|---|
| 坑 1 | no such option: --prerelease |
uv 参数用在了 pip 上 | 改用 --pre |
| 坑 2 | 大量依赖版本冲突 | pip 解析器尽力而为,RL 库与 NVIDIA 钉死版本冲突 | 只补 torchaudio,其余警告先忽略,别盲目钉版本 |
| 坑 3 | 看不到可视化窗口 | develop 默认 headless,--headless 已废弃 |
显式加 --viz kit |
| 坑 4 | GUI 报扩展依赖解析失败 | develop 超前引用 6.0.0 不存在的扩展 | 注释 kit 文件中三个缺失扩展(差集法定位) |
| 坑 5 | GUI 窗口黑屏退出 | 双卡 RTX 渲染(deviceMask 0x3)因 GPU1 跛脚而崩溃 | CUDA_VISIBLE_DEVICES=0 限定单卡渲染 |
| 附加 | 双卡 P2P 带宽仅 14GB/s | GPU1 PCIe 被 BIOS 拆成 x4 | 进 BIOS 改 lane 分配或换插槽(本文未操作) |
十二、关键经验提炼
-
Blackwell 用 cu128 即可,不必强求 cu130。CUDA 12.8 已含 sm_120 内核,新驱动向后兼容。装完务必用真实 matmul 算子验证,而不只是看
cuda.is_available()。 -
依赖冲突警告不等于错误。Isaac Lab develop + pip 的组合必然刷一堆
==冲突,多数不影响运行。判断标准是import isaacsim能否成功,而不是消灭所有警告。盲目钉版本反而会陷入死循环。 -
develop 是滚动分支,会超前引用未发布的扩展。GUI 崩溃时,先用差集法对比"引用的扩展"和"本地实际安装的扩展",定位缺失项再注释,比逐个试错快得多。这类修改会在 git pull 后失效,建议脚本化。
-
报错信息会误导方向。坑 4 的报错里有"连不上仓库",看似网络问题,实则是上游根本没发布该扩展。排查时要看本质(本地有没有、上游发没发),而不是被表面提示牵着走。
-
硬件问题会在特定路径上才暴露。GPU1 的 x4 链路在单卡训练时毫无影响,直到双卡 RTX 渲染才导致崩溃。遇到"时好时坏"的问题,要关注不同执行路径的差异。
希望这篇实录能帮到同样在 50 系新卡上部署 Isaac Lab 的同学,少走一些弯路。
更多推荐



所有评论(0)