Skip to content

Commit c14a1e8

Browse files
migrate wan vace lora tests to the pipeline-level mixins (#14614)
Co-authored-by: Sayak Paul <spsayakpaul@gmail.com>
1 parent 276ac2f commit c14a1e8

2 files changed

Lines changed: 61 additions & 190 deletions

File tree

tests/lora/test_lora_layers_wanvace.py

Lines changed: 0 additions & 188 deletions
This file was deleted.

tests/pipelines/wan/test_wan_vace.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
# limitations under the License.
1414

1515

16+
import os
17+
1618
import pytest
19+
import safetensors.torch
1720
import torch
1821
from PIL import Image
1922
from transformers import AutoConfig, AutoTokenizer, T5EncoderModel
@@ -25,9 +28,20 @@
2528
WanVACEPipeline,
2629
WanVACETransformer3DModel,
2730
)
31+
from diffusers.utils.import_utils import is_peft_available
32+
33+
from ...testing_utils import assert_tensors_close, require_peft_version_greater, torch_device
34+
from ..testing_utils import (
35+
BasePipelineTesterConfig,
36+
LoraMemoryTesterMixin,
37+
LoraTesterMixin,
38+
MemoryTesterMixin,
39+
PipelineTesterMixin,
40+
)
41+
2842

29-
from ...testing_utils import assert_tensors_close, torch_device
30-
from ..testing_utils import BasePipelineTesterConfig, MemoryTesterMixin, PipelineTesterMixin
43+
if is_peft_available():
44+
from peft.utils import get_peft_model_state_dict
3145

3246

3347
class WanVACEPipelineTesterConfig(BasePipelineTesterConfig):
@@ -242,3 +256,48 @@ def test_save_load_optional_components(self, tmp_path, expected_max_difference=1
242256

243257
class TestWanVACEPipelineMemory(WanVACEPipelineTesterConfig, MemoryTesterMixin):
244258
pass
259+
260+
261+
class TestWanVACEPipelineLoRA(WanVACEPipelineTesterConfig, LoraTesterMixin):
262+
"""LoRA tests for the Wan VACE pipeline."""
263+
264+
@require_peft_version_greater("0.13.2")
265+
def test_lora_exclude_modules(self, tmp_path, base_pipe_output):
266+
exclude_module_name = "vace_blocks.0.proj_out"
267+
pipe = self.get_pipeline().to(torch_device)
268+
269+
self.add_adapters_to_pipeline(
270+
pipe, components=["transformer"], target_modules=["proj_out"], exclude_modules=[exclude_module_name]
271+
)
272+
# The state dict should not contain the modules excluded from LoRA.
273+
state_dict_from_model = get_peft_model_state_dict(pipe.transformer, adapter_name="default")
274+
assert not any(exclude_module_name in k for k in state_dict_from_model)
275+
assert any("proj_out" in k for k in state_dict_from_model)
276+
output_lora_exclude_modules = self.run_pipe(pipe)
277+
278+
denoiser_state_dict = get_peft_model_state_dict(pipe.transformer)
279+
self.pipeline_class.save_lora_weights(tmp_path, transformer_lora_layers=denoiser_state_dict)
280+
pipe.unload_lora_weights()
281+
282+
# Check in the saved state dict.
283+
loaded_state_dict = safetensors.torch.load_file(os.path.join(tmp_path, "pytorch_lora_weights.safetensors"))
284+
assert not any(exclude_module_name in k for k in loaded_state_dict)
285+
assert any("proj_out" in k for k in loaded_state_dict)
286+
287+
# Check in the state dict obtained after loading LoRA.
288+
pipe.load_lora_weights(tmp_path)
289+
state_dict_from_model = get_peft_model_state_dict(pipe.transformer, adapter_name="default_0")
290+
assert not any(exclude_module_name in k for k in state_dict_from_model)
291+
assert any("proj_out" in k for k in state_dict_from_model)
292+
293+
output_lora_pretrained = self.run_pipe(pipe)
294+
assert not torch.allclose(base_pipe_output, output_lora_exclude_modules, atol=1e-3, rtol=1e-3), (
295+
"LoRA should change outputs."
296+
)
297+
assert torch.allclose(output_lora_exclude_modules, output_lora_pretrained, atol=1e-3, rtol=1e-3), (
298+
"Lora outputs should match."
299+
)
300+
301+
302+
class TestWanVACEPipelineLoRAMemory(WanVACEPipelineTesterConfig, LoraMemoryTesterMixin):
303+
"""LoRA offloading tests for the Wan VACE pipeline."""

0 commit comments

Comments
 (0)