运行性能测试#
本指南介绍 runtime 、 play 、 training 和 startup 性能测试工作流。单项操作见 编写微基准测试 ;Python 用法与框架扩展见 使用性能测试 API ;使用多个 GPU 的工作流见 多 GPU 。
选择工作流#
要回答的问题 |
工作流程 |
|---|---|
环境步进能力的大幅变化 |
|
已训练策略的行为或部署吞吐量 |
|
端到端学习吞吐量或学习行为 |
|
启动、导入、配置、场景创建或首步延迟 |
|
在多个 GPU 上测量上述任意内容 |
|
单个资产或传感器操作 |
每次比较都应:
保持负载及来源条件不变。
比较相同的数据结构字段和测量模式。
将冷启动与稳态运行分开。
运行时#
适用情况#
使用 runtime 测量任务的环境步进能力,不包含策略推理或学习,适合初步检查仿真或任务吞吐量的变化。
运行命令#
源码安装使用:
./isaaclab.sh benchmark runtime \
--task Isaac-Cartpole-Direct \
--num_envs 4096 \
--warmup_steps 50 \
--num_steps 1000 \
--seed 42 \
--visualizer none \
--benchmark_formatter schema,summary \
--output_path ./benchmark_results \
physics=isaacsim_physx
OVRTX 相机任务可通过 Hydra 覆盖相机渲染器配置,比较同步与异步(流水线)渲染:
./isaaclab.sh benchmark runtime \
--task Isaac-Cartpole-Camera-Direct \
--num_envs 256 \
--warmup_steps 30 \
--num_steps 200 \
--benchmark_formatter schema,omniperf \
--output_path ./results/ovrtx_async \
physics=newton_mjwarp renderer=ovrtx presets=rgb \
env.scene.tiled_camera.renderer_cfg.async_rendering=True
只有 OVRTX 渲染器实现了异步渲染。各模式下状态、观测和帧的对应关系见 异步渲染 。
读取结果#
运行结束后,命令打印吞吐量与资源摘要,完整结果保存在 JSON 输出中。
读取 runtime.environment_step_timing.environment_step_fps ,获取所有环境合计的步进速率。Runtime 在启动 env.step() 计时器前采样随机动作,因此动作生成不计入该时间。对于 runtime 运行, runtime.collection_fps 和 runtime.total_fps 描述同一个随机动作步进负载。
渲染与物理范围的性能分析,要求任务配置中的 benchmark_mode 不为 None 。如果该字段不存在或为 None ,即使设置对应分析标志,两种范围仍不会启用;标准运行时报告仍会生成。
对于 Isaac-RenderBenchmark-Franka-Cabinet ,未设置 BENCHMARK_MODE 时默认为 None :物理与相机渲染仍运行,但没有基准动画或范围性能分析。设置 BENCHMARK_MODE=render ,可在物理步之后写入解析计算的关节位姿; BENCHMARK_MODE=physics_render 则在物理步之前设置执行器目标。两种模式仍会推进物理。直接设置位姿要求 scene.lazy_sensor_update=True 。使用 Isaac RTX 时,此模式应指定 --visualizer none ,因为 Kit 可视化器会在写入位姿前渲染。
设置 ISAACLAB_PHYSICS_PROFILE=1 ,可在运行时测量循环中采集同步的物理步耗时。测试通过 profile_physics_steps() ,在测量期间封装所选物理管理器的 step 。类似地, ISAACLAB_RENDER_PROFILE=1 通过 profile_renderers() 封装已注册的渲染器,只测量 render() ,排除场景更新与输出读回。两个上下文管理器均在预热后安装封装,并在测量结束时恢复原方法,包括发生错误时,因此不会影响后续测试。渲染参数扫描启用两个标志,但必须显式设置 BENCHMARK_MODE=render 或 BENCHMARK_MODE=physics_render 才会采集耗时。按顺序记录的 [scope, elapsed_ms] 样本写入本地 <output_path>/profile_timings.json 的 timings_ms 。结果包的 extra 字典保存标量摘要 physics_mean_ms 、 physics_std_ms 、 physics_max_ms 、 physics_calls 和对应的 render_* 摘要;禁用范围不生成键。数据结构版本仍为 1.4,OmniPerf 输出包含相同摘要。这些统计描述预热后的单次调用;渲染扫描则按渲染帧汇总物理调用,并丢弃填充帧。扫描从每个配置各自的目录读取本地性能分析文件。设备同步会改变执行重叠,因此这些分析运行属于诊断,而非吞吐量测量。
标准工作站输出与来源条件
无界面运行时摘要(输出已省略部分内容):
| Summary Report |
| workflow_name: benchmark_runtime |
| task: Isaac-Cartpole-Direct |
| num_envs: 4096 |
| Collection FPS (mean/std/max): 857289.11 / 88395.50 / 983383.55 FPS |
| Total FPS (mean/std/max): 857289.11 / 88395.50 / 983383.55 FPS |
| Environment Step Host-Return FPS (mean/std/max): 857648.65 / 88448.67 / |
| 983822.18 FPS |
[... output abbreviated ...]
无界面运行的带类型数据结构节选:
{
"schema_version": "1.4",
"run": {
"config": {"physics_backend": "physx", "rendering_backend": "none", "presets": ["physx"]},
"task": "Isaac-Cartpole-Direct", "seed": 42, "status": "completed", "num_envs": 4096
},
"runtime": {
"iterations_completed": 1000,
"collection_fps": {"mean": 857289.1054855952},
"total_fps": {"mean": 857289.1054855952},
"environment_step_timing": {
"environment_step_fps": {"mean": 857648.6464583826},
"environment_step_calls": 1000, "measurement_mode": "host_return"
}
}
}
带渲染的运行时摘要(输出已省略部分内容):
| Summary Report |
| workflow_name: benchmark_runtime |
| task: Isaac-Cartpole-Camera-Direct |
| num_envs: 1024 |
| Collection FPS (mean/std/max): 31587.33 / 2203.25 / 36188.75 FPS |
| Total FPS (mean/std/max): 31587.33 / 2203.25 / 36188.75 FPS |
| Environment Step Host-Return FPS (mean/std/max): 31590.46 / 2203.47 / 36192.00 |
| FPS |
[... output abbreviated ...]
带渲染运行的带类型数据结构节选:
{
"schema_version": "1.4",
"run": {
"config": {
"physics_backend": "physx", "rendering_backend": "isaacsim_rtx",
"presets": ["physx", "isaacsim_rtx", "rgb"]
},
"task": "Isaac-Cartpole-Camera-Direct", "seed": 42,
"status": "completed", "num_envs": 1024
},
"runtime": {
"iterations_completed": 1000,
"collection_fps": {"mean": 31587.33014449644},
"total_fps": {"mean": 31587.33014449644},
"environment_step_timing": {
"environment_step_fps": {"mean": 31590.455581417973},
"environment_step_calls": 1000, "measurement_mode": "host_return"
}
}
}
采集条件:Intel(R) Core(TM) i9-14900K CPU、NVIDIA GeForce RTX 5090 GPU、Ubuntu 24.04.3,代码版本 f02ca894a91f9db3a9ab0d42fcf23a5bc5eae22d。两次运行均使用 PhysX、随机种子 42、50 个预热步,以及 1000 步测量窗口。无界面运行使用 Isaac-Cartpole-Direct 和 4096 个环境;带渲染运行使用 Isaac-Cartpole-Camera-Direct 和 1024 个环境,采用 RTX 渲染及 RGB 预设。认可的平衡电源配置使用 intel_pstate、powersave 调节策略和 balance_performance 能耗偏好。
--warmup_steps 在测量窗口前执行指定数量的环境步,这些步不计入测量。Runtime 总计执行 warmup_steps + num_steps 次 env.step() ,而吞吐量窗口始终恰好包含 num_steps 次调用。预热步数非零时,首次预热步提供单独的 first_step 启动诊断;预热为零时,首次测量步提供该诊断,但不会从测量窗口移除。
不能据此推断的内容#
不要从 runtime 结果推断策略服务或训练性能,因为它既不包含策略推理,也不包含策略更新。不要将其 FPS 与包含渲染、规模不同或插桩方式不同的负载比较。
回放#
适用情况#
使用 play 测量已训练策略的轨迹采集吞吐量或评估行为。先运行 training ,为同一强化学习库和任务生成检查点,或提供其他兼容检查点。
运行命令#
./isaaclab.sh benchmark play \
--rl_library rsl_rl \
--task Isaac-Cartpole-Direct \
--num_envs 4096 \
--num_steps 1000 \
--warmup_steps 50 \
--checkpoint /path/to/model.pt \
--seed 42 \
--visualizer none \
--benchmark_formatter schema,summary \
--output_path ./benchmark_results/play \
physics=isaacsim_physx
读取结果#
runtime.collection_fps 或 runtime.total_fps 用于策略推理加轨迹采集;在 play 中,二者描述同一范围。 runtime.environment_step_timing.environment_step_fps 单独测量 env.step() 边界。 reward 、 ep_length 和 success_rate 只根据已完成回合计算;测量窗口中没有完成回合,或任务未报告成功值时,它们可能为 null 。
runtime.collection_fps
runtime.total_fps
runtime.environment_step_timing.environment_step_fps
--warmup_steps 只将前 N 次 env.step() 调用排除在 runtime.environment_step_timing 之外,不会将这些步排除在采集 FPS、总 FPS、策略评估、回合统计或实际耗时之外。
带类型结果在上述标准运行时结果结构上,添加回放专用的 reward 、 ep_length 、 success_rate 和 checkpoint_path 字段。比较时记录相同的硬件、软件版本、负载、随机种子、预热、渲染及电源配置条件。
不能据此推断的内容#
不要将回放采集 FPS 解释为仅环境的性能。缺少回合指标不表示奖励或成功率为零。回放运行不测量学习或策略更新吞吐量。
训练#
适用情况#
使用 training 测量端到端学习吞吐量和学习行为。运行会写入强化学习库的常规日志与检查点;可将兼容的已保存检查点传给 play 。
运行命令#
./isaaclab.sh benchmark training \
--rl_library rsl_rl \
--task Isaac-Cartpole-Direct \
--num_envs 4096 \
--max_iterations 100 \
--warmup_steps 50 \
--seed 42 \
--visualizer none \
--benchmark_formatter schema,summary \
--output_path ./benchmark_results/training \
physics=isaacsim_physx
读取结果#
运行结束后,命令打印吞吐量、资源与学习摘要,完整结果保存在 JSON 输出中。
runtime.collection_fps 测量不含策略更新的轨迹采集, runtime.total_fps 测量采集加更新, runtime.environment_step_timing.environment_step_fps 测量仅环境的步进。通过 learning.reward 和 learning.ep_length 检查学习行为,不要用单一吞吐量值概括训练。
runtime.collection_fps
runtime.total_fps
runtime.environment_step_timing.environment_step_fps
learning.reward
learning.ep_length
--warmup_steps 只将前 N 次 env.step() 调用排除在 runtime.environment_step_timing 之外,不会将工作排除在采集 FPS、总 FPS、学习曲线、策略评估、回合统计或实际耗时之外。
带类型结果在上述标准运行时结果结构上,添加训练专用的 run.framework 、 run.max_iterations 、 learning 、 success_rate 和 checkpoint_path 字段。除相同来源条件外,还需记录强化学习库和训练迭代次数。
不能据此推断的内容#
更快的环境步进速率,不能证明端到端训练更快或学习效果等价。短期训练曲线也不能证明最终策略质量。
多 GPU#
在 startup 、 runtime 或 training 后添加 _multigpu ,可为每个 GPU 运行一个测试 rank。三种工作流、启动器选项、多节点配置、受支持强化学习库和结果解读,以 多 GPU 和多节点训练 指南为准。
启动#
适用情况#
使用 startup 排查启动或冷初始化。更快的启动可缩短编辑、运行、调试周期。该工作流区分五个冷启动阶段:
app_launch进入仿真启动器并初始化运行时。python_imports导入启动器、任务注册和运行时库。task_config解析请求的任务配置。env_creation运行gym.make()和初始env.reset()。first_step运行首次env.step()并等待设备完成。
运行命令#
./isaaclab.sh benchmark startup \
--task Isaac-Cartpole-Direct \
--num_envs 4096 \
--top_n 30 \
--seed 42 \
--visualizer none \
--benchmark_formatter schema,summary \
--output_path ./benchmark_results/startup \
physics=isaacsim_physx
读取结果#
运行结束后,控制台打印各阶段的实际耗时摘要,包括 env_creation 期间运行的计时器。完整分析结果保存在 JSON 输出中。
读取 phases 各条目下的实际耗时和耗时归属函数。
phases.<phase>.total_time_s
phases.<phase>.top_functions
传入 --whitelist_config scripts/benchmarks/startup_whitelist.yaml ,可为特定阶段选择稳定的 fnmatch 模式。白名单模式对已列出的阶段忽略 --top_n 。输出仍包含未匹配模式,其自身耗时、累计耗时和调用次数均为零,以保持仪表板键稳定。命令还会记录警告,指出每个未匹配模式。
模式匹配的是相对于各已安装包根目录构建的分析标签。仓库内函数没有包前缀,如 utils.assets:_find_asset_dependencies ;外部包保留完整点分路径,如 warp._src.context:launch 。
带类型结果用启动专用的 config 和 phases 映射取代运行时吞吐量字段。各阶段报告实际耗时与选定分析条目。除相同来源条件外,还需记录缓存状态、进程顺序、 top_n 和白名单配置。
启动测量有意不预热,因为冷启动工作本身就是被测对象。使用新进程运行,比较时控制缓存状态和执行顺序。
不能据此推断的内容#
cProfile 是带有测量开销的耗时归属分析工具。阶段实际耗时和函数归属应视为冷启动诊断,不能视为稳态吞吐量或未受干扰的计时跟踪。
测量边界#
主要速率指标采用以下边界:
字段与工作流 |
测量范围 |
|---|---|
|
随机动作下的 |
|
策略推理与轨迹采集,包含 |
|
仅 |
|
轨迹采集,排除策略更新。 |
|
采集与策略更新合计。 |
|
仅 |
|
冷启动工作,不是稳态吞吐量。 |
只有数据结构字段名和 runtime.environment_step_timing.measurement_mode 相同,才比较运行结果。仅 FPS 单位相同还不够。
带渲染的负载#
渲染会改变负载。应显式选择相机任务、启用相机,并指定渲染器和传感器预设:
./isaaclab.sh benchmark runtime \
--task Isaac-Cartpole-Camera-Direct \
--num_envs 1024 \
--warmup_steps 50 \
--num_steps 1000 \
--seed 42 \
--enable_cameras \
--visualizer none \
--benchmark_formatter schema,summary \
--output_path ./benchmark_results/rendered \
physics=isaacsim_physx renderer=isaacsim_rtx presets=rgb
选择 summary 会启用可用的 Kit 物理、渲染、应用和 GPU 帧耗时记录器。特定安装或后端组合中,某些记录器可能不可用。相机任务、1024 个环境、RTX 渲染器与 RGB 预设,使本负载不同于前文无界面的 Isaac-Cartpole-Direct 。不要将二者 FPS 差异解释为仅由后端产生。
物理后端#
保持命令不变,只替换物理选择项:
physics=isaacsim_physx
physics=newton_mjwarp
physics=ovphysx
比较后端时,保持任务、环境数、随机种子、预设、渲染器、预热、测量窗口和测量模式相同。一个后端可用的渲染器或任务,可能与另一个不兼容。采集比较数据前,先选择共同支持的负载。
读取输出#
--benchmark_formatter 接受逗号分隔的列表,各格式化器面向不同使用方:
schema写入稳定的带类型结果包,用于分析、比较和归档依据。summary打印终端报告,并写入扁平指标 JSON;在 runtime、play 和 training 中启用可用的 Kit 帧耗时记录器。json写入全部传统扁平阶段、测量和元数据。osmo写入各阶段的单值 KPI 文档,供 Osmo 接收。omniperf写入按阶段分组的 KPI JSON,用于性能跟踪和数据库上传。
交互运行使用 schema,summary 。以下 jq 查询对应带类型数据结构的路径:
jq '.run, .runtime.collection_fps, .runtime.total_fps' benchmark_*_schema.json
jq '.runtime.environment_step_timing' benchmark_*_schema.json
jq '.phases' benchmark_startup_*_schema.json
使用多个格式化器时,摘要文件名包含 _summary ,带类型结果包文件名包含 _schema 。
证据级别#
采集数据前,先确定所需证据级别:
单次探索: 通过一次受控运行判断方向、定位瓶颈或验证测试配置,不能据此公开作出性能结论。
明显性能退化的初筛: 至少使用三组成对的独立进程,轮换随机种子和执行顺序。在相同条件下采集并配对基准与候选运行。
性能结论: 至少使用三个独立进程,并进行更长、重复的训练运行。运行必须覆盖结论所描述的行为,短时吞吐量探测并不足够。
比较运行结果#
报告各次运行值、成对差值及离散程度或置信区间。差值区间跨过零时,应注明结果无法确定。避免只报告最好的一次,或只报告汇总值。
控制后台活动,并记录每次运行时的变化。
所有对外公布的结果都必须包含以下来源条件:
类别 |
必需字段 |
|---|---|
硬件 |
CPU 型号、物理核心数、RAM 和 GPU。 |
软件 |
操作系统、物理后端、软件版本和代码版本。 |
负载 |
任务、环境数量、随机种子、预热、测量窗口和渲染配置。 |
运行条件 |
电源配置与执行顺序。 |
性能取决于完整的 CPU、GPU、软件与负载配置,不是 GPU 单独的属性。进程 CPU 利用率按核心求和,因此可超过 100%。
同步步进诊断#
Runtime、play 和 training 接受以下可选诊断标志:
--measure_sync_step
它将 measurement_mode 从 host_return 改为 serialized_synchronized 。诊断在环境与仿真边界前执行同步,也会将通常异步运行的工作串行化,可能大幅降低 Newton 速度。带插桩工作流中的所有耗时和速率,都使用改变后的调度方式,不应作为吞吐量报告。
诊断将同步的环境步时间分为仿真时间和 仿真之外的剩余时间 。后者包含必要的动作、执行器、状态、管理器、重置、包装器和同步工作。它只是插桩调度下通过减法得到的剩余量,不是可移除的框架开销。绝不能减去它来预测可达到的吞吐量。
故障排除#
- 缺少检查点
先运行训练,或传入由所选强化学习库为同一任务及兼容智能体配置生成的检查点。检查路径和
--rl_library选择。- 回放回合未完成
增加
--num_steps。奖励、回合长度和成功率汇总需要已完成回合,否则可能为null。- 无效计数
--num_steps和显式提供的--max_iterations必须大于零;--warmup_steps必须非负。- 缺少资源或帧耗时指标
非常短的运行可能在周期性资源监视器采集足够样本前结束。帧耗时指标需要对应 Kit 记录器可用,并由
summary或omniperf启用。- 渲染器不兼容
检查物理后端、渲染器、相机任务、传感器预设和可视化器组合是否受支持。比较时使用相同的共同配置。
- 测量模式不一致
host_return只能与host_return比较,serialized_synchronized只能与相同诊断模式比较,还需确认数据结构字段名相同。- 其他 GPU 负载干扰
停止无关 GPU 作业与后台活动,再重复成对运行。记录执行顺序、电源模式和后台活动变化,以便发现温度或资源争用影响。