(ECCV 2026 oral) LingBot-Map: Geometric Context Transformer for Streaming 3D Reconstruction
| Files | Last commit | Last update |
|---|---|---|
| 3 months ago | ||
| 2 months ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 24 days ago | ||
| 3 months ago | ||
| 3 months ago | ||
| 3 months ago | ||
| 4 months ago | ||
| 7 days ago | ||
| 24 days ago | ||
| 4 months ago | ||
| 7 days ago | ||
| 4 months ago |
https://github.com/user-attachments/assets/fe39e095-af2c-4ec9-b68d-a8ba97e505ab
🗺️ 认识 LingBot-Map!我们构建了一个用于流式三维重建的前馈式三维基础模型!🏗️🌍
LingBot-Map 聚焦于:
- Geometric Context Transformer:通过锚点上下文、位姿参考窗口与轨迹记忆,在单一流式框架内实现坐标定位、密集几何线索与长程漂移校正的架构级统一。
- 高效流式推理:采用带分页 KV 缓存注意力机制的前馈架构,可在 518×378 分辨率下,对超过 10,000 帧的长序列实现约 20 FPS 的稳定推理。
- 先进重建:在多种基准测试上均优于现有流式方法与迭代优化方法。
📑 目录
点击展开
📰 动态
- 2026-06-28 — 修复了一个 SDPA KV cache 问题。SDPA 后端在长序列上的表现现在更好。我们仍推荐 FlashInfer 后端以获得最佳性能。
- 2026-05-25 — 📊 评测基准已发布。我们发布了 KITTI 和 Oxford Spires 的评测脚本 — 参见 benchmark/ 了解流水线,并在评测前运行
preprocess/oxford.py准备 Oxford Spires 数据。 - 2026-04-29 — 📹 长视频演示已发布。我们发布了一个超长视频示例(约 25 000 帧、13 分钟室内漫游),由离线流水线渲染生成 — 参见 实操示例 查看命令、参数说明和渲染输出。
- 2026-04-27 — 🚀 LingBot-Map 加速。拉取最新
main分支,并运行python demo.py --compile ...或python gct_profile.py --backend flashinfer --dtype bf16 --compile,在你的硬件上验证。 - 2026-04-24 — 修复了一个 FlashInfer KV cache 问题:当
--keyframe_interval > 1时,会静默缓存非关键帧。现在在运行超过 320 帧时,你应该能看到更好的位姿与重建质量。
📋 待办事项
- ✅ 发布评测基准
- ✅ Oxford Spires 数据集
- ✅ KITTI 数据集
- ✅ VBR 数据集
- ✅ Droid-W 数据集
- ✅ TUM-D 数据集
- ✅ 7-scenes 数据集
- ✅ ETH3D 数据集
- ✅ Tanks and Temples 数据集
- ✅ NRGBD 数据集
- ✅ 发布演示脚本
⚙️ 安装
1. 创建 conda 环境
conda create -n lingbot-map python=3.10 -y
conda activate lingbot-map
2. 安装 PyTorch (CUDA 12.8)
pip install torch==2.8.0 torchvision==0.23.0 --index-url https://download.pytorch.org/whl/cu128
推荐使用 PyTorch 2.8.0,因为批量渲染流水线所需的 NVIDIA Kaolin 已提供适用于
torch-2.8.0_cu128的预构建 wheel。如果只需要demo.py,也可以使用更新版本的 PyTorch,但批量渲染器需要从源码构建 Kaolin。 其他 CUDA 版本,请参见 PyTorch Get Started。
3. 安装 lingbot-map
pip install -e .
4. 安装 FlashInfer(推荐)
FlashInfer 为高效流式推理提供分页 KV 缓存注意力机制。它是一个纯 Python 包,会在首次使用时即时编译 CUDA 内核,因此同一个 wheel 即可适用于不同 CUDA/PyTorch 版本:
pip install --index-url https://pypi.org/simple flashinfer-python
--index-url https://pypi.org/simple仅当你的默认 pip 索引为缺少flashinfer-python的内部镜像时才需要。 (可选)为了加快首次使用,你还可以额外安装 CUDA 专用 JIT 缓存:pip install flashinfer-jit-cache -f https://flashinfer.ai/whl/cu128/flashinfer-jit-cache/。 有关详情,请参阅 FlashInfer 安装。如果未安装 FlashInfer,模型将通过--use_sdpa回退到 SDPA(PyTorch 原生注意力)。
5. 可视化依赖(可选)
pip install -e ".[vis]"
📦 模型下载
| 模型名称 | Huggingface 仓库 | ModelScope 仓库 | 说明 |
|---|---|---|---|
| lingbot-map | robbyant/lingbot-map | Robbyant/lingbot-map | 均衡检查点(用于论文、基准测试与离线演示)——在短序列与长序列上兼顾综合性能。 |
| lingbot-map-stage1 | robbyant/lingbot-map | Robbyant/lingbot-map | lingbot-map 的第一阶段训练检查点——可加载至 VGGT 模型,用于双向推理(c2w)。 |
🚧 即将上线: 我们正在训练一个支持更长序列的更强模型,敬请期待。
🚀 快速开始
安装完成后,运行你的第一个场景只需一条命令:
python demo.py --model_path /path/to/lingbot-map.pt \
--image_folder example/courthouse --mask_sky
这将在 http://localhost:8080 启动一个交互式 viser 查看器。完整场景列表与参数见下文 交互式演示,也可跳转到 离线渲染流水线 进行长序列批量渲染。
🎬 交互式演示(demo.py)
运行 demo.py,即可通过基于浏览器的 viser 查看器进行交互式 3D 可视化(默认地址为 http://localhost:8080)。
试试示例场景
我们在 example/ 中提供了三个示例场景,可直接运行:
# courthouse scene
python demo.py --model_path /path/to/lingbot-map.pt \
--image_folder example/courthouse --mask_sky
https://github.com/user-attachments/assets/aa10f7ab-8024-43c7-92f8-d56159ec85c8
# University scene
python demo.py --model_path /path/to/lingbot-map.pt \
--image_folder example/university --mask_sky
https://github.com/user-attachments/assets/212a1744-6ff5-4ccf-9bd4-728608248b57
# Loop scene (loop closure trajectory)
python demo.py --model_path /path/to/lingbot-map.pt \
--image_folder example/loop
https://github.com/user-attachments/assets/5ae0a292-b081-40c6-838c-b7c1a0538d75
🎯 精选:室内漫游(约 25 000 帧,13 分钟)
该序列对于交互式 viser 查看器而言过长——此片段由 Offline Rendering Pipeline 渲染生成。完整命令请参考该部分。
后续将提供更多示例。
动态演示(来自 Droid-W)
数据集: 请从 Hugging Face 的 robbyant/lingbot-map-demo 下载演示序列。
上述数据集中 dynamic 序列的示例运行(启用天空掩码、4 次相机优化迭代,且每 2 帧提取一个关键帧):
使用天空掩码、4 次相机优化迭代以及输入步长 2,运行 dynamic 序列:
python demo.py \
--image_folder /path/to/dynamic\
--model_path ../../Lingbot-Map/lingbot-map.pt \
--camera_num_iterations 4 \
--mask_sky \
--stride 2
https://github.com/user-attachments/assets/567b6e9b-1cbf-402a-96be-9bab70715ec3
基于关键帧间隔的流式处理
使用 --keyframe_interval 可以减少 KV 缓存的内存占用,仅保留每第 N 帧作为关键帧。非关键帧仍会生成预测结果,但不会被存入缓存。对于超过 320 帧的长序列,这一方式非常有用(我们在 320 个视角上使用视频 RoPE 进行训练,因此当 KV 缓存中存储超过 320 个视角时,性能会下降;采用关键帧策略可以在更长的序列上完成推理)。在 demo.py 中,关键帧间隔会自动计算。
关于推理范围的说明。 我们的方法默认不执行状态重置,因此最大推理范围受数据集训练时出现过的最长距离限制。超过该距离后,就需要进行状态重置。如果观察到位姿崩溃,请切换到窗口模式(
--mode windowed)——在大多数情况下,仅调整--keyframe_interval就足够了,窗口模式的其他参数可以保持默认值。
窗口式推理(适用于长序列,>3000 帧)
python demo.py --model_path /path/to/lingbot-map.pt \
--video_path video.mp4 --fps 10 \
--mode windowed --window_size 128 --overlap_keyframes 16 --keyframe_interval 2
天空掩膜
天空掩膜使用 ONNX 天空分割模型,从重建的点云中过滤掉天空点,从而提升室外场景的可视化质量。
设置:
# Install onnxruntime (required)
pip install onnxruntime # CPU
# or
pip install onnxruntime-gpu # GPU (faster for large image sets)
默认情况下,根目录的 demo.py 会将天空分割模型解析为相对于当前工作目录的 skyseg.onnx。如果该默认文件不存在,首次使用时会自动从 HuggingFace 下载。若下载失败或未生成普通文件,天空遮罩会停止,并抛出 RuntimeError,该错误会报告模型路径、下载 URL、原因以及手动配置指引;它绝不会在没有遮罩的情况下静默继续。
如需保留默认路径并手动恢复,请下载 skyseg.onnx 到你运行 demo.py 的目录:
wget -O skyseg.onnx https://huggingface.co/JianyuanWang/skyseg/resolve/main/skyseg.onnx
python demo.py --model_path /path/to/checkpoint.pt \
--image_folder /path/to/images/ --mask_sky
使用显式模型路径:
若需使用存储在其他位置的模型,请通过 --sky_model 提供其绝对路径:
python demo.py --model_path /path/to/checkpoint.pt \
--image_folder /path/to/images/ --mask_sky \
--sky_model /absolute/path/to/skyseg.onnx
天空掩码会缓存到 <image_folder>_sky_masks/,以便后续运行跳过重新生成。你也可以使用 --sky_mask_dir 指定自定义缓存目录,或使用 --sky_mask_visualization_dir 保存并排的掩码可视化结果:
python demo.py --model_path /path/to/checkpoint.pt \
--image_folder /path/to/images/ --mask_sky \
--sky_mask_dir /path/to/cached_masks/ \
--sky_mask_visualization_dir /path/to/mask_viz/
可视化选项
| 参数 | 默认值 | 说明 |
|---|---|---|
--port |
8080 |
Viser 查看器端口 |
--conf_threshold |
1.5 |
用于过滤低置信度点的可见性阈值 |
--point_size |
0.00001 |
点云点尺寸 |
--downsample_factor |
10 |
点云显示的空间降采样 |
性能与内存
不使用 FlashInfer(SDPA 回退)
python demo.py --model_path /path/to/checkpoint.pt \
--image_folder /path/to/images/ --use_sdpa
有限 GPU 显存下的运行
如果遇到显存不足问题,可尝试以下一项(或两项均使用):
--offload_to_cpu— 在推理期间将逐帧预测结果卸载到 CPU(默认开启;仅在显存充足时使用--no-offload_to_cpu)。--num_scale_frames 2— 将双向尺度帧数量从默认 8 降低到 2,从而降低初始尺度阶段的激活峰值。
更快的推理
降低相机头中迭代精化的步数,以少量位姿精度换取实际推理速度:
python demo.py --model_path /path/to/checkpoint.pt \
--image_folder /path/to/images/ --camera_num_iterations 1
--camera_num_iterations 默认为 4;将其设置为 1 会跳过相机头中的三轮细化(并将其 KV cache 减小到原来的 1/4)。
🎥 离线渲染管线 (demo_render/batch_demo.py)
当序列过长、不适合交互式 viser 查看器时,请使用此流程——例如,上方展示的室内漫游片段。demo_render/batch_demo.py 是一体化的离线入口:只需提供一个视频或一个图像文件夹,即可运行模型推理,并通过一条命令生成无界面的点云飞行视频 MP4。它与 demo.py 共享相同的 PyTorch / FlashInfer / checkpoint 技术栈。
对于受限于显存或 GPU 使用量的用户,也可以参考以下实现:https://github.com/ureeey/lingbot-map-rtx4060-8g/commit/eeee84a89cc97c1e39b736b46df4ee315275700b
安装(在主安装基础上扩展)
1. 渲染 Python 依赖
pip install -e ".[vis,render]"
render 会引入 open3d>=0.19 和 pyyaml(其中核心 numpy<2 约束来自基础 lingbot-map 安装)。该流程中的天空掩膜使用 onnxruntime-gpu 加载支持动态批次的 skyseg_batch.onnx,该模型已发布在 robbyant/lingbot-map 模型仓库中:
pip install onnxruntime-gpu
wget -O skyseg_batch.onnx \
https://huggingface.co/robbyant/lingbot-map/resolve/main/skyseg_batch.onnx
离线渲染器会在其配置路径缺失时自动下载 skyseg_batch.onnx。请在
demo_render/batch_demo.py 中使用
--skyseg_model_path /absolute/path/to/skyseg_batch.onnx;对于独立运行的
demo_render/rgbd_scan_render.py,请使用
--sky_model /absolute/path/to/skyseg_batch.onnx,或在 YAML 中设置
preprocess.sky_model。根级单图脚本 demo.py 仍会
使用 skyseg.onnx。
2. Kaolin — 与上文推荐的 PyTorch 2.8.0 + CUDA 12.8 相匹配:
pip install --index-url https://pypi.org/simple \
kaolin -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.8.0_cu128.html
使用
--index-url https://pypi.org/simple可以绕过可能返回 PyPI 占位 wheel 的内部镜像(该占位 wheel 在导入时会触发ImportError)。 NVIDIA Kaolin 未为 PyTorch 2.9.x 提供预编译 wheel。如果你因其他原因使用 PyTorch 2.9,请从源码构建 Kaolin(pip install --no-build-isolation git+https://github.com/NVIDIAGameWorks/kaolin.git,需要本地 CUDA toolkit)。其他 torch/CUDA 组合请参考 NVIDIA Kaolin installation。
3. ffmpeg
sudo apt install ffmpeg # or: brew install ffmpeg
4. CUDA 扩展(首次运行前必须安装)
cd demo_render/render_cuda_ext && python setup.py build_ext --inplace && cd ../..
该命令将就地构建 voxel_morton_ext 和 frustum_cull_ext —— 两者都会被 rgbd_render 导入,用于 GPU 体素化和视锥体剔除。
示例流程 —— 长室内漫游(约 25 000 帧,13 分钟)
数据集: 从 Hugging Face 上的 robbyant/lingbot-map-demo 下载示例视频。
python demo_render/batch_demo.py \
--video_path /data/demo_videos/indoor_travel.MP4 \
--output_folder /data/outputs/indoor_travel/ \
--model_path /path/to/lingbot-map.pt \
--config demo_render/config/indoor.yaml \
--mode windowed --window_size 128 \
--keyframe_interval 10 --overlap_keyframes 8 \
--sky_mask_dir /data/outputs/sky_masks \
--sky_mask_visualization_dir /data/outputs/sky_mask_viz \
--camera_vis default --keyframes_only_points \
--frame_tag --frame_tag_position top_right \
--save_predictions
各参数说明:
| 参数 | 作用 |
|---|---|
--mode windowed --window_size 128 |
当序列超过约 320 帧的 RoPE 训练范围后,需要启用滑动窗口推理;每个窗口都会重置 KV 缓存。window_size 统计的是 KV 缓存槽位,而不是实际帧数——前 num_scale_frames(=8)个槽位保存尺度帧,其余 128 − 8 = 120 个槽位保存关键帧。当 keyframe_interval = 13 时,一个窗口因此覆盖 8 + 120 × 13 = 1568 个实际帧。 |
--keyframe_interval 10 |
仅将每第 10 帧缓存为关键帧。非关键帧仍会输出逐帧预测,但不会增大 KV 缓存 |
--overlap_keyframes 8 |
相邻窗口共享 8 个关键帧的上下文,内部解析为 max(num_scale_frames, 8 × keyframe_interval) = 8 × 13 = 104 个实际帧的重叠。只要 keyframe_interval > 1,都建议使用,以保持跨窗口位姿对齐稳定。 |
--config demo_render/config/indoor.yaml |
从室内预设中初始化渲染/场景/相机/叠加层默认值(短景深、更紧的跟随相机)。用户显式传入的任何命令行参数都会覆盖 YAML 中的值。 |
--sky_mask_dir / --sky_mask_visualization_dir |
将天空掩码及其并排可视化结果持久化到磁盘,以便后续重新运行时直接复用,而不是再次运行 ONNX 分割。(渲染管线仅在启用天空掩码时才会使用它们——可通过 YAML 预设或 --mask_sky 启用。) |
--camera_vis default |
在渲染视频上叠加轨迹尾迹 + 最近帧点。 |
--keyframes_only_points |
仅将关键帧深度反投影到点云;非关键帧仍会将位姿用于轨迹/视锥叠加层。可在超长序列中保持点云稀疏。 |
--frame_tag --frame_tag_position top_right |
在 MP4 右上角添加 <i> / <N> 帧 计数标记。 |
--save_predictions |
将逐帧 NPZ 文件与 MP4 一起保存。便于检查,或稍后使用不同的相机/叠加层设置重新渲染。 |
快速模式和 Demo 复现
将 keyframe_interval = 10 替换为 image_stride = 10 可加快渲染速度。然后,取消 demo_render/config/indoor.yaml 中相机跟随部分的注释,并将鸟瞰范围设置为 [2000, 2500],以复现 Demo 中展示的室内飞行穿越效果:
https://github.com/user-attachments/assets/21b444ea-e6b6-48f0-8b34-3acad41166ac
实操示例 — 户外驾驶场景
数据集: 从 Hugging Face 上的 robbyant/lingbot-map-demo 下载示例视频。
python demo_render/batch_demo.py \
--video_path /data/demo_videos/drive_frames.mp4 \
--output_folder /data/outputs/drive/ \
--model_path /path/to/lingbot-map.pt \
--config demo_render/config/outdoor_drive.yaml \
--mode windowed --window_size 128 \
--max_non_keyframe_gap 100 --overlap_keyframes 8 \
--image_stride 1 \
--sky_mask_dir /data/outputs/sky_masks \
--sky_mask_visualization_dir /data/outputs/sky_mask_viz \
--camera_vis default --keyframes_only_points \
--frame_tag --frame_tag_position top_right \
--save_predictions
与上文室内示例的不同之处如下:
| 参数 | 为什么需要它 |
|---|---|
--config demo_render/config/outdoor_drive.yaml |
从室外预设中读取默认配置:启用天空掩膜,使用更深的渲染范围(max_depth: 250),并采用一个针对车辆轨迹调优的跟随相机,最后以鸟瞰视角收尾。 |
--image_stride 1 |
使用视频中的每一帧。可提高该值,对较长或高帧率的车行素材进行降采样。 |
--max_non_keyframe_gap 100 |
连续非关键帧的最大间隔,达到该值后强制选取一个关键帧。仅在基于光流的关键帧选择(--flow_threshold > 0)下生效;在默认的固定间隔模式下无影响。 |
其余参数(--mode windowed --window_size 128、--overlap_keyframes 8、天空掩膜缓存、叠加层、--save_predictions)沿用上文的室内示例,无需修改——参见上文的逐项参数表。
完整示例 — LingBot-World 场景
重建由 LingBot-World(我们的世界模型)生成的视频——同一套流水线可直接处理生成素材。
数据集: 下载示例视频(lingbo_world_frames.mp4、lingbo_world2_frames.mp4),可从 Hugging Face 上的 robbyant/lingbot-map-demo 获取。
python demo_render/batch_demo.py \
--video_path /data/demo_videos/lingbo_world_frames.mp4 \
--output_folder /data/outputs/lingbo_world/ \
--model_path /path/to/lingbot-map.pt \
--config demo_render/config/outdoor_drive.yaml \
--mode windowed --window_size 128 \
--max_non_keyframe_gap 100 --overlap_keyframes 8 \
--image_stride 1 \
--sky_mask_dir /data/outputs/sky_masks \
--sky_mask_visualization_dir /data/outputs/sky_mask_viz \
--camera_vis default --keyframes_only_points \
--frame_tag --frame_tag_position top_right \
--save_predictions
对于第二个视频片段,运行相同命令,并指定 --video_path /data/demo_videos/lingbo_world2_frames.mp4 --output_folder /data/outputs/lingbo_world2/(若希望将缓存掩码分开保存,请为 --sky_mask_dir 和 --sky_mask_visualization_dir 分别指定独立的目录)。
所有参数均与上文中的 户外驾驶场景 一致,仅输入视频和输出目录有所不同。有关逐项参数的说明,请参考驾驶场景与室内漫游表格中的内容。
相机路径(YAML)
虚拟相机路径由通过 --config 传入的 YAML 预设中的 camera.segments 列表描述。编辑 YAML 即可设计自定义镜头,无需修改命令行参数。
内置预设位于 demo_render/config/:default.yaml、indoor.yaml、outdoor_drive.yaml。复制其中一个,并编辑其中的 camera: 块。
YAML 结构
camera:
fov: 60.0 # camera field of view in degrees
transition: 30 # frames blended between adjacent segments
segments:
- mode: follow # chase cam following the input trajectory
frames: [0, 1500] # rendered-frame range this segment covers (-1 = end)
back_offset: 0.3 # how far behind the input camera (fraction of scene scale)
up_offset: 0.08 # vertical lift above the input camera
look_offset: 0.4 # how far ahead the lookat target points
smooth_window: 30 # trajectory smoothing window in frames
- mode: birdeye # rise up for a top-down reveal of the whole scene
frames: [1500, 1800]
reveal_height_mult: 2.5 # birdeye height = scene scale × this factor
- mode: follow # drop back into chase cam
frames: [1800, -1]
back_offset: 0.3
up_offset: 0.08
look_offset: 0.4
transition 控制相邻片段之间进行混合的帧数;frames: [0, -1] 表示“整个序列”。
可用模式
mode |
行为 | 可调字段 |
|---|---|---|
follow |
追迹相机以平滑偏移跟随输入轨迹。是虚拟漫游中最具电影感的选项。 | back_offset, up_offset, look_offset, smooth_window, scale_frames |
birdeye |
自上而下展现整个场景。适用于主体展示 / 概览镜头。 | reveal_height_mult |
static |
固定视点 + 注视目标,并自动从片段起始帧推导。 | — |
pivot |
固定视点,注视目标沿轨迹扫掠。 | — |
单镜头 YAML 示例
纯跟随(最常见):
camera:
fov: 60.0
segments:
- mode: follow
frames: [0, -1]
back_offset: 0.3
up_offset: 0.08
look_offset: 0.4
smooth_window: 30
全鸟瞰视角(适合总览 / 主视觉镜头):
camera:
fov: 60.0
segments:
- mode: birdeye
frames: [0, -1]
reveal_height_mult: 2.5
跟随镜头并插入鸟瞰视角:只需在 segments: 下按顺序列出多个片段 —— 相邻片段会通过 transition 帧进行插值。
注意:当
--config加载 YAML 预设时,传入任意用于片段调型的 CLI 参数(--camera_mode、--back_offset、--up_offset、--look_offset、--smooth_window、--follow_scale_frames、--birdeye_start、--birdeye_duration、--reveal_height_mult)都会丢弃 YAML 中的segments,并改为根据这些参数重建相机路径。若要完全由 YAML 驱动,请勿在命令行中传入其中任意一个。
输出文件
对于给定的输出名称(例如 <scene> 或 <video_name>):
| 文件 | 描述 |
|---|---|
<name>_pointcloud.mp4 |
渲染后的点云飞越视频 |
<name>_pointcloud_rgb.mp4 |
由原始 RGB 帧编码而成的视频 |
<name>_pointcloud_config.yaml |
本次运行的完整配置快照 |
batch_results.json |
按场景统计的成功状态 / 耗时摘要 |
📜 许可证
本项目基于 Apache License 2.0 许可证发布。详见 LICENSE 文件。
📖 引用
@article{chen2026geometric,
title={Geometric Context Transformer for Streaming 3D Reconstruction},
author={Chen, Lin-Zhuo and Gao, Jian and Chen, Yihang and Cheng, Ka Leong and Sun, Yipengjing and Hu, Liangxiao and Xue, Nan and Zhu, Xing and Shen, Yujun and Yao, Yao and Xu, Yinghao},
journal={arXiv preprint arXiv:2604.14141},
year={2026}
}
✨ 致谢
我们感谢 Shangzhan Zhang、Jianyuan Wang、Yudong Jin、Christian Rupprecht 和 Xun Cao 提供的有益讨论与支持。
本工作基于多个优秀的开源项目: