import%20marimo%0A%0A__generated_with%20%3D%20%220.19.9%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Shared%20imports%20for%20the%20notebook%0A%20%20%20%20import%20torch%0A%20%20%20%20from%20monarch.actor%20import%20Actor%2C%20endpoint%2C%20current_rank%2C%20this_host%0A%0A%20%20%20%20return%20(this_host%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Interactive%20DevX%3A%20Monarch%20as%20Remote%20Torchrun%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20The%20Pain%20of%20Traditional%20Development%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Traditional%20Distributed%20Development%20Loop%3A%0A%0A%20%20%20%20Developer%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SLURM%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Cluster%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20sbatch%20job.sh%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20queue...%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20(minutes%20to%20hours)%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%0A%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%20job%20started%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20...wait%20for%20completion...%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20cat%20slurm-*.out%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%20scattered%20logs%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%22Found%20bug%20on%20line%2042%22%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%20sbatch%20again...%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20(repeat%20forever)%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Key%20problems%3A**%0A%0A%20%20%20%20-%20Queue%20wait%20time%20dominates%20iteration%20time%0A%20%20%20%20-%20Logs%20scattered%20across%20nodes%0A%20%20%20%20-%20Each%20fix%20requires%20full%20resubmission%0A%20%20%20%20-%20No%20interactive%20debugging%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20The%20Monarch%20Solution%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20Monarch%20Development%20Loop%3A%0A%0A%20%20%20%20Developer%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Monarch%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Cluster%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20allocate%20hosts%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20(one%20time%2C%20slow)%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20gang%20schedule%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%0A%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%20HostMesh%20ready%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%3D%3D%3D%20Fast%20iteration%20loop%20%3D%3D%3D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20spawn_procs()%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20(instant)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20spawn%20actors%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20(instant)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20call%20endpoints%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20(instant)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%E2%97%84%E2%94%80%E2%94%80%20aggregated%20logs%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%A4%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%22Found%20bug%2C%20fixing...%22%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%9C%E2%94%80%E2%94%80%20spawn_procs()%20again%20%E2%94%80%E2%94%80%E2%96%BA%E2%94%82%20%20%20(instant%2C%20same%20hosts!)%20%E2%94%82%0A%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%20...%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Key%20insight%3A**%20Allocation%20is%20slow%2C%20but%20re-creating%20the%20HostMesh%20from%20existing%20hosts%20is%20fast.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20DDP%20with%20Monarch%0A%0A%20%20%20%20Let's%20make%20this%20concrete.%20Below%20is%20a%20standard%20PyTorch%20DDP%20training%20script%20%E2%80%94%20no%0A%20%20%20%20Monarch%20code%20at%20all.%20We'll%20use%20Monarch's%20%60SPMDActor%60%20to%20launch%20it%2C%20just%20like%0A%20%20%20%20%60torchrun%60%20would%2C%20but%20from%20this%20notebook.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20The%20Training%20Script%0A%0A%20%20%20%20This%20is%20%60train.py%60%20%E2%80%94%20a%20vanilla%20PyTorch%20DDP%20script%3A%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20import%20os%0A%20%20%20%20import%20torch%0A%20%20%20%20import%20torch.distributed%20as%20dist%0A%20%20%20%20import%20torch.nn%20as%20nn%0A%20%20%20%20import%20torch.optim%20as%20optim%0A%20%20%20%20from%20torch.nn.parallel%20import%20DistributedDataParallel%20as%20DDP%0A%0A%20%20%20%20def%20main()%3A%0A%20%20%20%20%20%20%20%20dist.init_process_group(%22nccl%22)%0A%20%20%20%20%20%20%20%20rank%20%3D%20dist.get_rank()%0A%20%20%20%20%20%20%20%20local_rank%20%3D%20int(os.environ%5B%22LOCAL_RANK%22%5D)%0A%20%20%20%20%20%20%20%20torch.cuda.set_device(local_rank)%0A%0A%20%20%20%20%20%20%20%20model%20%3D%20nn.Linear(10%2C%201).cuda()%0A%20%20%20%20%20%20%20%20ddp_model%20%3D%20DDP(model)%0A%0A%20%20%20%20%20%20%20%20optimizer%20%3D%20optim.SGD(ddp_model.parameters()%2C%20lr%3D0.01)%0A%0A%20%20%20%20%20%20%20%20for%20step%20in%20range(5)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20inputs%20%3D%20torch.randn(4%2C%2010).cuda()%0A%20%20%20%20%20%20%20%20%20%20%20%20outputs%20%3D%20ddp_model(inputs)%0A%20%20%20%20%20%20%20%20%20%20%20%20loss%20%3D%20outputs.sum()%0A%20%20%20%20%20%20%20%20%20%20%20%20optimizer.zero_grad()%0A%20%20%20%20%20%20%20%20%20%20%20%20loss.backward()%0A%20%20%20%20%20%20%20%20%20%20%20%20optimizer.step()%0A%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%5BRank%20%7Brank%7D%5D%20Step%20%7Bstep%7D%20loss%3D%7Bloss.item()%7D%22)%0A%0A%20%20%20%20%20%20%20%20dist.destroy_process_group()%0A%0A%20%20%20%20if%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%20%20%20%20main()%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Launching%20DDP%20via%20SPMDActor%0A%0A%20%20%20%20%60SPMDActor%60%20sets%20up%20the%20torch%20elastic%20environment%20variables%20(%60RANK%60%2C%20%60LOCAL_RANK%60%2C%0A%20%20%20%20%60WORLD_SIZE%60%2C%20%60MASTER_ADDR%60%2C%20%60MASTER_PORT%60)%20and%20executes%20the%20training%20script.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(this_host)%3A%0A%20%20%20%20import%20os%20as%20_os%0A%20%20%20%20from%20monarch.spmd%20import%20SPMDActor%0A%0A%20%20%20%20_GPUS_PER_HOST%20%3D%204%0A%20%20%20%20_TRAIN_SCRIPT%20%3D%20_os.path.join(_os.path.dirname(_os.path.abspath(__file__))%2C%20%22train.py%22)%0A%0A%20%20%20%20%23%20Spawn%20processes%20on%20the%20local%20host%0A%20%20%20%20local_proc_mesh%20%3D%20this_host().spawn_procs(per_host%3D%7B%22gpus%22%3A%20_GPUS_PER_HOST%7D)%0A%0A%20%20%20%20%23%20Spawn%20SPMDActor%20%E2%80%94%20it%20configures%20torch%20elastic%20env%20vars%20automatically%0A%20%20%20%20spmd_actors%20%3D%20local_proc_mesh.spawn(%22_SPMDActor%22%2C%20SPMDActor)%0A%0A%20%20%20%20%23%20Get%20master%20address%2Fport%20from%20the%20first%20actor%0A%20%20%20%20first_values%20%3D%20dict.fromkeys(local_proc_mesh._labels%2C%200)%0A%20%20%20%20master_addr%2C%20master_port%20%3D%20(%0A%20%20%20%20%20%20%20%20spmd_actors.slice(**first_values).get_host_port.call_one(None).get()%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Execute%20training%20script%20across%20all%20processes%0A%20%20%20%20spmd_actors.main.call(master_addr%2C%20master_port%2C%20%5B_TRAIN_SCRIPT%5D).get()%0A%0A%20%20%20%20print(%22DDP%20training%20completed!%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Making%20SPMD%20Interactive%20with%20%60serve()%60%20%2B%20%60run_spmd()%60%0A%0A%20%20%20%20The%20%60SPMDActor%60%20approach%20above%20works%2C%20but%20Monarch%20provides%20a%20higher-level%20API%0A%20%20%20%20that%20makes%20the%20interactive%20loop%20explicit%3A%20%60serve()%60%20allocates%20hosts%20and%20launches%0A%20%20%20%20workers%20once%2C%20then%20%60run_spmd()%60%20can%20be%20called%20repeatedly%20on%20the%20same%20hosts.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20os%20as%20_os%0A%20%20%20%20from%20monarch.job.spmd%20import%20serve%0A%0A%20%20%20%20_GPUS_PER_HOST%20%3D%204%0A%20%20%20%20_TRAIN_SCRIPT%20%3D%20_os.path.join(_os.path.dirname(_os.path.abspath(__file__))%2C%20%22train.py%22)%0A%0A%20%20%20%20%23%20serve()%20allocates%20hosts%20and%20launches%20workers%20(slow%2C%20one%20time)%0A%20%20%20%20job%20%3D%20serve(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22torchrun%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22--nproc-per-node%3D%7B_GPUS_PER_HOST%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22--standalone%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20_TRAIN_SCRIPT%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20scheduler%3D%22local_cwd%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20run_spmd()%20executes%20the%20training%20script%20on%20the%20reserved%20hosts%0A%20%20%20%20job.run_spmd()%0A%20%20%20%20return%20(job%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Iterate%20Without%20Reprovisioning%0A%0A%20%20%20%20Edit%20%60train.py%60%2C%20then%20call%20%60run_spmd()%60%20again%20%E2%80%94%20same%20hosts%2C%20no%20reallocation%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(job)%3A%0A%20%20%20%20%23%20After%20editing%20train.py%2C%20just%20re-run%20on%20the%20same%20hosts%0A%20%20%20%20job.run_spmd()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20You%20can%20also%20reload%20a%20cached%20job%20from%20a%20previous%20session%3A%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20from%20monarch.job.spmd%20import%20job_load%0A%0A%20%20%20%20job%20%3D%20job_load(%22.monarch%2Fjob_state.pkl%22)%0A%20%20%20%20job.run_spmd()%20%20%23%20runs%20on%20same%20reserved%20hosts%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20Remote%20Debugging%0A%0A%20%20%20%20Add%20%60breakpoint()%60%20anywhere%20in%20your%20training%20script%2C%20then%20attach%20from%20a%0A%20%20%20%20separate%20terminal%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20%24%20monarch%20debug%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20This%20opens%20an%20interactive%20pdb%20session%20across%20all%20ranks.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Multi-Node%20Training%20with%20SLURM%0A%0A%20%20%20%20The%20examples%20above%20use%20%60scheduler%3D%22local_cwd%22%60%20for%20single-node%20training.%20When%0A%20%20%20%20running%20on%20a%20cluster%20with%20a%20scheduler%20like%20SLURM%2C%20swap%20the%20command%20list%20for%20a%0A%20%20%20%20%60torchx%60%20%60AppDef%60%20%E2%80%94%20the%20same%20%60serve()%60%20%2B%20%60run_spmd()%60%20pattern%20applies%3A%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20from%20torchx%20import%20specs%0A%20%20%20%20from%20monarch.job.spmd%20import%20serve%0A%0A%20%20%20%20app%20%3D%20specs.AppDef(%0A%20%20%20%20%20%20%20%20name%3D%22multi-node-training%22%2C%0A%20%20%20%20%20%20%20%20roles%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20specs.Role(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22trainer%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20image%3D%22%5C%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entrypoint%3D%22torchrun%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20args%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22--nnodes%3D2%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22--nproc-per-node%3D8%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22--rdzv-backend%3Dc10d%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22--rdzv-endpoint%3D%24MASTER_ADDR%3A%24MASTER_PORT%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TRAIN_SCRIPT%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20num_replicas%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resource%3Dspecs.Resource(cpu%3D32%2C%20gpu%3D8%2C%20memMB%3D256000)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20job%20%3D%20serve(app%2C%20scheduler%3D%22slurm%22%2C%20scheduler_cfg%3D%7B%22partition%22%3A%20%22gpu%22%7D)%0A%20%20%20%20job.run_spmd()%0A%0A%20%20%20%20%23%20Edit%20train.py%2C%20then%20re-run%20without%20reprovisioning%3A%0A%20%20%20%20job.run_spmd()%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20---%0A%0A%20%20%20%20**Previous%3A**%20%5BNB01%20%E2%80%94%20History%20%26%20Vision%5D(.%2F01_history_and_vision.html)%20%C2%B7%20**Next%3A**%20%5BNB03%20%E2%80%94%20Fault%20Tolerance%5D(.%2F03_fault_tolerance.html)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
5a929f1c866d852ffc50d09cc620022c