Example Configurations for Using the Different Heads in LingBot-Map
LingBot-Map supports three prediction heads—camera, point, and depth—that you can enable, tune, or disable independently via command-line flags or YAML configuration files.
LingBot-Map is an open-source visual localization framework built around a shared transformer backbone that powers multiple task-specific prediction heads. Configuring these different heads allows you to trade off between computational cost and output richness, running anything from lightweight pose estimation to full dense reconstruction. Below are practical example configurations derived from the Robbyant/lingbot-map source code, showing exact file paths, class names, and runnable code snippets.
Where the Heads Are Defined
LingBot-Map implements three primary heads in the lingbot_map/heads/ directory. Each head receives aggregated tokens from the shared transformer trunk and runs its own specialized branch to produce final predictions.
According to the source code in lingbot_map/models/gct_base.py (lines 90-97), the model initializes heads conditionally:
self.camera_head = self._build_camera_head() if enable_camera else None
self.point_head = self._build_point_head() if enable_point else None
self.depth_head = self._build_depth_head() if enable_depth else None
The specific implementations are:
- CameraHead: Located in
lingbot_map/heads/camera_head.py(lines 23-46), this class builds a transformer trunk and pose-branch MLP for iterative camera pose refinement. TheCameraCausalHeadvariant (lines 57-89) adds KV-cache handling for streaming inference. - DPTHead (Depth): Implemented in
lingbot_map/heads/dpt_head.py(lines 21-38) using the dense prediction transformer architecture. - PointHead: Defined in
lingbot_map/heads/point_head.py, following the same construction pattern as the camera head.
How to Enable and Disable Heads
You control which heads are active using either command-line arguments for interactive demos or YAML presets for batch rendering.
Interactive Demo Flags
The demo.py script exposes boolean flags that toggle heads at runtime:
--enable_camera– Activates the camera head for pose estimation.--enable_point– Activates the point-cloud head for 3-D point prediction.--enable_depth– Activates the depth head for dense depth mapping.--camera_num_iterations N– Sets refinement steps for the camera head (default 4).--keyframe_interval K– Controls KV-cache size for streaming camera inference.
Example commands from the repository documentation:
# Camera-only pose estimation
python demo.py --model_path /path/to/lingbot-map-long.pt \
--image_folder example/courthouse --mask_sky --enable_camera
# Camera + depth for outdoor scenes
python demo.py --model_path /path/to/lingbot-map-long.pt \
--image_folder example/oxford --mask_sky \
--enable_camera --enable_depth
YAML Configuration for Batch Rendering
For offline video rendering via demo_render/batch_demo.py, heads are configured in YAML files located in demo_render/config/. Each preset contains a heads section:
# demo_render/config/indoor.yaml
heads:
camera: true
point: true
depth: false
The CLI respects these YAML values unless explicitly overridden with --enable_* flags.
Practical Code Examples
These snippets demonstrate how to instantiate the model classes with specific head combinations. All examples assume installation via pip install -e ..
Camera-Only Inference (Streaming)
For long video sequences, use the GCTStream class with CameraCausalHead to maintain a KV cache:
import torch
from lingbot_map.models.gct_stream import GCTStream
model = GCTStream(
enable_camera=True,
enable_point=False,
enable_depth=False,
camera_head_kwargs=dict(
num_iterations=2, # faster inference
keyframe_interval=2, # reduce memory usage
),
).eval()
# tokens from backbone: list of [B, S, C] tensors
tokens = [torch.randn(1, 32, 2048)]
poses = model(tokens)[0] # returns list of pose predictions per iteration
print(poses[-1].shape) # (1, 9) → translation + quaternion + FOV
As implemented in gct_stream.py (lines 18-23), the enable_camera parameter triggers construction of the causal head variant, while trunk_fn in camera_head.py (lines 96-104) handles the iterative refinement.
Depth-Only Inference (Batch)
For batch processing without pose estimation:
import torch
from lingbot_map.models.gct_base import GCTBase
model = GCTBase(
enable_camera=False,
enable_point=False,
enable_depth=True,
).eval()
images = torch.randn(1, 8, 3, 224, 224) # B, S, C, H, W
tokens = [torch.randn(1, 8, 2048)] # aggregated tokens
depth, conf = model(tokens, images, patch_start_idx=0)
print(depth.shape) # (1, 8, 1, 224, 224)
The _build_depth_head method in gct_base.py (lines 102-105) instantiates the DPTHead, which executes in the forward pass around lines 190-200.
Full Pipeline Configuration
To run all three heads simultaneously with sliding-window support for long sequences:
import torch
from lingbot_map.models.gct_stream_window import GCTStreamWindow
model = GCTStreamWindow(
enable_camera=True,
enable_point=True,
enable_depth=True,
sliding_window_size=128,
keyframe_interval=2,
).eval()
# Process 100-frame video
images = torch.randn(1, 100, 3, 224, 224)
tokens = [torch.randn(1, 100, 2048)]
poses, points, depth = model(tokens, images, patch_start_idx=0)
print(poses[-1].shape) # (1, 9)
print(points[-1].shape) # (1, 3, N)
print(depth.shape) # (1, 100, 1, 224, 224)
The gct_stream_window.py implementation (lines 19-27) manages the KV cache and sliding window logic, while the forward method (lines 120-150) sequences calls to all three heads.
Summary
- LingBot-Map provides three interchangeable heads—camera, point, and depth—defined in
lingbot_map/heads/camera_head.py,point_head.py, anddpt_head.py. - Enable heads via CLI flags (
--enable_camera,--enable_point,--enable_depth) indemo.pyor through theheads:block in YAML configs for batch rendering. - Tune camera head performance using
num_iterations(accuracy vs. speed) andkeyframe_interval(memory usage). - Use streaming variants (
GCTStream,GCTStreamWindow) for long videos to leverage KV-caching in the causal camera head. - Combine heads arbitrarily to match your pipeline needs, from lightweight pose-only tracking to full 3-D reconstruction with dense depth and point clouds.
Frequently Asked Questions
How do I run only the camera head for pose estimation?
Pass --enable_camera without the other enable flags when running demo.py, or construct GCTStream with enable_camera=True and enable_point=False, enable_depth=False. This configuration minimizes memory usage and inference time while outputting only camera poses (translation, quaternion, and FOV) as a (1, 9) tensor.
Can I activate the depth head without the camera head?
Yes. Set enable_camera=False and enable_depth=True when instantiating GCTBase or GCTStream. The depth head (DPTHead) operates independently on the transformer backbone tokens and returns dense depth maps regardless of whether pose estimation is active.
What is the difference between CameraHead and CameraCausalHead?
CameraHead in camera_head.py (lines 23-46) is designed for batch processing where all frames are available simultaneously. CameraCausalHead (lines 57-89) extends this with KV-cache management, allowing the model to process streaming video efficiently by caching only keyframe tokens, as controlled by the keyframe_interval parameter.
How do I optimize memory usage for long video sequences?
Use the GCTStreamWindow class with a reduced sliding_window_size (e.g., 128 frames) and increase the keyframe_interval to 2 or 4. Enable only the heads you need—typically just enable_camera—and set num_iterations to 2 instead of the default 4 to reduce the number of refinement steps per frame.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →