Skip to content

Commit ad1982e

Browse files
refactor wan video-to-video pipeline tests to the new mixin structure (#14235)
Co-authored-by: Sayak Paul <spsayakpaul@gmail.com>
1 parent 52a3a48 commit ad1982e

1 file changed

Lines changed: 32 additions & 55 deletions

File tree

tests/pipelines/wan/test_wan_video_to_video.py

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,27 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import unittest
1615

16+
import pytest
1717
import torch
1818
from PIL import Image
1919
from transformers import AutoConfig, AutoTokenizer, T5EncoderModel
2020

2121
from diffusers import AutoencoderKLWan, UniPCMultistepScheduler, WanTransformer3DModel, WanVideoToVideoPipeline
2222

23-
from ...testing_utils import (
24-
enable_full_determinism,
25-
)
26-
from ..pipeline_params import TEXT_TO_IMAGE_IMAGE_PARAMS, TEXT_TO_IMAGE_PARAMS
27-
from ..test_pipelines_common import (
28-
PipelineTesterMixin,
29-
)
23+
from ..testing_utils import BasePipelineTesterConfig, MemoryTesterMixin, PipelineTesterMixin
3024

3125

32-
enable_full_determinism()
33-
34-
35-
class WanVideoToVideoPipelineFastTests(PipelineTesterMixin, unittest.TestCase):
26+
class WanVideoToVideoPipelineTesterConfig(BasePipelineTesterConfig):
3627
pipeline_class = WanVideoToVideoPipeline
37-
params = TEXT_TO_IMAGE_PARAMS - {"cross_attention_kwargs"}
38-
batch_params = frozenset(["video", "prompt", "negative_prompt"])
39-
image_latents_params = TEXT_TO_IMAGE_IMAGE_PARAMS
40-
required_optional_params = frozenset(
41-
[
42-
"num_inference_steps",
43-
"generator",
44-
"latents",
45-
"return_dict",
46-
"callback_on_step_end",
47-
"callback_on_step_end_tensor_inputs",
48-
]
28+
required_input_params_in_call_signature = frozenset(
29+
["prompt", "negative_prompt", "height", "width", "guidance_scale", "prompt_embeds", "negative_prompt_embeds"]
30+
)
31+
batch_input_params = frozenset(["prompt", "video"])
32+
# Wan is a video pipeline: it exposes `num_videos_per_prompt`, not the base default `num_images_per_prompt`.
33+
optional_input_params = frozenset(
34+
["num_inference_steps", "num_videos_per_prompt", "generator", "latents", "output_type", "return_dict"]
4935
)
50-
test_xformers_attention = False
5136

5237
def get_dummy_components(self):
5338
torch.manual_seed(0)
@@ -81,69 +66,61 @@ def get_dummy_components(self):
8166
rope_max_seq_len=32,
8267
)
8368

84-
components = {
69+
return {
8570
"transformer": transformer,
8671
"vae": vae,
8772
"scheduler": scheduler,
8873
"text_encoder": text_encoder,
8974
"tokenizer": tokenizer,
9075
}
91-
return components
92-
93-
def get_dummy_inputs(self, device, seed=0):
94-
if str(device).startswith("mps"):
95-
generator = torch.manual_seed(seed)
96-
else:
97-
generator = torch.Generator(device=device).manual_seed(seed)
9876

77+
def get_dummy_inputs(self):
9978
video = [Image.new("RGB", (16, 16))] * 17
100-
inputs = {
79+
return {
10180
"video": video,
10281
"prompt": "dance monkey",
10382
"negative_prompt": "negative", # TODO
104-
"generator": generator,
83+
"generator": self.get_generator(0),
10584
"num_inference_steps": 4,
10685
"guidance_scale": 6.0,
10786
"height": 16,
10887
"width": 16,
10988
"max_sequence_length": 16,
89+
# Request torch outputs so tests compare torch tensors directly (see `BasePipelineTesterConfig`).
11090
"output_type": "pt",
11191
}
112-
return inputs
11392

114-
def test_inference(self):
115-
device = "cpu"
11693

117-
components = self.get_dummy_components()
118-
pipe = self.pipeline_class(**components)
119-
pipe.to(device)
120-
pipe.set_progress_bar_config(disable=None)
94+
class TestWanVideoToVideoPipeline(WanVideoToVideoPipelineTesterConfig, PipelineTesterMixin):
95+
def test_inference(self):
96+
# Run on CPU: the expected slice below is CPU-specific.
97+
pipe = self.get_pipeline()
12198

122-
inputs = self.get_dummy_inputs(device)
99+
inputs = self.get_dummy_inputs()
123100
video = pipe(**inputs).frames
124101
generated_video = video[0]
125-
self.assertEqual(generated_video.shape, (17, 3, 16, 16))
102+
assert generated_video.shape == (17, 3, 16, 16)
126103

127104
# fmt: off
128105
expected_slice = torch.tensor([0.4522, 0.4534, 0.4532, 0.4553, 0.4526, 0.4538, 0.4533, 0.4547, 0.513, 0.5176, 0.5286, 0.4958, 0.4955, 0.5381, 0.5154, 0.5195])
129-
# fmt:on
106+
# fmt: on
130107

131108
generated_slice = generated_video.flatten()
132109
generated_slice = torch.cat([generated_slice[:8], generated_slice[-8:]])
133-
self.assertTrue(torch.allclose(generated_slice, expected_slice, atol=1e-3))
134-
135-
@unittest.skip("Test not supported")
136-
def test_attention_slicing_forward_pass(self):
137-
pass
110+
assert torch.allclose(generated_slice, expected_slice, atol=1e-3)
138111

139-
@unittest.skip(
140-
"WanVideoToVideoPipeline has to run in mixed precision. Casting the entire pipeline will result in errors"
112+
@pytest.mark.skip(
113+
reason="WanVideoToVideoPipeline has to run in mixed precision. Casting the entire pipeline will result in errors"
141114
)
142-
def test_float16_inference(self):
115+
def test_half_precision_inference_no_nan(self):
143116
pass
144117

145-
@unittest.skip(
146-
"WanVideoToVideoPipeline has to run in mixed precision. Save/Load the entire pipeline in FP16 will result in errors"
118+
@pytest.mark.skip(
119+
reason="WanVideoToVideoPipeline has to run in mixed precision. Save/Load the entire pipeline in FP16 will result in errors"
147120
)
148121
def test_save_load_float16(self):
149122
pass
123+
124+
125+
class TestWanVideoToVideoPipelineMemory(WanVideoToVideoPipelineTesterConfig, MemoryTesterMixin):
126+
pass

0 commit comments

Comments
 (0)