Show HN: LingBot-World 2.0 (1.3B) running at 16 FPS on one RTX 5090 Kaarel Kaarelson released LingBot-World 2.0, a 1.3B-parameter world model that runs at 16.1 FPS on a single RTX 5090, 2.7× faster than the original paper's code at 6.0 FPS with no loss of output quality. The speedup comes from a stack of optimizations — GPU-side bookkeeping, an fp16 sub-pixel decoder, a single compiled graph, FP8 rowwise matmuls via torchao, SageAttention 2.2, and fused norm/RoPE/residual/FP8-quant kernels — cutting time per 16-frame chunk from 2.68 s to 0.98 s, raising GPU busy from 90% to 98%, and reducing kernel launches from ~20,000 to ~4,800. The code is available on GitHub, requires a Hugging Face token, and takes about 15 minutes to set up on Linux; the model checkpoint, sampler, and decoder are unchanged from upstream. 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. | Engine | s / chunk | FPS | Ours vs it | |---|---|---|---| | Original paper's code | 2.68 | 6.0 | 2.7× | | SGLang Diffusion | 2.48 | 6.45 | 2.5× | | LightX2V | 2.07 | 7.73 | 2.1× | | NVIDIA FlashDreams | 1.85 | 8.65 | 1.9× | | Ours | 0.98 | 16.1 | — | Measured with lingbot bench on a stock RunPod RTX 5090 2026-09-17 . ~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 lingbot play dragon The first start compiles for about 2.5 min, later starts take 35 s. | Key | Action | |---|---| | W A S D | move hold Shift to run | | Q E | down / up | | ← → ↑ ↓ | look 45°/s ; mouse drag also looks | | R | restart the world from the image | | Esc | quit | | 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 120 | no display a cloud pod : same model, no window, taps W and prints the HUD summary | | lingbot bench | the 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/ | | | GPU | | |---|---|---| | Recommended | RTX 5090, 32 GB | everything here was measured on it; setup.sh ships prebuilt kernels for it sm 120 | | Minimum | RTX 4090, 24 GB | untested: every patch supports sm 89, expect ~12 FPS; needs sageattention and flash attn built from source and T5 on the CPU to fit | 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. | Step | Before | After | s/chunk | |---|---|---|---| | Host syncs | CPU↔GPU sync on every layer | bookkeeping on the GPU | 2.68 → 2.57 | | Decoder | Wan 2.1 VAE https://arxiv.org/abs/2503.20314 in fp32 | fp16 with sub-pixel https://arxiv.org/abs/1609.05158 upsampling | 2.57 → 1.95 | | Compiler | PyTorch eager | one compiled graph | 1.95 → 1.68 | | Matmuls | bf16 linears | FP8 rowwise via torchao https://github.com/pytorch/ao/tree/main/torchao/float8 | 1.68 → 1.47 | | Attention | FlashAttention-2 | SageAttention 2.2 https://arxiv.org/abs/2505.21136 | 1.47 → 1.04 | | Kernel fusion | one kernel per operation | fused kernels for norm, RoPE, residual and FP8 quant | 1.04 → 0.98 | | Total | 6.0 FPS | 16.1 FPS | 2.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 code | Ours | |---|---|---| | FPS | 6.0 | 16.1 | | s / chunk | 2.68 | 0.98 | | DiT | 1.62 s | 0.64 s | | Decoder | 1.06 s | 0.34 s | | GPU busy | 90% | 98% | | Kernel launches | ~20,000 | ~4,800 | | Host syncs | 110 | 2 | 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. | Kernel | Reached | Peak on RTX 5090 | of peak | |---|---|---|---| | FP8 matmuls | 390 TFLOP/s | 419 TFLOP/s FP8 | 90 % | | Decoder convolutions | 173 TFLOP/s | 210 TFLOP/s FP16 | 83 % | | Fused elementwise | ~1.3 TB/s | 1.8 TB/s memory | ~70 % | | SageAttention | 543 TOPS | 838 TOPS INT8 | 65 % | 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 code | Ours | |---|---|---| | PSNR | reference | 43.6 dB | | SSIM https://doi.org/10.1109/TIP.2003.819861 | reference | 0.981 | | LPIPS https://arxiv.org/abs/1801.03924 | reference | 0.004 | | MUSIQ https://arxiv.org/abs/2108.05997 | 68.98 | 68.99 | | CLIP-IQA https://arxiv.org/abs/2207.12396 | 0.592 | 0.590 | | Sharpness Laplacian , first / last s | 1022 / 298 | 1023 / 298 | | Colourfulness, first / last s | 41.9 / 50.2 | 41.9 / 50.2 | | Brightness, first / last s | 0.692 / 0.384 | 0.692 / 0.384 | | Flicker | 0.0381 | 0.0381 | | DiT latents, exact preset | reference | bit-identical | OPTIMIZATIONS.md is the full log. It has every experiment with its measurement, the profiles, and the levers that were tried and rejected. | --preset | What runs | s / chunk | FPS | |---|---|---|---| | stock | the original paper's code | 2.68 | 6.0 | | exact | ours, with the DiT latents bit identical to the paper's bf16 model | 1.07 | 14.8 | | fast default | ours, FP8 linears, SageAttention, compiled and fused DiT, fused fp16 decoder | 0.98 | 16.1 | 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. This repository is derived from LingBot-World 2.0 https://github.com/Robbyant/lingbot-world-v2 by the Robbyant team, whose paper https://arxiv.org/abs/2607.07534 is by Zelin Gao and others. The model, the sampler and the examples are theirs. The weights https://huggingface.co/robbyant/lingbot-world-v2-1.3b-causal-fast are theirs too and are not redistributed here. Upstream is licensed under CC BY-NC-SA 4.0 https://creativecommons.org/licenses/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 https://github.com/Wan-Video/Wan2.2 , which is Apache 2.0. The kernels used are SageAttention https://github.com/thu-ml/SageAttention , torchao https://github.com/pytorch/ao and FlashAttention https://github.com/Dao-AILab/flash-attention . @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} }