CAIR-HKISI/SurgMotion

Official Code for "SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos"

Python

130

380 commits

updated Apr 1, 2026

See the code

README

SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos

Project Page arXiv GitHub HuggingFace

Main

SurgMotion is a video-native foundation model that shifts the learning paradigm from pixel-level reconstruction to latent motion prediction, with technical innovations tailored to surgical videos, built on top of V-JEPA 2.

Model Overview

Framework Key innovations:

  • Latent motion prediction — shifts from pixel-level reconstruction to abstract motion forecasting in latent space
  • Flow-Guided Latent Prediction — a novel objective that prevents feature collapse in homogeneous surgical tissue regions
  • Pre-trained on SurgMotion-15M — the largest multi-modal surgical video dataset to date (15M frames, 3,658 hours, 13+ anatomical regions)

Model Variants

VariantBackboneParametersPre-training Data
SurgMotion-LViT-Large300MSurgMotion-15M
SurgMotion-GViT-Giant-xformer1BSurgMotion-15M

Architecture

  1. Video Encoder (ViT) — processes 64-frame surgical video clips into spatiotemporal token sequences
  2. Latent Predictor — predicts masked region representations in latent space guided by optical flow
  3. Probing Head — lightweight temporal classifier for downstream phase recognition

Performance Highlights

SurgMotion achieves SOTA on all representative surgical tasks (workflow, action, segmentation, triplet, skill, depth estimation). For detailed results, see our paper and project page.

Quick Start

Project Structure

SurgMotion/
├── src/                        # V-JEPA2 core: ViT, VideoMAE, datasets, masks
├── evals/                      # Evaluation entry points & foundation phase probing
│   ├── main.py                 # Single-task entry: python -m evals.main --fname <yaml>
│   └── foundation_phase_probing/
│       ├── eval.py             # Probing evaluation logic
│       ├── models.py           # Probing head definitions
│       └── modelcustom/        # Per-model adapters (SurgMotion, DINOv3, SurgVLP, …)
├── configs/
│   └── foundation_model_probing/
│       ├── surgmotion/         # YAML configs per dataset
│       ├── dinov3/
│       ├── endofm/
│       ├── …                   # 15 model families supported
│       └── videomaev2/
├── data_process/               # End-to-end dataset preprocessing scripts
│   ├── autolaparo_prepare.py
│   ├── cholect80_prepare.py
│   ├── egosurgery_prepare.py
│   ├── m2cai2016_prepare.py
│   ├── ophnet_prepare.py
│   ├── pitvis_prepare.py
│   ├── pmlr50_prepare.py
│   ├── polypdiag_prepare.py
│   └── surgicalactions160_prepare.py
├── ckpts/                      # Store all the foundation models
├── scripts/                    # Batch probing & environment setup shells
├── foundation_models/          # Third-party model implementations (git submodules)
├── data/                       # Data directory
├── setup.py                    # pip install -e .
└── requirements.txt            # All dependencies (excluding EndoMamba)

Environment Installation

conda create -n SurgMotion python=3.12 -y
conda activate SurgMotion

# Install PyTorch matching your CUDA version first:
# https://pytorch.org/get-started/locally/

pip install -e .

EndoMamba (Separate Environment)

EndoMamba requires its own Conda env with custom CUDA extensions. Do not mix with the main environment.

bash scripts/srun_endomamba_complie.sh   # Creates env + compiles extensions
conda activate endomamba                 # Use only for EndoMamba configs

Dependency Files

FileScope
requirements.txtAll dependencies (V-JEPA2 core + foundation probing)
setup.pypip install -e . reads requirements.txt automatically

EndoMamba has its own isolated environment managed by scripts/srun_endomamba_complie.sh.

Data Preparation

All preprocessing scripts under data_process/ now follow a unified end-to-end pipeline and support one-command execution:

python data_process/<dataset>_prepare.py --step all

Common step options:

--step all|frames|metadata|clips
--window_size 64
--stride 1
--fps 1
--no_padding

Typical outputs:

  • clip_infos/*.txt — per-case frame path lists
  • {train,val,test}_metadata.csv — frame-level metadata for dense clip generation
  • clips_<window_size>f/{train,val,test}_dense_<window_size>f_detailed.csv
  • clips_<window_size>f/clip_dense_<window_size>f_info/{train,val,test}/*.txt

Frame-level metadata schema:

ColumnDescription
Case_IDNumeric case / video identifier
Frame_PathAbsolute/relative frame image path
Phase_GTInteger phase/class id for this frame
Phase_NameHuman-readable phase/class name

Dense Sampling Strategy

We use an online workflow recognition setting:

  • A clip is a sliding temporal window.
  • The last frame in the window is the target frame to predict.
  • Previous frames in the window are temporal context.
  • Neighboring windows overlap.

For window_size=64, stride=1:

  • clip 1: frames [0, ..., 63]
  • clip 2: frames [1, ..., 64]
  • clip 3: frames [2, ..., 65]

Padding at video start:

  • If the early timeline does not have enough preceding frames, we pad the window by repeating the current window's last frame.
  • This behavior is enabled by default; use --no_padding to disable.

Clip Labeling Rule

For phase recognition:

  • Frames are sampled at 1 fps.
  • Clip label = label of the clip's last frame.

Example:

  • frames 0-40: Phase 0
  • frames 41-63: Phase 1
  • clip [0, ..., 63] label is Phase 1.

Notes on Performance Gaps

If reproduced results are lower than expected, dense sampling mismatch is one possible source, but not the only one. We also recommend checking:

  • longer training schedules (e.g., 2 / 4 / 8 epochs)
  • class balancing / class weighting strategy

Class weighting can strongly affect surgical long-tail performance. See implementation in evals/foundation_phase_probing/eval.py.

Supported Datasets

Most datasets already provide extracted frames in data/Surge_Frames/.... The pipelines read annotations and frames; frame extraction from videos (--step frames) is optional and only needed if you have raw mp4 files.

DatasetScriptAnnotation PathFrames PathExtract?
Cholec80cholect80_prepare.pycholec80/phase_annotationsSurge_Frames/Cholec80/frames/{videoXX}/Optional
AutoLaparoautolaparo_prepare.pyautolaparo/task1/labelsSurge_Frames/AutoLaparo/frames/{NN}/Optional
M2CAI2016m2cai2016_prepare.pym2cai16/{train,test}_datasetSurge_Frames/M2CAI16/frames/{video}/No
EgoSurgeryegosurgery_prepare.pyEgoSurgery/annotations/phaseSurge_Frames/EgoSurgery/frames/{video_id}/No
PitVispitvis_prepare.pypitvits/26531686Surge_Frames/PitVis/frames/video_{XX}/No
OphNet2024ophnet_prepare.pyOphNet2024_trimmed_phase/*.csvSurge_Frames/OphNet2024_phase/frames/No
PmLR50pmlr50_prepare.pyPmLR50/PmLR50/labels/*.pickleSurge_Frames/PmLR50/frames/{XX}/No
SurgicalActions160surgicalactions160_prepare.py(from video filenames)Surge_Frames/SurgicalActions160_v1/frames/Yes
PolypDiagpolypdiag_prepare.py(from video filenames)Surge_Frames/PolypDiag/frames/Yes

All annotation and frame paths above are relative to the data/ directory (e.g., data/Landscopy/cholec80/phase_annotations).

Pipeline behavior

The scripts are built around frame-based clip CSVs. Depending on whether you already have extracted frames or only raw videos, use the path that matches your data.

You already have image sequences under --frames_root (e.g. data/Surge_Frames/...).

StepWhat it does
--step allRuns metadata → clips. Does not decode videos in most scripts (see table below).
--step metadataBuilds {train,val,test}_metadata.csv from annotations + Frame_Path.
--step clipsWrites dense sliding-window clip lists and detailed CSVs via gen_clips.py.

Typical command: python data_process/<dataset>_prepare.py --step all with correct --frames_root / annotation paths. No --videos_dir needed.

2) Videos-first input (optional extraction)

You only have .mp4 files and need JPEG/PNG frames under --frames_root first.

StepWhat it does
--step framesDecodes videos → frames (needs a directory of mp4s; flag name varies by script, usually --videos_dir or dataset-specific video roots).
ThenRun --step all or --step metadata then --step clips on the extracted frames.

Typical two-stage flow:

python data_process/<dataset>_prepare.py --step frames --videos_dir /path/to/mp4s  # if supported
python data_process/<dataset>_prepare.py --step all

3) How --step all treats frame extraction

Script--step all runs video→frames?Notes
cholect80_prepare.pyYes, if --videos_dir existsIf the directory is missing, extraction is skipped and existing --frames_root is assumed.
autolaparo_prepare.pyNoUse --step frames explicitly, then --step all or metadata + clips.
m2cai2016_prepare.py, pitvis_prepare.py, ophnet_prepare.py, pmlr50_prepare.py, egosurgery_prepare.pyNoSame as AutoLaparo: extraction is only --step frames.
surgicalactions160_prepare.py, polypdiag_prepare.pyYesall runs the full video pipeline (including optional rename where applicable), then metadata and clips.

Quick reference: flags vs. input type

You haveUse
Frames on disk--step all (or metadata + clips only). Point --frames_root at the image folders.
Only videos--step frames first (where supported), with the script’s video path argument, then --step all.
Bundled Surge_Frames + annotationsFrames-first row above; no extraction step.

Example: Prepare Cholec80

python data_process/cholect80_prepare.py \
    --frames_root data/Surge_Frames/Cholec80/frames \
    --annot_dir data/Landscopy/cholec80/phase_annotations \
    --output_dir data/Surge_Frames/Cholec80 \
    --step all \
    --debug

Example: Prepare SurgicalActions160 (with extraction)

python data_process/surgicalactions160_prepare.py \
    --src_root data/Landscopy/SurgicalActions160 \
    --fps 1 \
    --step all

Run Foundation Probing

Supported Foundation Models

ModelIdentifierArchitectureSource
DINOv3dinov3ViT-L, ViT-HGitHub
Endo-FMendofmViT-BGitHub
EndoMambaendomambaMamba-SGitHub
EndoSSLendosslViT-LGitHub
EndoViTendovitViT-LGitHub
GastroNetgastronetViT-SIEEE Xplore
GSViTgsvitViTGitHub
SelfSupSurgselfsupsurgResNet-50GitHub
SurgeNetsurgenetCAFormer-XL, ConvNeXtV2GitHub
SurgVLPsurgvlpResNet-50GitHub
VideoMAEv2videomaev2ViT-L, ViT-H, ViT-gGitHub

Model Preparation

  1. Download Model Weights from their corresponding repos.
  2. Put the Model under the ckpts folder:
# For SurgMotion
SurgMotion/ckpts 

# For Other Foundation Models
SurgMotion/ckpts/ckpts_foundation 
  1. Make sure the model path align with the corresponding adapters.py:
# For Other Foundation Models
SurgMotion/evals/foundation_phase_probing/modelcustom/adapters

Single Task

# SurgMotion
python -m evals.main \
    --fname configs/foundation_model_probing/surgmotion/AutoLaparo/surgmotion_vitl_64f_autolaparo.yaml \
    --devices cuda:0

# Dinov3
python -m evals.main \
    --fname configs/foundation_model_probing/dinov3/AutoLaparo/dinov3_vitl_64f_autolaparo.yaml \
    --devices cuda:0

Batch (Multi-GPU Parallel)

Edit the task list in scripts/run_foundation_probing.sh, then run:

bash scripts/run_foundation_probing.sh

The script auto-assigns one GPU per task from the available pool (default: all 8 GPUs). Logs are saved under logs/foundation/<Dataset>/.

Add a New Dataset

  1. Create data_process/<dataset>_prepare.py following the existing template (see polypdiag_prepare.py for reference).
  2. Output frame-level metadata CSVs with schema: Case_ID, Frame_Path, Phase_GT, Phase_Name.
  3. Generate dense clips via gen_clips.py (or --step clips) to produce clips_64f/*_dense_64f_detailed.csv.
  4. Create YAML configs under configs/foundation_model_probing/<model>/<Dataset>/.

Add a New Foundation Model

  1. Write an adapter under evals/foundation_phase_probing/modelcustom/adapters/:
# Input:  any shape, e.g. [B, C, F, H, W]
# Output: [B, F*N, D]  (spatial-temporal tokens)
  1. Register the model in evals/foundation_phase_probing/modelcustom/foundation_model_wrapper.py:
elif model_type == 'your_model':
    from .adapters.your_model_adapter import YourModelAdapter
    adapter = YourModelAdapter.from_config(
        resolution=resolution,
        checkpoint=checkpoint,
        model_name=model_name
    )
  1. Create YAML configs under configs/foundation_model_probing/your_model/<Dataset>/.
  2. Add entries to scripts/run_foundation_probing.sh and run.

Acknowledgement

This project is built on top of V-JEPA 2 by Meta. We sincerely thank the authors of the following works whose open-source models were used in our benchmark:

DINOv2 | Endo-FM | EndoMamba | EndoSSL | EndoViT | GastroNet | GSViT | SelfSupSurg | SurgeNet | SurgVISTA | SurgVLP | VideoMAEv2

Reference

If you find our work helpful, please cite our paper.

@misc{wu2026surgmotionvideonativefoundationmodel,
      title={SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos}, 
      author={Jinlin Wu and Felix Holm and Chuxi Chen and An Wang and Yaxin Hu and Xiaofan Ye and Zelin Zang and Miao Xu and Lihua Zhou and Huai Liao and Danny T. M. Chan and Ming Feng and Wai S. Poon and Hongliang Ren and Dong Yi and Nassir Navab and Gaofeng Meng and Jiebo Luo and Hongbin Liu and Zhen Lei},
      year={2026},
      eprint={2602.05638},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2602.05638}, 
}

Centre for Artificial Intelligence and Robotics, Hong Kong Institute of Science and Innovation, CAS

Project Page | Paper | Hugging Face

Contributors

yichuan9527

278 commits

Userccx

56 commits

felixholm

29 commits

ballasnicolas

4 commits

CAIR-HKISI/SurgMotion

Official Code for "SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos"

Python

130

380 commits

updated Apr 1, 2026

See the code

README

SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos

Project Page arXiv GitHub HuggingFace

Main

SurgMotion is a video-native foundation model that shifts the learning paradigm from pixel-level reconstruction to latent motion prediction, with technical innovations tailored to surgical videos, built on top of V-JEPA 2.

Model Overview

Framework Key innovations:

  • Latent motion prediction — shifts from pixel-level reconstruction to abstract motion forecasting in latent space
  • Flow-Guided Latent Prediction — a novel objective that prevents feature collapse in homogeneous surgical tissue regions
  • Pre-trained on SurgMotion-15M — the largest multi-modal surgical video dataset to date (15M frames, 3,658 hours, 13+ anatomical regions)

Model Variants

VariantBackboneParametersPre-training Data
SurgMotion-LViT-Large300MSurgMotion-15M
SurgMotion-GViT-Giant-xformer1BSurgMotion-15M

Architecture

  1. Video Encoder (ViT) — processes 64-frame surgical video clips into spatiotemporal token sequences
  2. Latent Predictor — predicts masked region representations in latent space guided by optical flow
  3. Probing Head — lightweight temporal classifier for downstream phase recognition

Performance Highlights

SurgMotion achieves SOTA on all representative surgical tasks (workflow, action, segmentation, triplet, skill, depth estimation). For detailed results, see our paper and project page.

Quick Start

Project Structure

SurgMotion/
├── src/                        # V-JEPA2 core: ViT, VideoMAE, datasets, masks
├── evals/                      # Evaluation entry points & foundation phase probing
│   ├── main.py                 # Single-task entry: python -m evals.main --fname <yaml>
│   └── foundation_phase_probing/
│       ├── eval.py             # Probing evaluation logic
│       ├── models.py           # Probing head definitions
│       └── modelcustom/        # Per-model adapters (SurgMotion, DINOv3, SurgVLP, …)
├── configs/
│   └── foundation_model_probing/
│       ├── surgmotion/         # YAML configs per dataset
│       ├── dinov3/
│       ├── endofm/
│       ├── …                   # 15 model families supported
│       └── videomaev2/
├── data_process/               # End-to-end dataset preprocessing scripts
│   ├── autolaparo_prepare.py
│   ├── cholect80_prepare.py
│   ├── egosurgery_prepare.py
│   ├── m2cai2016_prepare.py
│   ├── ophnet_prepare.py
│   ├── pitvis_prepare.py
│   ├── pmlr50_prepare.py
│   ├── polypdiag_prepare.py
│   └── surgicalactions160_prepare.py
├── ckpts/                      # Store all the foundation models
├── scripts/                    # Batch probing & environment setup shells
├── foundation_models/          # Third-party model implementations (git submodules)
├── data/                       # Data directory
├── setup.py                    # pip install -e .
└── requirements.txt            # All dependencies (excluding EndoMamba)

Environment Installation

conda create -n SurgMotion python=3.12 -y
conda activate SurgMotion

# Install PyTorch matching your CUDA version first:
# https://pytorch.org/get-started/locally/

pip install -e .

EndoMamba (Separate Environment)

EndoMamba requires its own Conda env with custom CUDA extensions. Do not mix with the main environment.

bash scripts/srun_endomamba_complie.sh   # Creates env + compiles extensions
conda activate endomamba                 # Use only for EndoMamba configs

Dependency Files

FileScope
requirements.txtAll dependencies (V-JEPA2 core + foundation probing)
setup.pypip install -e . reads requirements.txt automatically

EndoMamba has its own isolated environment managed by scripts/srun_endomamba_complie.sh.

Data Preparation

All preprocessing scripts under data_process/ now follow a unified end-to-end pipeline and support one-command execution:

python data_process/<dataset>_prepare.py --step all

Common step options:

--step all|frames|metadata|clips
--window_size 64
--stride 1
--fps 1
--no_padding

Typical outputs:

  • clip_infos/*.txt — per-case frame path lists
  • {train,val,test}_metadata.csv — frame-level metadata for dense clip generation
  • clips_<window_size>f/{train,val,test}_dense_<window_size>f_detailed.csv
  • clips_<window_size>f/clip_dense_<window_size>f_info/{train,val,test}/*.txt

Frame-level metadata schema:

ColumnDescription
Case_IDNumeric case / video identifier
Frame_PathAbsolute/relative frame image path
Phase_GTInteger phase/class id for this frame
Phase_NameHuman-readable phase/class name

Dense Sampling Strategy

We use an online workflow recognition setting:

  • A clip is a sliding temporal window.
  • The last frame in the window is the target frame to predict.
  • Previous frames in the window are temporal context.
  • Neighboring windows overlap.

For window_size=64, stride=1:

  • clip 1: frames [0, ..., 63]
  • clip 2: frames [1, ..., 64]
  • clip 3: frames [2, ..., 65]

Padding at video start:

  • If the early timeline does not have enough preceding frames, we pad the window by repeating the current window's last frame.
  • This behavior is enabled by default; use --no_padding to disable.

Clip Labeling Rule

For phase recognition:

  • Frames are sampled at 1 fps.
  • Clip label = label of the clip's last frame.

Example:

  • frames 0-40: Phase 0
  • frames 41-63: Phase 1
  • clip [0, ..., 63] label is Phase 1.

Notes on Performance Gaps

If reproduced results are lower than expected, dense sampling mismatch is one possible source, but not the only one. We also recommend checking:

  • longer training schedules (e.g., 2 / 4 / 8 epochs)
  • class balancing / class weighting strategy

Class weighting can strongly affect surgical long-tail performance. See implementation in evals/foundation_phase_probing/eval.py.

Supported Datasets

Most datasets already provide extracted frames in data/Surge_Frames/.... The pipelines read annotations and frames; frame extraction from videos (--step frames) is optional and only needed if you have raw mp4 files.

DatasetScriptAnnotation PathFrames PathExtract?
Cholec80cholect80_prepare.pycholec80/phase_annotationsSurge_Frames/Cholec80/frames/{videoXX}/Optional
AutoLaparoautolaparo_prepare.pyautolaparo/task1/labelsSurge_Frames/AutoLaparo/frames/{NN}/Optional
M2CAI2016m2cai2016_prepare.pym2cai16/{train,test}_datasetSurge_Frames/M2CAI16/frames/{video}/No
EgoSurgeryegosurgery_prepare.pyEgoSurgery/annotations/phaseSurge_Frames/EgoSurgery/frames/{video_id}/No
PitVispitvis_prepare.pypitvits/26531686Surge_Frames/PitVis/frames/video_{XX}/No
OphNet2024ophnet_prepare.pyOphNet2024_trimmed_phase/*.csvSurge_Frames/OphNet2024_phase/frames/No
PmLR50pmlr50_prepare.pyPmLR50/PmLR50/labels/*.pickleSurge_Frames/PmLR50/frames/{XX}/No
SurgicalActions160surgicalactions160_prepare.py(from video filenames)Surge_Frames/SurgicalActions160_v1/frames/Yes
PolypDiagpolypdiag_prepare.py(from video filenames)Surge_Frames/PolypDiag/frames/Yes

All annotation and frame paths above are relative to the data/ directory (e.g., data/Landscopy/cholec80/phase_annotations).

Pipeline behavior

The scripts are built around frame-based clip CSVs. Depending on whether you already have extracted frames or only raw videos, use the path that matches your data.

You already have image sequences under --frames_root (e.g. data/Surge_Frames/...).

StepWhat it does
--step allRuns metadata → clips. Does not decode videos in most scripts (see table below).
--step metadataBuilds {train,val,test}_metadata.csv from annotations + Frame_Path.
--step clipsWrites dense sliding-window clip lists and detailed CSVs via gen_clips.py.

Typical command: python data_process/<dataset>_prepare.py --step all with correct --frames_root / annotation paths. No --videos_dir needed.

2) Videos-first input (optional extraction)

You only have .mp4 files and need JPEG/PNG frames under --frames_root first.

StepWhat it does
--step framesDecodes videos → frames (needs a directory of mp4s; flag name varies by script, usually --videos_dir or dataset-specific video roots).
ThenRun --step all or --step metadata then --step clips on the extracted frames.

Typical two-stage flow:

python data_process/<dataset>_prepare.py --step frames --videos_dir /path/to/mp4s  # if supported
python data_process/<dataset>_prepare.py --step all

3) How --step all treats frame extraction

Script--step all runs video→frames?Notes
cholect80_prepare.pyYes, if --videos_dir existsIf the directory is missing, extraction is skipped and existing --frames_root is assumed.
autolaparo_prepare.pyNoUse --step frames explicitly, then --step all or metadata + clips.
m2cai2016_prepare.py, pitvis_prepare.py, ophnet_prepare.py, pmlr50_prepare.py, egosurgery_prepare.pyNoSame as AutoLaparo: extraction is only --step frames.
surgicalactions160_prepare.py, polypdiag_prepare.pyYesall runs the full video pipeline (including optional rename where applicable), then metadata and clips.

Quick reference: flags vs. input type

You haveUse
Frames on disk--step all (or metadata + clips only). Point --frames_root at the image folders.
Only videos--step frames first (where supported), with the script’s video path argument, then --step all.
Bundled Surge_Frames + annotationsFrames-first row above; no extraction step.

Example: Prepare Cholec80

python data_process/cholect80_prepare.py \
    --frames_root data/Surge_Frames/Cholec80/frames \
    --annot_dir data/Landscopy/cholec80/phase_annotations \
    --output_dir data/Surge_Frames/Cholec80 \
    --step all \
    --debug

Example: Prepare SurgicalActions160 (with extraction)

python data_process/surgicalactions160_prepare.py \
    --src_root data/Landscopy/SurgicalActions160 \
    --fps 1 \
    --step all

Run Foundation Probing

Supported Foundation Models

ModelIdentifierArchitectureSource
DINOv3dinov3ViT-L, ViT-HGitHub
Endo-FMendofmViT-BGitHub
EndoMambaendomambaMamba-SGitHub
EndoSSLendosslViT-LGitHub
EndoViTendovitViT-LGitHub
GastroNetgastronetViT-SIEEE Xplore
GSViTgsvitViTGitHub
SelfSupSurgselfsupsurgResNet-50GitHub
SurgeNetsurgenetCAFormer-XL, ConvNeXtV2GitHub
SurgVLPsurgvlpResNet-50GitHub
VideoMAEv2videomaev2ViT-L, ViT-H, ViT-gGitHub

Model Preparation

  1. Download Model Weights from their corresponding repos.
  2. Put the Model under the ckpts folder:
# For SurgMotion
SurgMotion/ckpts 

# For Other Foundation Models
SurgMotion/ckpts/ckpts_foundation 
  1. Make sure the model path align with the corresponding adapters.py:
# For Other Foundation Models
SurgMotion/evals/foundation_phase_probing/modelcustom/adapters

Single Task

# SurgMotion
python -m evals.main \
    --fname configs/foundation_model_probing/surgmotion/AutoLaparo/surgmotion_vitl_64f_autolaparo.yaml \
    --devices cuda:0

# Dinov3
python -m evals.main \
    --fname configs/foundation_model_probing/dinov3/AutoLaparo/dinov3_vitl_64f_autolaparo.yaml \
    --devices cuda:0

Batch (Multi-GPU Parallel)

Edit the task list in scripts/run_foundation_probing.sh, then run:

bash scripts/run_foundation_probing.sh

The script auto-assigns one GPU per task from the available pool (default: all 8 GPUs). Logs are saved under logs/foundation/<Dataset>/.

Add a New Dataset

  1. Create data_process/<dataset>_prepare.py following the existing template (see polypdiag_prepare.py for reference).
  2. Output frame-level metadata CSVs with schema: Case_ID, Frame_Path, Phase_GT, Phase_Name.
  3. Generate dense clips via gen_clips.py (or --step clips) to produce clips_64f/*_dense_64f_detailed.csv.
  4. Create YAML configs under configs/foundation_model_probing/<model>/<Dataset>/.

Add a New Foundation Model

  1. Write an adapter under evals/foundation_phase_probing/modelcustom/adapters/:
# Input:  any shape, e.g. [B, C, F, H, W]
# Output: [B, F*N, D]  (spatial-temporal tokens)
  1. Register the model in evals/foundation_phase_probing/modelcustom/foundation_model_wrapper.py:
elif model_type == 'your_model':
    from .adapters.your_model_adapter import YourModelAdapter
    adapter = YourModelAdapter.from_config(
        resolution=resolution,
        checkpoint=checkpoint,
        model_name=model_name
    )
  1. Create YAML configs under configs/foundation_model_probing/your_model/<Dataset>/.
  2. Add entries to scripts/run_foundation_probing.sh and run.

Acknowledgement

This project is built on top of V-JEPA 2 by Meta. We sincerely thank the authors of the following works whose open-source models were used in our benchmark:

DINOv2 | Endo-FM | EndoMamba | EndoSSL | EndoViT | GastroNet | GSViT | SelfSupSurg | SurgeNet | SurgVISTA | SurgVLP | VideoMAEv2

Reference

If you find our work helpful, please cite our paper.

@misc{wu2026surgmotionvideonativefoundationmodel,
      title={SurgMotion: A Video-Native Foundation Model for Universal Understanding of Surgical Videos}, 
      author={Jinlin Wu and Felix Holm and Chuxi Chen and An Wang and Yaxin Hu and Xiaofan Ye and Zelin Zang and Miao Xu and Lihua Zhou and Huai Liao and Danny T. M. Chan and Ming Feng and Wai S. Poon and Hongliang Ren and Dong Yi and Nassir Navab and Gaofeng Meng and Jiebo Luo and Hongbin Liu and Zhen Lei},
      year={2026},
      eprint={2602.05638},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2602.05638}, 
}

Centre for Artificial Intelligence and Robotics, Hong Kong Institute of Science and Innovation, CAS

Project Page | Paper | Hugging Face

Contributors

yichuan9527

278 commits

Userccx

56 commits

felixholm

29 commits

ballasnicolas

4 commits

Languages

Python

93.0%

Cuda

4.7%

C++

1.7%