"Every other depth net was trained to answer. This one was trained to imagine, and it turns out that a machine that has imagined a billion scenes already knows roughly how far away things are."
A Generative AI Agent
Prerequisites
This section assumes the affine-invariant depth framing of Section 41.1 (a model that predicts depth up to an unknown global scale and shift) and the encoder-decoder regressors of Section 41.2, against which diffusion depth is the deliberate contrast. It leans on the projection-throws-away-range intuition of Chapter 40, and on the generative-model and latent-diffusion vocabulary introduced for neural fields in Chapter 51. Ensemble variance as an uncertainty estimate connects back to Chapter 18. You need to know what a denoising diffusion model does at a high level (iteratively turn noise into a sample); the arithmetic here is deliberately light.
Why point a text-to-image model at depth
The models in the previous sections are discriminative: an image goes in, one depth map comes out, and the network was trained by regression to match ground truth. Marigold makes a different bet. A modern text-to-image diffusion model such as Stable Diffusion has, in the course of learning to paint photorealistic scenes, absorbed an enormous implicit prior about geometry: how surfaces recede, how occlusion works, how a table leg meets a floor. Marigold recovers that latent knowledge by reformatting depth estimation as conditional image generation. Instead of regressing a number, it samples a depth map from the distribution \(p(\text{depth}\mid\text{image})\). This one shift buys three things that regressors struggle to deliver: razor-sharp object boundaries and thin structures, strong zero-shot generalization from only tens of thousands of synthetic training images, and a free uncertainty signal from the spread of multiple samples. The cost is speed, and most of this section is about that tradeoff and how the field erased it.
The core trick: depth as a latent image
What Marigold (Ke et al., CVPR 2024) does is take a frozen pretrained Stable Diffusion v2 and fine-tune it into a depth estimator with minimal surgery. Stable Diffusion already contains two reusable parts: a variational autoencoder (VAE) that compresses a \(512\times512\) image into a small latent grid, and a denoising U-Net that runs the diffusion process in that latent space. Marigold keeps both. How it conditions on the input photograph is the whole idea: encode the RGB image to its latent \(\mathbf{z}^{(x)}\) with the frozen VAE, and at every denoising step concatenate that clean image latent with the current noisy depth latent \(\mathbf{z}^{(d)}_t\) along the channel axis. The U-Net therefore always sees the image it must explain while it denoises the depth. The generative process is the standard reverse diffusion,
$$\mathbf{z}^{(d)}_{t-1} = f_\theta\!\left(\mathbf{z}^{(d)}_{t},\, \mathbf{z}^{(x)},\, t\right),\qquad t = T, T-1,\dots,1,$$started from pure Gaussian noise and run down to a clean depth latent that the VAE decoder turns back into a depth map. Why depth can ride through an image VAE at all is a small trick: depth is a single channel, so Marigold replicates it into three channels, normalizes it to the VAE's expected range, and treats it exactly like a grayscale picture. Remarkably, the image VAE reconstructs depth maps faithfully without retraining.
When this becomes practical is thanks to how little data it needs. The fine-tuning set is roughly seventy-four thousand samples drawn entirely from two synthetic datasets, Hypersim (indoor) and Virtual KITTI 2 (driving), where perfect dense ground-truth depth is free. No real depth sensor, no lidar scans, no messy captured data. Because the pretrained prior already knows what the world looks like, a few days of fine-tuning on synthetic geometry is enough to generalize zero-shot to real photographs the model never saw, echoing the leakage-safe, train-on-synthetic discipline this book keeps returning to.
Generative depth gives you uncertainty for free
A regressor emits one depth map and cannot tell you where it is guessing. Because Marigold samples, you can run it several times from different noise seeds and get several plausible depth maps. Aligning them (each is affine-invariant, so fit a per-map scale and shift first) and taking the pixelwise mean gives a cleaner estimate, while the pixelwise standard deviation is a spatial uncertainty map: it lights up on transparent glass, mirrors, sky, and far-away regions, exactly the places where a single viewpoint genuinely underdetermines depth. This test-time ensembling is the same philosophy as the deep-ensemble uncertainty of Chapter 18, obtained here without training a single extra network. Downstream fusion (Section 41.7) can then downweight high-variance pixels instead of trusting them blindly.
The catch, and how the field killed it
The original recipe has an obvious weakness: reverse diffusion is iterative. Getting a good map meant running the U-Net for many denoising steps and, for the uncertainty ensemble, repeating that whole loop ten times. That is seconds per image on a strong GPU, hopeless for a robot or a wearable that needs frames now. Three lines of work collapsed this cost, and they matter because they turn a research curiosity into a deployable sensor.
First, consistency distillation: Marigold-LCM applies latent-consistency distillation so a usable depth map appears in one to four steps instead of dozens, a roughly ten-fold speedup with little quality loss. Second, and more surprising, end-to-end single-step fine-tuning: the follow-up work "Fine-Tuning Image-Conditional Diffusion Models is Easier than You Think" (Martin Garcia et al., 2024) traced a subtle inference bug in the original pipeline and showed that once fixed, a single deterministic forward pass matches or beats the multi-step sampler. The diffusion machinery was, in the end, a very good initialization rather than a process you must run to completion. Third, flow matching: DepthFM (Gui et al., 2024) trains a straight-line transport from image to depth that likewise needs very few function evaluations. The through-line is that the geometric prior lived in the pretrained weights all along; the many-step stochastic sampler was never the point.
The pipeline in the figure makes the reuse explicit: the two VAE blocks are lifted unchanged from Stable Diffusion, and only the U-Net learns to speak depth.
Sharp boundaries where a surgeon needs them
A minimally invasive surgery research group builds a monocular depth channel for a laparoscopic endoscope, aiming to overlay a pre-operative CT model onto the live view. Discriminative depth models, trained largely on driving and indoor scenes, smear the boundary between a glistening organ and the instrument tip into a soft ramp, and the overlay drifts by millimeters at exactly the edges that matter. Swapping in a Marigold-family model changes the character of the error: the strong generative prior produces crisp, well-localized depth discontinuities along tool and tissue silhouettes, and the wet, specular highlights that wreck stereo matching are hallucinated over plausibly rather than left as holes. The team runs the single-step end-to-end variant to hold a real-time frame rate, and uses the ensemble variance from a slower offline pass to flag frames where reflections make the depth untrustworthy, so the navigation system can suppress the overlay instead of pointing the surgeon at a confident-looking mistake.
Running it, and when to reach for it
Because Marigold ships in the Hugging Face diffusers library as a first-class pipeline, using it is short. The snippet below loads the distilled latent-consistency checkpoint, runs it in a handful of steps, and asks for a small ensemble so we also get an uncertainty map.
import torch
import diffusers
# Distilled few-step checkpoint from the ETH Photogrammetry group.
pipe = diffusers.MarigoldDepthPipeline.from_pretrained(
"prs-eth/marigold-depth-lcm-v1-0",
variant="fp16", torch_dtype=torch.float16,
).to("cuda")
image = diffusers.utils.load_image("scene.jpg")
out = pipe(
image,
num_inference_steps=4, # LCM: a few steps, not dozens
ensemble_size=5, # resample to estimate uncertainty
output_uncertainty=True,
)
depth = out.prediction # affine-invariant depth, HxW in [0, 1]
sigma = out.uncertainty # per-pixel std across the ensemble
depth_png = pipe.image_processor.visualize_depth(depth)[0]
depth_png.save("depth.png")
uncertainty field is the ensemble spread discussed in the key-insight callout.The output is affine-invariant, so it is ideal for tasks that care about relative geometry (matting, relighting, novel-view synthesis, obstacle ordering) and must be anchored before it can report meters. When to choose diffusion depth over the regressors of the previous sections comes down to three questions. Do crisp boundaries and thin structures matter more than raw throughput? Do you need calibrated-ish uncertainty without training an ensemble of networks? Is your domain far from any real depth dataset, so a strong pretrained prior beats a supervised regressor? If yes, Marigold-family models are the right tool. If you need metric depth out of the box or the tightest latency on a microcontroller, the metric and distilled feed-forward models of Section 41.3 remain the safer default.
State of the art and open threads
As of 2026 the strongest results in this family come from the single-step end-to-end fine-tuned Marigold variant and from flow-matching approaches such as DepthFM, both of which match multi-step sampling at a fraction of the cost. The same fine-tune-a-generator recipe now produces surface normals, intrinsic-image decomposition, and, via video diffusion backbones, temporally consistent depth for clips (a thread picked up in Section 41.2). Open questions that matter for sensing: turning the ensemble spread into calibrated uncertainty (Chapter 18), grounding the affine-invariant output to metric scale without a separate model, and shrinking these billion-parameter priors enough for the edge budgets of Chapter 59.
The library does the diffusion plumbing
A from-scratch Marigold inference stack means wiring the VAE encode and decode, the U-Net conditioning concatenation, an LCM or DDIM scheduler, the affine alignment across ensemble members, and depth colorization: comfortably 250 to 400 lines of careful PyTorch, plus the checkpoint-loading glue. The diffusers MarigoldDepthPipeline collapses all of it to the roughly twelve lines above, a better than 20x reduction, and it handles fp16 casting, tiling for large images, scheduler selection, and the ensemble statistics for you. You write the two lines that state how many steps and how many samples; the library owns everything between noise and a colorized depth PNG.
Exercise: does imagination cost accuracy?
Take twenty photographs that include hard cases (a chain-link fence, a potted plant with thin stems, a glass door, a distant skyline). Run three models on each: a Depth Anything v2 regressor (Section 41.2), Marigold with num_inference_steps=1, and Marigold with num_inference_steps=10, ensemble_size=10. Since all three are affine-invariant, align each prediction to the others with a least-squares scale-and-shift fit before comparing. (1) Where does the diffusion model produce visibly sharper boundaries, and where does it hallucinate structure the regressor correctly leaves flat? (2) Plot per-image the Marigold uncertainty map against your subjective difficulty ranking: does the spread track the genuinely ambiguous regions (sky, glass)? (3) Measure wall-clock latency for the three settings and state, for a wearable at 15 frames per second, which one you would actually ship.
Self-check
- Marigold fine-tunes a text-to-image diffusion model on only about seventy-four thousand synthetic RGB-D samples yet generalizes to real photos. Which property of the base model makes such a tiny, synthetic-only training set sufficient?
- A discriminative regressor cannot natively report where it is uncertain, but Marigold can. What is the mechanism, and why does it require no extra trained networks?
- Later work showed a single deterministic forward pass matches multi-step sampling. What does that reveal about where the geometric prior actually lives, and why is it good news for deployment latency?
What's Next
In Section 41.5, we confront the one thing every model in this chapter so far has refused to give us: absolute scale. We look at sensor-prompted depth, where a handful of sparse lidar or radar returns are fed into the network as a prompt, turning a beautiful but scale-free relative map into metric depth you can actually navigate by.