Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f3791f8
first commit for diffusion training
zirui Jun 17, 2026
313e7d0
docs(diffusion): unify single/multi-node torchrun launch in READMEs
zirui Jun 17, 2026
38830fe
docs(diffusion): simplify unified run instructions
zirui Jun 17, 2026
5f94542
fix(diffusion): broadcast Wan timesteps per sample
zirui Jun 18, 2026
b107de2
Remove unused pip packages and clean up README.md
zirui Jun 30, 2026
b3cf034
fix launch command
zirui Jul 1, 2026
38a04c1
set aiter as default attention backend
zirui Jul 1, 2026
696748a
fix: add missing newline at end of examples/diffusion/README.md
Copilot Jul 6, 2026
ed3327f
set aiter as default attention backend & add set seperated_timestep=T…
zirui Jul 7, 2026
e80b703
fix(diffusion): address Wan code quality findings
zirui Jul 7, 2026
8ec6419
fix(diffusion): resolve remaining code quality findings
zirui Jul 7, 2026
176545a
fix(diffusion): address Copilot PR review findings
zirui Jul 7, 2026
03d67a5
style(diffusion): apply pre-commit formatting
zirui Jul 7, 2026
c7d18ed
fix(diffusion): address remaining PR review comments
zirui Jul 7, 2026
5a974fd
fix(diffusion): align Wan timestep config naming
zirui Jul 7, 2026
814cfbc
fix(diffusion): resolve Wan training review issues
zirui Jul 7, 2026
fefe397
Fix black formatting in train_pipeline.py to pass code-lint CI
Copilot Jul 7, 2026
12a87d0
fix(diffusion): remove Wan attention debug leftovers
zirui Jul 7, 2026
1c71546
fix(diffusion): resolve Wan review follow-ups
zirui Jul 7, 2026
78053fa
fix(diffusion): address latest Wan review comments
zirui Jul 7, 2026
69263af
feat(diffusion): add FLUX training support
zirui Jun 18, 2026
d0dbbcb
fix(diffusion): make FLUX examples portable
zirui Jun 23, 2026
626c075
style(diffusion): apply pre-commit formatting
zirui Jun 23, 2026
2b10166
fix(diffusion): use AITER attention for FLUX
zirui Jul 8, 2026
377d09e
fix(tests): add __init__.py to test dirs to prevent module name confl…
Copilot Jul 6, 2026
0b9d37c
fix(diffusion): address PR review comments
zirui Jul 8, 2026
b8566cd
docs(diffusion): generalize utils docstring
zirui Jul 8, 2026
c8fa9e0
fix(diffusion): harden FLUX training numerics and edge cases
zirui Jul 14, 2026
c8d1f58
merge main into FLUX diffusion PR
zirui Jul 14, 2026
288442f
fix(diffusion): update module utils import after main merge
zirui Jul 14, 2026
cf894d4
docs(diffusion): clarify FLUX pretraining launch
zirui Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ local/
output
experiment
/data/*
!primus/backends/diffusion/data/
!primus/backends/diffusion/data/**
primus/backends/diffusion/data/**/__pycache__/
primus/backends/diffusion/data/**/*.pyc
pp_simulation_result
64 changes: 56 additions & 8 deletions examples/diffusion/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Wan Examples
# Diffusion Examples

Wan examples exercise the independent PyTorch Diffusion backend under
`primus/backends/diffusion`. For backend details, data/checkpoint layout, and minimal
configs, see `primus/backends/diffusion/README.md`.
These examples exercise the independent PyTorch diffusion backend under
`primus/backends/diffusion`, including Wan video training and FLUX text-to-image
training. For backend details, data/checkpoint layout, and minimal configs, see
`primus/backends/diffusion/README.md`.

## Data

The default smoke-test dataset is `zirui3/tiny-video-samples` on Hugging Face:
Wan examples use the `zirui3/tiny-video-samples` smoke-test dataset:

```bash
huggingface-cli download zirui3/tiny-video-samples \
Expand All @@ -22,6 +23,15 @@ Expected layout:
data/*.mp4
```

FLUX examples use either:

- precomputed encodings: a Hugging Face `datasets` directory with
`t5_encodings`, `clip_encodings`, `mean`, and `logvar` fields.
- raw image-text data: a local webdataset directory, a local JSONL file, a local
Hugging Face dataset, or a Hugging Face dataset repo.

See `primus/backends/diffusion/README.md` for checkpoint and data layout details.

## Run

Set the shared `torchrun` environment first:
Expand All @@ -34,7 +44,7 @@ export MASTER_PORT=${MASTER_PORT:-29500}
export GPUS_PER_NODE=${GPUS_PER_NODE:-8}
```

### Pretrain
### Wan Pretrain

```bash
DATASET_PATH=/data/tiny-video-samples/meta.jsonl \
Expand All @@ -53,7 +63,45 @@ torchrun \
Use `SP_SIZE=4` or `SP_SIZE=8` to enable Ulysses sequence parallelism
when the model head count supports it.

### Posttrain
### FLUX Precomputed Pretrain

```bash
DATASET_PATH=/data/flux_precomputed \
EMPTY_ENCODINGS_PATH=/data/flux_empty_encodings \
MAX_STEPS=10 \
torchrun \
--nnodes="$NNODES" --node_rank="$NODE_RANK" \
--master_addr="$MASTER_ADDR" --master_port="$MASTER_PORT" \
--nproc_per_node="$GPUS_PER_NODE" \
-m primus.cli.main train pretrain \
--config examples/diffusion/configs/MI355X/flux.1_dev_t2i-pretrain.yaml
```

Set `PRETRAINED_PATH=/path/to/flux1-dev.safetensors` only when you want to
initialize the DiT from existing FLUX weights. Empty `PRETRAINED_PATH` means
random initialization.

### FLUX Raw Image-Text Pretrain

```bash
DATASET=cc12m-test \
DATASET_PATH=/data/cc12m_test \
T5_ENCODER=google/t5-v1_1-xxl \
CLIP_ENCODER=openai/clip-vit-large-patch14 \
VAE_CHECKPOINT=black-forest-labs/FLUX.1-dev/ae.safetensors \
MAX_STEPS=10 \
torchrun \
--nnodes="$NNODES" --node_rank="$NODE_RANK" \
--master_addr="$MASTER_ADDR" --master_port="$MASTER_PORT" \
--nproc_per_node="$GPUS_PER_NODE" \
-m primus.cli.main train pretrain \
--config examples/diffusion/configs/MI355X/flux.1_dev_t2i-raw-pretrain.yaml
```

For raw training, `T5_ENCODER`, `CLIP_ENCODER`, and `VAE_CHECKPOINT` can be local
paths or Hugging Face identifiers.

### Wan Posttrain

```bash
INIT_CHECKPOINT=/models/Wan2.2-TI2V-5B \
Expand All @@ -70,5 +118,5 @@ torchrun \

The MI355X configs use Primus-style override sections such as `training`,
`data`, `parallelism`, `optimizer`, `runtime`, and `metrics`. The diffusion
adapter normalizes those sections into the Wan model/dataset/trainer
adapter normalizes those sections into diffusion model/dataset/trainer
arguments at runtime.
52 changes: 52 additions & 0 deletions examples/diffusion/configs/MI355X/flux.1_dev_t2i-pretrain.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
work_group: ${PRIMUS_TEAM:local}
user_name: ${PRIMUS_USER:local}
exp_name: ${PRIMUS_EXP_NAME:flux.1_dev_t2i-pretrain}
workspace: ${PRIMUS_WORKSPACE:./output}

platform:
config: platform_local.yaml

modules:
pre_trainer:
framework: diffusion
config: pre_trainer.yaml

model: flux.1_dev_t2i.yaml
overrides:
sink_level: null
file_sink_level: DEBUG
stderr_sink_level: INFO

metrics:
log_freq: 1
enable_wandb: false

training:
local_batch_size: ${LOCAL_BATCH_SIZE:1}
steps: ${MAX_STEPS:50}
num_train_epochs: 1000
gradient_accumulation_steps: 1
output_dir: ${OUTPUT_DIR:./output/flux.1_dev_t2i-pretrain}
save_steps: 0
save_strategy: ${SAVE_STRATEGY:dit_only}
run_name: flux.1_dev_t2i-pretrain

data:
dataset_path: ${DATASET_PATH:}
empty_encodings_path: ${EMPTY_ENCODINGS_PATH:}
prompt_dropout_prob: ${PROMPT_DROPOUT_PROB:0.1}
img_size: ${IMG_SIZE:256}

parallelism:
sp_size: 1
dp_replicate: ${DP_REPLICATE:1}

optimizer:
lr: ${LR:2.0e-4}
weight_decay: 0.01

runtime:
attention_backend: ${ATTENTION_BACKEND:flash_attn_aiter}
gradient_checkpointing: ${GRADIENT_CHECKPOINTING:false}
fsdp2_reshard_after_forward: ${FSDP2_RESHARD_AFTER_FORWARD:true}
report_to: none
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
work_group: ${PRIMUS_TEAM:local}
user_name: ${PRIMUS_USER:local}
exp_name: ${PRIMUS_EXP_NAME:flux.1_dev_t2i-raw-pretrain}
workspace: ${PRIMUS_WORKSPACE:./output}

platform:
config: platform_local.yaml

modules:
pre_trainer:
framework: diffusion
config: pre_trainer.yaml

model: flux.1_dev_t2i.yaml
overrides:
sink_level: null
file_sink_level: DEBUG
stderr_sink_level: INFO

model:
config:
encoder:
t5_encoder: ${T5_ENCODER:google/t5-v1_1-xxl}
clip_encoder: ${CLIP_ENCODER:openai/clip-vit-large-patch14}
autoencoder: ${VAE_CHECKPOINT:black-forest-labs/FLUX.1-dev/ae.safetensors}
max_t5_length: ${MAX_T5_LENGTH:256}

metrics:
log_freq: 1
enable_wandb: false

training:
local_batch_size: ${LOCAL_BATCH_SIZE:1}
steps: ${MAX_STEPS:50}
num_train_epochs: 1000
gradient_accumulation_steps: 1
output_dir: ${OUTPUT_DIR:./output/flux.1_dev_t2i-raw-pretrain}
save_steps: 0
save_strategy: ${SAVE_STRATEGY:dit_only}
run_name: flux.1_dev_t2i-raw-pretrain

data:
dataset_type: raw
dataset: ${DATASET:cc12m-test}
dataset_format: ${DATASET_FORMAT:webdataset}
dataset_path: ${DATASET_PATH:}
prompt_dropout_prob: ${PROMPT_DROPOUT_PROB:0.1}
img_size: ${IMG_SIZE:256}
skip_low_resolution: false

parallelism:
sp_size: 1
dp_replicate: ${DP_REPLICATE:1}

optimizer:
lr: ${LR:2.0e-4}
weight_decay: 0.01

runtime:
attention_backend: ${ATTENTION_BACKEND:flash_attn_aiter}
gradient_checkpointing: ${GRADIENT_CHECKPOINTING:false}
fsdp2_reshard_after_forward: ${FSDP2_RESHARD_AFTER_FORWARD:true}
report_to: none
Loading