关于 isaac-sim-troubleshooting
面向 Isaac Sim 6 和 Kit 110 开发者的故障排查技能,帮助诊断卡顿、加载停滞、渲染异常及性能或内存问题。内容按子系统整理症状,并提供检查步骤和处理方法。
主要功能
- 01启动与关闭卡顿诊断
- 02场景加载与着色器排查
- 03Physics 和 Replicator 卡顿指南
- 04Hydra、Nucleus 与 GPU 问题检查
- 05独立库诊断
适用场景
- 01调查 Isaac Sim 启动停滞
- 02诊断大型 USD 场景加载缓慢
- 03排查物理或渲染卡顿
- 04检查 GPU 内存和 Nucleus 延迟
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ isaac-sim/ isaacsim --skill isaac-sim-troubleshooting安装后在 Claude Code 中输入/isaac-sim-troubleshooting确认已加载。
详细介绍
Isaac Sim 故障排查
目的
诊断 Isaac Sim 启动挂起、场景加载停滞、MDL/着色器编译冻结、物理步进阻塞、Replicator/Hydra 问题、Nucleus 延迟以及 GPU OOM 崩溃。
先决条件
- 库故障需要配置好的构建环境或已安装的软件包环境。
- Kit/GPU 先决条件仅适用于正在诊断的 Kit 工作负载。
限制
- 症状列表仅供启发式参考;不同子系统的问题可能存在重叠。
- 某些修复需要本地 Kit 构建或仅供 NVIDIA 内部使用的软件包。
故障排查
| 错误/症状 | 原因 | 解决方案 |
|---|---|---|
| 找不到扩展或导入项 | $ISAAC_SIM_DIR 错误或构建已过时 | 将环境变量指向 _build/linux-x86_64/release,或重新构建 |
| 帧画面为黑色或空白 | 缺少灯光或未使用 RTX 渲染模式 | 添加穹顶灯/主光源;确认 RTX/PathTracing 设置 |
| 加载场景或首次渲染时挂起 | MDL 编译或场景过大 | 按照 isaac-sim-troubleshooting 中的隔离步骤操作 |
关闭时挂起/SimulationApp.close() | shutdown_and_release_framework() 期间,carb.tasking 线程池发生死锁 | 使用 SIGALRM 看门狗(参见第 1a 节)——当 GIL 被发生死锁的 C 扩展占用时,threading.Event 无法触发 |
针对 Isaac Sim 6.0(Kit 110)在大型 USD 场景(1 万至 15 万个以上 prim,工厂/仓库孪生场景)中的挂起、冻结和性能下降进行诊断与解决。
上游调试文档:docs/isaacsim/utilities/debugging/(性能分析、Python 调试教程)。将此技能与 profile-isaac-sim 配合使用,进行基于 Tracy 的诊断。
独立库诊断
在不使用 Kit 的情况下,通过普通进程复现问题。检查已安装的发行包、
wheel/本机依赖闭包、加载器路径和重定位。使用
isaacsim.common.logging.Logger 进行库诊断,使用 carb.log_* 诊断 Kit,
仅在有意输出到标准输出时使用 print()。
快速诊断流程图
Isaac Sim hangs/freezes
|
+-- During startup (before stage load)?
| -> Section 1: Startup Hangs
|
+-- During shutdown / SimulationApp.close()?
| -> Section 1a: Shutdown Hangs (Kit Framework Deadlock)
|
+-- During stage open / USD loading?
| -> Section 2: Stage Loading Hangs
|
+-- During shader/material compilation?
| -> Section 3: MDL/Shader Compilation
|
+-- During physics stepping / `SimulationManager` setup or timeline play?
| -> Section 4: Physics Hangs
|
+-- During Replicator / sensor capture?
| -> Section 5: Replicator Hangs
|
+-- During rendering (viewport frozen)?
| -> Section 6: Hydra/Rendering Hangs
|
+-- Nucleus/remote asset fetch?
| -> Section 7: Nucleus Network Hangs
|
+-- OOM crash or memory spike?
| -> Section 8: Memory Issues
|
+-- Slow but not frozen?
-> Section 9: Performance Optimization
第 1 节:启动挂起
常见原因和修复方法
1. 扩展冲突(循环导入)
./isaac-sim.sh --/app/extensions/exclude='["problematic.extension"]'
2. 渲染器初始化冻结
./isaac-sim.sh --vulkan # Force Vulkan
./isaac-sim.sh --reset-user # Reset user settings
3. 高核心数 CPU 上的线程过度订阅
./isaac-sim.sh \
--/plugins/carb.tasking.plugin/threadCount=16 \
--/plugins/omni.tbb.globalcontrol/maxThreadCount=16
simulation_app = SimulationApp({"headless": False, "limit_cpu_threads": 16})
4. Nucleus 登录弹窗挂起 — 强制终止 Isaac Sim 并重启。继续操作前请完成登录。
第 1a 节:关闭挂起(Kit 框架死锁)
症状
SimulationApp.close() 始终无法返回。进程无限期挂起(或直到 CI 在 1500 秒时将其终止)。堆栈跟踪显示,shutdown_and_release_framework() 或 unload_all_plugins() 期间,线程在 carb.tasking 线程池拆除过程中阻塞于 futex_wait。
根本原因
shutdown_and_release_framework() 会先调用 app->shutdown(),再调用 framework->unloadAllPlugins()。这些 C 扩展调用在内部因本机线程 join 而发生死锁时,会一直占用 GIL。Python 端的 threading.Event.wait() 看门狗无法触发,因为它需要 GIL 来检查超时并调用 os.kill()——因此会一直得不到调度。
修复方法:SIGALRM 看门狗
无论 GIL 状态如何,内核都会发送 SIGALRM。在阻塞的 C 调用之前设置闹钟;如果发生死锁,闹钟处理程序会无条件向进程发送 SIGKILL。
模式(通用化——适用于任何可能发生死锁的本机拆除操作):
- 保存之前的
SIGALRM处理程序。 - 安装一个调用
os.kill(os.getpid(), signal.SIGKILL)的处理程序。 signal.alarm(timeout_seconds)——完整关闭设置为 120 秒,卸载插件设置为 30 秒。- 调用阻塞的本机函数。
- 在
finally中:取消闹钟(signal.alarm(0))并恢复之前的处理程序。
何时怀疑此问题
- 所有测试断言均通过后,CI 作业仍然挂起(关闭阶段)。
strace显示主线程卡在 Kit 插件系统中的futex_wait。- 基于 Python 的超时机制(threading、asyncio)未能触发,且没有任何提示。
关键见解
每当 Python 看门狗必须监控一个可能无限期持有 GIL 的 C 扩展调用时,threading.Event/threading.Timer 都会因资源不足而无法运行。在 CPython 中,signal.alarm()(Linux)或 os.alarm() 是唯一可靠且不依赖 GIL 的超时机制。
参考
- 文件:
source/extensions/isaacsim.simulation_app/isaacsim/simulation_app/simulation_app.py
第 2 节:舞台加载卡住
诊断
检查图层数量:
for layer in stage.GetUsedLayers():
print(f" {layer.GetDisplayName()} ({layer.GetFileFormat().formatId})")
如果图层数量 > 1,000,这是主要瓶颈。
常见原因
1. 图层数量过多(>1,000 个图层)
| 策略 | 冷加载耗时 | 图层数 |
|---|---|---|
| 每个资产单独存储 | 4 分钟 | 11,488 |
| 库打包 | 53 秒 | 8 |
修复方法:将资产打包到库图层中(将每个资产单独存储的文件合并到少量库 .usd/.usdc 图层中;分层资产模式请参阅 usd-composition-architecture)。
2. 引用缺失或损坏 — 导致 USD 尝试所有解析器,包括网络回退。修复方法:审核引用:
from pxr import Sdf
for layer in stage.GetUsedLayers():
for ref in layer.GetExternalReferences():
if not os.path.exists(ref):
print(f"MISSING: {ref}")
第 3 节:着色器/MDL 编译
- 首次启动始终会编译 MDL 着色器,可能需要 5-15 分钟,属于正常现象
- 后续启动会使用着色器缓存
- 缓存位置:
~/.nvidia-omniverse/data/Kit/Isaac-Sim/shader_cache/ - 强制重新构建:删除缓存文件夹
第 4 节:物理卡住
物理设置/首次播放时卡住(SimulationManager.setup_simulation、timeline.play() 或旧版 world.reset() 流程——若要迁移并停止使用 omni.isaac.core.World,请参阅扩展重命名):通常由以下原因导致:
- 物理开始运行时,尚未定义
PhysicsScene。 - 首个步进中接触对过多。
- 启用了 GPU 动力学,且刚体过多(>100K)。
修复方法:
# Ensure PhysicsScene exists before reset
if not stage.GetPrimAtPath("/World/PhysicsScene"):
ps = UsdPhysics.Scene.Define(stage, "/World/PhysicsScene")
# Reduce initial contact storm
px_scene.CreateEnableStabilizationAttr().Set(True)
第 5 节:Replicator 卡住
rep.orchestrator.run()卡住:调用前确保时间轴正在播放(omni.timeline.get_timeline_interface().play()或isaacsim.core.experimental.utils.app.play(commit=True))。step_async()始终无法完成:确保在异步上下文中正确使用await rep.orchestrator.step_async()。- 帧捕获卡住:捕获前调用一次
app_utils.update_app()(或simulation_app.update()),让渲染器获取新帧。
第 6 节:渲染(Hydra)卡住
- 视口黑屏且冻结:检查 GPU 内存(
nvidia-smi) - RTX 渲染器内存溢出:降低纹理流送预算:
carb.settings.get_settings().set("/rtx/resourcemanager/textureMipCountBudget", 256)
第 7 节:Nucleus 网络卡住
- 设置超时:
carb.settings.set("/omni/client/timeout_seconds", 10.0) - 尽可能使用本地资产:将所需 USD 复制到本地磁盘
- 禁用 Nucleus:仅进行本地工作时,使用
--/omni/client/enabled=false启动
第 8 节:内存问题
- Prims > 150K:启用实例化(
UsdGeom.PointInstancer) - 纹理:使用纹理图集,降低分辨率
- 监控:
watch -n1 'nvidia-smi --query-gpu=memory.used,memory.free --format=csv'
第 9 节:性能优化
- 图层数量:打包到库图层中(参见第 2 节)
- 网格实例化:对重复资产使用
PointInstancer - 载荷加载:将大型子场景标记为未加载的载荷
- 物理:降低非关键对象的碰撞网格复杂度