"""Windows-friendly two-process DDP launcher for PyTorch builds without libuv.""" from __future__ import annotations import argparse import os import subprocess import sys def main(): parser = argparse.ArgumentParser() parser.add_argument("--nproc_per_node", type=int, default=2) parser.add_argument("--master_addr", default="127.0.0.1") parser.add_argument("--master_port", default="29500") parser.add_argument("training_script") parser.add_argument("training_args", nargs=argparse.REMAINDER) args = parser.parse_args() processes = [] for local_rank in range(args.nproc_per_node): env = os.environ.copy() env.update( { "MASTER_ADDR": args.master_addr, "MASTER_PORT": args.master_port, "WORLD_SIZE": str(args.nproc_per_node), "RANK": str(local_rank), "LOCAL_RANK": str(local_rank), "USE_LIBUV": "0", } ) cmd = [sys.executable, args.training_script, *args.training_args] processes.append(subprocess.Popen(cmd, env=env)) exit_code = 0 for process in processes: exit_code = max(exit_code, process.wait()) if exit_code: for process in processes: if process.poll() is None: process.terminate() raise SystemExit(exit_code) if __name__ == "__main__": main()