3232 "--xla_tpu_enable_async_collective_fusion_multiple_steps=true" ,
3333 "--xla_tpu_overlap_compute_collective_tc=true" ,
3434 "--xla_enable_async_all_gather=true" ,
35- "--xla_tpu_scoped_vmem_limit_kib=65536" ,
3635 "--xla_tpu_enable_async_all_to_all=true" ,
3736 "--xla_tpu_enable_all_experimental_scheduler_features=true" ,
3837 "--xla_tpu_enable_latency_hiding_scheduler=true" ,
@@ -75,9 +74,18 @@ def tiled_seq_len(full_seq: int, attention: str, context_shards: int, ulysses_sh
7574 return local_tiled_seq_len (full_seq , attention , context_shards , ulysses_shards )
7675
7776
78- @functools .partial (nnx .jit , static_argnames = ("num_frames" , "height" , "width" ))
77+ # xla_tpu_scoped_vmem_limit_kib per jax device_kind. Passed as a compile option
78+ # (not via LIBTPU_INIT_ARGS) because jax.devices() initializes libtpu, after
79+ # which LIBTPU_INIT_ARGS is no longer read.
80+ _SCOPED_VMEM_LIMIT_KIB = {
81+ "TPU v6 lite" : 32768 ,
82+ "TPU7x" : 65536 ,
83+ }
84+
85+
7986def _forward (
80- model ,
87+ graphdef ,
88+ state ,
8189 latents ,
8290 timestep ,
8391 prompt_embeds ,
@@ -90,6 +98,7 @@ def _forward(
9098 height ,
9199 width ,
92100):
101+ model = nnx .merge (graphdef , state )
93102 return model (
94103 hidden_states = latents ,
95104 audio_hidden_states = audio_latents ,
@@ -134,6 +143,14 @@ def __init__(
134143 self ._ulysses_shards = int (getattr (config , "ulysses_shards" , 1 ) or 1 )
135144 self ._vmem = int (vmem_limit_bytes )
136145 self .label = f"ltx2/{ self ._attention } /u{ self ._ulysses_shards } "
146+ device_kind = jax .devices ()[0 ].device_kind
147+ if "tpu" in device_kind .lower ():
148+ scoped_vmem = _SCOPED_VMEM_LIMIT_KIB .get (device_kind , 65536 )
149+ self ._compiler_options = {
150+ "xla_tpu_scoped_vmem_limit_kib" : str (scoped_vmem ),
151+ }
152+ else :
153+ self ._compiler_options = {}
137154
138155 self ._lf = (num_frames - 1 ) // 8 + 1
139156 self ._lh , self ._lw = height // 32 , width // 32
@@ -143,7 +160,13 @@ def __init__(
143160 self ._width_orig = width
144161
145162 data_shards = int (mesh .shape .get ("data" , 1 )) * int (mesh .shape .get ("fsdp" , 1 ))
146- self ._batch = batch if batch is not None else max (1 , data_shards )
163+ guidance_scale = getattr (config , "guidance_scale" , 1.0 )
164+ stg_scale = getattr (config , "stg_scale" , 0.0 )
165+ do_cfg = guidance_scale > 1.0
166+ do_stg = stg_scale > 0.0
167+ cfg_mult = 4 if (do_cfg and do_stg ) else (2 if do_cfg else 1 )
168+ default_batch = max (1 , data_shards ) * cfg_mult
169+ self ._batch = batch if batch is not None else default_batch
147170 self ._hf_cfg = LTX2VideoTransformer3DModel .load_config (config .pretrained_model_name_or_path , subfolder = "transformer" )
148171 self ._inputs = self ._make_inputs ()
149172
@@ -163,13 +186,21 @@ def tiled_seq_lens(self):
163186 return (s , s )
164187
165188 def vmem_bytes (self ):
166- return self ._vmem
189+ data_shards = int (self ._mesh .shape .get ("data" , 1 )) * int (self ._mesh .shape .get ("fsdp" , 1 ))
190+ local_batch = max (1 , self ._batch // max (1 , data_shards ))
191+ return self ._vmem // local_batch
167192
168193 def run (self , bq , bkv , * , bkv_compute = None , iters = 10 , warmup = 2 ):
169194 cmp = bkv_compute or bkv
170195 try :
171196 with self ._mesh :
172197 model = self ._build_model (bq , bkv , cmp )
198+ graphdef , state = nnx .split (model )
199+ forward = jax .jit (
200+ functools .partial (_forward , graphdef ),
201+ static_argnames = ("num_frames" , "height" , "width" ),
202+ compiler_options = self ._compiler_options ,
203+ )
173204 (
174205 latents ,
175206 timestep ,
@@ -181,8 +212,8 @@ def run(self, bq, bkv, *, bkv_compute=None, iters=10, warmup=2):
181212 ) = self ._inputs
182213 with self ._mesh , nn_partitioning .axis_rules (self ._rules ):
183214 mean , std , times , compile_ms = time_callable (
184- lambda : _forward (
185- model ,
215+ lambda : forward (
216+ state ,
186217 latents ,
187218 timestep ,
188219 prompt_embeds ,
@@ -268,10 +299,10 @@ def _make_inputs(self):
268299
269300 # Prompts
270301 prompt_embeds = jax .random .normal (k2 , (self ._batch , 1024 , 3840 ), dtype )
271- prompt_attention_mask = jnp .ones ((self ._batch , 1024 ), dtype = jnp .int32 )
302+ prompt_attention_mask = jnp .ones ((self ._batch , 1024 ), dtype = jnp .bool_ )
272303
273304 audio_prompt_embeds = jax .random .normal (k4 , (self ._batch , 1024 , 3840 ), dtype )
274- audio_prompt_attention_mask = jnp .ones ((self ._batch , 1024 ), dtype = jnp .int32 )
305+ audio_prompt_attention_mask = jnp .ones ((self ._batch , 1024 ), dtype = jnp .bool_ )
275306
276307 timestep = jnp .zeros ((self ._batch ,), jnp .float32 )
277308 repl = jax .sharding .NamedSharding (self ._mesh , jax .sharding .PartitionSpec ())
0 commit comments