# OPSD-V
On-Policy Self-Distillation for Post-Training Few-Step Autoregressive Video Generators
Hongyu Liu1,2 ·
Chun Wang1,2 ·
Feng Gao1,* ·
Xuanhua He1,2 ·
Yue Ma2 ·
Ziyu Wan3 ·
Yong Zhang1,† ·
Xiaoming Wei1 ·
Qifeng Chen2,*
1Meituan
2HKUST
3City University of Hong Kong
*Corresponding authors
†Project lead
News |
Installation |
Checkpoints |
Training |
Inference |
WeChat Group |
Citation
## News
- **9 Jul 2026:** We released the paper, model checkpoints, and training and inference code.
## WeChat Group
Scan the QR code to join the OPSD-V discussion group. The code is valid until August 26, 2026.
OPSD-V is an on-policy self-distillation paradigm for post-training few-step autoregressive video diffusion models. It targets long-horizon error accumulation and weakened motion dynamics in distilled AR video generators while preserving the original few-step inference path. The student follows the exact deployment rollout, generating each chunk from its own evolving KV cache, while the teacher is evaluated at the same student-visited denoising states with a cleaner AR-consistent temporal cache built from real long-video context. This provides dense trajectory-level velocity supervision and improves long-horizon visual quality and motion dynamics without changing the sampler, number of denoising steps, or inference-time cache mechanism.
## Motivation
Few-step autoregressive video generators can synthesize long videos with low
latency, but their long rollout quality is still limited by the temporal states
they create for themselves. Each generated chunk is written back into the KV
cache and becomes context for all later chunks, so small artifacts, weak motion,
or semantic drift can accumulate over time. OPSD-V addresses this bottleneck by
using real long videos as privileged temporal context during post-training: the
student stays on the exact generated-cache trajectory it will visit at inference
time, while the teacher receives a cleaner AR-consistent cache for constructing
dense corrective targets.
### Training-free GT-cache diagnostic
Before any post-training, the original generator already reveals the importance
of cache quality. Starting from the same real first chunk and prompt, we compare
standard rollout against a training-free intervention that refreshes older cache
history from the corresponding real video while keeping the most recent chunk
generated by the model. The improved rollout under this data-assisted cache
indicates that accumulated generated-cache degradation is a key bottleneck,
which motivates using real-video context to build a cleaner teacher during
OPSD-V training.
## Highlights
- **On-policy student rollout.** The student writes its own generated chunks into the KV cache and keeps rolling out from the resulting temporal states.
- **Cleaner teacher context.** The teacher is evaluated on the same student-visited noisy latents and timesteps, but uses real-video history for older cache context.
- **Few-step path preserved.** OPSD-V does not change the original 4-step autoregressive sampler used at inference.
- **Memory-conscious training.** Chunk-wise backward, detached denoising transitions, FSDP, gradient checkpointing, and LoRA/EMA support keep long rollouts feasible.
- **Deterministic prompt seeding.** `--per_prompt_seed` avoids noise drift when resuming a partially generated evaluation folder.
## Method
OPSD-V continues post-training an existing few-step AR generator without
changing its sampler or inference-time cache mechanism. The student performs the
deployed rollout: it denoises each chunk with the fixed few-step scheduler,
writes the generated chunk into its KV cache, and continues from the resulting
self-induced state. The teacher is evaluated at the same temporal position,
denoising timestep, and student-visited noisy latent, but uses a cleaner
AR-consistent cache in which older history is replaced by real-video context
while the most recent generated chunk is preserved for autoregressive
continuation. We then match the student and teacher velocity predictions on
these on-policy states, providing dense denoising-level correction while keeping
the original few-step generation path intact.
## Repository Layout
```text
configs/ Training and inference YAML files
model/ OPSD rollout, teacher cache, and loss logic
pipeline/ AR inference and OPSD streaming training pipelines
trainer/ FSDP/LoRA trainer, EMA, resume, and checkpointing
utils/ Dataset, scheduler, LoRA, memory, and Wan wrappers
wan/modules/ Wan2.1 modules and causal attention implementation
tools/ Utility scripts
example/ Prompt files for quick inference checks
train.py Distributed OPSD-V training entry point
inference.py Text/LMDB inference entry point
```
This release excludes generated videos, logs, checkpoints, datasets, and unrelated legacy trainers.
## Installation
We recommend Python 3.10 with CUDA-capable GPUs. OPSD-V uses
`torch.nn.attention.flex_attention` in the causal Wan blocks, so PyTorch 2.5+
is the safest baseline. Install PyTorch for your CUDA runtime first, then
install the remaining packages from [`requirements.txt`](requirements.txt).
```bash
git clone opsd-v
cd opsd-v
conda create -n opsdv python=3.10 -y
conda activate opsdv
pip install -U pip
```
For example, on CUDA 12.1:
```bash
pip install torch==2.5.1 torchvision==0.20.1 \
--index-url https://download.pytorch.org/whl/cu121
pip install -r requirements.txt
```
FlashAttention 2 or 3 is optional but strongly recommended for speed and
memory efficiency. Install the wheel that matches your PyTorch, CUDA, and GPU
architecture. For Ampere/Ada GPUs, FlashAttention 2 is usually enough; for
Hopper GPUs, FlashAttention 3 can be used when available. If FlashAttention is
not installed, the code falls back to PyTorch scaled-dot-product attention, but
long-video training/inference will be slower and may use more memory.
If you enable attention-mask debug visualizations in `utils/debug_option.py`,
install OpenCV as well:
```bash
pip install opencv-python
```
## Checkpoints
Download the official Wan2.1-T2V-1.3B backbone from Hugging Face and place it
under `checkpoints/Wan2.1-T2V-1.3B/`:
```bash
mkdir -p checkpoints
hf download Wan-AI/Wan2.1-T2V-1.3B \
--local-dir checkpoints/Wan2.1-T2V-1.3B
```
The directory should contain the Wan transformer, VAE, T5 encoder, tokenizer,
and model config files, e.g.:
```text
checkpoints/Wan2.1-T2V-1.3B/
├── config.json
├── diffusion_pytorch_model*.safetensors or equivalent transformer weights
├── Wan2.1_VAE.pth
├── models_t5_umt5-xxl-enc-bf16.pth
└── google/umt5-xxl/
```
You can override this location either in YAML:
```yaml
model_kwargs:
model_root: /path/to/Wan2.1-T2V-1.3B
```
or through an environment variable:
```bash
export WAN_MODEL_ROOT=/path/to/Wan2.1-T2V-1.3B
```
Download the OPSD-V released checkpoints into `checkpoints/`:
```bash
hf download MeiGen-AI/OPSD-V \
checkpoints/longlive_base.pt \
checkpoints/longlive_lora.pt \
checkpoints/opsdv_longlive_lora.pt \
checkpoints/self_forcing_dmd_ema_as_generator.pt \
checkpoints/opsdv_self_forcing_lora.pt \
--local-dir .
```
If your environment has not authenticated with Hugging Face yet, run
`hf auth login` first.
After downloading, the provided configs expect:
| File | Used by | Meaning |
| --- | --- | --- |
| `checkpoints/longlive_base.pt` | LongLive training/inference | Base few-step AR generator |
| `checkpoints/longlive_lora.pt` | LongLive training | Initial LongLive LoRA, if continuing from a released adapter |
| `checkpoints/self_forcing_dmd_ema_as_generator.pt` | Self-Forcing training/inference | Self-Forcing DMD/EMA generator |
| `checkpoints/opsdv_longlive_lora.pt` | LongLive inference | OPSD-V LoRA checkpoint |
| `checkpoints/opsdv_self_forcing_lora.pt` | Self-Forcing inference | OPSD-V LoRA checkpoint |
Base generator checkpoints may store weights under `generator`, `generator_ema`, or `model`. OPSD-V LoRA checkpoints store `generator_lora`, optional `generator_ema`, optimizer state, and `step`.
## Training Data
The full training dataset cannot be redistributed due to data licensing and
privacy constraints, and this repository does not include any video, latent,
embedding, or LMDB data files.
Training uses an LMDB containing precomputed text embeddings and Wan VAE latents.
See [`data_processing/`](data_processing/) for an audio-free preprocessing
pipeline that converts your own long videos into this LMDB format.
The loader accepts both naming schemes below:
```text
prompts_shape / text_shape
prompt_embeds_shape
latents_shape / video_shape
prompts_{i}_data / text_{i}_data UTF-8 prompt string
prompt_embeds_{i}_data float16 text embedding bytes
latents_{i}_data / video_{i}_data float16 latent bytes
```
For the released 480 x 832 setting, latent samples have shape:
```text
[T, 16, 60, 104]
```
The default configs sample from long latent windows with up to 243 frames and
train on a 180-frame OPSD rollout. They use a real-video first chunk, roll out
seven 3-frame chunks before applying loss (`opsd_loss_start_frame: 21`), and
supervise the later student-visited rollout states.
## Training
The paper experiments use 24 GPUs across 3 nodes, with 8 GPUs per node. On each node, set `MASTER_ADDR` to the address of rank-0 node and set `NODE_RANK` to `0`, `1`, or `2` respectively.
### LongLive continued post-training
```bash
export MASTER_ADDR=
export MASTER_PORT=29500
export NODE_RANK=<0|1|2>
torchrun --nnodes=3 --nproc_per_node=8 \
--node_rank=${NODE_RANK} \
--master_addr=${MASTER_ADDR} \
--master_port=${MASTER_PORT} \
train.py \
--config_path configs/train_longlive_lora.yaml \
--logdir logs/opsdv_longlive
```
### Self-Forcing continued post-training
```bash
export MASTER_ADDR=
export MASTER_PORT=29500
export NODE_RANK=<0|1|2>
torchrun --nnodes=3 --nproc_per_node=8 \
--node_rank=${NODE_RANK} \
--master_addr=${MASTER_ADDR} \
--master_port=${MASTER_PORT} \
train.py \
--config_path configs/train_self_forcing_lora.yaml \
--logdir logs/opsdv_self_forcing
```
Training resumes automatically from the latest `checkpoint_model_*/model.pt` in `--logdir`. Use `--no-auto-resume` for a fresh run or `--no_save` for a quick debugging run.
### Key OPSD-V options
| Option | Default | Purpose |
| --- | --- | --- |
| `opsd_student_context_mode` | `generated_kv` | Keep the student fully on-policy. |
| `opsd_teacher_context_mode` | `gt_kv` | Use real-video history for a cleaner teacher cache. |
| `opsd_teacher_trajectory_mode` | `student` | Evaluate teacher and student on student-visited noisy states. |
| `opsd_loss_type` | `flow` | Match velocity/flow predictions rather than reconstructed `x0`. |
| `opsd_loss_step_mode` | `all` | Supervise all denoising steps in the fixed few-step trajectory. |
| `opsd_loss_start_frame` | `21` | Skip the first seven 3-frame chunks before applying loss. |
| `opsd_backward_per_chunk` | `true` | Backpropagate chunk by chunk to reduce activation memory. |
| `opsd_use_relative_sink` | `true` | Match the relative-sink cache policy used at inference. |
## Inference
Generate from a text file with one prompt per line:
```bash
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_longlive.yaml \
--data_path example/long_example.txt \
--output_folder outputs/longlive \
--num_output_frames 243 \
--seed_list 1,2 \
--use_lmdb_pipeline \
--lmdb_cache_update_source generated \
--lmdb_use_relative_sink \
--per_prompt_seed
```
Use `configs/inference_self_forcing.yaml` for the Self-Forcing backbone:
```bash
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_self_forcing.yaml \
--data_path example/MovieGenVideoBench_extended.txt \
--output_folder outputs/self_forcing \
--num_output_frames 243 \
--seed_list 1,2 \
--use_lmdb_pipeline \
--lmdb_cache_update_source generated \
--lmdb_use_relative_sink \
--per_prompt_seed
```
`--per_prompt_seed` derives an independent deterministic noise seed from `(seed, prompt_index)`. This is useful for benchmarking because resuming a partially completed output folder will not shift the noise assigned to later prompts.
The text-prompt commands above run the cache-aware OPSD-V inference path, update the autoregressive cache with generated chunks, use relative-sink cache handling, and save videos at 16 FPS.
For LMDB inference with precomputed embeddings and optional real-video latents, add `--use_lmdb`:
```bash
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_longlive.yaml \
--data_path data/eval.lmdb \
--output_folder outputs/eval \
--num_output_frames 243 \
--use_lmdb \
--lmdb_cache_update_source generated \
--lmdb_use_relative_sink \
--per_prompt_seed
```
Arguments that expose GT cache replacement or future GT context are diagnostic tools, not the standard open-ended generation setting.
### Reproduce the cache diagnostic
The diagnostic in the Motivation section can be reproduced with an LMDB that
contains prompts, text embeddings, and corresponding real-video latents. The
goal is not open-ended generation; it is to compare two cache policies under the
same original checkpoint and seed. The `generated` run is the standard rollout.
The `gt` run keeps the latest chunk model-generated but refreshes older cache
history from real-video latents, isolating the effect of cache degradation.
For LongLive, the original model uses its released LoRA adapter:
```bash
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_longlive_original.yaml \
--data_path data/eval.lmdb \
--output_folder outputs/longlive_generated_cache \
--num_output_frames 243 \
--use_lmdb \
--lmdb_use_gt_first_chunk \
--lmdb_cache_update_source generated \
--lmdb_use_relative_sink \
--per_prompt_seed
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_longlive_original.yaml \
--data_path data/eval.lmdb \
--output_folder outputs/longlive_gt_cache \
--num_output_frames 243 \
--use_lmdb \
--lmdb_use_gt_first_chunk \
--lmdb_cache_update_source gt \
--lmdb_use_relative_sink \
--per_prompt_seed
```
For Self-Forcing, the original checkpoint is loaded without any LoRA adapter:
```bash
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_self_forcing_original.yaml \
--data_path data/eval.lmdb \
--output_folder outputs/self_forcing_generated_cache \
--num_output_frames 243 \
--use_lmdb \
--lmdb_use_gt_first_chunk \
--lmdb_cache_update_source generated \
--lmdb_use_relative_sink \
--per_prompt_seed
CUDA_VISIBLE_DEVICES=0 python inference.py \
--config_path configs/inference_self_forcing_original.yaml \
--data_path data/eval.lmdb \
--output_folder outputs/self_forcing_gt_cache \
--num_output_frames 243 \
--use_lmdb \
--lmdb_use_gt_first_chunk \
--lmdb_cache_update_source gt \
--lmdb_use_relative_sink \
--per_prompt_seed
```
## Future Work
OPSD-V explicitly uses real long-video data as privileged temporal context for
post-training. Our current experiments are intentionally modest in scale: about
3,800 one-minute videos, 24 H800 GPUs, and a short continued-training schedule.
Scaling the amount and diversity of real long-video data, increasing training
compute, or designing stronger teacher-cache policies may further improve
long-horizon stability and motion dynamics. We leave this data-and-compute
scaling direction as an important avenue for future exploration.
## Citation
```bibtex
@article{liu2026opsd,
title={OPSD-V: On-Policy Self-Distillation for Post-Training Few-Step Autoregressive Video Generators},
author={Liu, Hongyu and Wang, Chun and Gao, Feng and He, Xuanhua and Ma, Yue and Wan, Ziyu and Zhang, Yong and Wei, Xiaoming and Chen, Qifeng},
journal={arXiv preprint arXiv:2607.08766},
year={2026}
}
```
## Acknowledgements
This codebase builds on [Wan2.1](https://github.com/Wan-Video/Wan2.1), [Self-Forcing](https://github.com/guandeh17/Self-Forcing), [LongLive](https://github.com/NVlabs/LongLive), and [D-OPSD](https://github.com/vvvvvjdy/D-OPSD). We thank their authors for releasing models and code. Please follow the licenses and usage terms of the corresponding base checkpoints and upstream components.
## License
OPSD-V code is released under the Apache License 2.0. See [LICENSE](LICENSE). This repository also contains files adapted from upstream projects, including Wan2.1 and Self-Forcing; those files retain their original copyright notices and license identifiers. Please follow the licenses and usage terms of the corresponding upstream code, models, and checkpoints.