[Lingbot World] Bound image condition storage and extend temporal RoPE (#6838)

Signed-off-by: wtz2333 <2955110911@qq.com>
This commit is contained in:
wtz2333 authored and GitHub committed 2026-09-15 18:49:55 +08:00
1 parent 4a8ac29775
commit a3dee6fdf5
12 files changed
+592 -195

No files matched your search

@@ -24,10 +24,9 @@ Examples::
``--action-script`` is a JSON list with one camera action list per AR block,
for example ``[[["w"], ["w"], ["w"]], [["a"], [], []]]`` for a checkpoint that
generates three latent frames per block. The frames per block, the temporal
compression and the number of blocks that fit the condition horizon are read
off the checkpoint rather than assumed, so the script can be repointed with
``--model``.
generates three latent frames per block. The frames per block and temporal
compression are read off the checkpoint rather than assumed, so the script
can be repointed with ``--model``.
"""
from __future__ import annotations
@@ -49,9 +48,6 @@ if TYPE_CHECKING:
import numpy as np
_MODEL = "robbyant/lingbot-world-v2-14b-causal-fast-diffusers"
# Mirrors _MAX_RAW_FRAMES in vllm_omni/diffusion/models/lingbot_world/pipeline.py:
# the image-condition horizon is the pipeline's constant, not the checkpoint's.
_MAX_RAW_FRAMES = 117
def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
@@ -67,8 +63,8 @@ def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
"--action-script",
required=True,
help=(
"JSON file holding one camera action list per AR block. Both the per-block frame count "
"and the number of blocks that fit are read off the checkpoint, not assumed."
"JSON file holding one camera action list per AR block. "
"The per-block frame count is read off the checkpoint, not assumed."
),
)
parser.add_argument("--output-dir", required=True, help="Directory for decoded frames and metadata.")
@@ -154,12 +150,6 @@ def _validate_against_checkpoint(
f"--action-script block {block_index} holds {len(block)} frame action lists, but this "
f"checkpoint generates {frames_per_block} latent frames per AR block."
)
max_chunks = ((_MAX_RAW_FRAMES - 1) // temporal_compression + 1) // frames_per_block
if len(script) > max_chunks:
raise ValueError(
f"--action-script holds {len(script)} blocks, but this checkpoint's "
f"{_MAX_RAW_FRAMES}-frame image-condition horizon fits at most {max_chunks}."
)
return (len(script) * frames_per_block - 1) * temporal_compression + 1
@@ -32,7 +32,6 @@ import numpy as np
_MODEL = "robbyant/lingbot-world-v2-14b-causal-fast-diffusers"
_MAX_SEQUENCE_LENGTH = 512
_MAX_PIXEL_AREA = 480 * 832
_MAX_RAW_FRAMES = 117
_MAX_SOURCE_CAMERA_FRAMES = 4096
_TEMPORAL_COMPRESSION = 4
_LATENT_FRAMES_PER_BLOCK = 3
@@ -191,8 +190,6 @@ def build_request(
raise ValueError("--height * --width must not exceed 480 * 832 pixels.")
if args.num_frames <= 0:
raise ValueError("--num-frames must be a positive integer.")
if args.num_frames > _MAX_RAW_FRAMES:
raise ValueError("--num-frames must not exceed 117 raw frames.")
if args.num_frames > paths.camera_frames:
raise ValueError("Camera arrays must contain at least --num-frames frames.")
if (args.num_frames - 1) % _TEMPORAL_COMPRESSION:
@@ -1,13 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Run LingBot-World 2.0 as an in-process realtime AR-Diffusion session.
This example exercises the internal session API. It is not a public HTTP or
WebSocket protocol. Each JSONL event advances the world by one three-latent
frame AR block and writes the latent plus its identity metadata. The current
scoped implementation supports at most ten ticks per generation epoch because
its image condition is bounded to 117 pixel frames; reset or create a session
to start a new world.
frame AR block and writes the latent plus its identity metadata. Session-owned
causal VAE encoder state produces each condition block without retaining or
repeating a full image-condition horizon.
"""
from __future__ import annotations
@@ -24,8 +23,6 @@ from typing import Any
_MODEL = "robbyant/lingbot-world-v2-14b-causal-fast-diffusers"
_CAMERA_ACTION_SCHEMA = "lingbot.camera_actions.v1"
_FRAMES_PER_BLOCK = 3
# ((117 pixel frames - 1) / VAE temporal factor 4 + 1) / 3 latent frames.
_MAX_REALTIME_TICKS = 10
def _camera_event_data(frames: list[list[str]]) -> dict[str, Any]:
@@ -41,7 +38,7 @@ def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
parser.add_argument(
"--events",
required=True,
help="JSONL file with one prompt/action event per AR block; at most 10 events.",
help="JSONL file with one prompt/action event per AR block.",
)
parser.add_argument("--output-dir", required=True, help="Directory for chunk latents and metadata.")
parser.add_argument("--session-id", default="lingbot-world", help="Persistent world session identifier.")
@@ -84,12 +81,6 @@ def _load_events(path: Path) -> list[dict[str, Any]]:
events.append({"event_id": event_id, "prompt": prompt, "frames": frames})
if not events:
raise ValueError("events file must contain at least one event.")
if len(events) > _MAX_REALTIME_TICKS:
raise ValueError(
"events file must contain at most "
f"{_MAX_REALTIME_TICKS} events because the current LingBot realtime "
"image-condition horizon is 117 pixel frames."
)
event_ids = [event["event_id"] for event in events]
if event_ids != sorted(set(event_ids)):
raise ValueError("event_id values must be unique and strictly increasing.")