@@ -20,10 +20,13 @@ class DiffSynthEngine:
2020 def from_pretrained (cls , model_path_or_config : str | PipelineConfig , ** kwargs ):
2121 pipeline_config = _resolve_pipeline_config (model_path_or_config )
2222 num_workers = pipeline_config .parallelism
23+ master_addr = kwargs .get ("master_addr" , "localhost" )
2324 master_port = kwargs .get ("master_port" , 29500 )
25+ nnodes = kwargs .get ("nnodes" , 1 )
26+ node_rank = kwargs .get ("node_rank" , 0 )
2427
2528 if num_workers > 1 :
26- return DistributedEngine (pipeline_config , num_workers , master_port )
29+ return DistributedEngine (pipeline_config , num_workers , master_addr , master_port , nnodes , node_rank )
2730 return LocalEngine (pipeline_config )
2831
2932 def generate (self , ** kwargs ):
@@ -210,41 +213,66 @@ def stop_profile(self):
210213
211214
212215class DistributedEngine (DiffSynthEngine ):
213- def __init__ (self , pipeline_config : PipelineConfig , num_workers : int , master_port : int ):
214- logger .info (f"Initializing { num_workers } workers..." )
216+ def __init__ (
217+ self ,
218+ pipeline_config : PipelineConfig ,
219+ num_workers : int ,
220+ master_addr : str = "localhost" ,
221+ master_port : int = 29500 ,
222+ nnodes : int = 1 ,
223+ node_rank : int = 0 ,
224+ ):
225+ if nnodes <= 0 :
226+ raise ValueError (f"nnodes must be positive, got { nnodes } " )
227+ if not 0 <= node_rank < nnodes :
228+ raise ValueError (f"node_rank must be in [0, { nnodes } ), got { node_rank } " )
229+ if num_workers % nnodes != 0 :
230+ raise ValueError (f"num_workers ({ num_workers } ) must be a multiple of nnodes ({ nnodes } )" )
231+
232+ nproc_per_node = num_workers // nnodes
233+ rank_offset = node_rank * nproc_per_node
234+ self .node_rank = node_rank
235+
236+ logger .info (
237+ f"Initializing { nproc_per_node } workers on node { node_rank } "
238+ f"(world_size={ num_workers } , master={ master_addr } :{ master_port } )..."
239+ )
215240
216241 set_device (0 )
217242
218243 self .workers = []
219244 self .conns = []
220245
221246 ctx = mp .get_context ("spawn" )
222- for rank in range (num_workers ):
247+ for local_rank in range (nproc_per_node ):
248+ global_rank = rank_offset + local_rank
223249 conn_main , conn_worker = ctx .Pipe (duplex = True )
224250
225251 process = ctx .Process (
226252 target = run_worker_loop ,
227253 args = (
228- rank , # local_rank
229- rank , # rank
254+ local_rank , # local_rank
255+ global_rank , # rank
230256 num_workers , # world_size
257+ master_addr , # master_addr
231258 master_port , # master_port
232259 conn_worker , # conn
233260 pipeline_config , # pipeline_config
234261 ),
235- name = f"diffsynth-worker-{ rank } " ,
262+ name = f"diffsynth-worker-{ global_rank } " ,
236263 daemon = True ,
237264 )
238265 process .start ()
239266
240267 self .workers .append (process )
241268 self .conns .append (conn_main )
242269
243- for rank , conn in enumerate (self .conns ):
270+ for i , conn in enumerate (self .conns ):
244271 result = conn .recv ()
245272 if result ["status" ] != "ready" :
246- raise RuntimeError (f"Worker { rank } failed to start: { result .get ('error' , 'Unknown error' )} " )
247- logger .info ("All workers are ready" )
273+ global_rank = rank_offset + i
274+ raise RuntimeError (f"Worker { global_rank } failed to start: { result .get ('error' , 'Unknown error' )} " )
275+ logger .info (f"All workers on node { node_rank } are ready" )
248276
249277 def _dispatch (self , method : str , output_rank : int | None = 0 , ** kwargs ):
250278 self .conns [0 ].send (
0 commit comments