Skip to content

Commit 08566b1

Browse files
Merge pull request #419 from AI-Hypercomputer:ninatu/wan_load_params
PiperOrigin-RevId: 936088152
2 parents 9616d1c + ef5af09 commit 08566b1

15 files changed

Lines changed: 833 additions & 444 deletions

src/maxdiffusion/checkpointing/wan_checkpointer.py

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,27 @@
1616

1717
from abc import ABC, abstractmethod
1818
import json
19-
from typing import Optional, Tuple
19+
from typing import Optional, Tuple, Generic, TypeVar, Type
2020
import jax
2121
from flax import nnx
2222
from maxdiffusion.checkpointing.checkpointing_utils import (
2323
add_sharding_to_struct,
2424
create_orbax_checkpoint_manager,
2525
get_cpu_mesh_and_sharding,
2626
)
27-
from ..pipelines.wan.wan_pipeline_2_1 import WanPipeline2_1
28-
from ..pipelines.wan.wan_pipeline_2_2 import WanPipeline2_2
29-
from ..pipelines.wan.wan_pipeline_i2v_2p1 import WanPipelineI2V_2_1
30-
from ..pipelines.wan.wan_pipeline_i2v_2p2 import WanPipelineI2V_2_2
27+
from ..pipelines.wan.wan_pipeline import WanPipeline
3128
from .. import max_logging, max_utils
3229
import orbax.checkpoint as ocp
3330

3431

3532
WAN_CHECKPOINT = "WAN_CHECKPOINT"
3633

3734

38-
class WanCheckpointer(ABC):
35+
T = TypeVar("T", bound=WanPipeline)
36+
37+
38+
class WanCheckpointer(Generic[T], ABC):
39+
pipeline_class: Optional[Type[T]] = None
3940

4041
def __init__(self, config, checkpoint_type: str = WAN_CHECKPOINT):
4142
self.config = config
@@ -176,16 +177,61 @@ def _pretrained_save_items(pipeline, pretrained_state_sources, pretrained_config
176177
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
177178
raise NotImplementedError
178179

179-
@abstractmethod
180-
def load_diffusers_checkpoint(self):
181-
raise NotImplementedError
180+
def load_diffusers_checkpoint(
181+
self,
182+
vae_only=False,
183+
load_vae=None,
184+
load_text_encoder=None,
185+
load_transformer=None,
186+
load_scheduler=None,
187+
) -> T:
188+
pipeline = self.pipeline_class.from_pretrained(
189+
self.config,
190+
vae_only=vae_only,
191+
load_vae=load_vae,
192+
load_text_encoder=load_text_encoder,
193+
load_transformer=load_transformer,
194+
load_scheduler=load_scheduler,
195+
)
196+
return pipeline
182197

183-
@abstractmethod
184198
def load_checkpoint(
185-
self, step=None
186-
) -> Tuple[
187-
Optional[WanPipeline2_1 | WanPipeline2_2 | WanPipelineI2V_2_1 | WanPipelineI2V_2_2], Optional[dict], Optional[int]
188-
]:
199+
self,
200+
step=None,
201+
vae_only=False,
202+
load_vae=None,
203+
load_text_encoder=None,
204+
load_transformer=None,
205+
load_scheduler=None,
206+
) -> Tuple[T, Optional[dict], Optional[int]]:
207+
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
208+
opt_state = None
209+
if restored_checkpoint:
210+
max_logging.log("Loading WAN pipeline from checkpoint")
211+
pipeline = self.pipeline_class.from_checkpoint(
212+
self.config,
213+
restored_checkpoint,
214+
vae_only=vae_only,
215+
load_vae=load_vae,
216+
load_text_encoder=load_text_encoder,
217+
load_transformer=load_transformer,
218+
load_scheduler=load_scheduler,
219+
)
220+
opt_state = self._extract_opt_state(restored_checkpoint)
221+
else:
222+
max_logging.log("No checkpoint found, loading default pipeline.")
223+
pipeline = self.load_diffusers_checkpoint(
224+
vae_only=vae_only,
225+
load_vae=load_vae,
226+
load_text_encoder=load_text_encoder,
227+
load_transformer=load_transformer,
228+
load_scheduler=load_scheduler,
229+
)
230+
231+
return pipeline, opt_state, step
232+
233+
@abstractmethod
234+
def _extract_opt_state(self, restored_checkpoint):
189235
raise NotImplementedError
190236

191237
@abstractmethod

src/maxdiffusion/checkpointing/wan_checkpointer_2_1.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from ..pipelines.wan.wan_pipeline_2_1 import WanPipeline2_1
2525

2626

27-
class WanCheckpointer2_1(WanCheckpointer):
27+
class WanCheckpointer2_1(WanCheckpointer[WanPipeline2_1]):
28+
pipeline_class = WanPipeline2_1
2829

2930
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
3031
if step is None:
@@ -58,23 +59,10 @@ def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dic
5859
max_logging.log(f"optimizer state saved in attribute self.opt_state {self.opt_state}")
5960
return restored_checkpoint, step
6061

61-
def load_diffusers_checkpoint(self):
62-
pipeline = WanPipeline2_1.from_pretrained(self.config)
63-
return pipeline
64-
65-
def load_checkpoint(self, step=None) -> Tuple[WanPipeline2_1, Optional[dict], Optional[int]]:
66-
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
67-
opt_state = None
68-
if restored_checkpoint:
69-
max_logging.log("Loading WAN pipeline from checkpoint")
70-
pipeline = WanPipeline2_1.from_checkpoint(self.config, restored_checkpoint)
71-
if "opt_state" in restored_checkpoint.wan_state.keys():
72-
opt_state = restored_checkpoint.wan_state["opt_state"]
73-
else:
74-
max_logging.log("No checkpoint found, loading default pipeline.")
75-
pipeline = self.load_diffusers_checkpoint()
76-
77-
return pipeline, opt_state, step
62+
def _extract_opt_state(self, restored_checkpoint):
63+
if "opt_state" in restored_checkpoint.wan_state.keys():
64+
return restored_checkpoint.wan_state["opt_state"]
65+
return None
7866

7967
def save_checkpoint(self, train_step, pipeline: WanPipeline2_1, train_states: dict):
8068
"""Saves the training state and model configurations."""

src/maxdiffusion/checkpointing/wan_checkpointer_2_2.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from maxdiffusion.checkpointing.wan_checkpointer import WanCheckpointer
2525

2626

27-
class WanCheckpointer2_2(WanCheckpointer):
27+
class WanCheckpointer2_2(WanCheckpointer[WanPipeline2_2]):
28+
pipeline_class = WanPipeline2_2
2829

2930
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
3031
if step is None:
@@ -79,26 +80,12 @@ def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dic
7980
max_logging.log(f"optimizer state saved in attribute self.opt_state {self.opt_state}")
8081
return restored_checkpoint, step
8182

82-
def load_diffusers_checkpoint(self):
83-
pipeline = WanPipeline2_2.from_pretrained(self.config)
84-
return pipeline
85-
86-
def load_checkpoint(self, step=None) -> Tuple[WanPipeline2_2, Optional[dict], Optional[int]]:
87-
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
88-
opt_state = None
89-
if restored_checkpoint:
90-
max_logging.log("Loading WAN pipeline from checkpoint")
91-
pipeline = WanPipeline2_2.from_checkpoint(self.config, restored_checkpoint)
92-
# Check for optimizer state in either transformer
93-
if "opt_state" in restored_checkpoint.low_noise_transformer_state.keys():
94-
opt_state = restored_checkpoint.low_noise_transformer_state["opt_state"]
95-
elif "opt_state" in restored_checkpoint.high_noise_transformer_state.keys():
96-
opt_state = restored_checkpoint.high_noise_transformer_state["opt_state"]
97-
else:
98-
max_logging.log("No checkpoint found, loading default pipeline.")
99-
pipeline = self.load_diffusers_checkpoint()
100-
101-
return pipeline, opt_state, step
83+
def _extract_opt_state(self, restored_checkpoint):
84+
if "opt_state" in restored_checkpoint.low_noise_transformer_state.keys():
85+
return restored_checkpoint.low_noise_transformer_state["opt_state"]
86+
elif "opt_state" in restored_checkpoint.high_noise_transformer_state.keys():
87+
return restored_checkpoint.high_noise_transformer_state["opt_state"]
88+
return None
10289

10390
def save_checkpoint(self, train_step, pipeline: WanPipeline2_2, train_states: dict):
10491
"""Saves the training state and model configurations."""

src/maxdiffusion/checkpointing/wan_checkpointer_i2v_2p1.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from ..pipelines.wan.wan_pipeline_i2v_2p1 import WanPipelineI2V_2_1
2525

2626

27-
class WanCheckpointerI2V_2_1(WanCheckpointer):
27+
class WanCheckpointerI2V_2_1(WanCheckpointer[WanPipelineI2V_2_1]):
28+
pipeline_class = WanPipelineI2V_2_1
2829

2930
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
3031
if step is None:
@@ -58,23 +59,10 @@ def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dic
5859
max_logging.log(f"optimizer state saved in attribute self.opt_state {self.opt_state}")
5960
return restored_checkpoint, step
6061

61-
def load_diffusers_checkpoint(self):
62-
pipeline = WanPipelineI2V_2_1.from_pretrained(self.config)
63-
return pipeline
64-
65-
def load_checkpoint(self, step=None) -> Tuple[WanPipelineI2V_2_1, Optional[dict], Optional[int]]:
66-
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
67-
opt_state = None
68-
if restored_checkpoint:
69-
max_logging.log("Loading WAN pipeline from checkpoint")
70-
pipeline = WanPipelineI2V_2_1.from_checkpoint(self.config, restored_checkpoint)
71-
if "opt_state" in restored_checkpoint.wan_state.keys():
72-
opt_state = restored_checkpoint.wan_state["opt_state"]
73-
else:
74-
max_logging.log("No checkpoint found, loading default pipeline.")
75-
pipeline = self.load_diffusers_checkpoint()
76-
77-
return pipeline, opt_state, step
62+
def _extract_opt_state(self, restored_checkpoint):
63+
if "opt_state" in restored_checkpoint.wan_state.keys():
64+
return restored_checkpoint.wan_state["opt_state"]
65+
return None
7866

7967
def save_checkpoint(self, train_step, pipeline: WanPipelineI2V_2_1, train_states: dict):
8068
"""Saves the training state and model configurations."""

src/maxdiffusion/checkpointing/wan_checkpointer_i2v_2p2.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from maxdiffusion.checkpointing.wan_checkpointer import WanCheckpointer
2525

2626

27-
class WanCheckpointerI2V_2_2(WanCheckpointer):
27+
class WanCheckpointerI2V_2_2(WanCheckpointer[WanPipelineI2V_2_2]):
28+
pipeline_class = WanPipelineI2V_2_2
2829

2930
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
3031
if step is None:
@@ -79,26 +80,12 @@ def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dic
7980
max_logging.log(f"optimizer state saved in attribute self.opt_state {self.opt_state}")
8081
return restored_checkpoint, step
8182

82-
def load_diffusers_checkpoint(self):
83-
pipeline = WanPipelineI2V_2_2.from_pretrained(self.config)
84-
return pipeline
85-
86-
def load_checkpoint(self, step=None) -> Tuple[WanPipelineI2V_2_2, Optional[dict], Optional[int]]:
87-
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
88-
opt_state = None
89-
if restored_checkpoint:
90-
max_logging.log("Loading WAN pipeline from checkpoint")
91-
pipeline = WanPipelineI2V_2_2.from_checkpoint(self.config, restored_checkpoint)
92-
# Check for optimizer state in either transformer
93-
if "opt_state" in restored_checkpoint.low_noise_transformer_state.keys():
94-
opt_state = restored_checkpoint.low_noise_transformer_state["opt_state"]
95-
elif "opt_state" in restored_checkpoint.high_noise_transformer_state.keys():
96-
opt_state = restored_checkpoint.high_noise_transformer_state["opt_state"]
97-
else:
98-
max_logging.log("No checkpoint found, loading default pipeline.")
99-
pipeline = self.load_diffusers_checkpoint()
100-
101-
return pipeline, opt_state, step
83+
def _extract_opt_state(self, restored_checkpoint):
84+
if "opt_state" in restored_checkpoint.low_noise_transformer_state.keys():
85+
return restored_checkpoint.low_noise_transformer_state["opt_state"]
86+
elif "opt_state" in restored_checkpoint.high_noise_transformer_state.keys():
87+
return restored_checkpoint.high_noise_transformer_state["opt_state"]
88+
return None
10289

10390
def save_checkpoint(self, train_step, pipeline: WanPipelineI2V_2_2, train_states: dict):
10491
"""Saves the training state and model configurations."""

src/maxdiffusion/checkpointing/wan_vace_checkpointer_2_1.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
from ..pipelines.wan.wan_vace_pipeline_2_1 import VaceWanPipeline2_1
2424

2525

26-
class WanVaceCheckpointer2_1(WanCheckpointer):
26+
class WanVaceCheckpointer2_1(WanCheckpointer[VaceWanPipeline2_1]):
27+
pipeline_class = VaceWanPipeline2_1
2728

2829
def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dict], Optional[int]]:
2930
if step is None:
@@ -57,23 +58,10 @@ def load_wan_configs_from_orbax(self, step: Optional[int]) -> Tuple[Optional[dic
5758
max_logging.log(f"optimizer state saved in attribute self.opt_state {self.opt_state}")
5859
return restored_checkpoint, step
5960

60-
def load_diffusers_checkpoint(self):
61-
pipeline = VaceWanPipeline2_1.from_pretrained(self.config)
62-
return pipeline
63-
64-
def load_checkpoint(self, step=None) -> Tuple[VaceWanPipeline2_1, Optional[dict], Optional[int]]:
65-
restored_checkpoint, step = self.load_wan_configs_from_orbax(step)
66-
opt_state = None
67-
if restored_checkpoint:
68-
max_logging.log("Loading WAN pipeline from checkpoint")
69-
pipeline = VaceWanPipeline2_1.from_checkpoint(self.config, restored_checkpoint)
70-
if "opt_state" in restored_checkpoint.wan_state.keys():
71-
opt_state = restored_checkpoint.wan_state["opt_state"]
72-
else:
73-
max_logging.log("No checkpoint found, loading default pipeline.")
74-
pipeline = self.load_diffusers_checkpoint()
75-
76-
return pipeline, opt_state, step
61+
def _extract_opt_state(self, restored_checkpoint):
62+
if "opt_state" in restored_checkpoint.wan_state.keys():
63+
return restored_checkpoint.wan_state["opt_state"]
64+
return None
7765

7866
def save_checkpoint(self, train_step, pipeline: VaceWanPipeline2_1, train_states: dict):
7967
"""Saves the training state and model configurations."""

0 commit comments

Comments
 (0)