| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
torch.func.grad / grad_and_value / jacrev invoke autograd through torch.autograd.grad, which fires the engine's output-tensor hooks but intentionally bypasses engine.backward(). The prologue then raises on ZeRO-0 (the safety net for direct loss.backward() callers) and the epilogue indexes empty ZeRO-1/2 grad bucket bookkeeping that the transformed graph never populated. Parameters are not leaves under the transform, so per-param post-accumulate-grad hooks never fire. Detect the active functorch interpreter via torch._C._functorch.peek_interpreter_stack and short-circuit both hooks early. The existing safety net for non-functorch direct loss.backward() callers (deepspeedai#7665) is preserved. Signed-off-by: Sung Hyun Cho <hope5487@gmail.com>
…0/1/2 Compare each transform's output to a non-DeepSpeed baseline cloned from the same initialization so a future regression that silently zeros gradients fails the test. Includes a negative case that locks in the ZeRO-0 direct-loss.backward() safety net. Signed-off-by: Sung Hyun Cho <hope5487@gmail.com>
Signed-off-by: Sung Hyun Cho <hope5487@gmail.com>
There was a problem hiding this comment.
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a4bd2ad5a
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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".
Sorry, something went wrong.
Signed-off-by: Sung Hyun Cho <hope5487@gmail.com>
Signed-off-by: Sung Hyun Cho <hope5487@gmail.com>
…epspeedai#8026) Follow-up to deepspeedai#7916 and deepspeedai#8023. Makes `torch.func.grad / grad_and_value / jacrev` and `vmap(grad)` work when called directly on a DeepSpeed engine for ZeRO 0/1/2. | API | ZeRO-0 | ZeRO-1 | ZeRO-2 | ZeRO-3 | |---|---|---|---|---| | `torch.func.grad(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.grad_and_value(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.jacrev(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(torch.func.grad(...))(x_batch)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(lambda x: engine(x))(x_batch)` | already ✓ | already ✓ | already ✓ | not yet | | `engine.backward(loss)` (regression) | ✓ | ✓ | ✓ | ✓ | `vmap` alone runs only the forward graph so it never hit the broken backward hooks and already worked before this PR; included in the table for completeness. Usage: ```python engine, _, _, _ = deepspeed.initialize(model=model, ...) # input gradient g = torch.func.grad(lambda xi: engine(xi))(x) # gradient and value in one pass g, v = torch.func.grad_and_value(lambda xi: engine(xi))(x) # Jacobian of output w.r.t. input J = torch.func.jacrev(lambda xi: engine(xi))(x) # per-sample input gradients (batched) per_sample_g = torch.func.vmap(torch.func.grad(lambda xi: engine(xi)))(x_batch) ``` ZeRO-3 hits a separate SIGSEGV from the same APIs and is tracked separately. Test: `pytest tests/unit/v1/zero/test_zero_torch_func.py` --------- Signed-off-by: Sung Hyun Cho <hope5487@gmail.com> Co-authored-by: Masahiro Tanaka <81312776+tohtana@users.noreply.github.com>
…epspeedai#8026) Follow-up to deepspeedai#7916 and deepspeedai#8023. Makes `torch.func.grad / grad_and_value / jacrev` and `vmap(grad)` work when called directly on a DeepSpeed engine for ZeRO 0/1/2. | API | ZeRO-0 | ZeRO-1 | ZeRO-2 | ZeRO-3 | |---|---|---|---|---| | `torch.func.grad(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.grad_and_value(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.jacrev(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(torch.func.grad(...))(x_batch)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(lambda x: engine(x))(x_batch)` | already ✓ | already ✓ | already ✓ | not yet | | `engine.backward(loss)` (regression) | ✓ | ✓ | ✓ | ✓ | `vmap` alone runs only the forward graph so it never hit the broken backward hooks and already worked before this PR; included in the table for completeness. Usage: ```python engine, _, _, _ = deepspeed.initialize(model=model, ...) # input gradient g = torch.func.grad(lambda xi: engine(xi))(x) # gradient and value in one pass g, v = torch.func.grad_and_value(lambda xi: engine(xi))(x) # Jacobian of output w.r.t. input J = torch.func.jacrev(lambda xi: engine(xi))(x) # per-sample input gradients (batched) per_sample_g = torch.func.vmap(torch.func.grad(lambda xi: engine(xi)))(x_batch) ``` ZeRO-3 hits a separate SIGSEGV from the same APIs and is tracked separately. Test: `pytest tests/unit/v1/zero/test_zero_torch_func.py` --------- Signed-off-by: Sung Hyun Cho <hope5487@gmail.com> Co-authored-by: Masahiro Tanaka <81312776+tohtana@users.noreply.github.com> Signed-off-by: nathon-lee <leejianwoo@gmail.com>
…epspeedai#8026) Follow-up to deepspeedai#7916 and deepspeedai#8023. Makes `torch.func.grad / grad_and_value / jacrev` and `vmap(grad)` work when called directly on a DeepSpeed engine for ZeRO 0/1/2. | API | ZeRO-0 | ZeRO-1 | ZeRO-2 | ZeRO-3 | |---|---|---|---|---| | `torch.func.grad(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.grad_and_value(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.jacrev(lambda x: engine(x))(x)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(torch.func.grad(...))(x_batch)` | ✓ | ✓ | ✓ | not yet | | `torch.func.vmap(lambda x: engine(x))(x_batch)` | already ✓ | already ✓ | already ✓ | not yet | | `engine.backward(loss)` (regression) | ✓ | ✓ | ✓ | ✓ | `vmap` alone runs only the forward graph so it never hit the broken backward hooks and already worked before this PR; included in the table for completeness. Usage: ```python engine, _, _, _ = deepspeed.initialize(model=model, ...) # input gradient g = torch.func.grad(lambda xi: engine(xi))(x) # gradient and value in one pass g, v = torch.func.grad_and_value(lambda xi: engine(xi))(x) # Jacobian of output w.r.t. input J = torch.func.jacrev(lambda xi: engine(xi))(x) # per-sample input gradients (batched) per_sample_g = torch.func.vmap(torch.func.grad(lambda xi: engine(xi)))(x_batch) ``` ZeRO-3 hits a separate SIGSEGV from the same APIs and is tracked separately. Test: `pytest tests/unit/v1/zero/test_zero_torch_func.py` --------- Signed-off-by: Sung Hyun Cho <hope5487@gmail.com> Co-authored-by: Masahiro Tanaka <81312776+tohtana@users.noreply.github.com>
| Back | FazBrowse Home | New Git URL |
Follow-up to #7916 and #8023.
Makes torch.func.grad / grad_and_value / jacrev and vmap(grad) work when called directly on a DeepSpeed engine for ZeRO 0/1/2.
vmap alone runs only the forward graph so it never hit the broken backward hooks and already worked before this PR; included in the table for completeness.
Usage:
ZeRO-3 hits a separate SIGSEGV from the same APIs and is tracked separately.
Test:
pytest tests/unit/v1/zero/test_zero_torch_func.py