The tensor the UNet actually receives is a channel-wise concatenation of two latents, and the model names its slots rather than slicing with magic numbers:
One thing about that tensor is worth more than any diagram of it: the conditioning half is never noised. The first four channels are on the schedule from the previous topics — at they are indistinguishable from noise — and the last four are a clean encode of the hazy input, byte-identical at every one of the twenty-five sampler steps.
Once that is seen, most of the concept is done. The target is what diffuses; the condition is what stays still.
Now the problem. The pretrained SD2.1 conv_in is a convolution from four channels, because SD2.1 generates images from a latent and has nothing to condition on. It has to become a convolution from eight.
Structurally that is trivial — construct a new convolution with the same kernel size, stride, padding and output channels, copy the bias verbatim, and assign the weights. The bias needs no thought because it is per-output-channel and the output channels have not changed. The weights do, and the choice is not cosmetic: whatever the new half starts at, the very first forward pass of training runs the entire pretrained network on activations whose scale that choice determined.
Why one scale is ½ and another is 1/√2
-
The pretrained first layer and the activation variance it produces. Every downstream block — every normalisation, every nonlinearity — was trained against this V, so preserving it is what "not breaking the pretrained network" means here.
-
The widened layer, with the pretrained kernel reused in both halves and scaled by s. The two halves see different inputs — x is the noisy target, u the second group — and the whole question is how those two are related.
-
If the two halves carry the same content, the layer computes the same thing twice and the outputs add coherently — amplitudes sum, so halving each restores the original. This is the assumption behind the ×0.5 initialisation.
-
If the two halves are independent, the outputs add incoherently — variances sum, not amplitudes — and the preserving scale is 1/√2. This is the assumption stated in the code beside the single-pass constant: variance-preserving for two independent noisy latents.
-
The two answers differ by 41 %, and neither is a rounding of the other. They are the same question — what scale preserves the pretrained activation statistics — answered under opposite assumptions about the correlation between the two halves.
You widen conv_in with the duplicate mode and training loss is worse than the marigold run from step zero — before any learning could have happened. Why?
Show answer
Because the damage is at initialisation, not in the learning.
duplicate leaves both halves at full pretrained magnitude, so the first convolution's output is between and times its trained scale depending on how correlated the two halves are at that timestep. Every subsequent block sees inputs outside the range its normalisation statistics and nonlinearities were fitted on, and the error compounds with depth rather than staying put.
The useful diagnostic is that this is visible before training: run one forward pass under each init mode and compare the activation statistics at the first few blocks. If the histograms have moved, you have found it, and you have found it in seconds rather than in a training run. It is also why marigold and the constant exist at all — both are attempts to make that first forward pass land where the pretrained network expects.