Implement thread-local config with contextvars#173568
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/173568
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 6e3c08b with merge base 4026771 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
|
||
|
|
||
|
|
||
| speech_transformer,pass,16 |
There was a problem hiding this comment.
I'm not sure why this is passing now, but I was getting CI failures before since the expected result was missing
| return cls._instance | ||
|
|
||
| def submit(self, fn, *args, **kwargs): | ||
| ctx = contextvars.copy_context() |
There was a problem hiding this comment.
This is needed since the spawned threads need access to the config. If we want to avoid doing this manually, another option would be to only use contextvars in python 3.14 (or even 3.14t), where PYTHON_THREAD_INHERIT_CONTEXT is available
There was a problem hiding this comment.
This seems like a good idea to me. Even with PYTHON_THREAD_INHERIT_CONTEXT, ThreadPoolExecutor tasks don't inherit the context from their submitter -- the threads inherit their context from the the thread that created the pool. (This is something we are considering changing for 3.15)
|
This looks like a good approach to me, but I'm not very familiar with the code |
|
Whoever accepts and shepherds this, please note the last time we switched config to thread local it caused a SEV, so you're going to have to watch deployment very carefully. |
|
@pytorchbot rebase |
|
@pytorchbot started a rebase job onto refs/remotes/origin/viable/strict. Check the current status here |
|
Successfully rebased |
This reverts commit c904bdc. Reverted pytorch#173568 on behalf of https://github.com/georgehong due to tests failing with torch._dynamo hit config.recompile_limit (8) ([comment](pytorch#173568 (comment)))
|
@pytorchbot merge |
Merge startedYour change will be merged once all checks pass (ETA 0-4 Hours). Learn more about merging in the wiki. Questions? Feedback? Please reach out to the PyTorch DevX Team |
This was triggered by an internal test failure on #173568 (thanks to @williamwen42 for help debugging). See https://gist.github.com/williamwen42/a31bee4f3175c0f540d4170c2dd7ceae for more context/detail Authored with Claude. Differential Revision: [D99142314](https://our.internmc.facebook.com/intern/diff/D99142314) Pull Request resolved: #178950 Approved by: https://github.com/williamwen42
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42
This reverts commit c904bdc. Reverted #173568 on behalf of https://github.com/georgehong due to tests failing with torch._dynamo hit config.recompile_limit (8) ([comment](#173568 (comment)))
This was triggered by an internal test failure on pytorch#173568 (thanks to @williamwen42 for help debugging). See https://gist.github.com/williamwen42/a31bee4f3175c0f540d4170c2dd7ceae for more context/detail Authored with Claude. Differential Revision: [D99142314](https://our.internmc.facebook.com/intern/diff/D99142314) Pull Request resolved: pytorch#178950 Approved by: https://github.com/williamwen42
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42 ghstack dependencies: pytorch#178950
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42
This reverts commit c904bdc. Reverted pytorch#173568 on behalf of https://github.com/georgehong due to tests failing with torch._dynamo hit config.recompile_limit (8) ([comment](pytorch#173568 (comment)))
This was triggered by an internal test failure on pytorch#173568 (thanks to @williamwen42 for help debugging). See https://gist.github.com/williamwen42/a31bee4f3175c0f540d4170c2dd7ceae for more context/detail Authored with Claude. Differential Revision: [D99142314](https://our.internmc.facebook.com/intern/diff/D99142314) Pull Request resolved: pytorch#178950 Approved by: https://github.com/williamwen42
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42 ghstack dependencies: pytorch#178950
This was triggered by an internal test failure on pytorch#173568 (thanks to @williamwen42 for help debugging). See https://gist.github.com/williamwen42/a31bee4f3175c0f540d4170c2dd7ceae for more context/detail Authored with Claude. Differential Revision: [D99142314](https://our.internmc.facebook.com/intern/diff/D99142314) Pull Request resolved: pytorch#178950 Approved by: https://github.com/williamwen42
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42 ghstack dependencies: pytorch#178950
This was triggered by an internal test failure on pytorch#173568 (thanks to @williamwen42 for help debugging). See https://gist.github.com/williamwen42/a31bee4f3175c0f540d4170c2dd7ceae for more context/detail Authored with Claude. Differential Revision: [D99142314](https://our.internmc.facebook.com/intern/diff/D99142314) Pull Request resolved: pytorch#178950 Approved by: https://github.com/williamwen42
This is an alternative approach to pytorch#118387 using context vars Pull Request resolved: pytorch#173568 Approved by: https://github.com/williamwen42 ghstack dependencies: pytorch#178950
There's potential deadlock related to _stash_obj_in_tls. As of #173568 the context object is stored in the calling thread TLS during _engine_run_backward. Normally this object deallocated after the backward pass completes, but there's a race where the autograd device thread can end up holding the last reference. If this happens the context object gets deallocated by the device thread, which needs to acquire the GIL. If another thread happens to be holding the GIL while blocked on the device thread the result is a deadlock. See #173568 for more detail The fix here avoids aquiring the GIL in the device thread by clearing the GraphTask's shared_ptr to the context object during cleanup. Since the TLS in the calling thread also has a shared_ptr, this avoids calling the SafePyObject destructor (and therefore acquiring the GIL). I'm not a huge fan of this approach since it introduces a manual cleanup step, but I wasn't able to come up with something better. Another option would be to use SafePyHandle instead of SafePyObject and introduce a `_remove_obj_from_tls` python API. But that makes the python side responsible for refcounting, which feels wrong. I'm also not sure exactly how we end up with a thread holding the GIL and also blocked on an autograd device thread. That feels like a bug, but it seems to be triggered by Meta-internal code, so I'm not able to debug it. All of which is to say that this is the best approach I can come up with, but I'm very open to other suggestions. ghstack-source-id: 81c9703 Pull-Request: #180700
Stack from ghstack (oldest at bottom):
This is an alternative approach to #118387 using context vars
cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @ipiszy @kadeng @muchulee8 @amjames @chauhang @aakhundov @coconutruben @jataylo @Lucaskabela @azahed98