LoGo-Fuse is a training-free 3D point cloud OOD detection codebase built on frozen ULIP-2 features.
This public repository keeps the cleaned mainline only:
- local graph propagation
- global prototype refinement
- negative prototype bank
- scalar local/global fusion
Historical experimental branches such as gsp_ot, old OT/OODD scoring, geometry-side fusion branches, and legacy few-shot prototype clustering variants are not part of the intended public workflow.
Included:
main_logofuse.pyood_methods/,models/,utils/data/metadata and dataset configstools/helper scripts
Not included in GitHub:
- checkpoints (
*.pt,*.pth) - dataset binaries (
*.dat) - runtime caches and logs (
outputs/,logs_*)
Python 3.10+ is recommended.
CUDA is required for ULIP-2 evaluation in this repository.
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install -r requirements.txtInstall PyTorch separately for your CUDA version. Example for CUDA 11.8:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118Optional acceleration for PointBERT KNN:
pip install --no-build-isolation git+https://github.com/unlimblue/KNN_CUDA.gitIf knn_cuda is not installed, LoGo-Fuse falls back to the built-in torch KNN implementation.
Download the ULIP-2 checkpoint:
Place it at the repository root as:
ULIP-2-PointBERT-8k-xyz-pc-slip_vit_b-objaverse-pretrained.pt
or override with:
export TEST_CKPT_ADDR=/abs/path/to/ULIP-2-PointBERT-8k-xyz-pc-slip_vit_b-objaverse-pretrained.ptDownload the dat bundle:
Expected paths:
data/scanobjectnn15_normal_resampled/scanobjectnn15_train_2048pts_fps.dat
data/scanobjectnn15_normal_resampled/scanobjectnn15_test_2048pts_fps.dat
data/shapenetcore54_normal_resampled/shapenetcore54_train_4096pts_fps.dat
data/shapenetcore54_normal_resampled/shapenetcore54_test_4096pts_fps.dat
data/modelnet40_normal_resampled/modelnet40_train_8192pts_fps.dat
data/modelnet40_normal_resampled/modelnet40_test_8192pts_fps.dat
The repository already includes the required lightweight metadata such as:
data/templates.jsondata/labels.jsondata/SR,data/SN,data/MN*_train.txt,*_test.txt,*_shape_names.txt
This repository currently documents three evaluation tracks.
Zero-shot example (SN1):
python main_logofuse.py \
--model ULIP_PointBERT --method logofuse --evaluate_3d \
--dataset_name ShapeNetCore54 --dataset_split SN1 \
--npoints 4096 --validate_dataset_prompt shapenet_64 \
--test_ckpt_addr "${TEST_CKPT_ADDR}" --shot 0Full-shot example (SN1):
python main_logofuse.py \
--model ULIP_PointBERT --method logofuse --evaluate_3d \
--dataset_name ShapeNetCore54 --dataset_split SN1 \
--npoints 4096 --validate_dataset_prompt shapenet_64 \
--test_ckpt_addr "${TEST_CKPT_ADDR}" --shot 999999Officially this track is used for SR1 and SR2.
The target/eval dataset remains ScanObjectNN15. Synthetic support is injected through a custom train .dat via --scanobject_train_dat.
The support .dat must already be prepared in a ScanObject-compatible label space.
Helper script:
bash tools/run_synth2real_sr12.sh /abs/path/to/modelnet_as_support_train.datOptional override for the ScanObject test dat:
SCANOBJECT_TEST_DAT=/abs/path/to/scanobject_test.dat \
bash tools/run_synth2real_sr12.sh /abs/path/to/modelnet_as_support_train.datZero-shot (SR1/SR2/SR3):
bash tools/run_zeroshot_sr123.shFull-shot (SR1/SR2/SR3):
bash tools/run_fullshot_sr123.shNegative-bank sweep (K_neg, full-shot):
bash tools/run_kneg_sweep_fullshot.sh 1 15These numbers were re-verified with the cleaned mainline configuration.
SR1:AUROC 0.930279,FPR95 0.306383SR2:AUROC 0.919289,FPR95 0.369697SR3:AUROC 0.859724,FPR95 0.530387Macro Average:AUROC 0.903097,FPR95 0.402156
SN1:AUROC 0.913809,FPR95 0.464525SN2:AUROC 0.932384,FPR95 0.338373SN3:AUROC 0.963097,FPR95 0.248195Macro Average:AUROC 0.936430,FPR95 0.350364
- logs:
logs_* - per-run summaries:
results.tsv,summary.tsv - feature cache:
outputs/feature_cache_logofuse*
- The helper scripts prefer
./.venv/bin/pythonwhen present. - The public helper scripts force
--rebuild_feature_cacheby default. This avoids stale cached features from older runs or changed code paths from contaminating final metrics. - If you run commands manually with
--cache_features, prefer pairing it with--rebuild_feature_cachefor any formal reproduction run. - Full-shot support comes from the packaged train split, or from
--scanobject_train_datin the Synth-to-Real track. - Zero-shot uses the same pipeline with
--shot 0. - The public scripts are aligned with the cleaned mainline configuration and do not rely on removed historical flags.