| name | kimodo-motion-diffusion |
| description | Generate high-quality 3D human and humanoid robot motions using Kimodo, a kinematic motion diffusion model controlled via text prompts and kinematic constraints. |
| triggers | ["generate human motion with text prompt","create robot animation with diffusion model","use kimodo to generate walking motion","add keyframe constraints to motion generation","generate G1 robot motion for mujoco","control end effector position in motion","run kimodo interactive demo","export motion to AMASS or qpos format"] |
Kimodo Motion Diffusion
Skill by ara.so — Daily 2026 Skills collection.
Kimodo is a kinematic motion diffusion model trained on 700 hours of commercially-friendly optical mocap data. It generates high-quality 3D human and humanoid robot motions controlled through text prompts and kinematic constraints (full-body keyframes, end-effector positions/rotations, 2D paths, 2D waypoints).
Installation
git clone https://github.com/nv-tlabs/kimodo.git
cd kimodo
pip install -e .
docker build -t kimodo .
docker run --gpus all -p 7860:7860 kimodo
Requirements:
- ~17GB VRAM (GPU: RTX 3090/4090, A100 recommended)
- Linux (Windows supported via Docker)
- Models download automatically on first use from Hugging Face
Available Models
| Model | Skeleton | Dataset | Use Case |
|---|
Kimodo-SOMA-RP-v1 | SOMA (human) | Bones Rigplay 1 (700h) | General human motion |
Kimodo-G1-RP-v1 | Unitree G1 (robot) | Bones Rigplay 1 (700h) | Humanoid robot motion |
Kimodo-SOMA-SEED-v1 | SOMA | BONES-SEED (288h) | Benchmarking |
Kimodo-G1-SEED-v1 | Unitree G1 | BONES-SEED (288h) | Benchmarking |
Kimodo-SMPLX-RP-v1 | SMPL-X | Bones Rigplay 1 (700h) | Retargeting/AMASS export |
CLI: kimodo_gen
Basic Text-to-Motion
kimodo_gen "a person walks forward at a moderate pace"
kimodo_gen "a person jogs in a circle" --duration 5.0 --num_samples 3
kimodo_gen "a robot walks forward" --model Kimodo-G1-RP-v1 --duration 4.0
kimodo_gen "a person waves their right hand" --model Kimodo-SMPLX-RP-v1
kimodo_gen "a person sits down slowly" --seed 42
kimodo_gen "a person does a jumping jack" --diffusion_steps 50
Output Formats
kimodo_gen "a person walks" --output ./outputs/walk.npz
kimodo_gen "robot walks forward" --model Kimodo-G1-RP-v1 --output ./outputs/walk.csv
kimodo_gen "a person waves" --model Kimodo-SMPLX-RP-v1 --output ./outputs/wave.npz
kimodo_gen "a person walks" --no-postprocess
Multi-Prompt Sequences
kimodo_gen "a person stands still" "a person walks forward" "a person stops and turns"
kimodo_gen "a person jogs" "a person slows to a walk" "a person stops" \
--duration 8.0 --num_samples 2
Constraint-Based Generation
kimodo_gen "a person walks to a table and picks something up" \
--constraints ./my_constraints.json
kimodo_gen "a person performs a complex motion" \
--constraints ./keyframe_constraints.json \
--model Kimodo-SOMA-RP-v1 \
--num_samples 5
Interactive Demo
kimodo_demo
kimodo_demo --server-name 0.0.0.0 --server-port 7860
The demo provides:
- Timeline editor for text prompts and constraints
- Full-body keyframe constraints
- 2D root path/waypoint editor
- End-effector position/rotation control
- Real-time 3D visualization with skeleton and skinned mesh
- Export of constraints as JSON and motions as NPZ
Low-Level Python API
Basic Model Inference
from kimodo.model import Kimodo
model = Kimodo(model_name="Kimodo-SOMA-RP-v1")
result = model(
prompts=["a person walks forward at a moderate pace"],
duration=4.0,
num_samples=1,
seed=42,
)
print(result["posed_joints"].shape)
print(result["global_rot_mats"].shape)
print(result["local_rot_mats"].shape)
print(result["foot_contacts"].shape)
print(result["root_positions"].shape)
Advanced API with Guidance and Constraints
from kimodo.model import Kimodo
import numpy as np
model = Kimodo(model_name="Kimodo-SOMA-RP-v1")
result = model(
prompts=["a person stands", "a person walks forward", "a person sits"],
duration=9.0,
num_samples=3,
diffusion_steps=50,
guidance_scale=7.5,
seed=0,
)
for i in range(3):
joints = result["posed_joints"][i]
print(f"Sample {i}: {joints.shape}")
Working with Constraints Programmatically
from kimodo.model import Kimodo
from kimodo.constraints import ConstraintSet, FullBodyKeyframe, EndEffectorConstraint
import numpy as np
model = Kimodo(model_name="Kimodo-SOMA-RP-v1")
constraints = ConstraintSet()
keyframe_pose = np.zeros((model.num_joints, 3))
constraints.add_full_body_keyframe(frame=30, joint_positions=keyframe_pose)
constraints.add_end_effector(
joint_name="right_hand",
frame_start=45,
frame_end=60,
position=np.array([0.5, 1.2, 0.3]),
rotation=None,
)
constraints.add_root_waypoints(
waypoints=np.array([[0, 0], [1, 0], [1, 1], [0, 1]]),
)
result = model(
prompts=["a person walks in a square"],
duration=6.0,
constraints=constraints,
num_samples=2,
)
Loading and Using Saved Constraints
from kimodo.model import Kimodo
from kimodo.constraints import ConstraintSet
import json
model = Kimodo(model_name="Kimodo-SOMA-RP-v1")
with open("constraints.json") as f:
constraint_data = json.load(f)
constraints = ConstraintSet.from_dict(constraint_data)
result = model(
prompts=["a person performs a choreographed sequence"],
duration=8.0,
constraints=constraints,
)
Saving and Loading Generated Motions
import numpy as np
result = model(prompts=["a person walks"], duration=4.0)
np.savez("walk_motion.npz", **result)
data = np.load("walk_motion.npz")
posed_joints = data["posed_joints"]
global_rot_mats = data["global_rot_mats"]
local_rot_mats = data["local_rot_mats"]
foot_contacts = data["foot_contacts"]
root_positions = data["root_positions"]
smooth_root_pos = data["smooth_root_pos"]
global_root_heading = data["global_root_heading"]
Robotics Integration
MuJoCo Visualization (G1 Robot)
kimodo_gen "a robot walks forward and waves" \
--model Kimodo-G1-RP-v1 \
--output ./robot_walk.csv \
--duration 5.0
python -m kimodo.scripts.mujoco_load
import mujoco
import numpy as np
CSV_PATH = "./robot_walk.csv"
MJCF_PATH = "./assets/g1/g1.xml"
qpos_data = np.loadtxt(CSV_PATH, delimiter=",")
model = mujoco.MjModel.from_xml_path(MJCF_PATH)
data = mujoco.MjData(model)
with mujoco.viewer.launch_passive(model, data) as viewer:
for frame_qpos in qpos_data:
data.qpos[:] = frame_qpos
mujoco.mj_forward(model, data)
viewer.sync()
ProtoMotions Integration
kimodo_gen "a person runs and jumps" --model Kimodo-SOMA-RP-v1 \
--output ./run_jump.npz --duration 5.0
GMR Retargeting (SMPL-X to Other Robots)
kimodo_gen "a person performs a cartwheel" \
--model Kimodo-SMPLX-RP-v1 \
--output ./cartwheel.npz
NPZ Output Format Reference
| Key | Shape | Description |
|---|
posed_joints | [T, J, 3] | Global joint positions in meters |
global_rot_mats | [T, J, 3, 3] | Global joint rotation matrices |
local_rot_mats | [T, J, 3, 3] | Parent-relative joint rotation matrices |
foot_contacts | [T, 4] | Contact labels: [L-heel, L-toe, R-heel, R-toe] |
smooth_root_pos | [T, 3] | Smoothed root trajectory from model |
root_positions | [T, 3] | Actual root joint (pelvis) trajectory |
global_root_heading | [T, 2] | Heading direction (2D unit vector) |
T = number of frames (30fps), J = number of joints (skeleton-dependent)
Scripts Reference
python scripts/generate.py "a person walks" --duration 4.0
python -m kimodo.scripts.mujoco_load
kimodo_gen --help
Common Patterns
Batch Generation Pipeline
from kimodo.model import Kimodo
import numpy as np
from pathlib import Path
model = Kimodo(model_name="Kimodo-SOMA-RP-v1")
output_dir = Path("./batch_outputs")
output_dir.mkdir(exist_ok=True)
prompts = [
"a person walks forward",
"a person runs",
"a person jumps in place",
"a person sits down",
"a person picks up an object from the floor",
]
for i, prompt in enumerate(prompts):
result = model(
prompts=[prompt],
duration=4.0,
num_samples=1,
seed=i,
)
out_path = output_dir / f"motion_{i:03d}.npz"
np.savez(str(out_path), **result)
print(f"Saved: {out_path}")
Comparing Model Variants
from kimodo.model import Kimodo
import numpy as np
prompt = "a person walks forward"
models = ["Kimodo-SOMA-RP-v1", "Kimodo-SOMA-SEED-v1"]
results = {}
for model_name in models:
model = Kimodo(model_name=model_name)
results[model_name] = model(
prompts=[prompt],
duration=4.0,
seed=0,
)
print(f"{model_name}: joints shape = {results[model_name]['posed_joints'].shape}")
Troubleshooting
Out of VRAM (~17GB required):
nvidia-smi
kimodo_gen "a person walks" --num_samples 1
kimodo_gen "a person walks" --diffusion_steps 20
Model download issues:
export HF_ENDPOINT=https://huggingface.co
export HUGGINGFACE_HUB_VERBOSITY=debug
export HF_HOME=/path/to/your/cache
Motion quality issues:
- Be specific in prompts: "a person walks forward at a moderate pace" > "walking"
- For complex motions, use the interactive demo to add keyframe constraints
- Increase
--diffusion_steps (default ~20-30, try 50 for higher quality)
- Generate multiple samples (
--num_samples 5) and select the best
- Avoid prompts with extremely fast or physically impossible actions
- The model operates at 30fps; very short durations (<1s) may yield poor results
Foot skating artifacts:
kimodo_gen "a person walks"
kimodo_gen "a person walks" --no-postprocess
Interactive demo not loading:
lsof -i :7860
kimodo_demo --server-port 7861
kimodo_demo --server-name 0.0.0.0 --server-port 7860