[Slurm] Multi-node clusters#8219
Conversation
Summary of ChangesHello @kevinmingtarja, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances SkyPilot's integration with Slurm by introducing full support for multi-node clusters. It achieves this through a dedicated Slurm executor script that manages per-node task execution, environment variable propagation, and synchronized setup/run phases. The changes also involve refactoring the core task code generation to accommodate distributed logging and robust command execution, alongside updates to the Slurm cloud backend and test suite to validate the new capabilities. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
/smoke-test --slurm -k test_cli_logs |
There was a problem hiding this comment.
Code Review
This pull request introduces multi-node cluster support for Slurm, which is a significant enhancement. The changes involve a major refactoring of the Slurm code generation logic, moving it to a dedicated remote executor module (sky.skylet.executor.slurm). This is a good architectural decision that improves modularity and maintainability. The implementation details for multi-node support, such as node IP discovery, per-node logging, and synchronization, appear to be well-thought-out. However, I've identified a critical issue in the provisioning script that could prevent clusters from being set up correctly. Overall, this is a great step forward, and with the identified issue fixed, it will be a solid contribution.
|
/smoke-test --slurm -k test_multi_echo |
1 similar comment
|
/smoke-test --slurm -k test_multi_echo |
|
/smoke-test --slurm -k ray_basic |
|
/smoke-test --slurm -k test_cancel_pytorch |
|
/smoke-test --slurm -k test_cancel_pytorch |
|
/smoke-test --slurm -k ray_train |
|
/smoke-test --slurm -k test_multi_node_failure |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
/smoke-test --slurm -k test_cancel_pytorch |
| 'has_setup_cmd = False', | ||
| 'setup_cmd = None', | ||
| 'setup_envs = None', | ||
| 'setup_log_path = None', | ||
| 'setup_log_dir = None', | ||
| 'setup_num_nodes = None', | ||
| ] |
There was a problem hiding this comment.
I'm generally a fan of moving things out of the string scripts for maintainability, since any scripts in string doesn't benefit from automated tools, etc. What do you think about doing something here like:
self._code += [
'autostop_lib.set_last_active_time_to_now()',
f'job_lib.set_status({job_id!r}, job_lib.JobStatus.PENDING)',
]
self._has_setup_cmd = False
self._setup_cmd = None,
self._setup_envs = None,
self._setup_log_dir = None,
self._setup_num_nodes = None,
and build the command dynamically on add_task?
There was a problem hiding this comment.
Sounds good, that would indeed be cleaner.
There was a problem hiding this comment.
Nice! I have more ideas on how to clean up this part more, but let's merge this PR in and I can make a separate PR incorporating those cleanups. The code is functional, and that's what matters for now.
| # Clean up sky runtime directory on each node. | ||
| srun --nodes={num_nodes} rm -rf {skypilot_runtime_dir} | ||
| rm -rf {sky_home_dir} | ||
| }} | ||
| trap cleanup TERM | ||
|
|
||
| # Create sky directory for the cluster. | ||
| mkdir -p {sky_home_dir} {skypilot_runtime_dir} | ||
| # Create sky home directory for the cluster. | ||
| mkdir -p {sky_home_dir} | ||
| # Create sky runtime directory on each node. | ||
| srun --nodes={num_nodes} mkdir -p {skypilot_runtime_dir} |
There was a problem hiding this comment.
When you do multiple sruns of multiple nodes, are these sruns guarenteed to run on the same set of nodes?
There was a problem hiding this comment.
In this case yes, because it is being run from inside an sbatch script.
There was a problem hiding this comment.
But actually in this case, it's just because we do srun --nodes N (N number of nodes requested by sbatch).
If we did srun --nodes M, M < N, I think there are no guarantees that multiple sruns would run on the same subset of M nodes.
There was a problem hiding this comment.
That makes sense, it is a quirk so I'd ideally like it jotted down in a comment somewhere
| 'failed': status_lib.ClusterStatus.INIT, | ||
| 'failed': None, |
There was a problem hiding this comment.
I'm curious what this change was motivated by
There was a problem hiding this comment.
Ah yes so apparently when we sky down a cluster in Slurm, under the hood we will call scancel, and the job will go into failed state and will remain in squeue for a few minutes:
$ squeue --states failed
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3111 CPUs sky-93c7 ubuntu F 40:50 2 (NonZeroExitCode)And so then if we relaunch a new cluster with the same name, our status refresh / query_instances would include the status of this previously downed cluster in the statuses map it returns, which would be confusing.
So by making it None, it is omitted when non_terminated_only is True.
There was a problem hiding this comment.
Ah ok, interesting. Could we jot this done in a comment somewhere as well
SeungjinYang
left a comment
There was a problem hiding this comment.
Thanks @kevinmingtarja, awesome work! This PR is ready to be merged in my opinion, once all the tests listed in the PR description is run successfully.
|
/smoke-test --slurm -k ray_train |
|
/smoke-test --slurm -k test_cli_logs |
|
/smoke-test -k test_job_pipeline --slurm --jobs-consolidation |
|
/quicktest-core |
|
/smoke-test --slurm -k ray_basic |
This PR implements multi-node clusters support for Slurm.
Tested (run the relevant ones):
bash format.sh/smoke-test(CI) orpytest tests/test_smoke.py(local)/smoke-test -k test_name(CI) orpytest tests/test_smoke.py::test_name(local)/quicktest-core(CI) orpytest tests/smoke_tests/test_backward_compat.py(local)