ZOYKU火線榜

karimknaebel/surge技術文件

karimknaebel/surge open-source repository on GitHub

多語言回退提示:當前倉庫原作者暫未發布在地化文件,已為您無縫切換至官方英文原版(English),排版及程式碼實例完整保真。
極速安裝
git clone https://github.com/karimknaebel/surge.git

🌊 SurGe: Improved Surface Geometry in Point Maps

[Paper] [arXiv] [Project Page] [Weights] [Demo] [BibTeX]

architecture

📢 News

  • 2026-11-09: Replaced NATTEN with custom Triton and Metal kernels for Neighborhood Attention.
  • 2026-09-25: Accepted to NeurIPS 2026.
  • 2026-08-21: Evaluation code released.
  • 2026-06-01: arXiv v1, inference code, weights, and demo released.

Installation

From a local clone

Clone the repository:

git clone https://github.com/karimknaebel/surge
cd surge

Then install SurGe with the Inference CLI, Gradio app, and evaluation dependencies:

uv sync --all-extras

This creates a virtual environment in .venv/. Run commands with uv run (e.g., uv run surge-infer ...), or just activate it as usual with source .venv/bin/activate.

Alternatively, with pip: pip install -e ".[cli,app,eval]"

As a library

Use SurGe in an existing project:

uv add git+https://github.com/karimknaebel/surge

Alternatively, with pip: pip install git+https://github.com/karimknaebel/surge

Usage

Python API

SurGe expects image tensors in BCHW format with unnormalized RGB values in [0, 1]. Do not apply ImageNet normalization or similar preprocessing.

import torch
from surge import SurGe

model = SurGe.from_pretrained("karimknaebel/surge-large").eval().cuda()
image = torch.rand(1, 3, 518, 518, device="cuda")

with torch.autocast("cuda", dtype=torch.float16):
    result = model.infer(image)
points = result["points"]          # (B, H, W, 3)
depth = result["depth"]            # (B, H, W)
intrinsics = result["intrinsics"]  # (B, 3, 3)

🚀 Inference CLI

Run inference on an image or a directory of images:

uv run surge-infer path/to/image.jpg --output-dir output

By default, the Inference CLI writes mesh.glb for each input image. Add output flags as needed:

uv run surge-infer path/to/images --save-maps --save-glb --save-ply

Useful options include --max-size 1200, --tokens max, --fov-x 60, --fp16, and --filter-sky. For interactive viewing, use --show-mesh to open the reconstructed mesh with trimesh, or --rerun to log the inference results to a Rerun viewer.

🖥️ Gradio App

Launch the local demo app:

uv run surge-app

The app lets you upload an image, adjust the token budget and mesh cleanup settings, view the reconstructed mesh, and download the generated maps and geometry.

📊 Evaluation

Download MoGe's processed evaluation datasets from Hugging Face and extract them under data/eval:

mkdir -p data/eval
uv run hf download Ruicheng/monocular-geometry-evaluation \
  --repo-type dataset \
  --local-dir data/eval

cd data/eval
unzip '*.zip'
cd ../..

Run the full suite:

uv run surge-eval --output eval_output/surge.json

We include official surge-large results for reference.

Output Conventions

Coordinate frames:

  • point_map.exr and point_normal_map.png: RDF (OpenCV); +X right, +Y down, +Z forward.
  • mesh.glb and point_cloud.ply: RUB; +X right, +Y up, +Z backward.

File formats:

  • depth_colorized.png: colorized depth visualization.
  • point_map.exr: float32 XYZ points. Masked pixels are NaN.
  • point_normal_map.png: unit normals. RGB stores [X, -Y, -Z] mapped from [-1, 1] to [0, 255]; invalid pixels are [127, 127, 127]. Renormalize after decoding if needed.
  • intrinsics.json: camera intrinsics as a 3×3 JSON array.
  • fov.json: horizontal and vertical fields of view in degrees.

🧩 Neighborhood Attention Decoder (NAD) Module

The NAD is implemented as a reusable PyTorch module. To reuse it outside SurGe, copy it together with the attention operators.

import torch
from surge.models.modules.heads.nad import NAD

nad = NAD(
    dim_in=[1024, None, None, None, None],
    dim_out=[None, None, None, None, 3],
    embed_dim=[1024, 512, 256, 128, 64],
    depth=[3, 3, 3, 3, 3],
).cuda()
features = [torch.rand(1, 1024, 32, 32, device="cuda"), None, None, None, None]

with torch.autocast("cuda", dtype=torch.float16):
    output = nad(features)[-1]  # (1, 3, 512, 512)

We recommend FP16 during training. It is much faster and we saw no degradation compared to FP32 in our tests. You will likely need torch.amp.GradScaler with FP16 training. BF16 also works, but its lower precision can produce slightly less clean results in the highest-resolution stages.

🧩 Point Gradient Matching ($\mathcal{L}_{\mathrm{pgm}}$)

The self-contained point gradient matching loss used to train SurGe is included for reference.

🧩 Point Map Normal Mean Angular Error ($\mathrm{MAE}_{\mathrm{normal}}$)

The normal mean angular error metric used to evaluate surface normals is included in the evaluation code.

⚖️ License

The SurGe code is released under the MIT license. The SurGe weights are released under CC BY-NC 4.0, due to the training datasets used.

🙏 Acknowledgments

We thank the MoGe project for their open-source code.

🎓 Citation

If you use our work in your research, please use the following BibTeX entry.

@inproceedings{knaebel2026surge,
    title     = {{SurGe}: Improved Surface Geometry in Point Maps},
    author    = {Knaebel, Karim and Martin Garcia, Gonzalo and Schmidt, Christian and Fradlin, Ilya and Nunes, Lucas and de Geus, Daan and Leibe, Bastian},
    year      = 2026,
    booktitle = {Advances in Neural Information Processing Systems},
}
文件鏡像歸檔自 GitHub 官方源路徑 · 造訪原專案 GitHub
最後同步快照:2026-11-09