2525
2626class FastGenModel (torch .nn .Module ):
2727 # Preprocessor sub-objects of ``net`` (handled specially for device/dtype placement
28- # in on_train_begin and for torch.compile in compile_dict ). Single source of truth.
28+ # in on_train_begin and for torch.compile in apply_torch_compile ). Single source of truth.
2929 _PREPROCESSOR_ATTRS = ("vae" , "text_encoder" , "image_encoder" )
3030
3131 def __init__ (self , config : BaseModelConfig ):
@@ -268,22 +268,28 @@ def build_model(self):
268268 if hasattr (self .net , "init_preprocessors" ) and self .config .enable_preprocessors :
269269 self .net .init_preprocessors ()
270270
271- @property
272- def compile_dict (self ) -> dict :
273- """Return dict of modules to compile with torch.compile, keyed by name.
274-
275- Built from model_dict (e.g. net, plus fake_score/discriminator for DMD2)
276- minus the EMA networks, plus the teacher (if any, cf. fsdp_dict) and the
277- net's preprocessors. Compilation is applied in place (via
278- ``nn.Module.compile``) by ``apply_torch_compile``, which the trainer calls
279- *after* DDP/FSDP wrapping so torch.compile composes with the wrappers.
271+ def apply_torch_compile (self ):
272+ """Compile the training networks in place with torch.compile.
273+
274+ Called by the trainer after DDP/FSDP wrapping (and after the networks
275+ have been moved to their device in ``on_train_begin``) so torch.compile
276+ composes with the distributed wrappers. No-op when
277+ ``config.torch_compile_mode`` is None.
278+
279+ The modules compiled are those in model_dict (e.g. net, plus
280+ fake_score/discriminator for DMD2) minus the EMA networks, plus the
281+ teacher (if any, cf. fsdp_dict) and the net's preprocessors.
280282 """
283+ mode = self .config .torch_compile_mode
284+ if mode is None :
285+ return
286+
281287 # model_dict contains the trainable networks (incl. EMA); EMA networks are
282288 # weight-averaged copies that aren't run during training, so drop them.
283- compile_dict = {name : net for name , net in self .model_dict .items () if name not in self .ema_dict }
289+ modules = {name : net for name , net in self .model_dict .items () if name not in self .ema_dict }
284290 # The teacher is not part of model_dict; add it when present (cf. fsdp_dict).
285291 if getattr (self , "teacher" , None ) is not None :
286- compile_dict ["teacher" ] = self .teacher
292+ modules ["teacher" ] = self .teacher
287293 # Preprocessors (VAE, text/image encoders) are often lightweight wrappers
288294 # (e.g. WanVideoEncoder, SDVAE) that are not nn.Modules themselves but hold
289295 # the actual nn.Module under an attribute; compile those submodules too.
@@ -292,24 +298,13 @@ def compile_dict(self) -> dict:
292298 if obj is None :
293299 continue
294300 if isinstance (obj , torch .nn .Module ):
295- compile_dict [name ] = obj
301+ modules [name ] = obj
296302 else :
297303 for attr , submodule in getattr (obj , "__dict__" , {}).items ():
298304 if isinstance (submodule , torch .nn .Module ):
299- compile_dict [f"{ name } .{ attr } " ] = submodule
300- return compile_dict
301-
302- def apply_torch_compile (self ):
303- """Compile the modules in ``compile_dict`` in place with torch.compile.
305+ modules [f"{ name } .{ attr } " ] = submodule
304306
305- Called by the trainer after DDP/FSDP wrapping (and after the networks
306- have been moved to their device in ``on_train_begin``). No-op when
307- ``config.torch_compile_mode`` is None.
308- """
309- mode = self .config .torch_compile_mode
310- if mode is None :
311- return
312- for name , module in self .compile_dict .items ():
307+ for name , module in modules .items ():
313308 logger .info (f"Applying torch.compile (mode={ mode } ) to { name } " )
314309 module .compile (mode = mode )
315310
0 commit comments