fix: Use default torch timeout for nccl watchdog unless overridden#521
Conversation
2ab4c09 to
0cbbe2b
Compare
RobotSail
left a comment
There was a problem hiding this comment.
We just need some comments explaining why we're doing it this way, otherwise I think it's good. 👍
0cbbe2b to
ca87077
Compare
JamesKunstle
left a comment
There was a problem hiding this comment.
I like this solution.
I'm curious whether the torch environment variable TORCH_NCCL_HEARTBEAT_TIMEOUT_SEC from the docs overrides this or this overrides that var.
https://pytorch.org/docs/stable/torch_nccl_environment_variables.html
|
@JamesKunstle below is my understanding of how this works. I may be wrong since I'm new to the topic, but I'll try to link the relevant code for reference. Please double check me: it's important we understand how this works. So, there are three separate entities - a timeout for process group, a NCCL monitoring thread and a NCCL watchdog. They are separate entities serving separate needs. The process group timeout is what you configure when passing Each backend will implement it in some way, for example, NCCL will assign the timeout to each work item. This parameter is not backend specific. If we ever use a different backend (not Now, to watchdogs. These are backend specific. It's up to the backend to run a watchdog or some other mechanism to implement the PG timeout. Each NCCL rank starts a separate native thread running a peer watchdog. The watchdog thread will periodically check on each worker to see if it failed or timed out, and report back. It has its own sleep timer between iterations (just 100ms). There's also a NCCL monitoring thread. Also backend specific. This thread is running separate to a watchdog and monitors the watchdog itself. Specifically, it watches for its heartbeats. If a single heartbeat is not detected in In case you wonder, the monitoring thread is enabled by default since 2.3.0. It is controlled by What's a heartbeat? Just an atomic integer increment on a shared variable that is executed by the watchdog thread and watched by the monitoring thread. Important to note: for a watchdog thread heartbeat to happen, currently running collectives don't have to make any progress: as long as the watchdog thread is alive, it will heartbeat. So tuning The watchdog may even be disabled with |
|
This pull request has merge conflicts that must be resolved before it can be |
The default value is recommended, and we should not change it in production. The knob may still be useful for debugging or testing purposes though. Signed-off-by: Ihar Hrachyshka <ihar.hrachyshka@gmail.com>
ca87077 to
2cdb409
Compare
| # time of writing) default: to cover the unlikely event torch decides to tweak | ||
| # the default. | ||
| def _get_collective_timeout() -> datetime.timedelta | None: | ||
| timeout_var = os.getenv("INSTRUCTLAB_NCCL_TIMEOUT_MS") |
There was a problem hiding this comment.
It might be worthwhile to also update the README.md to let people know that this env can be used to set the timeout
There was a problem hiding this comment.
It's already documented in README:
## Environment variables
Below is a list of custom environment variables users can set in the training library.
1. `INSTRUCTLAB_NCCL_TIMEOUT_MS`, this environment variable controls the NCCL timeout in milliseconds. Consider increasing if seeing FSDP related NCCL errors.
There was a problem hiding this comment.
Ah I see, I must have missed that. Thank you!
|
I believe comment from @RobotSail is addressed but please double-check. |
The default value is recommended, and we should not change it in
production. The knob may still be useful for debugging or testing
purposes though.
Signed-off-by: Ihar Hrachyshka ihar.hrachyshka@gmail.com