How to Use NVIDIA Warp and MjWarp to Accelerate Robotics Simulation and Learning Workflows
https://huggingface.co/blog/nvidia/how-to-use-nvidia-warp-and-mjwarp📌 【NVIDIA】把 MuJoCo 機器人模擬推向 GPU 規模:一次跑 2,048 個平行世界
TL;DR:NVIDIA Warp 與 MJWarp 讓相容的 MuJoCo 模型從單一 CPU 世界擴展到上千個 GPU 平行環境。
傳統 MuJoCo 在 CPU 上跑一個機器人世界已經夠快,甚至能把取樣工作平行分散到多個 CPU 核心。但當學習任務的規模持續擴大,問題不再是「一個世界能跑多快」,而是「同時能跑多少個世界」。這正是 NVIDIA Warp 與建立在其上的 MuJoCo Warp(MJWarp)要解決的問題。
🤔 從「一個世界跑得快」到「上千個世界一起跑」
強化學習與大規模取樣最在意的不是單一環境的延遲(latency),而是每秒完成的世界步數總量,也就是聚合吞吐量(aggregate throughput)。MJWarp 的價值不必然是讓單一世界的一步算得更快,而是能把數百甚至上千個世界一起推進,讓 GPU 有足夠的平行工作量把吞吐量真正拉起來。這篇文章是 NVIDIA「State of Simulation for Physical AI」系列的第二篇,重點是準備並擴展模擬環境本身,並不涉及訓練策略;後續的 Newton 與 Isaac Lab 文章才會處理更上層的整合。
🧩 三層架構:Warp、MJWarp、你的場景
整個技術棧可以拆成三層:NVIDIA Warp 是 Python kernel 語言,提供 SIMT(single instruction, multiple threads)平行執行、自動微分(autodiff)以及與 PyTorch/JAX 的互通性;MJWarp 則是在 Warp 上實作的 MuJoCo 物理引擎,使用同一份 MJCF 模型檔案,但把批次化的 GPU 吞吐量做出來;再上層就是你的場景,例如文中示範的 SO-101 follower arm,沿用熟悉的 Menagerie/Robot Studio 資產與任務幾何。
Warp 的核心賣點有三個:效能上透過 JIT 編譯、kernel 融合與 CUDA Graphs 達到接近原生 CUDA 的速度;易用性上維持純 Python 撰寫,並內建向量、矩陣、四元數、BVH、hash grid、稀疏矩陣等結構;能力上則支援可微分 kernel 與類似 DLPack 的互通格式,讓模擬能直接嵌入 ML 訓練迴圈。一個最小範例是這樣的 kernel:透過 wp.tid() 取得目前執行緒對應的點索引,套用重力更新速度,再更新位置——同一段程式碼可以從兩個點無痛擴展到數百萬個點,控制流程完全不必寫進 GPU 相關術語。
從 MuJoCo 遷移到 MJWarp 的 API 對應也很直接:mujoco.MjModel 對應 mjw.put_model(mjm),mujoco.MjData 對應 mjw.put_data(mjm, mjd, ...),mujoco.mj_step(mjm, mjd) 對應 mjw.step(m, d),而原本 mjd.ctrl 這類 host 端陣列,會變成形狀為 (nworld, nu) 的批次化裝置陣列。文章也指出一個實務細節:想要保留初始化後的精確 MuJoCo 狀態,要用 mjw.put_data();只需要預設或全新狀態時,用 mjw.make_data() 就夠了。
💡 可微分與確定性:兩個目前用不到、但值得知道的能力
Warp kernel 本身是可微分的:wp.Tape 會記錄 context 內的前向 kernel 呼叫,呼叫 backward() 時再反向重播其伴隨運算,這也是為什麼團隊會用 Warp 打造可微分幾何、CFD 甚至客製物理引擎,應用在 CAE 的模擬與設計最佳化上。另外,Warp 1.15 引入了確定性執行模式:GPU atomics 預設依排程而定,重複執行同一個 kernel 可能有微小差異,開啟確定性模式可以用一些效能換取可重現的執行順序,適合驗證與回歸測試。但要注意,這是 Warp 本身的能力,並不代表整條 MJWarp rollout 都自動具備可微分性或確定性保證。
⚠️ 這篇文章沒有涵蓋的範圍
文中明確指出,solver 調校、Jacobian 表示方式,以及多 GPU 或確定性的進階主題,並不是這次遷移的必要條件,會留到之後另外說明。這篇也只走到「驗證單一世界、遷移到 MJWarp、組成批次、驗證、正確測量」為止,並未實際訓練策略。
🎯 該用哪一個工具?
文章給了一個很實用的決策捷徑:只需要單機器人 MPC 或遙操作,用 MuJoCo CPU 就好;要在原生 MuJoCo 物理上榨出最大吞吐量,選 MJWarp(或 mjlab);需要 JAX 訓練流程,用 MuJoCo Playground/MJX(impl='warp');要多 solver API 加上 Isaac Lab 整合,就等系列下一篇的 Newton。想試試 Warp,可以直接 pip install warp-lang(GPU 確定性需求要 1.15 以上),再跑 python -m warp.examples.browse 或官方 tutorial notebooks。
🔗 來源
- 標題:How to Use NVIDIA Warp and MjWarp to Accelerate Robotics Simulation and Learning Workflows
- 作者/機構:Johnny Nuñez Cano、Asier Arranz、Rishabh Chadha、Ben Oliveri(NVIDIA)/HuggingFace Blog
- 連結:https://huggingface.co/blog/nvidia/how-to-use-nvidia-warp-and-mjwarp
#NVIDIA #Warp #MuJoCo #MJWarp #RoboticsSimulation #ReinforcementLearning #GPUComputing #PhysicalAI #SO101 #CUDA
原始資料 HuggingFace Blog · 收集於 2026-09-23
摘要原文
Back to Articles How to Use NVIDIA Warp and MjWarp to Accelerate Robotics Simulation and Learning Workflows Enterprise + Article Published September 23, 2026 Upvote - Johnny Nuñez Cano johnnynv Follow nvidia Asier Arranz asiernvidia Follow nvidia Rishabh Chadha rchadha-nv Follow nvidia Ben Oliveri BenOliveri Follow nvidia Classic MuJoCo provides fast CPU-based robot simulation for developing, testing, and controlling robots and it can parallelize sampling across CPU cores. But as learning workloads grow, the question shifts from how quickly one world can run to how many worlds can run at once. GPU acceleration makes it possible to advance those worlds in large batches while keeping simulation and learning data close to the device. MuJoCo Warp (MJWarp) , built on NVIDIA Warp , takes compatible MuJoCo models into that GPU-scale regime. In this article, we will move an SO-101 follower arm from a familiar MuJoCo workflow to as many as 2,048 parallel MJWarp environments and examine the technology and validation steps that make the transition possible. Figure 1. How MJWarp connects Python to GPU simulation. MuJoCo loads and compiles the MJCF model; MJWarp implements the physics in NVIDIA Warp, which compiles CUDA kernels to advance simulation states on NVIDIA GPUs. This is the second article in our State of Simulation for Physical AI series. The first article mapped the robot-simulation landscape. Here, we prepare and scale the simulation environment; we do not train a policy. The later Newton and Isaac Lab installments cover the next integration layers. Putting it together Layer Role in the stack NVIDIA Warp Python kernel language: single instruction, multiple threads (SIMT), autodiff, PyTorch/JAX interop MJWarp MuJoCo physics on Warp: same MJCF, batched GPU throughput Your scene (SO-101) Familiar Menagerie / Robot Studio assets + task geometry Next (Newton / Isaac Lab) Multi-solver API, USD, sensors, managers, training loops Decision shortcut: If you need… Reach for… Single-robot MPC / teleop MuJoCo CPU Max throughput on raw MuJoCo physics MJWarp (or mjlab ) JAX training recipes MuJoCo Playground / MJX (impl='warp') Multi-solver + Isaac Lab integration Newton — next post in this series Start with one useful Warp Kernel NVIDIA Warp is a Python framework for writing high-performance, GPU-accelerated kernels. Warp lets developers author statically typed kernels in Python and compiles them for CPU or CUDA execution. The first launch builds and caches a native module; later launches reuse it. The kernel language is a performance-oriented subset of Python, while ordinary Python remains responsible for configuration, allocation, and launch orchestration. This small robotics-oriented kernel advances point positions under gravity. One logical thread handles one point, so the same code scales from two points to millions without introducing GPU terminology into the control flow. The three value propositions of Warp are: Pillar What you get Performance Native-CUDA speed via JIT compilation, kernel fusion, and CUDA Graphs Ease of use Pure Python authoring with built-in vectors, matrices, quaternions, BVHs, hash grids, sparse matrices, and tile primitives Capability Differentiable kernels and DLPack-style interop so simulation can sit inside an ML training loop import numpy as np import warp as wp @wp.kernel def integrate ( positions: wp.array[wp.vec3], velocities: wp.array[wp.vec3], dt: float , ): i = wp.tid() velocities[i] += wp.vec3( 0.0 , 0.0 , - 9.81 ) * dt positions[i] += velocities[i] * dt wp.init() device = "cuda:0" if wp.is_cuda_available() else "cpu" start = np.array([[ 0.0 , 0.0 , 0.5 ], [ 0.2 , 0.0 , 0.5 ]], dtype=np.float32) positions = wp.array(start, dtype=wp.vec3, device=device) velocities = wp.zeros_like(positions) wp.launch( integrate, dim= len (start), inputs=[positions, velocities, 0.01 ], device=device, ) wp.synchronize_device(device) print (positions.numpy()) Three properties make this useful in robotics: Explicit parallel work. wp.tid() identifies the point, contact, body, or world owned by the current logical thread. Explicit device arrays. An array lives on the selected device. Calling .numpy() on a CUDA array synchronizes and copies it to CPU memory; it is not a zero-copy path. For a device-resident PyTorch or JAX pipeline, use Warp’s framework adapters or DLPack-compatible sharing instead. Composable kernel launches. A program can launch a sequence of focused kernels and capture supported CUDA work into a graph to reduce repeated dispatch overhead. Graph capture replays launches against existing buffers; it does not fuse arbitrary kernels. Differentiability and Determinism. Two further Warp capabilities are worth knowing, even though neither is used in the SO-101 workflow in this article. Warp kernels are differentiable : a wp.Tape records the forward kernel launches made inside its context and replays their adjoints in reverse when backward() is called, which is why teams build differentiable geometry, CFD, and custom physics in Warp, including CAE workflows for simulation and design optimization. Warp also supports deterministic execution , introduced in Warp 1.15 : GPU atomics are scheduler-dependent by default, so repeated launches of the same kernel can differ slightly, and the opt-in deterministic modes trade some performance for reproducible ordering in simulation, validation, and regression tests. These are Warp capabilities, not guarantees of differentiability or determinism for an entire MJWarp rollout. See the Warp documentation on differentiability and deterministic execution for the details. Try Warp: pip install warp-lang (≥ 1.15 for GPU determinism), then python -m warp.examples.browse, or the tutorial notebooks . What is MuJoCo Warp (MJWarp)? A robot simulator repeatedly computes what happens next: given the current joint positions, velocities, controls, and contacts, it advances the scene by one small timestep. In this article, a world means one independent copy of that scene and its state. One world might contain the SO-101 arm reaching for a cube; another can contain the same arm starting from a slightly different pose. MuJoCo and MJWarp can run the same compatible robot and task, but they organize the work differently. MuJoCo naturally suits developing and inspecting one or a few CPU worlds. MJWarp is a NVIDIA Warp implementation of MuJoCo ’s physics pipeline that places the model and a batch of independent states on NVIDIA GPUs; one call to mjw.step advances the entire batch. MJWarp’s value is not necessarily a faster step for one world. It is the ability to advance hundreds or thousands together, giving the GPU enough parallel work to improve aggregate throughput , the total world-steps completed per second. That favors reinforcement learning and large-scale sampling, where collecting experience matters more than minimizing one environment’s latency. This blog covers the following: validate one MuJoCo world, move it to MJWarp, form a batch, verify it, and measure it correctly. Solver tuning, Jacobian representation, and specialized multi-GPU or determinism topics are not required for this migration and can be covered separately. Then, the distinction is precise: Latency is wall-clock time for one simulation step. Aggregate throughput is the total number of world-steps completed per measured wall-clock second. Basic usage: structs, batch sizes, and a minimal step The core API transition is small: MuJoCo host workflow MJWarp workflow mujoco.MjModel mjw.put_model(mjm) creates a device model mujoco.MjData mjw.put_data(mjm, mjd, ...) preserves and batches an existing state mujoco.mj_step(mjm, mjd) mjw.step(m, d) advances every world in d Host arrays such as mjd.ctrl Batched device arrays such as d.ctrl with shape (nworld, nu) Use mjw.make_data() when default/fresh state is intended. Use mjw.put_data() when the exact initialized MuJoCo state must cross the migration boundary.
由 claude-code/sonnet 自動生成