| name | temporal-in-context-video-diffusion |
| title | Temporal In-Context Fine-Tuning for Versatile Control of Video Diffusion Models |
| version | 0.0.2 |
| engine | skillxiv-v0.0.2-claude-opus-4.6 |
| license | MIT |
| url | https://arxiv.org/abs/2506.00996 |
| keywords | ["Video Generation","Diffusion Models","Conditional Generation","In-Context Learning"] |
| description | Adapt pretrained video diffusion models to conditional tasks using only 10-30 samples without architectural changes. |
Temporal In-Context: Control Video Diffusion With Minimal Data
Video diffusion models are powerful but require extensive fine-tuning to adapt to new conditional tasks (image-to-video, video-to-video, style transfer). Temporal in-context fine-tuning inverts this constraint: teach the model to condition on frames using only 10-30 training examples and no architectural changes. The trick is concatenating condition and target frames temporally with progressively noisier buffer frames between them, enabling smooth transitions and condition fidelity without retraining embeddings or attention layers.
This enables rapid adaptation of large video models to custom tasks and domains with minimal data, making video generation accessible for specialized applications.
Core Concept
Instead of modifying model architecture or embeddings, inject condition information through the temporal dimension. Place condition frames at the start of the sequence, target frames at the end, and progressively noisier interpolation frames between them. The diffusion model learns to reconstruct clean target frames conditioned on the condition context. This leverages the model's existing temporal reasoning without any architectural surgery, works with any pretrained video diffusion model, and requires minimal data.
Architecture Overview
- Temporal Concatenation: Stack condition frames + buffer frames (with escalating noise) + target frames along time axis
- Noise Scheduling: Buffer frames transition smoothly from condition (no noise) to full diffusion (maximum noise) to target frames
- Diffusion Forward Pass: Standard diffusion operates on concatenated temporal sequence; learns to reconstruct target given condition context
- Pretrained Model Reuse: No changes to model weights or architecture; works as an in-context learning mechanism
- Multi-Task Adaptation: Same approach handles image-to-video, video-to-video, and other conditional generation tasks
Implementation
This implementation demonstrates temporal in-context fine-tuning for conditional video generation.
Build the temporal concatenation pipeline:
import torch
import torch.nn.functional as F
from typing import List, Tuple
from dataclasses import dataclass
@dataclass
class ConditionalVideoFrames:
condition_frames: torch.Tensor
target_frames: torch.Tensor
buffer_frames: int = 4
class TemporalContextBuilder:
"""Build temporal sequences for in-context video conditioning."""
@staticmethod
def create_noise_schedule(num_steps: int) -> torch.Tensor:
"""
Create noise schedule for buffer frames.
Start at 0 (clean condition) -> increase to ~0.7 (diffusion regime) -> 1.0 (target).
"""
t = torch.linspace(0, 1, num_steps)
noise_levels = t ** 2
return noise_levels
@staticmethod
def add_noise_to_frame(frame: torch.Tensor, noise_level: float,
num_timesteps: int = 1000) -> torch.Tensor:
"""
Add Gaussian noise to a frame proportional to noise level.
noise_level: 0 = clean, 1 = full noise
"""
variance = noise_level
noise = torch.randn_like(frame) * variance
noisy_frame = frame + noise
torch.clamp(noisy_frame, -, )
() -> torch.Tensor:
cond_frames = condition.condition_frames
target_frames = condition.target_frames
cond_frames.dim() == :
cond_frames = cond_frames.unsqueeze()
B, C, H, W = target_frames.shape target_frames.dim() == \
(, *target_frames.shape)
add_buffer:
num_buffer = condition.buffer_frames
noise_schedule = .create_noise_schedule(num_buffer)
buffer_frames = []
i, noise_level (noise_schedule):
alpha = (i + ) / num_buffer
interpolated = ( - alpha) * cond_frames[-] + alpha * target_frames[]
noisy = .add_noise_to_frame(interpolated, noise_level)
buffer_frames.append(noisy)
buffer_frames = torch.stack(buffer_frames, dim=)
full_sequence = torch.cat(
[cond_frames, buffer_frames, target_frames],
dim=
)
:
full_sequence = torch.cat([cond_frames, target_frames], dim=)
full_sequence
builder = TemporalContextBuilder()
condition = ConditionalVideoFrames(
condition_frames=torch.randn(, , ),
target_frames=torch.randn(, , , ),
buffer_frames=
)
full_seq = builder.build_temporal_context(condition)
()
Implement efficient fine-tuning on the concatenated sequences:
from transformers import AutoModel
import torch.optim as optim
class TemporalInContextFinetuner:
"""Fine-tune video diffusion model on conditional tasks."""
def __init__(self, pretrained_model_name: str = "cogvideo",
num_condition_tokens: int = 8,
learning_rate: float = 1e-4):
self.model = AutoModel.from_pretrained(pretrained_model_name)
self.num_condition_tokens = num_condition_tokens
self.optimizer = optim.AdamW(
[p for p in self.model.parameters() if p.requires_grad],
lr=learning_rate
)
self.context_builder = TemporalContextBuilder()
def forward_pass(self, temporal_sequence: torch.Tensor,
target_indices: Tuple[int, int]) -> torch.Tensor:
"""
Forward pass through diffusion model.
target_indices: (start_idx, end_idx) of target frames in sequence.
"""
output = self.model(temporal_sequence, output_hidden_states=True)
return output
def () -> torch.Tensor:
outputs = .forward_pass(temporal_sequence,
(target_start_idx, (temporal_sequence)))
target_predictions = outputs.last_hidden_state[target_start_idx:]
target_frames = temporal_sequence[target_start_idx:]
loss = F.mse_loss(target_predictions, target_frames)
loss
() -> :
full_seq = .context_builder.build_temporal_context(condition)
target_start_idx = condition.condition_frames.shape[] + condition.buffer_frames
loss = .compute_conditional_loss(full_seq, target_start_idx)
loss.backward()
torch.nn.utils.clip_grad_norm_(.model.parameters(), )
.optimizer.step()
.optimizer.zero_grad()
{: loss.item()}
finetuner = TemporalInContextFinetuner(learning_rate=)
training_data = [
ConditionalVideoFrames(
condition_frames=torch.randn(, , ),
target_frames=torch.randn(, , , ),
buffer_frames=
)
_ ()
]
()
epoch ():
epoch_loss =
sample training_data:
stats = finetuner.train_step(sample)
epoch_loss += stats[]
()
Implement inference for multiple conditional generation modes:
class ConditionalVideoGenerator:
"""Generate videos conditioned on images/videos using fine-tuned model."""
def __init__(self, finetuned_model):
self.model = finetuned_model.model
self.context_builder = TemporalContextBuilder()
def generate_image_to_video(self, condition_image: torch.Tensor,
num_frames: int = 8,
steps: int = 50) -> torch.Tensor:
"""
Generate video sequence starting from a single image.
Uses temporal context: condition_image + buffer + target_frames.
"""
condition = ConditionalVideoFrames(
condition_frames=condition_image,
target_frames=torch.randn(num_frames, *condition_image.shape),
buffer_frames=4
)
temporal_seq = self.context_builder.build_temporal_context(condition)
for step in range(steps):
with torch.no_grad():
denoised = self.model(temporal_seq)
condition_len = 1 + 4
temporal_seq[condition_len:] = denoised.last_hidden_state[condition_len:]
video = temporal_seq[5:]
return video
() -> torch.Tensor:
condition = ConditionalVideoFrames(
condition_frames=condition_video[-:],
target_frames=torch.randn(num_target_frames, *condition_video.shape[:]),
buffer_frames=
)
temporal_seq = .context_builder.build_temporal_context(condition)
step (steps):
torch.no_grad():
denoised = .model(temporal_seq)
temporal_seq[:] = denoised.last_hidden_state[:]
temporal_seq[:]
generator = ConditionalVideoGenerator(finetuner)
test_image = torch.randn(, , )
generated_video = generator.generate_image_to_video(test_image, num_frames=)
()
test_video = torch.randn(, , , )
adapted_video = generator.generate_video_to_video(test_video, num_target_frames=)
()
Practical Guidance
| Aspect | Details |
|---|
| Training Samples | 10-30 pairs sufficient; more helps but diminishing returns |
| Buffer Frames | 4-6 optimal; allows smooth transition between condition and generation |
| Training Epochs | 3-10 depending on dataset size; watch for overfitting |
| Learning Rate | Start 1e-4, reduce to 1e-5 if loss oscillates |
| Target Frame Count | 4-16 per sample; balance between diversity and memory |
When to Use:
- Need to adapt pretrained video diffusion to custom tasks quickly
- Limited training data (10-30 samples) for your specific application
- Want to preserve base model capabilities while specializing on new task
- Image-to-video, video-to-video, style transfer, aspect ratio conversion
- Don't have resources for full model retraining
When NOT to Use:
- Large training datasets available (full fine-tuning better)
- Need to modify model architecture or capabilities fundamentally
- Real-time generation required (iterative denoising adds latency)
- Task requires pixel-perfect control beyond what conditioning allows
- Model's base knowledge is insufficient for task domain
Common Pitfalls:
- Too few buffer frames: abrupt transitions between condition and target
- Too many target frames: model spreads attention thin, quality degrades
- Mismatch between condition and target: model learns artifacts; validate data
- Insufficient training iterations: underfitting causes blurry or incoherent frames
- Not preserving condition frames: model learns to ignore context if targets always different
Reference
Temporal In-Context Fine-Tuning for Versatile Control of Video Diffusion Models
https://arxiv.org/abs/2506.00996