Part IV ยท Ch. 8 โ€” Making It Move

Part IV ยท Chapter 8 of 8

Making It Move

Video diffusion: the same idea, with time added as a dimension


Every apple we have made stands perfectly still

Every apple we have made stands perfectly still, frozen in a single instant. Now we make it move. Put our apple on the wooden table and ask for two seconds of it slowly turning, so the little dimple by the stem swings from the left edge round toward the middle. That is a video, and a video is not a fundamentally new kind of object โ€” it is image data with one more axis stapled on, the axis we call time.

So here is the honest first attempt, and I want us to take it seriously rather than skip it, because its failure is the whole chapter. We already know how to make one apple. Run Chapter 5's sampler sixteen times with the same prompt and the same weights, and we have sixteen apples. Lay them end to end at eight frames per second and play them. What do we get?

Two filmstrips of five frames each, stacked. The top strip is labeled 'independently sampled โ€” five different apples' in red: each of its five cells holds a visibly different apple โ€” a large amber one, a small mint-green one with no leaf, a small spotted amber one, a big amber one, and a mid-sized speckled mint-green one with no leaf. The bottom strip is labeled 'one block, denoised together โ€” one apple, turning' in mint: all five cells hold the same amber apple, with only the stem and the pale highlight traveling a little further to the right across the strip.
Both strips are made of good apples. Only one is a video. Every cell in the top strip is a perfectly valid apple โ€” nothing in it is blurry, broken, or low quality. The problem is that no two cells are the same apple, because nothing tied the five samples together. The bottom strip is one object with a time axis, denoised as a unit.

We get flicker: an apple that jumps between varieties, sizes, and shadows eight times a second. And the precise diagnosis matters, so let me state it carefully. Not one of those frames is wrong. Each one is a clean, believable apple โ€” a fresh sample that landed squarely inside the data distribution, the apple neighborhood from Chapter 1. The failure is not quality. The failure is that the frames are independent samples, and independence is exactly what motion is not. Motion means frame 2 is a small, structured change to frame 1 โ€” the same fruit, the same light, one instant later. Sixteen independent draws have no mechanism for "same".

One block, with a time axis

The fix follows straight from the diagnosis. If independence is the disease, stop making independent things. We stop treating a video as $F$ separate images and start treating it as a single object with a time axis: a spatiotemporal latent block, written $\mathbf{Z}$ โ€” capital Z, because it is a stack, not a single frame's latent. One noise blob is drawn for the whole block. One noise predictor looks at the whole block. One sampler walks the whole block down to zero together.

Let me take that name apart, because it sounds worse than it is. Spatio means space, the width and height we already had. Temporal means time, the axis we are adding. Latent is Chapter 4's word for the compressed summary of a picture. And block means all of them stacked into one array.

Let us count what that block holds, because the arithmetic is the entire story of why video is expensive. From Chapter 4, a latent for a single $512\times512$ image, at the typical Stable-Diffusion-style setting of downscale factor $f = 8$ and 4 channels, is a 64-by-64 grid of 4 channels: 16,384 numbers per frame, counted out in that chapter.

One small warning about letters before we go on: in Chapter 4, $f$ was the downscale factor 8; in this chapter $f$ is a frame index, and $F$ is the total number of frames. The field reuses the letter, and we are stuck with it โ€” from here on, $f$ counts frames.

Now stack $F = 16$ frames, an illustrative length that at 8 frames per second buys us two seconds of turning apple:

$$\mathbf{Z} \text{ holds } 16 \times 64 \times 64 \times 4 = 16 \times 16{,}384 = 262{,}144 \text{ numbers}$$

In words: sixteen frames, each of 16,384 latent numbers, is 262,144 numbers in the block โ€” sixteen times as many as one still image.

That factor of 16 is the plain cost of video, and it is not hiding anywhere: every sampler step now denoises sixteen frames' worth of numbers instead of one. It is worth seeing what the compression trick is buying us here, because it buys the same 48ร— it always did: the same sixteen frames in raw pixels would be 12,582,912 numbers rather than 262,144 โ€” the same 48-fold saving Chapter 4 found for a single image, unchanged by adding frames.

Five square latent grids in mint outline, overlapping like cards in a deck that recedes to the upper right, the front one labeled 'frame 1' and the back one 'frame F'. A muted arrow runs parallel to the deck's top-left edge, labeled 'time โ€” frames 1 to F'. Top-left annotation: 'one frame, 64 x 64 x 4 = 16,384 numbers'. Top-right annotation: 'the block Z, F = 16 frames, 16 x 16,384 = 262,144 numbers'. The same single cell is tinted amber on every grid, and a dashed amber line joins those five cells through the deck, labeled 'the same patch, through time โ€” the column attention looks along'.
Not sixteen latents โ€” one block. The time axis is a genuine fourth axis of one array, which is why we can noise it, denoise it, and reason about it as a single object. The amber square marks one patch position tracked through every frame; that column is what the next section learns to look along.

With the block defined, the forward process โ€” adding noise on purpose โ€” needs no new mathematics at all. Chapter 2's closed form carries over exactly, with $\mathbf{Z}$ in place of $\mathbf{z}$:

$$\mathbf{Z}_t = \sqrt{\bar{\alpha}_t}\,\mathbf{Z}_0 + \sqrt{1-\bar{\alpha}_t}\,\boldsymbol{\epsilon}$$

In words: the noisy block at noise level $t$ is the clean block faded by $\sqrt{\bar{\alpha}_t}$ โ€” alpha-bar-t, the cumulative fraction of signal still kept by step $t$ โ€” plus one blob of noise $\boldsymbol{\epsilon}$ scaled by the rest.

Two things about that line deserve saying out loud. First, $\boldsymbol{\epsilon}$ is now a blob of 262,144 random numbers drawn in one go for the entire block, not sixteen separate blobs โ€” the block is noised as a unit. Second, $\bar{\alpha}_t$ is a single number, the same for every frame, because the noise schedule is a property of the timestep $t$, not of position or frame. All sixteen frames sit at the same noise level at all times. That is what lets them be denoised together.

Letting the frames see each other

Bundling the frames into one array is necessary but not sufficient. If the noise predictor still processed each frame in its own private lane, never comparing them, we would have rebuilt independent sampling with extra steps. Something inside the network has to let frame 2 look at frame 1.

Let us watch why that helps on the smallest possible video: three frames, one pixel each, and take the numbers as the brightness of that pixel after the reverse process โ€” the denoising process โ€” has finished. Denoised independently, the three frames come out as $0.81$, $0.44$, $0.77$ โ€” picked so the middle frame is visibly darker than its neighbors, a flash you could actually see. Each value is fine on its own. The trouble is in the differences:

$$0.81 - 0.44 = 0.37, \qquad 0.77 - 0.44 = 0.33$$

In words: the pixel jumps down by 0.37 from frame 1 to frame 2, then back up by 0.33 from frame 2 to frame 3. On screen, that is a flash.

Now let each frame blend itself with its neighbors instead of standing alone. Give the frame itself half the weight and each neighbor a quarter โ€” weights $[0.25,\, 0.5,\, 0.25]$ โ€” with the edge frames, which have only one neighbor, reusing themselves in the missing slot. Those three numbers are chosen for a reason: they add up to exactly one, so the blend can smooth the sequence but can never brighten or darken it overall. Every multiplication, printed:

Worked example: three frames, blended

Frame 1 (its missing left neighbor is itself, $0.81$):

$$0.25(0.81) + 0.5(0.81) + 0.25(0.44) = 0.2025 + 0.405 + 0.11 = 0.7175$$

In words: a quarter of 0.81 is 0.2025, half of 0.81 is 0.405, a quarter of 0.44 is 0.11; adding the three gives 0.7175.

Frame 2 (neighbors $0.81$ and $0.77$):

$$0.25(0.81) + 0.5(0.44) + 0.25(0.77) = 0.2025 + 0.22 + 0.1925 = 0.615$$

In words: 0.2025 from the frame before, 0.22 from itself, 0.1925 from the frame after; the total is 0.615.

Frame 3 (its missing right neighbor is itself, $0.77$):

$$0.25(0.44) + 0.5(0.77) + 0.25(0.77) = 0.11 + 0.385 + 0.1925 = 0.6875$$

In words: 0.11 from frame 2, 0.385 from half of itself, 0.1925 from the reused edge copy; the total is 0.6875.

And the new differences:

$$0.7175 - 0.615 = 0.1025, \qquad 0.6875 - 0.615 = 0.0725$$

In words: the frame-to-frame jumps have fallen from 0.37 and 0.33 to 0.1025 and 0.0725 โ€” roughly a quarter of what they were.

The sequence still moves โ€” 0.7175, 0.615, 0.6875 is not a flat line, and nothing here forbids change. What it forbids is unstructured change. That is the whole trick of temporal coherence: leave a channel open through which each frame's answer is pulled toward what its neighbors are doing.

Where the weights come from

We hand-picked $[0.25,\, 0.5,\, 0.25]$. A real video model learns them, per patch and per moment, using machinery we already own: attention, from Chapter 6 and, in its original form, from the LLM book's attention chapter. In Chapter 6 an image patch formed a query and aimed it at the prompt's keys. Here the axis changes and nothing else does: the patch at a given position in frame $f$ forms a query $\mathbf{q}^{(f)}$, and aims it at the keys $\mathbf{k}^{(1)}, \dots, \mathbf{k}^{(F)}$ belonging to the same patch position in every frame. That is the amber column in the block figure above. Because it looks along time rather than across the image, this is called temporal attention, and the block of network layers that houses it is usually called a motion module.

Work one softmax to see the weights appear. Say our patch in frame 2 scores its three candidates โ€” frames 1, 2, 3 โ€” at $[1,\, 2,\, 1]$: it matches itself best, and its two neighbors equally and less well. Exponentiate each score โ€” that is, raise $e$, the fixed constant near $2.718$ we met in Chapter 6, to the power of each score โ€” rounding to four significant figures as we have throughout the book:

$$e^{1} = 2.718, \qquad e^{2} = 7.389, \qquad e^{1} = 2.718$$

In words: raising $e$ to each score turns the scores into positive numbers that grow fast, so the winner pulls away from the others.

$$2.718 + 7.389 + 2.718 = 12.825$$

In words: add the three exponentials to get the total, 12.825, which is what we divide by.

$$\frac{2.718}{12.825} = 0.212, \qquad \frac{7.389}{12.825} = 0.576, \qquad \frac{2.718}{12.825} = 0.212$$

In words: dividing each exponential by the total gives three shares โ€” 0.212, 0.576, 0.212 โ€” which add to 1.000 and say how much of each frame this patch takes.

Now spend them the way we spent the hand-picked weights. Frame 2's three candidates carry $0.81$, $0.44$ and $0.77$, so the blended value for frame 2 is:

$$0.212(0.81) + 0.576(0.44) + 0.212(0.77) = 0.1717 + 0.2534 + 0.1632 = 0.5884$$

In words: multiply each frame's value by the share the softmax gave it and add the three products; frame 2 comes out at 0.5884, against the 0.615 the hand-picked weights produced.

One small piece of honesty about that total. Every number on screen is rounded to four figures, so adding the three rounded pieces on a calculator lands a hair under the figure I just gave you. The number printed there is the true sum, correctly rounded, and that difference is the rounding.

Those three shares play exactly the role our hand-picked $[0.25,\, 0.5,\, 0.25]$ played, and $0.5884$ against $0.615$ is how close that role is: the same smoothing, arrived at by the network instead of chosen by us. The difference is that the network computes them fresh from the content: on a patch of still tablecloth the shares spread out and the frames lock together hard, while on the fast-moving edge of the turning apple the patch can concentrate its share on itself and let that region change quickly. Coherence stops being a fixed rule and becomes something decided per patch, per frame.

Five small three-by-three frame grids in a row, labeled frame 1 to frame 5, each with the same middle-left cell tinted amber. From the amber patch in frame 3, four mint arcs curve over the row and land on the amber patch in frames 1, 2, 4 and 5, each arc carrying a share in a small box: 0.07 to frame 1, 0.18 to frame 2, 0.18 to frame 4, 0.07 to frame 5. A mint line under frame 3 reads 'keeps 0.50 of itself'. Headings read 'one patch in frame 3 queries the same patch in every frame', 'the shares add to 1.00', and 'temporal attention โ€” its keys run along time, not across the prompt'.
Attention, turned ninety degrees. Chapter 6's queries and keys are unchanged; only the direction they look has moved from "across the prompt" to "along time". The shares shown are an illustrative five-frame version of the three-frame softmax worked above.

Starting from a picture we already have

Everything so far generates a video from nothing but noise and a prompt. Far more often, what we actually want is this: here is my apple, this exact photograph on this exact table โ€” now make it turn. That is image-to-video, and the block gives us a clean way to say it.

Encode the starting picture with the VAE encoder from Chapter 4, and hold the result fixed as the block's first frame:

$$\mathbf{z}^{(1)}_0 = \mathrm{Enc}(\text{start image}), \text{ held fixed while frames } 2, \dots, F \text{ are sampled}$$

In words: frame 1 of the clean block is not something the sampler gets to invent โ€” it is the encoded starting image, pinned in place, while the sampler is left to fill in the other fifteen frames around it.

The reason this is easy rather than awkward is that we know frame 1's value at every noise level, not only at $t = 0$. Chapter 2's closed form hands it to us directly: $\sqrt{\bar{\alpha}_t}\,\mathbf{z}^{(1)}_0 + \sqrt{1-\bar{\alpha}_t}\,\boldsymbol{\epsilon}$ is the correctly-noised version of our known frame at level $t$, computable in one line. So at each sampler step the common approach re-imposes the constraint: run Chapter 5's update rule on the whole block โ€” unchanged, there is no new sampler mathematics here โ€” and then set frame 1's slot back to the value we know it must have.

And now temporal attention earns its keep twice over. Frame 2's patches are attending to frame 1's patches, and frame 1's patches are not a guess โ€” they are our photograph. That fixed anchor propagates: frame 2 is pulled toward frame 1, frame 3 toward frame 2, and the apple's identity โ€” its exact color, its blemish, the grain of the table under it โ€” is carried down the strip instead of being re-invented sixteen times. Pin one frame, and coherence spreads the pin.

See it move

Watch (18:59): track the dimple beside the apple's stem. In the independent strip it teleports around the fruit every frame; once the frames attend to each other, it travels โ€” the same dimple, moving a little further each time.

Where you'll meet this

Open any video workflow and the shapes from this chapter are printed on the wires. Where an image workflow has an Empty Latent Image node with width and height, a video workflow has one with width, height, and a frame count โ€” that third box is $F$, and it is the number that multiplied our 16,384 up to 262,144. When it turns out that a clip is too long to fit in memory, this is the arithmetic that explains it: doubling the frame count doubles the block, and every sampler step pays.

The loading of a separate motion module on top of an image model is the second place. That file is not a new U-Net and it does not replace the base model any more than a LoRA does โ€” it supplies the temporal layers that let the frames look at each other, and it is inert without the image model underneath it. You will also see an image-to-video node with a slot for a starting picture; that slot is $\mathbf{z}^{(1)}_0$, the pinned first frame.

Finally, the failure modes now have names. A clip whose subject morphs identity every few frames is losing the coherence channel โ€” the frames are drifting back toward independence. A clip that is beautifully stable and utterly motionless has the opposite problem: the temporal blend is dominating, every frame is being dragged too hard toward its neighbors, and the video has collapsed into a still. Those are the two extremes the "slow down" callout above put numbers on, and good video generation lives in the band between them.

Every arrow, explained

We began this book with one picture: an apple, an arrow to a field of static, and an arrow back out to a different apple. I promised then that every arrow in it was a piece we would unpack. Let us go back and look at it now, because the picture has not changed at all โ€” only you have.

Chapter 1's three-panel thesis arc, redrawn with chapter labels, under the heading 'the same diagram we opened with โ€” every arrow now has a name'. Left panel: a golden apple, captioned 'a real apple โ€” one point in the apple neighborhood'. A muted arrow points right, labeled 'the forward process, Chapter 2', into a middle panel of gray static captioned 'pure noise โ€” no apple at all, a seed made it'. A mint arrow continues right, labeled 'the reverse process, Chapters 3 to 7 โ€” and Chapter 8 adds time', into a right panel holding a different, mint-green apple captioned 'a brand-new apple โ€” never seen, never stored'. Below a hairline, eight mint chapter chips each carry one line: Ch. 1 an image is a point and apples form one cloud; Ch. 2 fade the apple, add noise, any level at once; Ch. 3 the noise predictor names the noise it got; Ch. 4 latent space, 786,432 numbers down to 16,384; Ch. 5 the sampler walks K steps down from a seed; Ch. 6 conditioning steers it and the guidance scale pushes; Ch. 7 a LoRA teaches the frozen model one concept; Ch. 8 stack frames into one block with a time axis.
The opening diagram, fully labeled. Nothing was added to the picture between Chapter 1 and here. Every arrow just grew a name, a symbol, and a chapter that derived it.

Read it left to right. The apple on the left is $\mathbf{x}_0$, and Chapter 1 taught us that it is not really a picture at all but a single point in a space of 786,432 numbers, sitting inside a tight cloud of other apple points. Generating meant landing a fresh point inside that cloud, which was hopeless as a single blind leap.

The first arrow is the forward process, and Chapter 2 built it: fade the apple by $\sqrt{\bar{\alpha}_t}$, add noise scaled by $\sqrt{1-\bar{\alpha}_t}$, and you can reach any noise level in one shot. The static in the middle panel is the end of that road โ€” and also, read the other way, the beginning of ours, because Chapter 5 showed that the pure noise we start a generation from comes from a seed and belongs to no apple at all.

The second arrow โ€” the long one, the one that does the real work โ€” took four chapters. Chapter 3 trained $\boldsymbol{\epsilon}_\theta$ to look at a noisy input and name the noise inside it, and showed why that is the learnable question: we make the training data ourselves, so we always know the answer. Chapter 4 moved the whole apparatus into latent space, cutting 786,432 numbers to 16,384 and leaving every equation otherwise untouched. Chapter 5 turned the trained predictor into the sampler, walking $K$ sampler steps down the schedule, removing a fraction of the predicted noise each time. Chapter 6 gave that walk a steering wheel, turning "a green apple on a wooden table" into conditioning $\mathbf{c}$ and pushing the prediction away from the generic answer by the guidance scale $s$. Chapter 7 taught the frozen model one new thing with a small pair of skinny matrices. And this chapter gave the whole object a time axis.

That is the entire book, and it is the entire diagram. Two arrows.

What you now know

  • Generating each frame independently produces flicker, and the reason is precise: every frame is a perfectly valid apple, but nothing connects consecutive samples, and independence is exactly what motion is not.
  • A video is handled as one spatiotemporal latent block $\mathbf{Z}$, and the count is plain: $16 \times 64 \times 64 \times 4 = 262{,}144$ numbers for an illustrative sixteen-frame clip, sixteen times a still image's 16,384 โ€” while latents still save the same 48ร— against 12,582,912 raw pixel numbers.
  • The forward process is unchanged in form, $\mathbf{Z}_t = \sqrt{\bar{\alpha}_t}\mathbf{Z}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}$, with one noise blob drawn for the whole block and every frame sitting at the same noise level.
  • Temporal attention is Chapter 6's attention aimed along time instead of at the prompt: the same patch in every frame supplies a key, and a softmax over scores $[1, 2, 1]$ gives shares $0.212$, $0.576$, $0.212$ โ€” learned weights doing the job our hand-picked $[0.25, 0.5, 0.25]$ blend did when it cut the frame-to-frame jumps from $0.37$ and $0.33$ down to $0.1025$ and $0.0725$.
  • Image-to-video is a constraint, not a new algorithm: pin $\mathbf{z}^{(1)}_0$ to the encoded starting picture at every sampler step, and let temporal attention carry that fixed identity down the rest of the strip.

Where we're headed. Nowhere new โ€” and that is the point. Eight chapters ago we had a picture of an apple, a pile of static, and two arrows nobody could read, and I said every part of this book would unpack one of them. It has. You can now fade an apple to noise with $\bar{\alpha}_t$ and jump to any noise level in one line; you can say exactly what $\boldsymbol{\epsilon}_\theta$ predicts and why that target is the learnable one; you can explain what a latent is, what VAE Decode does, where the seed lives, why the sampler removes only a fraction of the noise per step, what the guidance scale is extrapolating past, what is actually inside a LoRA file, and how a time axis turns a still into a video. When you next open a workflow and see a step count, a cfg number, a seed, a LoRA strength, and a frame count sitting in their little boxes, none of them are magic numbers any more โ€” they are the arithmetic you just did by hand. Go make a new apple. Then make it move.