mando2222 commited on
Commit
cccfdf7
·
verified ·
1 Parent(s): eb9a315

Device VAE on the 1xN mesh path (reclaims ~5s; 2-card 1024 E2E 1.68x->1.75x)

Browse files
Files changed (2) hide show
  1. ttnn_moss/pipeline_mesh.py +5 -1
  2. ttnn_moss/vae.py +15 -1
ttnn_moss/pipeline_mesh.py CHANGED
@@ -20,7 +20,11 @@ from .dit_tp import TtMossImageTransformerTP
20
  class MeshDiTPipeline(MossImagePipeline):
21
  def __init__(self, mesh_device, weights_root, **kw):
22
  self.mesh = mesh_device
23
- kw.setdefault("vae_device", False) # host VAE on the mesh path
 
 
 
 
24
  super().__init__(mesh_device, weights_root=weights_root, **kw)
25
 
26
  def _build_dit(self):
 
20
  class MeshDiTPipeline(MossImagePipeline):
21
  def __init__(self, mesh_device, weights_root, **kw):
22
  self.mesh = mesh_device
23
+ # VAE decode runs ON-DEVICE by default, REPLICATED across the mesh dies
24
+ # (the decoder isn't the compute bulk and needs no sharding; from_torch
25
+ # replicates the input, vae.py's _mesh_to_torch takes die-0's result).
26
+ # This reclaims the host-VAE penalty on the mesh path. MOSS_VAE_DEVICE=0
27
+ # still forces the host diffusers decode (the validated fallback).
28
  super().__init__(mesh_device, weights_root=weights_root, **kw)
29
 
30
  def _build_dit(self):
ttnn_moss/vae.py CHANGED
@@ -49,6 +49,20 @@ GN_EPS = 1e-6
49
  _CORE = None # set per-device in decoder init
50
 
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  def _num_out_blocks(hw: int) -> int:
53
  """L1 tiling for DRAM-interleaved group_norm; larger HW -> more blocks."""
54
  if hw <= 4096:
@@ -350,6 +364,6 @@ class TtFlux2VaeDecoder:
350
  x = ttnn.to_memory_config(x, ttnn.DRAM_MEMORY_CONFIG)
351
  x, H, W = self.conv_out(x, H, W)
352
 
353
- out = ttnn.to_torch(x).reshape(1, H, W, self.conv_out.cout).permute(0, 3, 1, 2)
354
  ttnn.deallocate(x)
355
  return out.float().clamp(-1, 1)
 
49
  _CORE = None # set per-device in decoder init
50
 
51
 
52
+ def _mesh_to_torch(device, t):
53
+ """to_torch that is mesh-aware. On a 1xN mesh the decoder runs REPLICATED
54
+ (from_torch replicates), so its output tensor is distributed and a plain
55
+ ttnn.to_torch fails ('supply a mesh composer'). Compose the identical shards
56
+ and keep the first copy; on a single device, unchanged."""
57
+ try:
58
+ multi = device.get_num_devices() > 1
59
+ except Exception:
60
+ multi = False
61
+ if multi:
62
+ return ttnn.to_torch(t, mesh_composer=ttnn.ConcatMeshToTensor(device, dim=0))[0:1]
63
+ return ttnn.to_torch(t)
64
+
65
+
66
  def _num_out_blocks(hw: int) -> int:
67
  """L1 tiling for DRAM-interleaved group_norm; larger HW -> more blocks."""
68
  if hw <= 4096:
 
364
  x = ttnn.to_memory_config(x, ttnn.DRAM_MEMORY_CONFIG)
365
  x, H, W = self.conv_out(x, H, W)
366
 
367
+ out = _mesh_to_torch(self.device, x).reshape(1, H, W, self.conv_out.cout).permute(0, 3, 1, 2)
368
  ttnn.deallocate(x)
369
  return out.float().clamp(-1, 1)