@@ -48,6 +48,21 @@ def _update_cache(cache, idx, value):
4848 return cache [:idx ] + (value ,) + cache [idx + 1 :]
4949
5050
51+ def _spatial_sharding (mesh : Optional [jax .sharding .Mesh ], shape : Sequence [int ]) -> Optional [NamedSharding ]:
52+ """Returns the sharding of a (N, D, H, W, C) array over the vae_spatial axis.
53+
54+ Shards the width, or the height if only the height is divisible by
55+ vae_spatial. If neither is, the width is still sharded and XLA pads it.
56+ """
57+ if mesh is None or "vae_spatial" not in mesh .shape :
58+ return None
59+ _ , _ , height , width , _ = shape
60+ num_shards = mesh .shape ["vae_spatial" ]
61+ if width % num_shards != 0 and height % num_shards == 0 :
62+ return NamedSharding (mesh , P ("redundant" , None , "vae_spatial" , None , None ))
63+ return NamedSharding (mesh , P ("redundant" , None , None , "vae_spatial" , None ))
64+
65+
5166# Helper to ensure kernel_size, stride, padding are tuples of 3 integers
5267def _canonicalize_tuple (x : Union [int , Sequence [int ]], rank : int , name : str ) -> Tuple [int , ...]:
5368 """Canonicalizes a value to a tuple of integers."""
@@ -121,7 +136,7 @@ def __init__(
121136
122137 def __call__ (self , x : jax .Array , cache_x : Optional [jax .Array ] = None , idx = - 1 ) -> jax .Array :
123138 if self .mesh is not None and "vae_spatial" in self .mesh .shape :
124- spatial_sharding = NamedSharding (self .mesh , P ( "redundant" , None , None , "vae_spatial" , None ) )
139+ spatial_sharding = _spatial_sharding (self .mesh , x . shape )
125140 if spatial_sharding is not None :
126141 x = jax .lax .with_sharding_constraint (x , spatial_sharding )
127142
@@ -1169,12 +1184,6 @@ def _encode(self, x: jax.Array, feat_cache: AutoencoderKLWanCache):
11691184 iter_ = 1 + ((t - 1 + CHUNK_SIZE - 1 ) // CHUNK_SIZE ) if t > 1 else 1
11701185 enc_feat_map = feat_cache ._enc_feat_map
11711186
1172- spatial_sharding = (
1173- NamedSharding (self .mesh , P ("redundant" , None , None , "vae_spatial" , None ))
1174- if self .mesh is not None and "vae_spatial" in self .mesh .shape
1175- else None
1176- )
1177-
11781187 def finalize (out , enc_feat_map ):
11791188 feat_cache ._enc_feat_map = enc_feat_map
11801189 enc = self .quant_conv (out )
@@ -1184,6 +1193,7 @@ def finalize(out, enc_feat_map):
11841193 with jax .named_scope ("AutoencoderKLWan_encode_chunk_0" ):
11851194 chunk_0 = x [:, :1 , ...]
11861195 out_0 , enc_feat_map , _ = self .encoder (chunk_0 , feat_cache = enc_feat_map , feat_idx = 0 )
1196+ spatial_sharding = _spatial_sharding (self .mesh , out_0 .shape )
11871197 if spatial_sharding is not None :
11881198 out_0 = jax .lax .with_sharding_constraint (out_0 , spatial_sharding )
11891199
@@ -1280,25 +1290,23 @@ def _decode(
12801290 x = self .post_quant_conv (z )
12811291
12821292 dec_feat_map = feat_cache ._feat_map
1283- spatial_sharding = (
1284- NamedSharding (self .mesh , P ("redundant" , None , None , "vae_spatial" , None ))
1285- if self .mesh is not None and "vae_spatial" in self .mesh .shape
1286- else None
1287- )
1293+ spatial_sharding = _spatial_sharding (self .mesh , x .shape )
12881294
12891295 # First chunk (i=0)
12901296 with jax .named_scope ("AutoencoderKLWan_decode_chunk_0" ):
1297+ chunk_in_0 = x [:, 0 :1 , ...]
12911298 if spatial_sharding is not None :
1292- chunk_in_0 = jax .lax .with_sharding_constraint (x [:, 0 : 1 , ...] , spatial_sharding )
1299+ chunk_in_0 = jax .lax .with_sharding_constraint (chunk_in_0 , spatial_sharding )
12931300 out_0 , dec_feat_map , _ = self .decoder (chunk_in_0 , feat_cache = dec_feat_map , feat_idx = 0 )
12941301 if spatial_sharding is not None :
12951302 out_0 = jax .lax .with_sharding_constraint (out_0 , spatial_sharding )
12961303
12971304 if iter_ > 1 :
12981305 # Run chunk 1 outside scan to properly form the cache shape
12991306 with jax .named_scope ("AutoencoderKLWan_decode_chunk_1" ):
1307+ chunk_in_1 = x [:, 1 :2 , ...]
13001308 if spatial_sharding is not None :
1301- chunk_in_1 = jax .lax .with_sharding_constraint (x [:, 1 : 2 , ...] , spatial_sharding )
1309+ chunk_in_1 = jax .lax .with_sharding_constraint (chunk_in_1 , spatial_sharding )
13021310 out_chunk_1 , dec_feat_map , _ = self .decoder (chunk_in_1 , feat_cache = dec_feat_map , feat_idx = 0 )
13031311 if spatial_sharding is not None :
13041312 out_chunk_1 = jax .lax .with_sharding_constraint (out_chunk_1 , spatial_sharding )
0 commit comments