# How batch_demo.py Handles Sequences Too Long for Interactive Viewing in LingBot-MAP

> Learn how batch_demo.py manages long sequences in LingBot-MAP. It automatically uses windowed batch processing for inputs exceeding the 1024 frame limit with max_frame_num.

- Repository: [Robbyant/lingbot-map](https://github.com/Robbyant/lingbot-map)
- Tags: how-to-guide
- Published: 2026-07-04

---

**The LingBot-MAP demo script caps frame sequences at 1024 frames by default using the `--max_frame_num` argument, automatically switching to a windowed batch processing mode when inputs exceed this limit.**

In the **Robbyant/lingbot-map** repository, the [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py) entry-point (often referenced as batch_demo.py in documentation) manages memory constraints by refusing to load arbitrarily long video sequences into a single interactive view. Instead of risking GPU out-of-memory errors on extended frame sequences, the script implements a configurable hard ceiling and an intelligent fallback mechanism that partitions long inputs into manageable, overlapping batches.

## Maximum Frame Cap and Automatic Mode Selection

The script defines a command-line argument **`--max_frame_num`** with a default value of `1024` that sets the absolute upper bound on frames processed in a single batch. When the input sequence length exceeds this threshold, the demo automatically abandons the streaming approach in favor of **windowed processing**.

Two distinct modes control this behavior:

- **Streaming mode** – Uses a KV-cache to process frames sequentially one at a time, suitable for sequences that fit comfortably within the `max_frame_num` limit.
- **Windowed mode** – Divides the sequence into overlapping fixed-size windows, processing each as an independent batch when the input exceeds the configured maximum.

As implemented in [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py), the mode selection logic checks the input frame count against `max_frame_num` before any model inference begins, ensuring the runtime never attempts to allocate tensors for unreasonably large sequences.

## Window Creation and Overlap Logic

When operating in windowed mode, the script constructs segments using two critical parameters defined in [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py):

- **`--num_scale_frames`** – Specifies the number of initial frames used to establish a reference scale for the entire sequence.
- **`--keyframe_interval`** – Determines how frequently keyframes are sampled after the scale frames.

Each window contains the scale frames plus the configured keyframes, with the total window size calculated to guarantee it never exceeds the `max_frame_num` boundary. The windows overlap to preserve temporal continuity between segments, allowing the model to maintain context across batch boundaries without requiring the full sequence to reside in memory simultaneously.

## Batch Processing Implementation

The actual inference logic resides in the model-specific streaming modules. In **[`lingbot_map/models/gct_stream_window.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream_window.py)**, the windowed inference routine accepts the pre-sliced batches and processes them through the model's forward pass using explicit `batch_size` arguments. After processing, results from individual windows are concatenated to produce a seamless output sequence.

For sequences that fall within the frame limit, **[`lingbot_map/models/gct_stream.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream.py)** provides the streaming path that processes frames individually using the KV-cache mechanism. If a user supplies a sequence longer than `max_frame_num` while requesting streaming mode, [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py) automatically trims the tail frames before inference begins, strictly enforcing the memory budget regardless of user preference.

## Practical Command-Line Examples

The following examples demonstrate how to control long-sequence handling via command-line arguments:

```bash

# Process a short sequence (under 1024 frames) in streaming mode

python demo.py \
  --model_path /path/to/checkpoint.ckpt \
  --image_folder /data/short_clip \
  --mode streaming

```

```bash

# Handle a long video (5000 frames) using windowed batch processing

python demo.py \
  --model_path /path/to/checkpoint.ckpt \
  --image_folder /data/long_video \
  --mode windowed \
  --max_frame_num 1024 \
  --num_scale_frames 8 \
  --keyframe_interval 4

```

In the second example, the script automatically segments the 5000-frame input into overlapping windows of at most 1024 frames each, processes each window as a discrete batch, and stitches the outputs together withoutever loading the full video into GPU memory.

## Summary

- **`--max_frame_num`** (default `1024`) sets a hard ceiling on frames processed per batch in [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py).
- **Windowed mode** automatically activates when inputs exceed the frame limit, splitting sequences into overlapping segments.
- **Scale frames and keyframes** define window boundaries while preserving temporal coherence across batches.
- **Automatic trimming** discards excess tail frames if the user explicitly requests streaming mode on oversized inputs.
- The implementation spans [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py), [`lingbot_map/models/gct_stream_window.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream_window.py), and [`lingbot_map/models/gct_stream.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream.py).

## Frequently Asked Questions

### What happens if I try to process a video longer than 1024 frames in streaming mode?

The demo script automatically trims the sequence to the first 1024 frames before processing begins. As implemented in [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py), the `max_frame_num` argument acts as a strict memory safety guard, discarding tail frames rather than attempting to process them and risking out-of-memory errors.

### How does the windowed mode maintain consistency between separate batches?

The windowing logic uses overlapping segments where each window includes the initial scale frames plus regularly spaced keyframes defined by `--keyframe_interval`. This overlap ensures that spatial references and temporal context carry forward between adjacent windows, allowing seamless concatenation of results after batch processing.

### Can I adjust the maximum frame limit for hardware with larger GPU memory?

Yes. The `--max_frame_num` argument accepts any positive integer, allowing you to increase the limit if your hardware supports larger batch sizes. However, the script will still enforce this new limit strictly, switching to windowed processing if the input exceeds your custom threshold.

### Where is the actual batch processing logic implemented?

While [`demo.py`](https://github.com/Robbyant/lingbot-map/blob/main/demo.py) handles command-line parsing and window orchestration, the core inference routines reside in [`lingbot_map/models/gct_stream_window.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream_window.py) for windowed batches and [`lingbot_map/models/gct_stream.py`](https://github.com/Robbyant/lingbot-map/blob/main/lingbot_map/models/gct_stream.py) for streaming sequences. Both modules expose `forward` methods that accept explicit batch size parameters to control memory allocation during inference.