Skip to content

Commit 6212212

Browse files
author
ThomasNing
committed
Generate WAN dummy latents uniformly
1 parent f6c36b9 commit 6212212

2 files changed

Lines changed: 57 additions & 23 deletions

File tree

src/maxdiffusion/maxdiffusion_utils.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -357,30 +357,29 @@ def get_dummy_ltx2_inputs(config, pipeline, batch_size):
357357
)
358358

359359

360+
def _get_wan_transformer_for_dummy_inputs(pipeline):
361+
for transformer_attr in ("transformer", "low_noise_transformer", "high_noise_transformer"):
362+
transformer = getattr(pipeline, transformer_attr, None)
363+
if transformer is not None:
364+
return transformer
365+
raise ValueError("WAN dummy inputs require a transformer, low_noise_transformer, or high_noise_transformer.")
366+
367+
368+
def _get_dummy_wan_latents(config, pipeline, batch_size):
369+
transformer = _get_wan_transformer_for_dummy_inputs(pipeline)
370+
num_channels_latents = transformer.config.in_channels
371+
num_latent_frames = (int(config.num_frames) - 1) // pipeline.vae_scale_factor_temporal + 1
372+
latent_height = int(config.height) // pipeline.vae_scale_factor_spatial
373+
latent_width = int(config.width) // pipeline.vae_scale_factor_spatial
374+
return jax.random.normal(
375+
jax.random.key(config.seed),
376+
(batch_size, num_channels_latents, num_latent_frames, latent_height, latent_width),
377+
dtype=jnp.float32,
378+
)
379+
380+
360381
def get_dummy_wan_inputs(config, pipeline, batch_size):
361-
if getattr(pipeline, "transformer", None) is not None:
362-
latents = pipeline.prepare_latents(
363-
batch_size,
364-
vae_scale_factor_temporal=pipeline.vae_scale_factor_temporal,
365-
vae_scale_factor_spatial=pipeline.vae_scale_factor_spatial,
366-
height=config.height,
367-
width=config.width,
368-
num_frames=config.num_frames,
369-
num_channels_latents=pipeline.transformer.config.in_channels,
370-
)
371-
else:
372-
# The two-expert Wan2.2 I2V pipeline (WanPipelineI2V_2_2) has no `.transformer`
373-
# and a different `prepare_latents()` signature, so build dummy latents directly
374-
# in the (B, C, F, H, W) layout WanModel.__call__ expects.
375-
transformer = getattr(pipeline, "low_noise_transformer", None) or pipeline.high_noise_transformer
376-
num_channels_latents = transformer.config.in_channels
377-
num_latent_frames = (config.num_frames - 1) // pipeline.vae_scale_factor_temporal + 1
378-
latent_height = config.height // pipeline.vae_scale_factor_spatial
379-
latent_width = config.width // pipeline.vae_scale_factor_spatial
380-
latents = jax.random.normal(
381-
jax.random.key(config.seed),
382-
(batch_size, num_channels_latents, num_latent_frames, latent_height, latent_width),
383-
)
382+
latents = _get_dummy_wan_latents(config, pipeline, batch_size)
384383
bsz = latents.shape[0]
385384
prompt_embeds = jax.random.normal(jax.random.key(config.seed), (batch_size, 512, 4096))
386385
timesteps = jnp.array([0] * bsz, dtype=jnp.int32)

src/maxdiffusion/tests/maxdiffusion_utils_test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"""
1616

1717
import os
18+
from types import SimpleNamespace
1819
import unittest
20+
from unittest.mock import Mock
1921

2022
from jax.sharding import Mesh
2123

@@ -35,6 +37,39 @@ class MaxDiffusionUtilsTest(unittest.TestCase):
3537
def setUp(self):
3638
MaxDiffusionUtilsTest.dummy_data = {}
3739

40+
def test_get_dummy_wan_inputs_generates_latents_without_pipeline_prepare_latents(self):
41+
config = SimpleNamespace(height=64, width=80, num_frames=9, seed=0)
42+
pipeline = SimpleNamespace(
43+
transformer=SimpleNamespace(config=SimpleNamespace(in_channels=16)),
44+
vae_scale_factor_temporal=4,
45+
vae_scale_factor_spatial=8,
46+
prepare_latents=Mock(side_effect=AssertionError("prepare_latents should not be called")),
47+
)
48+
49+
latents, prompt_embeds, timesteps = maxdiffusion_utils.get_dummy_wan_inputs(config, pipeline, batch_size=2)
50+
51+
pipeline.prepare_latents.assert_not_called()
52+
self.assertEqual(latents.shape, (2, 16, 3, 8, 10))
53+
self.assertEqual(prompt_embeds.shape, (2, 512, 4096))
54+
self.assertEqual(timesteps.shape, (2,))
55+
56+
def test_get_dummy_wan_inputs_supports_two_expert_pipeline(self):
57+
config = SimpleNamespace(height=64, width=80, num_frames=9, seed=0)
58+
pipeline = SimpleNamespace(
59+
low_noise_transformer=SimpleNamespace(config=SimpleNamespace(in_channels=48)),
60+
high_noise_transformer=SimpleNamespace(config=SimpleNamespace(in_channels=48)),
61+
vae_scale_factor_temporal=4,
62+
vae_scale_factor_spatial=8,
63+
prepare_latents=Mock(side_effect=AssertionError("prepare_latents should not be called")),
64+
)
65+
66+
latents, prompt_embeds, timesteps = maxdiffusion_utils.get_dummy_wan_inputs(config, pipeline, batch_size=2)
67+
68+
pipeline.prepare_latents.assert_not_called()
69+
self.assertEqual(latents.shape, (2, 48, 3, 8, 10))
70+
self.assertEqual(prompt_embeds.shape, (2, 512, 4096))
71+
self.assertEqual(timesteps.shape, (2,))
72+
3873
def test_create_scheduler(self):
3974
"""Test create scheduler with different schedulers"""
4075
pyconfig.initialize(

0 commit comments

Comments
 (0)