@@ -1152,6 +1152,66 @@ def _denormalize_latents(
11521152 latents = latents * latents_std / scaling_factor + latents_mean
11531153 return latents
11541154
1155+ def _decode_latents_to_video (
1156+ self ,
1157+ latents : jax .Array ,
1158+ generator : jax .Array ,
1159+ batch_size : int ,
1160+ decode_timestep : Union [float , List [float ]],
1161+ decode_noise_scale : Optional [Union [float , List [float ]]],
1162+ output_type : str ,
1163+ replicate_vae : bool ,
1164+ ):
1165+ if replicate_vae :
1166+ try :
1167+ mesh = latents .sharding .mesh
1168+ replicated_sharding = NamedSharding (mesh , P ())
1169+ # Replicate VAE weights
1170+ graphdef , state = nnx .split (self .vae )
1171+ state = jax .tree_util .tree_map (
1172+ lambda x : jax .lax .with_sharding_constraint (x , replicated_sharding ) if isinstance (x , jax .Array ) else x , state
1173+ )
1174+ self .vae = nnx .merge (graphdef , state )
1175+ except Exception as e : # pylint: disable=broad-exception-caught
1176+ max_logging .log (f"[Tuning] Failed to replicate VAE weights: { e } " )
1177+
1178+ t0_video_vae = time .perf_counter ()
1179+ with jax .named_scope ("video_vae_decode" ):
1180+ if getattr (self .vae .config , "timestep_conditioning" , False ):
1181+ noise = jax .random .normal (generator , latents .shape , dtype = latents .dtype )
1182+
1183+ if not isinstance (decode_timestep , list ):
1184+ decode_timestep = [decode_timestep ] * batch_size
1185+ if decode_noise_scale is None :
1186+ decode_noise_scale = decode_timestep
1187+ elif not isinstance (decode_noise_scale , list ):
1188+ decode_noise_scale = [decode_noise_scale ] * batch_size
1189+
1190+ timestep = jnp .array (decode_timestep , dtype = latents .dtype )
1191+ decode_noise_scale = jnp .array (decode_noise_scale , dtype = latents .dtype )[:, None , None , None , None ]
1192+
1193+ latents = (1 - decode_noise_scale ) * latents + decode_noise_scale * noise
1194+
1195+ latents = latents .astype (self .vae .dtype )
1196+ video = self .vae .decode (latents , temb = timestep , return_dict = False )[0 ]
1197+ else :
1198+ latents = latents .astype (self .vae .dtype )
1199+ video = self .vae .decode (latents , return_dict = False )[0 ]
1200+
1201+ video = video .block_until_ready ()
1202+ video_vae_time = time .perf_counter () - t0_video_vae
1203+ max_logging .log (f"Video VAE decode time: { video_vae_time :.2f} s" )
1204+
1205+ # VAE outputs (B, T, H, W, C), but video processor expects (B, C, T, H, W)
1206+ t0_video_post = time .perf_counter ()
1207+ video = jax .experimental .multihost_utils .process_allgather (video , tiled = True )
1208+ video_np = np .array (video ).transpose (0 , 4 , 1 , 2 , 3 )
1209+ video = self .video_processor .postprocess_video (torch .from_numpy (video_np ), output_type = output_type )
1210+ video_post_time = time .perf_counter () - t0_video_post
1211+ max_logging .log (f"Video Post-processing time (numpy+PIL): { video_post_time :.2f} s" )
1212+
1213+ return video , video_vae_time , video_post_time
1214+
11551215 @staticmethod
11561216 def _normalize_audio_latents (latents : jax .Array , latents_mean : jax .Array , latents_std : jax .Array ):
11571217 latents_mean = latents_mean .astype (latents .dtype )
@@ -1849,55 +1909,18 @@ def convert_to_vel(lat, x0, sig):
18491909 except Exception as e : # pylint: disable=broad-exception-caught
18501910 max_logging .log (f"[Tuning] Failed to apply replicate VAE latents sharding: { e } " )
18511911
1852- if replicate_vae :
1853- try :
1854- mesh = latents .sharding .mesh
1855- replicated_sharding = NamedSharding (mesh , P ())
1856- # Replicate VAE weights
1857- graphdef , state = nnx .split (self .vae )
1858- state = jax .tree_util .tree_map (
1859- lambda x : jax .lax .with_sharding_constraint (x , replicated_sharding ) if isinstance (x , jax .Array ) else x , state
1860- )
1861- self .vae = nnx .merge (graphdef , state )
1862- except Exception as e : # pylint: disable=broad-exception-caught
1863- max_logging .log (f"[Tuning] Failed to replicate VAE weights: { e } " )
1864-
18651912 latent_processing_time += time .perf_counter () - t0_latent_processing
18661913 timings ["Latent Processing" ] = latent_processing_time
18671914
1868- t0_video_vae = time .perf_counter ()
1869- with jax .named_scope ("video_vae_decode" ):
1870- if getattr (self .vae .config , "timestep_conditioning" , False ):
1871- noise = jax .random .normal (generator , latents .shape , dtype = latents .dtype )
1872-
1873- if not isinstance (decode_timestep , list ):
1874- decode_timestep = [decode_timestep ] * batch_size
1875- if decode_noise_scale is None :
1876- decode_noise_scale = decode_timestep
1877- elif not isinstance (decode_noise_scale , list ):
1878- decode_noise_scale = [decode_noise_scale ] * batch_size
1879-
1880- timestep = jnp .array (decode_timestep , dtype = latents .dtype )
1881- decode_noise_scale = jnp .array (decode_noise_scale , dtype = latents .dtype )[:, None , None , None , None ]
1882-
1883- latents = (1 - decode_noise_scale ) * latents + decode_noise_scale * noise
1884-
1885- latents = latents .astype (self .vae .dtype )
1886- video = self .vae .decode (latents , temb = timestep , return_dict = False )[0 ]
1887- else :
1888- latents = latents .astype (self .vae .dtype )
1889- video = self .vae .decode (latents , return_dict = False )[0 ]
1890-
1891- video = video .block_until_ready ()
1892- video_vae_time = time .perf_counter () - t0_video_vae
1893- max_logging .log (f"Video VAE decode time: { video_vae_time :.2f} s" )
1894-
1895- # VAE outputs (B, T, H, W, C), but video processor expects (B, C, T, H, W)
1896- t0_video_post = time .perf_counter ()
1897- video_np = np .array (video ).transpose (0 , 4 , 1 , 2 , 3 )
1898- video = self .video_processor .postprocess_video (torch .from_numpy (video_np ), output_type = output_type )
1899- video_post_time = time .perf_counter () - t0_video_post
1900- max_logging .log (f"Video Post-processing time (numpy+PIL): { video_post_time :.2f} s" )
1915+ video , video_vae_time , video_post_time = self ._decode_latents_to_video (
1916+ latents = latents ,
1917+ generator = generator ,
1918+ batch_size = batch_size ,
1919+ decode_timestep = decode_timestep ,
1920+ decode_noise_scale = decode_noise_scale ,
1921+ output_type = output_type ,
1922+ replicate_vae = replicate_vae ,
1923+ )
19011924
19021925 # Decode Audio
19031926 t0_audio_vae = time .perf_counter ()
@@ -1917,6 +1940,7 @@ def convert_to_vel(lat, x0, sig):
19171940 audio = self ._jitted_vocoder (self .vocoder , generated_mel_spectrograms )
19181941
19191942 # Convert audio to numpy
1943+ audio = jax .experimental .multihost_utils .process_allgather (audio , tiled = True )
19201944 audio = np .array (audio )
19211945 vocoder_time = time .perf_counter () - t0_vocoder
19221946 max_logging .log (f"Vocoder & Audio numpy time: { vocoder_time :.2f} s" )
0 commit comments