How to Address Pose Collapse in LingBot-Map for Very Long Sequences

Use windowed inference with keyframe selection to bound the KV cache size and prevent 3-D RoPE positional encoding drift.

LingBot-Map predicts camera poses frame-by-frame while maintaining a KV cache that stores attention keys and values from previously seen frames. When processing videos significantly longer than the training data (~320 frames), the cache grows beyond the model's 3-D Rotary Positional Embedding (RoPE) temporal range, causing estimated poses to drift—a phenomenon documented as pose collapse. This guide explains how to address pose collapse in LingBot-Map for very long sequences using the windowed inference and keyframe selection mechanisms implemented in the Robbyant/lingbot-map repository.

Understanding Pose Collapse in LingBot-Map

Pose collapse occurs due to two interacting architectural constraints in lingbot_map/models/gct_stream_window_v2.py:

  • 3-D RoPE Limitations: The model uses 3-D Rotary Positional Embedding to encode temporal information, assuming a maximum frame index (max_frame_num, default 1024). When the KV cache stores more frames than seen during training, the positional encoding becomes out-of-range, and learned attention patterns fail to align correctly.

  • Unbounded KV Cache Growth: In standard streaming mode (--mode streaming), the cache grows linearly with frame count. For videos exceeding 3000 frames, this quickly surpasses the trained RoPE range, resulting in accumulated pose drift.

Windowed Inference: The Primary Solution

The windowed inference mechanism processes video in overlapping segments, resetting the KV cache at the start of each window to keep memory bounded.

In GCTStream.inference_windowed (lines 1023-1039), each window receives a fresh KV cache limited by window_size (measured in keyframes, not raw frames). This guarantees that the cache never exceeds the RoPE temporal space regardless of total video length.

Cache Management and Window Stitching

When a window completes, the model must align its predictions to the previous window to maintain global consistency. The repository implements this through:

  • _pairwise_alignment (line 1065): Computes a similarity transform (scale-rotation-translation) between overlapping regions.
  • _warp_predictions: Applies this transform to stitch windows together without drift.
  • _stitch_windows (line 1045): Orchestrates the alignment using overlap_keyframes (or overlap_size) to ensure at least one paired keyframe exists for robust alignment.

This stitching process ensures that while each window operates with an independent, bounded cache, the final trajectory remains globally consistent.

Keyframe Selection Strategies

Beyond windowing, LingBot-Map provides mechanisms to reduce KV cache growth within each window by storing attention values only for selected frames.

Fixed Interval Keyframes

The keyframe_interval parameter (default 1) specifies that only every N-th frame retains its KV cache entry. In inference_streaming (lines 1064-1069), non-keyframes invoke _set_skip_append(True), which prevents appending to the cache while still allowing pose prediction.

Setting --keyframe_interval 4 reduces cache memory usage by approximately 75% without requiring optical flow computation.

Flow-Based Adaptive Keyframes

For scenes with variable motion, the --flow_threshold flag enables dynamic keyframe selection. The _compute_flow_magnitude function (lines 92-124) measures optical flow between the current frame and the last keyframe. When mean flow exceeds the threshold (in pixels), the frame automatically becomes a keyframe regardless of the fixed interval.

This ensures fast-motion sections retain sufficient temporal context while static sections benefit from aggressive pruning.

Code Examples: Running Long Sequence Inference

The following commands demonstrate how to configure LingBot-Map for arbitrarily long sequences using the windowed inference pipeline:

Basic Windowed Inference

python demo.py \
    --model_path /path/to/lingbot-map-long.pt \
    --video_path video.mp4 \
    --fps 10 \
    --mode windowed \
    --window_size 128

Reduced Cache Growth with Fixed Intervals

python demo.py \
    --model_path /path/to/lingbot-map-long.pt \
    --video_path video.mp4 \
    --fps 10 \
    --mode windowed \
    --window_size 128 \
    --overlap_keyframes 16 \
    --keyframe_interval 4

Flow-Based Adaptive Keyframes

python demo.py \
    --model_path /path/to/lingbot-map-long.pt \
    --video_path video.mp4 \
    --fps 10 \
    --mode windowed \
    --window_size 128 \
    --overlap_keyframes 16 \
    --flow_threshold 2.0

CPU Offloading for Extremely Long Sequences

python demo.py \
    --model_path /path/to/lingbot-map-long.pt \
    --video_path video.mp4 \
    --fps 10 \
    --mode windowed \
    --window_size 128 \
    --overlap_keyframes 16 \
    --keyframe_interval 3 \
    --output_device cpu

Summary

  • Pose collapse results from 3-D RoPE encoding limitations when the KV cache exceeds the trained temporal range (~320 frames, max 1024).
  • Windowed inference (--mode windowed) in gct_stream_window_v2.py bounds cache size by processing video in overlapping segments with fresh caches.
  • Window stitching via _pairwise_alignment and _warp_predictions maintains global trajectory consistency across segments.
  • Keyframe selection through --keyframe_interval or --flow_threshold further reduces cache growth by skipping KV storage for non-essential frames.
  • Combining these mechanisms allows LingBot-Map to process tens of thousands of frames without pose drift.

Frequently Asked Questions

What exactly causes pose collapse in LingBot-Map?

Pose collapse occurs when the KV cache grows larger than the 3-D RoPE positional encoding can represent (default max_frame_num of 1024). Since the model was trained on sequences of approximately 320 frames, attention patterns become unreliable when the cache contains significantly more frames, causing estimated camera poses to drift progressively.

How does windowed inference prevent pose drift?

Windowed inference resets the KV cache at the start of each window (controlled by --window_size), ensuring the cache never exceeds the RoPE range. The _stitch_windows method aligns consecutive windows using a similarity transform computed from overlapping keyframes, effectively "re-zeroing" the positional encoding without losing trajectory continuity.

What is the difference between keyframe_interval and flow_threshold?

--keyframe_interval uses a fixed temporal subsampling (every Nth frame), while --flow_threshold enables adaptive selection based on optical flow magnitude. Fixed intervals provide predictable memory usage, whereas flow-based selection preserves more keyframes during rapid camera motion and fewer during static scenes, optimizing cache efficiency dynamically.

Where is the windowed inference logic implemented?

The core implementation resides in lingbot_map/models/gct_stream_window_v2.py, specifically within the GCTStream.inference_windowed method (lines 1023-1039). Supporting utilities including _pairwise_alignment (line 1065), _warp_predictions, and _compute_flow_magnitude (lines 92-124) are defined in the same file.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →