This repository is based on Marigold, CVPR 2024 Best Paper: Repurposing Diffusion-Based Image Generators for Monocular Depth Estimation
We present ApDepth, a deterministic single-step diffusion framework for monocular depth estimation. Built upon Marigold (derived from Stable Diffusion) and fine-tuned on synthetic datasets (Hypersim and Virtual KITTI), ApDepth overcomes the feature representation bottlenecks of standard diffusion models. Ultimately, our framework achieves highly competitive geometric accuracy and exceptional object edge refinement, all while delivering significantly accelerated inference speeds.
- 2026-10-14 The paper was released on SSRN
-
2026-04-06:
ApDepth V2-0is released! - 2026-04-03: We officially release the code for ApDepth! Stage 1 feature-alignment training is maintained in ApDepth_Stage1; this repository provides Stage 2 training, inference and evaluation.
-
2026-01-15: We successfully introduce a spatial-preserving Conv Adapter and a Cosine Similarity Loss to enhance feature alignment, alongside a Pixel-level
$L_1$ Loss to establish an accurate global metric scale. -
2025-10-25: Inspired by DepthMaster, we propose a two-stage loss function training strategy based on
ApDepth V1-0. In the first stage, we perform foundational training using MSE loss. In the second stage, we learn edge structures through FFT loss. Based on this, we introduceApDepth V1-1. - 2025-10-09: We propose a novel diffusion-based depth estimation framework guided by pre-trained models.
- 2025-09-23: We change Marigold from Stochastic multi-step generation to Deterministic one-step perception.
- 2025-08-10: Trying to make some optimizations in Feature Expression.
-
2025-05-08: Clone
Marigoldto local.
We offer several ways to interact with ApDepth:
-
Local development instructions with this codebase are given below.
The Model was trained on:
- Ubuntu 22.04 LTS, Python 3.12.9, CUDA 11.8,
NVIDIA RTX 6000 Ada Generation
The inference code was tested on:
- Ubuntu 22.04 LTS, Python 3.12.9, CUDA 11.8,
NVIDIA GeForce RTX 4090
We recommend running the code in WSL2:
- Install WSL following installation guide.
- Install CUDA support for WSL following installation guide.
- Find your drives in
/mnt/<drive letter>/; check WSL FAQ for more details. Navigate to the working directory of choice.
Clone the repository (requires git):
git clone https://github.com/Haruko386/ApDepth.git
cd ApDepthUsing Conda: Alternatively, create a Python native virtual environment and install dependencies into it:
conda create -n apdepth python==3.12.9
conda activate apdepth
pip install -r requirements.txtNote
Keep the environment activated before running the inference script. Activate the environment again after restarting the terminal session.
For a streamlined setup, we provide a Docker environment that pre-installs all necessary dependencies, including PyTorch, CUDA, and evaluation tools.
1. Build the Docker Image
Ensure you have Docker installed. Run the following command in the root directory of the repository:
docker build -t apdepth:latest .2. Run the Container
To utilize GPU acceleration, ensure the NVIDIA Container Toolkit is installed. We recommend mounting your local input and output directories to easily access your inference results:
docker run --gpus all -it --rm \
-v $(pwd)/input:/workspace/ApDepth/input \
-v $(pwd)/output:/workspace/ApDepth/output \
apdepth:latest
Once inside the container, the apdepth conda environment is activated by default, and you can directly execute the inference or training scripts.-
Use selected images under
input -
Or place your images in a directory, for example, under
input/test-image, and run the following inference command.
This setting corresponds to our paper. For academic comparison, please run with this setting.
python run.py \
--checkpoint checkpoint/ApDepth \
--ensemble_size 1 \
--processing_res 0 \
--input_rgb_dir input/example-1 \
--output_dir output/example-1You can find all results in output/example-1. Enjoy!
The default settings are optimized for the best result. However, the behavior of the code can be customized:
-
Trade-offs between the accuracy and speed (for both options, larger values result in better accuracy at the cost of slower inference.)
--ensemble_size: Number of inference passes in the ensemble.--processing_res: the processing resolution; set as 0 to process the input resolution directly. When unassigned (None), will read default setting from model config. Default:768None.--output_processing_res: produce output at the processing resolution instead of upsampling it to the input resolution. Default: False.--resample_method: the resampling method used to resize images and depth predictions. This can be one ofbilinear,bicubic, ornearest. Default:bilinear.
-
--half_precisionor--fp16: Run with half-precision (16-bit float) to have faster speed and reduced VRAM usage, but might lead to suboptimal results. -
--seed: Random seed can be set to ensure additional reproducibility. Default: None (unseeded). Note: forcing--batch_size 1helps to increase reproducibility. To ensure full reproducibility, deterministic mode needs to be used. -
--batch_size: Batch size of repeated inference. Default: 0 (best value determined automatically). -
--color_map: Colormap used to colorize the depth prediction. Default: Spectral. Set toNoneto skip colored depth map generation. -
--apple_silicon: Use Apple Silicon MPS acceleration.
Install additional dependencies:
pip install -r requirements+.txt -r requirements.txtSet data directory variable (also needed in evaluation scripts) and download evaluation datasets into corresponding subfolders:
export BASE_DATA_DIR=<YOUR_DATA_DIR> # Set target data directory
wget -r -np -nH --cut-dirs=4 -R "index.html*" -P ${BASE_DATA_DIR} https://share.phys.ethz.ch/~pf/bingkedata/marigold/evaluation_dataset/Run inference and evaluation scripts, for example:
# Run inference
bash script/eval/11_infer_nyu.sh
# Evaluate predictions
bash script/eval/12_eval_nyu.shAlternatively, use the following script to evaluate all datasets.
# Evaluate all datasets
bash script/eval/00_test_all.shYou can get the result under output/eval
Important
Although the seed has been set, the results might still be slightly different on different hardware.
The workflow is Stage 1 feature alignment โ Stage 2 main training โ optional VKITTI far-depth post-training. Complete Stage 2, including its FFT refinement, before starting the optional post-training run.
Based on the previously created environment, install extended requirements:
pip install -r requirements++.txt -r requirements+.txt -r requirements.txtSet environment parameters for the data directory:
export BASE_DATA_DIR=YOUR_DATA_DIR # directory of training data
export BASE_CKPT_DIR=YOUR_CHECKPOINT_DIR # directory of pretrained checkpointDownload Stable Diffusion v2 checkpoint into ${BASE_CKPT_DIR}
Download the ViT-G checkpoint of Depth-Anything-V2 to DA2/checkpoints/depth_anything_v2_vitg.pth. The ApDepth pipeline uses it to generate the depth prior during training and inference.
Prepare Hypersim and Virtual KITTI 2 under ${BASE_DATA_DIR}. Please refer to this README for Hypersim preprocessing. Configure the training paths in config/dataset/dataset_train.yaml and prepare the validation datasets listed in config/dataset/dataset_val.yaml and config/dataset/dataset_vis.yaml.
Stage 1: feature alignment pre-training
Stage 1 is maintained separately in Haruko386/ApDepth_Stage1. Follow that repository's setup and training instructions. This repository contains only the main Stage 2 trainer; it does not include Stage 1 code or dependencies.
Stage 2: main ApDepth training
To initialize Stage 2 from an existing Stage 1 checkpoint, start a new run with
--init_checkpoint. This loads only the U-Net; optimizer and iteration counters
start fresh using the Stage 2 config. config/train_apdepth.yaml keeps far-depth
supervision disabled throughout the main training stage:
python train.py --config config/train_apdepth.yaml \
--init_checkpoint /path/to/stage1/checkpoint/iter_020000 --no_wandbThe initialization directory must contain
unet/diffusion_pytorch_model.safetensors. --init_checkpoint rejects .bin
checkpoints.
To train the main stage directly from the base model without Stage 1 initialization:
python train.py --config config/train_apdepth.yaml --no_wandbThe transition to latent frequency loss is controlled by
latent_freq_loss.gradual_transition in config/train_apdepth.yaml. When true,
the reconstruction loss weight decreases linearly from 1 to 0 between iteration
20,000 and max_iter, while the frequency-loss weight increases from 0 to 1.
When false or omitted, training preserves the original hard switch immediately
after iteration 20,000. TensorBoard records the active frequency weight as
train/freq_loss_weight.
Resume from a checkpoint, e.g.
python train.py --resume_run output/train_apdepth/checkpoint/latest --no_wandbStart this step only after Stage 2 training has finished. The new VKITTI
far-depth supervision feature is enabled by config/train_sky_finetune.yaml for
a separate post-training run initialized from the completed Stage 2 U-Net.
Measured depths in [80, 655.35] m supply an additional clipped far-depth target
before VAE encoding; missing depth remains excluded. Evaluation masks and
normalization quantiles are unchanged. The separately averaged far latent MSE
and pixel L1 terms have weight 0.5. For a post-training ablation, set
far_depth_supervision.enabled: false in the post-training config.
Use the same environment, datasets and base checkpoints prepared for Stage 2. First audit the native VKITTI depth and target coverage:
python -m script.audit_far_supervision --config config/train_sky_finetune.yaml \
--base_data_dir "${BASE_DATA_DIR}" --samples 20Check the RGB, far masks, target images and coverage.json in output/far_audit.
If preprocessing replaced the far-plane values with zero, restore the original
depth files. Zero depth is not treated as sky. Adjust each dataset config's dir
to match the actual layout under BASE_DATA_DIR.
Start a new post-training run from the final Stage 2 checkpoint (adjust the path if Stage 2 was saved elsewhere):
python train.py --config config/train_sky_finetune.yaml \
--init_checkpoint output/train_apdepth/checkpoint/iter_021000 --no_wandbThis resets the optimizer, learning-rate schedule and iteration counter, then
runs 6000 new optimization steps at LR 5e-6 with 100 warmup steps and saves
backups every 1000 steps in output/train_sky_finetune/checkpoint. It retains the
90% Hypersim / 10% VKITTI sampling, original batch settings and periodic validation.
These 6000 steps use latent MSE + pixel L1 reconstruction plus the new far-depth
loss; the Stage 2 FFT refinement has already finished. Initialization requires
unet/diffusion_pytorch_model.safetensors in the supplied checkpoint directory.
If this post-training run is interrupted, resume its own checkpoint:
python train.py --resume_run output/train_sky_finetune/checkpoint/latest --no_wandb--resume_run restores the saved config and training state. Starting post-training
requires --init_checkpoint with the post-training config above; resuming a
Stage 2 checkpoint would continue Stage 2 with its saved settings.
--resume_run and --init_checkpoint cannot be combined.
Monitor train/far_loss, train/far_pixel_ratio and train/far_latent_ratio.
Compare KITTI and NYU against the completed Stage 2 model after post-training; this change
alone does not establish a metric improvement.
Stage 2 and optional post-training update and save the U-Net. For inference, copy a complete
ApDepth pipeline checkpoint to a new directory, then replace that copy's unet/
folder with the selected training checkpoint's unet/. The pipeline's VAE,
tokenizer, text encoder and scheduler are still required; a training checkpoint
alone is not a complete inference pipeline. Then refer to evaluation.
Important
Although random seeds have been set, the training result might be slightly different on different hardwares. It's recommended to train without interruption.
Please refer to this instruction.
| Problem | Solution |
|---|---|
(Windows) Invalid DOS bash script on WSL / $'\r': command not found / set: invalid option
|
Run dos2unix <script_name> to convert script format |
(Windows) Multiple .sh scripts fail due to CRLF line endings |
Run find . -name "*.sh" -exec dos2unix {} + to fix all scripts |
(Windows) error on WSL: Could not load library libcudnn_cnn_infer.so.8. Error: libcuda.so: cannot open shared object file
|
Run export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
|
| HuggingFace model download incomplete / corrupted | Re-run with --resume-download or ensure stable network |
model_index.json not found when loading checkpoint |
Ensure the model is fully downloaded and placed at checkpoints/ApDepth/
|
Dataset loading error: tarfile.ReadError: unexpected end of data
|
Re-download dataset; the .tar file is likely corrupted or incomplete |
Please cite our paper:
@InProceedings{wang26apdepth,
title={ApDepth: Aiming for Precise Monocular Depth Estimation Based on Diffusion Models},
author={Jiawei Wang, Mingbo Lei, Haoze Shou, Yusu Liang and Yuan Shuai},
booktitle = {Arxiv},
year={2026}
}This work is licensed under the Apache License, Version 2.0 (as defined in the LICENSE).
By downloading and using the code and model you agree to the terms in the LICENSE.
