You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scope request only. I will not start implementation until a maintainer confirms
that this optimization is worth pursuing, agrees with the boundary below, and
clarifies coordination with #208.
Current production path
The shared portable, non-tensor-parallel linear_logp backward is reachable from
the DeepSpeed training path:
This helper is used by the portable CUDA/ROCm path and by the non-TP SM90
fallback. The normal SM90 fused backward extension has its own implementation
and does not use this helper.
Current accumulation
chunked_linear_logp_backward initializes an FP32 gradient table and, for every
chunk, materializes a GEMM result before adding it to that table:
The proposed change preserves the FP32 zero-initialization but lets GEMM
accumulate directly into grad_w when both operands are already FP32 and
ambient autocast is disabled:
The existing path remains the fallback for autocast-enabled or non-FP32
operands. dW operands, including hidden.float(), will only be constructed when
the weight gradient is requested.
No public API, forward computation, registry, TP metadata, or collective changes
are proposed.
For N=4096, D=2048, V=32768, default chunking gives K=8. The proposed
accumulation therefore removes eight framework-visible aten::add_ device
operations and reduces logical gradient-table traffic by 4.0 GiB.
These are static logical quantities. They are not claims of eight fewer GPU
kernels, 4 GiB lower measured peak VRAM, or 4 GiB lower physical HBM traffic.
Local feasibility evidence
A throwaway prototype compared the current and proposed accumulation on an RTX
3050 Ti / SM86 with PyTorch 2.12.1+cu126.
For forced four-chunk cases across BF16, FP16, and FP32:
complete backward helper: 1.076–1.175x
isolated dW: 1.139–1.235x
no stable peak-memory improvement
The prototype also covers:
bias and no-bias;
N=0;
hidden-only, weight-only, and bias-only gradients;
zero upstream gradients and signed-zero comparison;
same-input repeat determinism;
ambient autocast fallback;
higher-order autograd smoke.
The isolated dW result is diagnostic only. It is not proposed as the performance
acceptance result.
Correctness boundary
The proposal deliberately retains grad_w=zeros(...). An earlier experiment
that assigned the first chunk directly changed some zero gradients from +0 to -0, so that version is excluded.
The intended contract is:
current-vs-candidate agreement under the repository's existing tolerance;
same-input repeat determinism;
preserved N=0 behavior;
zero-upstream numerical zeros with matching signbit;
autocast-enabled execution retains the current accumulation path;
no extra dW casts or allocations when the weight gradient is not requested.
Universal bitwise equality for arbitrary random inputs is not required: FP32
GEMM accumulation may differ by approximately one ULP.
The device-specific autocast check must remain compatible with the repository's
minimum supported PyTorch version (2.4.1).
Proposed target validation
Before implementation is promoted to a PR, I will compare base and candidate on
the maintainer-selected authoritative portable target.
The headline measurement will be portable operator forward+backward latency,
not isolated dW or helper-only latency. Validation will include:
representative default-chunking RL shapes;
paired base-vs-candidate measurements;
bias and no-bias;
BF16, plus supported FP16/FP32 checks;
a 1/2/4/8-chunk diagnostic sweep;
incremental peak allocation and profiler/device-op evidence;
the normal SM90 fused path as an unchanged control when testing H100.
I propose proceeding only if the portable operator shows a stable, repeatable
positive gain without a material regression on the other measured production
shapes. I am not proposing a single fixed percentage requirement for every
shape before target data is available.
Expected implementation scope
Only:
rl_engine/kernels/ops/pytorch/loss/linear_logp.py
focused coverage in tests/test_linear_logp.py
The existing benchmarks/benchmark_linear_logp.py will be reused for base/head
measurements. No new operator, configuration flag, benchmark file, or user-facing
documentation is planned unless requested during review.
No forward, API, registry, trainer, or dispatch changes.
A current issue/PR search found no equivalent non-TP addmm_ accumulation work.
Maintainer decision requested
Is this portable/non-TP backward optimization worth pursuing within the
two-file scope above?
Which portable hardware target should be authoritative for the base-vs-head
performance decision: A100, H100 forced fallback, a ROCm target, or another
GPU-CI target?
Current production path
The shared portable, non-tensor-parallel
linear_logpbackward is reachable fromthe DeepSpeed training path:
Relevant code:
rl_engine/executors/deepspeed_trainer.pyrl_engine/kernels/ops/triton/loss/linear_logp.pyrl_engine/kernels/ops/pytorch/loss/linear_logp.pyThis helper is used by the portable CUDA/ROCm path and by the non-TP SM90
fallback. The normal SM90 fused backward extension has its own implementation
and does not use this helper.
Current accumulation
chunked_linear_logp_backwardinitializes an FP32 gradient table and, for everychunk, materializes a GEMM result before adding it to that table:
The proposed change preserves the FP32 zero-initialization but lets GEMM
accumulate directly into
grad_wwhen both operands are already FP32 andambient autocast is disabled:
The existing path remains the fallback for autocast-enabled or non-FP32
operands. dW operands, including
hidden.float(), will only be constructed whenthe weight gradient is requested.
No public API, forward computation, registry, TP metadata, or collective changes
are proposed.
Static traffic model
Let:
Considering only gradient-table traffic:
For
N=4096, D=2048, V=32768, default chunking givesK=8. The proposedaccumulation therefore removes eight framework-visible
aten::add_deviceoperations and reduces logical gradient-table traffic by 4.0 GiB.
These are static logical quantities. They are not claims of eight fewer GPU
kernels, 4 GiB lower measured peak VRAM, or 4 GiB lower physical HBM traffic.
Local feasibility evidence
A throwaway prototype compared the current and proposed accumulation on an RTX
3050 Ti / SM86 with PyTorch
2.12.1+cu126.For forced four-chunk cases across BF16, FP16, and FP32:
1.076–1.175x1.139–1.235xThe prototype also covers:
N=0;The isolated dW result is diagnostic only. It is not proposed as the performance
acceptance result.
Correctness boundary
The proposal deliberately retains
grad_w=zeros(...). An earlier experimentthat assigned the first chunk directly changed some zero gradients from
+0to-0, so that version is excluded.The intended contract is:
N=0behavior;signbit;Universal bitwise equality for arbitrary random inputs is not required: FP32
GEMM accumulation may differ by approximately one ULP.
The device-specific autocast check must remain compatible with the repository's
minimum supported PyTorch version (
2.4.1).Proposed target validation
Before implementation is promoted to a PR, I will compare base and candidate on
the maintainer-selected authoritative portable target.
The headline measurement will be portable operator forward+backward latency,
not isolated dW or helper-only latency. Validation will include:
I propose proceeding only if the portable operator shows a stable, repeatable
positive gain without a material regression on the other measured production
shapes. I am not proposing a single fixed percentage requirement for every
shape before target data is available.
Expected implementation scope
Only:
rl_engine/kernels/ops/pytorch/loss/linear_logp.pytests/test_linear_logp.pyThe existing
benchmarks/benchmark_linear_logp.pywill be reused for base/headmeasurements. No new operator, configuration flag, benchmark file, or user-facing
documentation is planned unless requested during review.
Non-goals and overlap
explicitly confirms that parallel work is appropriate.
A current issue/PR search found no equivalent non-TP
addmm_accumulation work.Maintainer decision requested
two-file scope above?
performance decision: A100, H100 forced fallback, a ROCm target, or another
GPU-CI target?