Hello! Welcome back to our series on video generation.
In our last lesson, we adapted a 2D U-Net for video by "inflating" it with temporal layers. By adding temporal convolutions and attention, we gave the model the architectural capacity to learn relationships between frames. This provides an implicit form of temporal consistency.
Today, we'll build on that by implementing a more direct and explicit method for ensuring coherence over time. Your learning outcome is to implement a frame-to-frame consistency technique by conditioning on the previous frame. We'll explore the autoregressive approach to video generation, where each new frame is generated as a direct function of the one that came before it. This is a foundational technique for creating smooth and logical motion.
The Autoregressive Approach to Video
The core idea behind autoregressive generation is simple and powerful. Instead of trying to generate an entire sequence of frames at once, we generate them one by one. The generation of frame is explicitly conditioned on the previously generated frame . This is analogous to how large language models generate text word by word, where each new word is predicted based on the sequence of words that came before it.
This iterative process helps maintain a strong causal link between frames, which is crucial for temporal consistency. The diagram below illustrates this concept in the context of generating a long video. An initial set of frames is generated, and then the last few frames from that segment are used as the starting point, or condition, for the next segment.

The fundamental challenge is making the model "aware" of the previous frame. Let's first build some intuition for why this is so important.
Temporal Frame Motion Control Concept: Extending video lengths with motion consistency to Infinity
The video 'Temporal Frame Motion Control Concept' from AI Artistry Atelier provides a great high-level demonstration of this principle. It shows how providing a model with previous frames helps it disambiguate motion and continue a sequence coherently.
Please watch these two clips: Introduction (00:00 - 01:22): This part introduces the core problem. Pay attention to the bouncing ball example—it clearly shows how a single frame is ambiguous, while a sequence of frames provides clear information about motion direction. Single vs. Multiple Frame Comparison (25:38 - 30:08): This is a direct comparison. Notice how the generation conditioned on just one frame loses character identity and motion coherence, while the one conditioned on multiple frames preserves them much better. This highlights the practical benefit of our goal for today.
As the video demonstrates, providing context from previous frames is essential for the model to generate a logical continuation. Now, let's move from this high-level concept to the specific implementation details.
The Core Mechanism: Channel-wise Conditioning
How do we actually "show" the model the previous frame? A common and effective technique is to concatenate the conditioning frame with the noisy input for the frame we want to generate.
The paper "SinFusion" proposes a clean and effective framework for this, centered around a model they call the DDPM Frame Predictor. This is precisely the kind of implementation you would build.
SinFusion: Training Diffusion Models on a Single Image or ...
The paper 'SinFusion: Training Diffusion Models on a Single Image or Video' details an autoregressive framework for video generation. We'll focus on the 'DDPM Frame Predictor', which is the component responsible for generating the next frame based on the previous one.
Please read the subsection 'DDPM Frame Predictor' within Section 5. Pay close attention to two key implementation details: How the condition frame and the noisy target frame are combined before being passed to the model. How the temporal difference (i.e., the gap between the frames) is encoded and used.
As you've just read, the mechanism is straightforward yet powerful:
-
Input Concatenation: The clean conditioning frame is concatenated with the noisy target frame along the channel axis. If each frame has a latent representation of shape
(C, H, W), the input to the U-Net becomes a tensor of shape(2*C, H, W). Your U-Net's initial convolution layer would need to be adjusted to accept2*Cinput channels instead ofC. -
Temporal Embedding: The time difference, , between the frames is passed through an embedding layer (similar to the DDPM timestep embedding ) and then concatenated or added to the main timestep embedding. This gives the model explicit information about how far forward (or backward) in time it's supposed to predict.
This approach effectively turns the denoising task into: "Given this clean frame , denoise the noisy frame to produce a coherent follow-up frame ."
The Generation Loop and The Problem of Error Accumulation
With the Frame Predictor defined, we can now outline the full autoregressive generation loop. But as with any autoregressive system, we must be mindful of a critical failure mode: error accumulation.
Let's first read about the full generation process and a clever solution to this problem.
SinFusion: Training Diffusion Models on a Single Image or ...
Let's return to the SinFusion paper to see how the Frame Predictor is used in a full generation loop and how they address error accumulation.
Please read the following sections: DDPM Frame Projector (Section 5): Understand the role of this second model. What is it trained on, and what is its purpose? Diverse Video Generation (Section 6): See how the Predictor and Projector work together in an iterative loop to generate a video. Importance of DDPM frame Projector (Appendix A.1): This ablation study provides quantitative and qualitative evidence for why the Projector is necessary.
The generation process, combining the Predictor and Projector, works as follows:
- Initialization: Start with an initial frame, . This can be a real frame from a video or an image generated from scratch (e.g., using the Projector model).
- Prediction: Use the Frame Predictor to generate a noisy prediction for the next frame, , conditioned on .
- Correction: This is the crucial step to prevent error accumulation. Take the predicted frame and refine it using the Frame Projector. The Projector, having been trained on the distribution of single, high-quality frames, "cleans up" any small artifacts or drifts introduced by the Predictor. This yields a corrected frame, .
- Iteration: Repeat the process. Use the corrected frame as the new condition to predict , correct it, and so on, for the desired video length.
This two-model system elegantly separates concerns: one model is an expert in motion prediction, while the other is an expert in image quality and fidelity. This design pattern is highly effective for maintaining quality in long generative sequences. The ablation study in the appendix clearly shows that without the Projector, quality degrades rapidly as artifacts compound with each new frame.
Test your understanding!
You are tasked with implementing the training logic for the DDPM Frame Predictor. You have a dataloader that yields batches of short video clips, each as a tensor of shape (B, F, C, H, W), where B is batch size and F is the number of frames.
In your training loop, for a single batch video_clips, describe the steps you would take to prepare the model_input tensor and the target tensor (i.e., the noise) before passing them to your U-Net and calculating the loss. Assume your U-Net expects a (B, 2*C, H, W) input.
Show answer
Here is a typical sequence of steps within the training loop:
-
Sample Frame Indices: For each clip in the batch, randomly select an index
nfor the conditioning frame and an indexmfor the target frame. For simplicity, let's saym = n + 1. So, you'll haveconditioning_frames = video_clips[:, n, :, :, :]andtarget_frames = video_clips[:, n+1, :, :, :]. Both will have shape(B, C, H, W). -
Sample Noise and Timesteps: Generate a random noise tensor
noisewith the same shape astarget_framesand sample a batch of timestepst. -
Create Noisy Target: Apply the forward diffusion process to
target_framesto get the noisy version,noisy_target_frames, using the samplednoiseandt. -
Prepare Model Input: Concatenate the clean
conditioning_frameswith thenoisy_target_framesalong the channel dimension.# conditioning_frames.shape -> (B, C, H, W) # noisy_target_frames.shape -> (B, C, H, W) model_input = torch.cat([conditioning_frames, noisy_target_frames], dim=1) # model_input.shape -> (B, 2*C, H, W) -
Set the Target: The target for the loss function is the original noise tensor you sampled in step 2.
target = noise -
Forward Pass and Loss: Pass
model_inputandtto the U-Net, get the predicted noise, and compute the loss (e.g., MSE) between the predicted noise and thetarget.
Conclusion
In this lesson, we have established a robust and explicit method for ensuring frame-to-frame consistency in video generation. By moving to an autoregressive framework, we create a strong causal link between frames, leading to more coherent and stable videos.
Key Takeaways:
- Autoregressive generation is a powerful paradigm for video, where each frame is generated conditioned on the previous one.
- A practical way to implement this conditioning is by concatenating the clean previous frame with the noisy current frame along the channel dimension and feeding it to the U-Net.
- A critical challenge in this approach is error accumulation, where small prediction artifacts compound over time.
- This can be mitigated by using a two-model system: a Predictor for generating motion and a Projector (or corrector) for refining frame quality at each step.
Next Lesson Preview:
So far, our conditioning has been based on the final, clean output of the previous frame. In the next lesson, we will explore a more deeply integrated approach: implementing a consistency mechanism based on latent variable propagation between frames. This involves passing hidden states or other latent information from the generation process of one frame to the next, potentially allowing for even smoother and more complex temporal dynamics.