kaarelkaarelson/lingbot-world-v2-realtime

1.3B world model running at 16 FPS on an RTX 5090

Python

0

108 commits

updated Sep 18, 2026

See the code

See what people are saying (1)

README

LingBot-World 2.0 realtime

Blog  ·  Original paper

A 1.3B world model running at 16.1 FPS on one RTX 5090. 2.7× faster than the original paper's code with lossless performance.

lingbot play dragon at 16 fps

Performance vs other engines

Engines / chunkFPSOurs vs it
Original paper's code2.686.02.7×
SGLang Diffusion2.486.452.5×
LightX2V2.077.732.1×
NVIDIA FlashDreams1.858.651.9×
Ours0.9816.1

the same clip at each engine's measured cadence

Measured with lingbot bench on a stock RunPod RTX 5090 (2026-09-17).

Quick start

Setup

~15 min on Linux, needs a Hugging Face token to download the weights.

git clone https://github.com/kaarelkaarelson/lingbot-world-v2-realtime
cd lingbot-world-v2-realtime
HF_TOKEN=hf_... ./setup.sh && . .venv/bin/activate

Play

lingbot play dragon

The first start compiles for about 2.5 min, later starts take 35 s.

Commands

KeyAction
W A S Dmove (hold Shift to run)
Q Edown / up
look (45°/s); mouse drag also looks
Rrestart the world from the image
Escquit

Scripts

Script
lingbot play [scene]a window on the world; scenes: lake (default), wall, stonehenge, alley, castle, dragon
lingbot play --image me.jpg --prompt "..."your own world from any image
SDL_VIDEODRIVER=dummy lingbot play --headless-seconds 120no display (a cloud pod): same model, no window, taps W and prints the HUD summary
lingbot benchthe 22 s clip to outputs/, prints s/chunk and FPS
lingbot clip --image me.jpg --action_path my_poses/ --prompt "..."offline generation from a camera path, poses.npy and intrinsics.npy as in examples/

Requirements

GPU
RecommendedRTX 5090, 32 GBeverything here was measured on it; setup.sh ships prebuilt kernels for it (sm_120)
MinimumRTX 4090, 24 GBuntested: every patch supports sm_89, expect ~12 FPS; needs sageattention and flash_attn built from source and T5 on the CPU to fit

Optimizations

Nothing about the model changed. The checkpoint, the sampler and the decoder are upstream's, with the same 4 steps, chunks of 4 latents and a KV window of 18 frames. I worked through the stack from the top down, cheapest and most general layer first, measured each step, and stopped at the kernel boundary. The table shows seconds per chunk after each step in the order they were applied. A chunk is 16 frames, one second of video.

StepBeforeAfters/chunk
Host syncsCPU↔GPU sync on every layerbookkeeping on the GPU2.68 → 2.57
DecoderWan 2.1 VAE in fp32fp16 with sub-pixel upsampling2.57 → 1.95
CompilerPyTorch eagerone compiled graph1.95 → 1.68
Matmulsbf16 linearsFP8 rowwise via torchao1.68 → 1.47
AttentionFlashAttention-2SageAttention 2.21.47 → 1.04
Kernel fusionone kernel per operationfused kernels for norm, RoPE, residual and FP8 quant1.04 → 0.98
Total6.0 FPS16.1 FPS2.68 → 0.98

The table compares the original paper's code with ours, per chunk. GPU busy and kernel launches come from profiler traces of both, described in sections 13 and 17 of OPTIMIZATIONS.md. Host syncs are counted over three chunks.

Original paper's codeOurs
FPS6.016.1
s / chunk2.680.98
DiT1.62 s0.64 s
Decoder1.06 s0.34 s
GPU busy90%98%
Kernel launches~20,000~4,800
Host syncs1102

What is left runs in four kernels written by others, and three of them are near the card's peak. Attention has the most room. A hand written kernel at 90 % of peak would gain about one frame per second, so there is none. The details are in section 17 of OPTIMIZATIONS.md. The peaks are from NVIDIA's RTX 5090 specification.

KernelReachedPeak on RTX 5090of peak
FP8 matmuls390 TFLOP/s419 TFLOP/s FP890 %
Decoder convolutions173 TFLOP/s210 TFLOP/s FP1683 %
Fused elementwise~1.3 TB/s1.8 TB/s memory~70 %
SageAttention543 TOPS838 TOPS INT865 %

The result is lossless. Four of the six steps are bit identical to the paper's code, and FP8 and the attention kernel were checked on identical inputs. PSNR, SSIM and LPIPS compare the same latents decoded by the paper's fp32 decoder and by ours. The rest are no reference metrics on the generated clips, measured on the first and last second. The numbers are in quality_summary.tsv from experiment 15.

Original paper's codeOurs
PSNRreference43.6 dB
SSIMreference0.981
LPIPSreference0.004
MUSIQ68.9868.99
CLIP-IQA0.5920.590
Sharpness (Laplacian), first / last s1022 / 2981023 / 298
Colourfulness, first / last s41.9 / 50.241.9 / 50.2
Brightness, first / last s0.692 / 0.3840.692 / 0.384
Flicker0.03810.0381
DiT latents, exact presetreferencebit-identical

OPTIMIZATIONS.md is the full log. It has every experiment with its measurement, the profiles, and the levers that were tried and rejected.

Presets

--presetWhat runss / chunkFPS
stockthe original paper's code2.686.0
exactours, with the DiT latents bit identical to the paper's bf16 model1.0714.8
fast (default)ours, FP8 linears, SageAttention, compiled and fused DiT, fused fp16 decoder0.9816.1

Tests

pytest tests/ runs on the CPU, no GPU needed. It checks the fused decoder and DiT against the stock modules and runs lingbot play --dry on a stand in model.

License and credit

This repository is derived from LingBot-World 2.0 by the Robbyant team, whose paper is by Zelin Gao and others. The model, the sampler and the examples are theirs. The weights are theirs too and are not redistributed here. Upstream is licensed under CC BY-NC-SA 4.0, and so is this repository, see LICENSE.txt. That means non commercial use, attribution, and the same license for anything built on it. It is provided as is, without warranty. My changes are the inference patches listed under Optimizations and the lingbot CLI, applied on upstream commit 1895d30. The wan/ directory is upstream's copy of Wan2.2, which is Apache 2.0. The kernels used are SageAttention, torchao and FlashAttention.

@article{lingbot-world-v2,
  title   = {Infinite Worlds with Versatile Interactions},
  author  = {Zelin Gao and Qiuyu Wang and Jiapeng Zhu and Jingye Chen and Zichen Liu and Qingyan Bai and Jiahao Wang and Yufeng Yuan and Hanlin Wang and Yichong Lu and Ka Leong Cheng and Haojie Zhang and Jian Gao and Tianrui Feng and Yuzheng Liu and Yao Yao and Yinghao Xu and Xing Zhu and Yujun Shen and Hao Ouyang},
  journal = {arXiv preprint arXiv:2607.07534},
  year    = {2026}
}

Contributors

kaarelkaarelson

92 commits

qiuyu96

4 commits

zelingao98

3 commits

zhujiapeng

2 commits

kaarelkaarelson/lingbot-world-v2-realtime

1.3B world model running at 16 FPS on an RTX 5090

Python

0

108 commits

updated Sep 18, 2026

See the code

See what people are saying (1)

README

LingBot-World 2.0 realtime

Blog  ·  Original paper

A 1.3B world model running at 16.1 FPS on one RTX 5090. 2.7× faster than the original paper's code with lossless performance.

lingbot play dragon at 16 fps

Performance vs other engines

Engines / chunkFPSOurs vs it
Original paper's code2.686.02.7×
SGLang Diffusion2.486.452.5×
LightX2V2.077.732.1×
NVIDIA FlashDreams1.858.651.9×
Ours0.9816.1

the same clip at each engine's measured cadence

Measured with lingbot bench on a stock RunPod RTX 5090 (2026-09-17).

Quick start

Setup

~15 min on Linux, needs a Hugging Face token to download the weights.

git clone https://github.com/kaarelkaarelson/lingbot-world-v2-realtime
cd lingbot-world-v2-realtime
HF_TOKEN=hf_... ./setup.sh && . .venv/bin/activate

Play

lingbot play dragon

The first start compiles for about 2.5 min, later starts take 35 s.

Commands

KeyAction
W A S Dmove (hold Shift to run)
Q Edown / up
look (45°/s); mouse drag also looks
Rrestart the world from the image
Escquit

Scripts

Script
lingbot play [scene]a window on the world; scenes: lake (default), wall, stonehenge, alley, castle, dragon
lingbot play --image me.jpg --prompt "..."your own world from any image
SDL_VIDEODRIVER=dummy lingbot play --headless-seconds 120no display (a cloud pod): same model, no window, taps W and prints the HUD summary
lingbot benchthe 22 s clip to outputs/, prints s/chunk and FPS
lingbot clip --image me.jpg --action_path my_poses/ --prompt "..."offline generation from a camera path, poses.npy and intrinsics.npy as in examples/

Requirements

GPU
RecommendedRTX 5090, 32 GBeverything here was measured on it; setup.sh ships prebuilt kernels for it (sm_120)
MinimumRTX 4090, 24 GBuntested: every patch supports sm_89, expect ~12 FPS; needs sageattention and flash_attn built from source and T5 on the CPU to fit

Optimizations

Nothing about the model changed. The checkpoint, the sampler and the decoder are upstream's, with the same 4 steps, chunks of 4 latents and a KV window of 18 frames. I worked through the stack from the top down, cheapest and most general layer first, measured each step, and stopped at the kernel boundary. The table shows seconds per chunk after each step in the order they were applied. A chunk is 16 frames, one second of video.

StepBeforeAfters/chunk
Host syncsCPU↔GPU sync on every layerbookkeeping on the GPU2.68 → 2.57
DecoderWan 2.1 VAE in fp32fp16 with sub-pixel upsampling2.57 → 1.95
CompilerPyTorch eagerone compiled graph1.95 → 1.68
Matmulsbf16 linearsFP8 rowwise via torchao1.68 → 1.47
AttentionFlashAttention-2SageAttention 2.21.47 → 1.04
Kernel fusionone kernel per operationfused kernels for norm, RoPE, residual and FP8 quant1.04 → 0.98
Total6.0 FPS16.1 FPS2.68 → 0.98

The table compares the original paper's code with ours, per chunk. GPU busy and kernel launches come from profiler traces of both, described in sections 13 and 17 of OPTIMIZATIONS.md. Host syncs are counted over three chunks.

Original paper's codeOurs
FPS6.016.1
s / chunk2.680.98
DiT1.62 s0.64 s
Decoder1.06 s0.34 s
GPU busy90%98%
Kernel launches~20,000~4,800
Host syncs1102

What is left runs in four kernels written by others, and three of them are near the card's peak. Attention has the most room. A hand written kernel at 90 % of peak would gain about one frame per second, so there is none. The details are in section 17 of OPTIMIZATIONS.md. The peaks are from NVIDIA's RTX 5090 specification.

KernelReachedPeak on RTX 5090of peak
FP8 matmuls390 TFLOP/s419 TFLOP/s FP890 %
Decoder convolutions173 TFLOP/s210 TFLOP/s FP1683 %
Fused elementwise~1.3 TB/s1.8 TB/s memory~70 %
SageAttention543 TOPS838 TOPS INT865 %

The result is lossless. Four of the six steps are bit identical to the paper's code, and FP8 and the attention kernel were checked on identical inputs. PSNR, SSIM and LPIPS compare the same latents decoded by the paper's fp32 decoder and by ours. The rest are no reference metrics on the generated clips, measured on the first and last second. The numbers are in quality_summary.tsv from experiment 15.

Original paper's codeOurs
PSNRreference43.6 dB
SSIMreference0.981
LPIPSreference0.004
MUSIQ68.9868.99
CLIP-IQA0.5920.590
Sharpness (Laplacian), first / last s1022 / 2981023 / 298
Colourfulness, first / last s41.9 / 50.241.9 / 50.2
Brightness, first / last s0.692 / 0.3840.692 / 0.384
Flicker0.03810.0381
DiT latents, exact presetreferencebit-identical

OPTIMIZATIONS.md is the full log. It has every experiment with its measurement, the profiles, and the levers that were tried and rejected.

Presets

--presetWhat runss / chunkFPS
stockthe original paper's code2.686.0
exactours, with the DiT latents bit identical to the paper's bf16 model1.0714.8
fast (default)ours, FP8 linears, SageAttention, compiled and fused DiT, fused fp16 decoder0.9816.1

Tests

pytest tests/ runs on the CPU, no GPU needed. It checks the fused decoder and DiT against the stock modules and runs lingbot play --dry on a stand in model.

License and credit

This repository is derived from LingBot-World 2.0 by the Robbyant team, whose paper is by Zelin Gao and others. The model, the sampler and the examples are theirs. The weights are theirs too and are not redistributed here. Upstream is licensed under CC BY-NC-SA 4.0, and so is this repository, see LICENSE.txt. That means non commercial use, attribution, and the same license for anything built on it. It is provided as is, without warranty. My changes are the inference patches listed under Optimizations and the lingbot CLI, applied on upstream commit 1895d30. The wan/ directory is upstream's copy of Wan2.2, which is Apache 2.0. The kernels used are SageAttention, torchao and FlashAttention.

@article{lingbot-world-v2,
  title   = {Infinite Worlds with Versatile Interactions},
  author  = {Zelin Gao and Qiuyu Wang and Jiapeng Zhu and Jingye Chen and Zichen Liu and Qingyan Bai and Jiahao Wang and Yufeng Yuan and Hanlin Wang and Yichong Lu and Ka Leong Cheng and Haojie Zhang and Jian Gao and Tianrui Feng and Yuzheng Liu and Yao Yao and Yinghao Xu and Xing Zhu and Yujun Shen and Hao Ouyang},
  journal = {arXiv preprint arXiv:2607.07534},
  year    = {2026}
}

Contributors

kaarelkaarelson

92 commits

qiuyu96

4 commits

zelingao98

3 commits

zhujiapeng

2 commits

Languages

Python

94.7%

Shell

5.3%