OPEN SOURCE DEEP DIVE
Genesis World:面向物理 AI 的统一多物理仿真平台
Genesis AI 开源的物理 AI 仿真平台:一套 Pythonic API 之下是多物理引擎(刚体、FEM、MPM、PBD、SPH、Stable Fluid、IPC)、Nyx 路径追踪渲染器,以及跨平台 Python-to-GPU 编译器 Quadrants。它的定位是机器人基础模型的评测引擎而不是数据工厂——单卡 3 万并行环境跑出 43M FPS;在零样本 real-to-sim 协议下,仿真与真实的评测一致性皮尔逊相关 0.8996、平均最大排序违背 0.0166。Apache 2.0,29.9k star。
一个为"评测"而造的仿真平台,不只是数据工厂
Genesis World 是面向物理 AI 的仿真平台:一套统一的多物理引擎、一个照片级渲染器 Nyx,以及一个跨平台的 Python-to-GPU 编译器 Quadrants,三者都藏在同一套 Pythonic API 之后。仓库里 genesis/ 目录下约有 262 个 Python 模块(源码约 5.9 MB)、122 个可直接运行的示例、89 个测试文件,以 Apache 2.0 许可证发布在 PyPI 上,包名 genesis-world,要求 Python 3.10 到 3.13。撰写本文时项目有 29.9k star、2,853 fork,最新版本 1.4.0 发布于 2026 年 9 月 6 日。
它的来历解释了很大一部分设计。项目最早是 2024 年 12 月启动的学术工作,当时叫 Genesis,定位是"面向机器人及更广领域的生成式通用物理引擎";GitHub 仓库本身创建于 2023 年 10 月。过去一年里,最初那版被重写成更系统的框架,开发工作现在由公司 Genesis AI 正式支持,改名 Genesis World 也发生在这次转轨中。2026 年 5 月的博客《The Role of Simulation in Scalable Robotics, Genesis World 1.0, and the Path Forward》把立场说得很清楚:仿真是机器人基础模型的评测与迭代引擎,而不只是一个数据生成器。
四层结构,一个场景,一份状态
架构文档和 README 都把这个平台描述成四层。四层之上是你要构建的东西(机器人环境、机器学习流水线、数据生成、智能体仿真),四层之下是你手上恰好有的算力后端。
- 仿真接口层——面向用户的 API:资产解析(URDF、URDF xacro、MJCF、USD、OBJ、STL、GLB/GLTF)、实体访问器、控制器、传感器、并行与异构环境,以及内置 GUI。
- 物理层——一个引擎集成了 Rigid、FEM、MPM、粒子法(PBD / SPH)与 Stable Fluid 求解器,外加
libuipc,并用三种可互换的耦合器求解它们之间的接触。所有内容共享同一个场景、同一份状态。 - 渲染层——三条渲染路径,都以相机传感器的形式接入:Nyx(为机器人自研的路径追踪器)、Luisa(DSL 光线追踪器)、Pyrender(光栅化器)。
- 编译器层——Quadrants 把 Python 写的核函数编译到 CUDA、AMD ROCm、Apple Metal、Vulkan、x86 与 ARM64,并承载自动微分、GPU graph 与 fast-cache 机制。
flowchart TB
subgraph Above["你要构建的东西"]
APP["机器人环境 · 机器学习流水线 · 数据生成 · 智能体仿真"]
end
subgraph GW["Genesis World"]
SI["仿真接口层
URDF/MJCF/USD 解析 · 实体 · 控制器
传感器 · 并行与异构环境 · GUI"]
PH["物理层
Rigid · FEM · MPM · PBD · SPH · Stable Fluid
一个场景,一份状态"]
RD["渲染层
Nyx 路径追踪 · Luisa 光线追踪 · Pyrender 光栅化"]
CO["编译器层:Quadrants
Python 核函数 → CUDA · ROCm · Metal · Vulkan · x86 · ARM64
自动微分 · 核函数图 · fastcache"]
SI --> PH --> RD --> CO
end
subgraph Below["算力后端"]
HW["数据中心 GPU · 工作站 GPU · 笔记本 CPU"]
end
APP --> SI
CO --> HW
理念章节里的两条信念决定了它下面的一切。第一,引擎是开源的、用 Python 写的,所以你和物理之间没有不透明的二进制:你可以读它、调它、扩展它。第二,各求解器不是在边缘处拼起来的——rigid、FEM、MPM 与粒子求解器共享一个场景和一份状态,耦合器恰好在它们的实体相接触的地方求解相互作用。项目还明确说明梯度是被设计成可以穿过物理的:编译器里有反向模式自动微分,最难的几个核函数则手工推导梯度。
每类材料一个求解器,三种把它们耦合起来的办法
跑哪个求解器由你给实体指定的材料决定,而不是靠切换某个模式。MPM 把质量挂在粒子上、在背景网格上求解受力,因此一个求解器就能覆盖弹性固体、塑性体、沙子和雪。FEM 把实体离散成四面体网格并在其上求解弹性,当你需要网格级精度时就用它:刚度较大的弹性体、体积肌肉、接触密集的软体操作。PBD 把实体表示成由约束连接的粒子并直接求解位置,因此对布料和绳索又快又稳。SPH 是纯拉格朗日方法,面向由真实流体参数(静止密度、黏度、表面张力)支配的自由液面液体。Stable Fluid 在固定的欧拉网格上工作,平流速度场和标量密度场,再用 Jacobi 压力投影把速度场变成无散场;气体是通过速度射流进入场景的,而不是通过你添加的某个实体。
| 求解器 | 表示方式 | 材料 | 什么时候该用它 |
|---|---|---|---|
| Rigid | 铰接连杆与几何体 | gs.materials.Rigid | 来自 URDF / MJCF / USD 的机器人与刚体物件 |
| MPM | 粒子 + 背景网格的混合表示 | Elastic、Liquid、ElastoPlastic、Sand、Snow、Muscle | 用一个求解器覆盖最广的连续介质材料 |
| FEM | 四面体网格 | Elastic、Cloth、Muscle | 精确弹性、体积肌肉 |
| PBD | 粒子 + 约束 | Cloth、Elastic、Liquid、Particle | 快速布料、绳索、保持拓扑的可变形体 |
| SPH | 拉格朗日粒子 | Liquid | 由物理参数驱动的自由液面液体 |
| SF | 固定三维网格(欧拉) | 速度射流 + 密度场 | 烟雾等气体现象 |
有意思的是怎么把它们混起来。仿真器为每个场景恰好实例化一个耦合器,由你传入的 options 对象决定:SAPCoupler、LegacyCoupler 或 IPCCoupler,传别的会在构造时直接抛错。耦合器每个子步交换一次状态,这也是它必须在子步频率确定之后才构建的原因;它围绕物理跑三个钩子——preprocess(f)、couple(f),以及反向传播里的 couple_grad(f)。换耦合器是一行代码的事,资产、传感器和策略接口都不用动。
快速通用耦合器负责常见组合(布料贴在刚体上、刚体与 MPM 附着、切割、水车)。SAP 耦合器是 Drake 风格的半解析原始(Semi-Analytic Primal)形式,带水弹性接触:源码里用可配置的 hydroelastic_stiffness 对无符号接触距离做缩放,从而算出一个压力场;它为 FEM 和刚体分别维护水弹性场初始化,并用 marching-tetrahedra 边表做表面提取。IPC 耦合器封装 libuipc,为娇贵的可变形体提供无穿透接触,也是这一轮新增物理最集中的地方。
为了把 IPC 和铰接机器人紧耦合,团队给 libuipc 扩展了一个外部铰接约束(External Articulation Constraint),把关节空间动力学直接嵌进 IPC 的优化问题里,于是关节空间力和接触力同时求解,而不是在两个独立求解器之间交替传递。对一个有 $m$ 个关节的铰接系统,刚体求解器先预测关节位移 $\tilde{\delta\boldsymbol{\theta}}$ 并算出关节空间有效质量矩阵 $\mathbf{M}^t$,再把它作为外部铰接动能注入 IPC:
$$ K = \frac{1}{2}\left( \delta\boldsymbol{\theta}(\mathbf{q}, \mathbf{q}^t) - \tilde{\delta\boldsymbol{\theta}} \right)^T \mathbf{M}^t \left(\delta\boldsymbol{\theta}(\mathbf{q}, \mathbf{q}^t) - \tilde{\delta\boldsymbol{\theta}} \right) $$
其中 $\delta\boldsymbol{\theta}$ 把 IPC 的仿射体状态 $\mathbf{q}$ 映射到关节空间位移。IPC 把这一项与接触障碍、摩擦、关节约束一起联合最小化。没有接触时求解器精确复现铰接预测;有接触时它只偏离到刚好足以解开接触的程度,并按有效质量加权,所以越重的连杆越抗拒被修正。源码里就是这么写的:uipc constitution 的导入清单包含 ExternalArticulationConstraint、AffineBodyRevoluteJoint 和 AffineBodyPrismaticJoint,模块里定义了 100.0 的关节强度比,默认刚度 1e4。
在接触求解本身这一侧,团队提出了无障碍弹性动力学(barrier-free elastodynamics)来加速接触密集场景中的 IPC 类仿真。标准 IPC 用对数障碍函数强制不穿透,这让紧接触时的 Hessian 病态,也因为带过滤的线搜索拖慢了活跃集探索。替代方案是一个自定义的增广拉格朗日:连续碰撞检测返回的每一个接触对都立刻进入活跃集,约束满足靠自适应的拉格朗日乘子更新来驱动,而不是不断抬高罚刚度。对每个线性化穿透深度为 $c_i(\mathbf{x})$ 的接触对 $i$,引入松弛变量 $s_i$,把不等式 $c_i(\mathbf{x}) \geq 0$ 变成等式 $c_i(\mathbf{x}) - s_i = 0$,单步目标函数成为
$$ L(\mathbf{x}, \mathbf{s}, \boldsymbol{\lambda}) = E(\mathbf{x}) + \sum_{i \in \mathcal{A}} \psi\bigl(c_i(\mathbf{x}),\, s_i, \lambda_i,\, \mu\bigr) $$
其中 $E$ 是增量势能,$\mathcal{A}$ 是活跃约束集,$\psi$ 是带刚度 $\mu$ 和乘子 $\lambda_i$ 的增广拉格朗日项。每次原始求解交替执行 $\mathbf{x}\leftarrow\arg\min_\mathbf{x} L$ 与 $s_i \leftarrow \max(0,\, c_i(\mathbf{x}) - \lambda_i/\mu)$,然后按 $\lambda_i \leftarrow \lambda_i - \mu(c_i(\mathbf{x}) - s_i)$ 更新乘子,并刷新 $\mathcal{A}$ 使其在保持有效的前提下尽量紧凑。应力增大时 Hessian 依然良态,博客报告的接触密集基准在复杂场景下比传统 IPC 快至 103 倍,同时仍然保证不穿透。
除了耦合,引擎还沿着三条明说的轴线走向成熟。规模化速度方面:线搜索里的协同线程、分解求解中的 GPU graph、分块(tile-blocked)Hessian 分解、宽相优化、只用寄存器的 Cholesky 与求解 tile,以及为最小化线程分歧调过的窄相。数值稳定性方面:为自由关节稳定性做的惯性轴对齐、自动标定的求解器容差、安全的 GJK 回退、抑制滑移与漂移的 noslip,以及分解求解器与整体求解器共用的统一线搜索路径。覆盖面方面:隐式 FEM(Newton + CG)与线性 corotated 弹性加入求解器集合,资产支持扩展到 URDF xacro、MuJoCo 通用执行器、复合/联动(mimic)关节和等式/焊接约束,公开 API 现在覆盖顶点操作、动能与势能查询、正运动学、指定点处的雅可比,以及质量矩阵访问。
Nyx:一个被"评测吞吐量"塑形出来的路径追踪器
自研渲染器的理由在于:每个渲染器都是被它的目标用例塑形的。游戏引擎优化的是观感,靠烘焙撑住性能;离线渲染器物理上准确,但常常一帧要几分钟,几乎没有按场景做优化的余地。机器人需要的是数百万帧、看起来像真实相机拍到的画面,生成速度要快到能大规模评测策略,而且引擎得是团队能持续扩展的那一种。
Nyx 就是这个答案,它的目标很具体:在高端消费级 GPU 上,4 毫秒以内出一张无噪声的 1080p 帧,不烘焙、不拖影。为此它用到可见性缓冲、无绑定(bindless)GPU 驱动架构、MSAA、硬件光线追踪、硬件矩阵核和视频压缩,全部围绕 GPU 占用率调优。它确实走了一些捷径,但这些捷径是按"保住对策略有用的视觉信号"来挑的——这是陈述一个面向学习的渲染取舍时最诚实的说法。
缩小 sim-to-real 差距被当作整个渲染栈的属性,而不是某个着色器设置。路径追踪是基线,所以多次弹射光照、软阴影和间接光照在构造上就是正确的,上面再叠一个有物理依据的相机模型。能用真实数据的地方都用真实数据:HDRI 流水线用实测辐照度打光,资产来自内部扫描和摄影测量而不是手工搭的替身,3D 高斯泼溅则在网格重建不够用时把这一原则延续下去。明说的难点是把基于图像的光照与基于泼溅的几何体调和起来,让采集来的资产在路径追踪的光传输里正确参与。
接入方式是按相机而不是按场景,这是一处刻意设计得很有用的接缝:其他后端是用 gs.Scene(renderer=...) 为整个场景选定一次的,而 Nyx 是用 scene.add_sensor(NyxCameraOptions(...)) 挂上去的。于是同一个场景里,控制回路可以用快速的光栅化相机,而你要留档的那些帧交给一台照片级的 Nyx 相机。渲染发生在 scene.step() 期间,帧通过 cam.read().rgb 取回。Nyx 以独立的 gs-nyx 包发布,目前通过内部包索引分发,项目正在为公开发布做准备。旧的 Luisa 路径追踪器(gs.renderers.RayTracer())仍在,可以出照片级静帧,但已标记为弃用,推荐 Nyx。
plant.ply 高斯泼溅立在 Genesis World 的平面上,由 Nyx 在一张 HDRI 环境贴图下渲染。这个泼溅是作为相机上的 LightFieldAsset 声明的,而不是场景实体,所以环境贴图只需要照亮它旁边那些被仿真的几何体。Nyx 是由批处理物理驱动的,而不是逐场景执行,这让成千上万条并行 rollout 各自带着自己的场景、光照和相机轨迹,跑在同一条统一流水线上。正是这种耦合把渲染吞吐量变成了评测吞吐量,也是一个渲染器有资格出现在物理平台叙事里的原因。
Quadrants:一个围绕"核函数编排成本"重建的 Taichi 分支
同一条物理流水线既要跑在机器人的机载计算机上,也要跑在工程师的 MacBook 上,还要跑在 GPU 集群上,而且不能为每个目标分叉一份代码。Quadrants 始于 2025 年 6 月对 Taichi 的一次分叉——名字本身就是对这段出身的致意——它与 Genesis 自动捆绑,在项目依赖里锁定为 quadrants==1.3.0。核函数用普通 Python 写,JIT 编译到 NVIDIA CUDA、AMD ROCm、Apple Metal、Vulkan,以及经 LLVM 到 x86/ARM64 CPU。分叉之后团队重建了对仿真负载最关键的那些部分,报告在自己的操作与运动基准上运行时最快提升 4.6 倍。
更有意思的诊断是:在仿真规模下成本究竟待在哪里。它从单个核函数的计算量,转移到了每个物理步里编排大量小核函数的开销上,Quadrants 从几个方向同时下手。每个物理步被录制成一张核函数图,在 CUDA 上走硬件加速(SM90 及以上支持条件循环),在其他所有后端上用软件方式支持,这就把启动延迟从每一个顶层循环里去掉了。相互独立的核函数通过多流重叠执行,而不是在一条队列里串行。仍然需要启动的地方,用手工调优、并在多级内存层缓存的核函数启动上下文,把派发开销压到亚微秒级,即便许多小核函数背靠背地发射也是如此。
可移植性的处理办法是把子组(subgroup)与块(block)级的 SIMT 原语映射到各后端的原生等价物——NVIDIA 上 32 线程的 warp、AMD 上 64 线程的 wave、Metal 上的 subgroup——这样一个手工调优过的接触求解器不必写按平台分支的代码就能跑。反向模式自动微分从实验状态变成了每个后端上的一等公民,这正是可微仿真能在策略部署的同一批硬件上可移植的原因。另外还加了一个纯 Python 后端,用于调试和系统性的覆盖测试。
核函数内部,Cholesky 分解、三角求解这类稠密线性代数用可读的 Python 表达,编译成 16x16 的分块代码路径;整核函数级的公共子表达式消除能抓到块内局部优化器漏掉的重复计算。性能派发层会在某个参数形状首次调用时对核函数的各个变体做基准测试,并按签名缓存最快的那个,于是同一份前端代码会自适应它跑在什么硬件上。这一切外面还套着三层编译产物缓存——磁盘上的已编译核函数,加上用于进程启动的 PTX 层和 fast-cache 层——团队把超过 10 倍的启动加速归因于它,启动时间从几分钟降到几秒。数据侧,张量有两种可互换类型:field 追求运行时峰值吞吐,ndarray 追求快速启动与编译,可通过统一封装在运行时切换。核函数接受可嵌套的 Python dataclass,里面可以同时装这两种;张量通过 DLPack 与 PyTorch 共享设备内存;在 Metal 上还与 PyTorch 共享一条命令队列,因此零拷贝不会带来同步开销。
对用户来说,能直接感知到的后果是核函数缓存行为。用一个新的场景配置第一次构建时会现场编译核函数,很慢;之后同样配置的运行从缓存加载,启动就快了——前提是第一次运行是正常退出或用 Ctrl-C 退出,而不是 Ctrl-\。
传感器、资产,以及一个很小的 API 面
仿真接口层是大多数用户实际生活的地方。每个 Genesis World 程序都从一个调用开始——gs.init():它选定算力后端、固定数值精度、给随机数发生器播种、配置日志。gs.gpu 的后端解析顺序是 CUDA、AMD、Metal、CPU,取第一个能初始化的,全部失败则退回 CPU 并给出警告,而不是直接报错。精度默认 32 位,刚度大或病态的场景用 precision="64",不过 Apple Metal 上不支持双精度,整数索引则始终是 32 位。有一个旋钮值得知道:performance_mode=True 会把静态张量形状烧进已编译的核函数,仿真大约快 30%,代价是场景一变就要重新编译好几分钟。研究和交互开发时关掉它,策略训练和生产运行时打开。
实体由 morph 创建——morph 是几何与初始位姿的合并描述——既可以来自基本体(Plane、Box、Cylinder、Sphere、Terrain、Drone),也可以来自文件:MJCF、URDF(.xacro 会自动预处理)、.usd/.usda/.usdc/.usdz 格式的 USD,以及 .obj/.stl/.glb/.gltf 的非铰接网格(支持 Draco 压缩)。相对路径会同时在工作目录和项目自带的 genesis/assets 目录树下解析,所以 xml/franka_emika_panda/panda.xml 加载的就是随项目发布的那台 Franka。URDF 的基座默认是自由的(MJCF 会指定基座关节,URDF 不会),在你传 fixed=True 之前这是一个实实在在的坑。
传感器覆盖面很广,三个渲染器都通过同一套相机传感器接口暴露出来。目录树里的传感器模块有 camera、depth_camera、imu、raycaster(激光雷达)、contact_force、joint_torque、kinematic_tactile、point_cloud_tactile、probe、surface_distance_probe 和 temperature,由一个 sensor_manager 统一管理。过去一年里,点云触觉、温度栅格和接近度传感器加入了原有的 FOTS 弹性体位移、磁力计 IMU 与接触探针阵列。控制器覆盖 control_dofs_position、control_dofs_force、逐自由度的 kp/kv 与力范围、批量逆运动学,以及一个 Diff-IK 控制器示例。GUI 侧随包提供 ImGui 关节控制、调试绘制、网格点选择器和鼠标交互,都以 viewer 插件的形式存在。
资产生产被当成一条独立流水线来做。摄影测量流水线把多视角采集——可以用自研 iOS 应用、数码相机,或带 VIO 位姿作为初值的现成设备——变成精确的三维地图,再从原始图像和位姿端到端训练出网格与高斯泼溅。两者都供 Nyx 渲染、供 Genesis 做物理。在重建之上,还有一条程序化流水线生成仿真环境,包括场景布局、资产选择、环境代码和成功判据,因此复杂环境可以被自动搭出来。
并行环境与异构环境,以及它们量出了什么
单个环境喂不饱一块 GPU,所以 Genesis World 一次步进同一个场景的许多副本。并行不是实体的属性:你按单环境教程里那样描述平面和机械臂,然后在构建时选择副本数量。
gs.init(backend=gs.gpu)
scene = gs.Scene(show_viewer=False)
plane = scene.add_entity(gs.morphs.Plane())
franka = scene.add_entity(gs.morphs.MJCF(file="xml/franka_emika_panda/panda.xml"))
# 20 个并行环境;env_spacing 只影响 viewer 里的布局
B = 20
scene.build(n_envs=B, env_spacing=(1.0, 1.0))
franka.control_dofs_position(
torch.tile(torch.tensor([0, 0, 0, -1.0, 0, 1.0, 0, 0.02, 0.02], device=gs.device), (B, 1)),
)
# 把一条指令收窄到部分环境
franka.control_dofs_position(
torch.zeros(3, 9, device=gs.device),
envs_idx=torch.tensor([1, 5, 7], device=gs.device),
)
一旦 n_envs > 0,每个按环境计的量都会多出一个前置批次维,文档里用方括号记法 ([n_envs,] ...) 标注。对这台 9 自由度的 Franka,get_dofs_position() 返回 (20, 9)。envs_idx 参数在状态读取方法以及所有 control_dofs_*、set_dofs_* 方法上都可用——训练中各环境在不同时刻结束 episode 时,你需要的正是这个模式。张量应当在 gs.device 上构建,避免主机到设备的拷贝,那是大批量下的主要开销。
被引用最多的就是吞吐量那条主张,而仓库里的基准脚本把条件写得很明确。它在 GPU 后端上以 performance_mode=True 跑 30,000 个并行环境(平面上的 Franka),源码注释记录了施加位置控制时 43M FPS、不施加时 32M FPS(不施加时机械臂与地面处于碰撞状态)。文档另外说明单块 GPU 支持数万个环境,理念页则声称吞吐量最高是此前 GPU 加速仿真器(如 Isaac Gym/Sim/Lab 和 MuJoCo MJX)的 10-80 倍,并把方法论交给博客文章而不是在文中断言。
异构仿真再往前走一步:不同的并行环境可以装同一实体的不同几何变体。给 add_entity() 传一个 morph 列表时,当 n_envs >= n_variants,变体按均衡分块分配到各环境(4 个变体配 8 个环境,变体 0-3 成对分布);当 n_envs < n_variants,第 i 个环境拿第 i 个变体,多出来的变体不使用。示例在一个批次里对所有环境跑抓取-抬起,每个环境各自做 IK,物件的尺寸和形状各不相同。
横向扩展是第二条独立的轴,而给出的建议很保守:等第一块 GPU 饱和了再加第二块。Genesis World 不会把单个场景切到多块 GPU 上;每个进程初始化自己的运行时、构建自己的场景,并通过 CUDA_VISIBLE_DEVICES、QD_VISIBLE_DEVICE(为 Quadrants 选 GPU)和用于离屏渲染的 EGL_DEVICE_ID 钉死在恰好一块设备上——这些都要在 gs.init() 之前设好。训练方面,examples/rigid/ddp_multi_gpu.py 用 PyTorch DDP 配 torchrun --standalone --nnodes=1 --nproc_per_node=2,每个 rank 一个完整场景,并按 rank 给 Genesis 播种,使各 GPU 上的环境互不相关。有效批量等于单卡 n_envs 乘以 GPU 数量。强化学习通过外部库接入:运动示例用 rsl-rl 的 OnPolicyRunner 和 PPO 训练一台宇树 Go2(clip 0.2、自适应 KL 0.01、GAE 取 gamma 0.99 与 lambda 0.95,actor 与 critic 都是 512-256-128 的 MLP,每环境 24 步)。
结果可信吗?主张背后的那些数字
这个平台的核心主张是关于评测成本的,而且它是被量化的,不是被断言的。Genesis AI 一次典型的模型评测要横跨数百个任务,每个任务重复数百个 episode。在真实世界里,一名操作员加一个机器人工作站,单跑一遍评测累计就是 200 多个小时的连续作业,而要在多个 checkpoint 之间做出统计上有意义的比较,需要跑很多遍。在仿真里,同样的数万个 episode 不到 0.5 小时就跑完——快两个数量级——不需要人或硬件在回路里,而且跨次运行结果逐位一致。
团队给自己定的标准是零样本 real-to-sim:在仿真里被评测的策略只用真实世界数据训练,让训练与评测两条工作流解耦。这样分离的理由是方法论上的。当训练和评测共用同一个仿真分布时,一次提升可能意味着配方真的更好,也可能只意味着对仿真器动力学的拟合更紧。把两条流水线分开,才能对"哪些实验真的提升了模型性能"给出更干净的信号。
| 指标 | 数值 | 95% 置信区间 | 含义 |
|---|---|---|---|
| 皮尔逊相关系数(仿真 vs 真实) | 0.8996 | [0.7439, 0.9314] | 仿真能跟上真实世界的性能趋势 |
| MMRV(平均最大排序违背) | 0.0166 | [0.0102, 0.0474] | 仿真保住了模型之间的排序 |
| 基于 FID 的 reality gap | 小 45% | 对比次优的替代仿真器 | 渲染出的图像更贴近真实分布 |
| 单遍评测的墙钟时间 | < 0.5 小时 vs > 200 小时 | 两个数量级 | 评测不再是迭代的瓶颈 |
这些数字背后的实验协议值得仔细读,因为那正是区分营销主张与工程结果的地方。三个规模与架构各不相同的模型(Small、Medium、Large)在 14 个任务上被评测,每个任务 200 个 episode,真实世界和仿真各跑一遍。相关性指标用 1,000,000 次 bootstrap 迭代算出置信区间;每个数据点都连同它的 bootstrap 分布一起可视化,并叠上 500 条采样回归线,用以展示相关系数估计的不确定性。MMRV 来自 SimplerEnv。团队还指出,开环指标(在固定数据集上动作预测的 R 平方与平均绝对误差)一旦落进一个窄带内,就不再反映真实世界的性能差异——开环分数能抓住突变、可以当健全性检查,但真正携带信息的是闭环指标。
定位差距靠的是仪器化,而不是猜。一套遥测系统加一个实时并排(side-by-side)装置让仿真器和真实机器人从同一初始化并行运行;这个装置允许你独立选择策略输入的来源:相机帧、本体感受等观测可以来自仿真器、来自机器人,或来自两者可调比例的混合。一次只换一个组件,看分歧在哪里出现,就能把差距归因到某一层——物理、渲染、通信还是控制——而不是把一切塌缩成一个二值的成功/失败结果。团队调过的三层是:视觉保真度(材质属性、光照模型、相机特性)、机器人运动学与动力学(关节行为、摩擦、接触),以及底层控制(忠实复刻真实机载控制器,包括时序、延迟和通信特性)。
确定性、回放,以及一个便于报 bug 的 CLI
可复现性是被工程出来的,不是被指望出来的。1.3.2 版让仿真在同一台机器上对 CPU 和 GPU 都完全确定,1.3.3 版加了一个类 torch 的 use_deterministic_algorithms 选项以实现逐位可复现。1.4.0 版走得更远:一个场景加一条完整轨迹可以导出成独立归档,在任何机器上加载,并通过 gs replay 保证逐位一致的回放,明说的目标是让报 bug 容易得多。Scene.export() 写出场景是被什么创作出来的、以及它的构建解析成了什么,所以文件能自足——打开它不会从磁盘读任何网格、模型文件或纹理。save_checkpoint() 则把场景加上每一个仿真数组(包括 scratch)写成单帧的 .gstraj,load_trajectory() 可以打开它。
导出支持的范围说得很老实:今天只有刚体和运动学实体带描述,场景里若含任何会改变仿真的东西(发射器、力场)会抛错并点名它;而描述里省略掉的那些(相机、传感器、逐步回调、HDR/EXR 纹理、运行时可视化顶点)会被写出来,同时给一条警告。这一时期刚体求解器的接触精度也有提升。1.3.1 版引入 contact_resolution,新默认值是 gs.contact_resolution.signorini,它按接触实际发展出的法向力来约束摩擦,于是法向力不再被摩擦系数或滑动速度带偏。1.3.3 版改进了 MuJoCo 兼容模式,覆盖原生的基于接触块(contact patch)的多点接触,取代旧的基于扰动的做法,通过 RigidOptions.enable_contact_patch 暴露。
这个包安装了一个 gs 控制台入口,带四个子命令:gs launch 可视化一个资产(Mesh/URDF/MJCF/USD),可配碰撞几何、旋转、缩放和连杆坐标系等开关;gs play 打开带 ImGui 关节控制和仿真的交互式 viewer;gs replay 在 viewer 里回放录制的 .gstraj 轨迹;gs animate 把一批图片文件按给定帧率编成视频。gs view 作为 launch 的弃用别名保留。
从仓库里读得到的工程纪律
仓库里有两份文档,比功能列表更能说明这个项目是怎么维护的。CODING_GUIDELINES.md 和开发指南文件写下的规则具体得不寻常,其中好几条直接关乎测试的诚实性。
- 永远不要为了让一个失败的测试通过而放宽容差,也永远不要把偏差当成浮点噪声打发掉。fp32 的舍入量级在 1e-6;一个数学上应当精确的量漂了 5e-3,就意味着某处丢了一项或算错了一项。为了让测试绕开失败而限制它的后端或参数化组合,等同于变相放宽容差。
- 断言物理,不要断言执行。"仿真跑起来没报错"不算测试。期望值要解析推导:自由落体位移 $z = z_0 - \tfrac{1}{2}gt^2$、不穿透地面、静止时速度衰减到零、接触能止住下落。
- 打包测试:一个测试只构建一次场景。一次 build 要重新编译核函数,本地约 18 秒,CI 上要几分钟,所以哪怕测试因此更难读,也必须避免多余的 build。批处理行为按
n_envs=[0, 2]参数化,因为形状 bug 就藏在多环境里。 - 步数预算是硬的。100 步以内没问题;100 到 300 步需要给出理由;300 步以上近乎禁止,整个测试套件里只留给四五个测试,并且总的环境步数也有上限,因为 CI 成本会把每一步在整个矩阵上乘一遍。
- MuJoCo 对齐是被认可的例外。
enable_mujoco_compatibility(默认关)让刚体求解器在浮点容差内复现 MuJoCo 的动力学,于是 Genesis 可以充当自己的基线:切换这个开关就能证明一个更快的替代实现积分到了同一状态。这个模式只用于验证、绝不用于生产,所以它必须对得上,而不必快。 - 梯度容差钉在实测下限上。在配置的 epsilon 处测出下限 $T = \max|\text{ana} - \text{fd}| / (1 + |\text{fd}|)$,取 CPU 与两种 GPU 架构里最差的那个(它们的 fp32 下限可以差 4 倍);容差取下限的 1.5 到 5 倍,数值限定在 {1, 2, 5}e-X。下限恰好为零意味着这项检查是空的,那就去修 loss,而不是修容差。
代码层面的规则同样有主见,读起来像伤疤组织:getattr/hasattr 被禁用,改用 None 初始化加 isinstance 判断;用普通 dict 打包属性被禁用,改用 dataclass 或 NamedTuple;除多进程里的异常转发之外,禁用兜底 except;内存分配必须精确尺寸,禁止按最大尺寸预分配;NaN 通过 errno 机制直接让仿真停下,因为给一条警告是不可接受的;遗留层和弃用层要被删掉而不是背着走;领域名词限定为 entity、link、geom——当这三个之一能表达时,绝不发明 "body"、"object" 或 "piece",这同时是一条正确性提示,因为刚体的单位就是 link。核函数签名遵循一套规范的参数顺序(索引,然后是动态标量与固定尺寸向量,然后是张量,然后是状态结构体,然后是信息结构体,然后是静态配置,然后是编译期开关,errno 放最后)。
测试套件映射了同样的结构:按组件分文件夹(rigid/ 18 个文件、sensors/ 10 个、grad/ 9 个、core/ 8 个、rendering/ 8 个、ipc/ 5 个、particles/ 5 个、parsers/ 4 个、coupling/ 3 个、deformable/ 3 个,外加 benchmarks/ 和 integration/),一个能力一个文件,新增覆盖要加进已经覆盖它的那个测试里,而不是新开一个同级函数。修 bug 的 PR 必须带一个回归测试,在 main 上失败、带上修复后通过。依赖锁定并把理由写在行内——dev 依赖里 MuJoCo 被限制在 >=3.10.0,<3.11.0,因为 3.10.0 把原始求解器与 Genesis 对齐了(Hager-Zhang CG 更新、带偏移的线搜索代价),而逐步求解器一致性测试只有在两个引擎跑同一个算法时才成立。
安装、可选组件,以及它要往哪走
装好 PyTorch 之后,安装是一条命令:Python 3.10 到 3.13 用 pip install genesis-world,贡献者从克隆里用 pip install -e ".[dev]"——文档建议每次 HEAD 移动后重跑一遍,让依赖和入口点保持最新。uv sync 也可以。两个可选组件:pip install pyuipc 装 IPC 求解器后端(Linux / Windows x86,NVIDIA GPU),pip install gs-nyx 装 Nyx 渲染器。Quadrants 自动捆绑;另外也有独立的 pip install quadrants wheel,给想在 Genesis 之外单独用这个编译器的用户。
122 个示例的目录组织映射了那几个层次:物理(rigid 37 个、coupling 12 个、IPC 6 个、SAP coupling 5 个、deformable 5 个、collision 5 个、fluid 2 个),渲染(仓库内 6 个相机设置示例,Nyx 的教程放在 genesis-nyx 仓库里),仿真接口(sensors 11 个、drone 9 个、locomotion 7 个、manipulation 5 个、viewer 插件 4 个、GUI 2 个、速度基准 4 个)。可编辑安装之后大多数示例能端到端跑通;IPC 和 Nyx 的示例需要装对应的可选组件。
下一步明说了三个方向。第一,用扩展仿真环境来扩展后训练:闭环评测变成一个供探索用的数据引擎,模型尝试任务、失败、被打分、在数百万次迭代和数千个并行任务中改进,仿真器同时充当环境和评审——这正是大规模强化学习在大语言模型研发中走过的路子。第二,混合仿真器。今天的 Genesis World 是经典且启发式的,这带来对每一层的完全可控与可观测:每个旋钮都是显式的,每个行为都能被检视、修改和归因。学习式仿真器进展很快,但它大量状态仍是隐式且无据可查的,那正是经典仿真器仍然更强的地方。计划是以数据驱动的方式把两者合起来:经典仿真带来接地(grounding),学习到的世界模型带来规模与真实感。第三,自演化的物理 AI 作为北极星:仿真里的内循环,智能体生成环境、模型行动、仿真器打分、策略改进;真实世界里的外循环,部署暴露出的边缘情况反过来重新标定仿真器,并被折叠回任务分布。研究者平时会去动的每一个变量——数据配比、架构、奖励、课程、新环境——只要每次改动都可验证,就都变成智能体可调的东西。
许可证是 Apache 2.0,致谢里点名了这项工作所站立的项目:Quadrants 分叉自的 Taichi;IPC 后端 libuipc;作为 MPM 与 SPH 参考实现的 FluidLab 和 SPH_Taichi;PBD 方面的 Ten Minute Physics 与 PBF3D;刚体动力学的 MuJoCo 与碰撞检测的 libccd;光栅化的 PyRender;光线追踪 DSL 的 LuisaCompute 与 LuisaRender;以及作为批渲染后端的 Madrona 与 Madrona-mjx。提供了两条引用:Genesis World 1.0 引 2026 年 5 月的 Genesis AI 博客,而它生长出来的那个学术项目引 2024 年 12 月的原始 Genesis 条目。