Migrate norms and softmax kernels to NVRTC#3156
Conversation
4e8d10a to
5235723
Compare
|
/te-ci pytorch |
Greptile SummaryThis PR migrates the fused softmax (3 variants) and norm (LayerNorm/RMSNorm forward and backward) kernels from ahead-of-time NVCC compilation to JIT compilation via NVRTC, reducing the library binary size by 36% and total build time by ~26%. The legacy AOT path is preserved behind
Confidence Score: 5/5The change is safe to merge. The NVRTC dispatch path is additive, the legacy AOT path is fully preserved behind build flags, and all prior review concerns have been addressed. Thread-safety is correctly handled via shared_mutex with a double-check inside the unique lock. The dx_add_t specialization fix for zero-length arrays is correct. The softmax kernel changes are semantically equivalent to the original. Only minor inefficiencies remain, neither of which affects correctness. transformer_engine/common/normalization/rtc_dispatch.cpp — the set_function_attribute call inside the launch closure and the two-compilation pattern for backward kernels are worth a follow-up optimization. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller as Caller
participant Dispatch as Dispatch
participant KMgr as KernelManager
participant NVRTC as NVRTC
participant Driver as CUDA Driver
Caller->>Dispatch: forward/backward call
Dispatch->>KMgr: is_compiled(label) [shared_lock]
alt Not compiled - first call
KMgr-->>Dispatch: false
Dispatch->>KMgr: compile(label, kernel_expr, src, opts, headers)
KMgr->>KMgr: acquire unique_lock and re-check cache
KMgr->>NVRTC: nvrtcCreateProgram + nvrtcCompileProgram
NVRTC-->>KMgr: PTX or cubin plus mangled name
KMgr->>Driver: cuModuleLoadData
KMgr->>KMgr: insert into cache and release lock
else Already compiled
KMgr-->>Dispatch: true returns early
end
Dispatch->>KMgr: "set_function_attribute if smem >= 48KB"
Dispatch->>KMgr: occupancy_max_active_blocks_per_sm [shared_lock]
Dispatch->>KMgr: launch or launch_cooperative [shared_lock]
KMgr->>Driver: cuLaunchKernel or cuLaunchCooperativeKernel
Driver-->>Caller: kernel running on GPU
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Caller as Caller
participant Dispatch as Dispatch
participant KMgr as KernelManager
participant NVRTC as NVRTC
participant Driver as CUDA Driver
Caller->>Dispatch: forward/backward call
Dispatch->>KMgr: is_compiled(label) [shared_lock]
alt Not compiled - first call
KMgr-->>Dispatch: false
Dispatch->>KMgr: compile(label, kernel_expr, src, opts, headers)
KMgr->>KMgr: acquire unique_lock and re-check cache
KMgr->>NVRTC: nvrtcCreateProgram + nvrtcCompileProgram
NVRTC-->>KMgr: PTX or cubin plus mangled name
KMgr->>Driver: cuModuleLoadData
KMgr->>KMgr: insert into cache and release lock
else Already compiled
KMgr-->>Dispatch: true returns early
end
Dispatch->>KMgr: "set_function_attribute if smem >= 48KB"
Dispatch->>KMgr: occupancy_max_active_blocks_per_sm [shared_lock]
Dispatch->>KMgr: launch or launch_cooperative [shared_lock]
KMgr->>Driver: cuLaunchKernel or cuLaunchCooperativeKernel
Driver-->>Caller: kernel running on GPU
Reviews (8): Last reviewed commit: "Fix tests" | Re-trigger Greptile |
700a1eb to
b909589
Compare
|
/te-ci pytorch |
ptrendx
left a comment
There was a problem hiding this comment.
Generally OK. One general comment is that with this move to NVRTC we could actually expand the tuned kernel coverage not just to those predetermined cases, but also to other row lengths (previously we did not want to do that just because of the binary size and the compilation time). This should give a good benefit, since the general kernel is not very efficient compared with the tuned one. I'm not sure even if there is even a need for the general kernel (apart from the very long row lengths that would not fit) in that case.
I did consider this, but we also rely on the registration for the optimal launch parameters, for different shapes / archs right? I think its a cool idea but would probably defer it to a separate PR |
|
/te-ci |
|
Generally speaking the tuning should not be difficult, but I agree that this can be done in a subsequent PR. |
5da6586 to
9772be5
Compare
|
/te-ci |
|
/te-ci |
Move the fused-softmax and LayerNorm/RMSNorm kernels from build-time template
instantiation to runtime NVRTC compilation, with full coverage of the existing
kernel set so the NVRTC path is the default.
Fused softmax:
- RTC compile/launch path for scaled / scaled-masked / scaled-upper-triangular /
scaled-aligned-causal softmax, keyed by dtype, shape and mask/causal mode.
- NVTE_BUILD_LEGACY_STATIC_FUSED_SOFTMAX (default OFF) restores the static
template dispatch.
Normalization (LayerNorm + RMSNorm, forward + backward):
- Replace the static REGISTER_NORM_LAUNCHER template fanout with an NVRTC
registry that compiles the selected (norm type, direction, dtypes, hidden size,
CTA config) kernel on first use and caches it.
- NVTE_BUILD_LEGACY_STATIC_NORM (default OFF) restores the static launchers.
- NVRTC-safe kernel sources: kernel sources/headers avoid common.h under
__CUDACC_RTC__; add the dtype aliases and a minimal std::is_same/conditional_t
in the RTC build, and replace a zero-length padding array (a GNU extension nvcc
accepts but NVRTC rejects) with a no-padding union specialization.
KernelManager (util/rtc.{h,cpp}) gains occupancy / function-attribute /
cooperative-launch helpers needed by the norm launchers.
Validated on sm_89 (RTX 6000 Ada): full normalization operator suite 192/192,
softmax + NVRTC unit tests pass; libtransformer_engine.so shrinks ~72 MB -> ~65 MB.
On sm_100a the NVRTC norm forward kernel builds where the static instantiation
crashed the compiler.
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
for more information, see https://pre-commit.ci
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
for more information, see https://pre-commit.ci
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
Signed-off-by: CarlosGomes98 <carlosmiguel.gomes@live.com.pt>
595286d to
c7d875a
Compare
|
/te-ci |
Description
Enables JIT compilation through NVRTC for Norm and Softmax kernels.
Reduces TE binary size by 36%, sequential build time by 5% (measured in cpu_user total time, hard to measure real impact due to parallelization, machine specs)
This is the first chunk of work related to #3054 .
The softmax kernels were chosen as they seemed like one of the simplest to migrate, for my understanding of the system.
The norm kernels include
normalization/layernorm/ln_fwd_cuda_kernel.cu, which is one of the heaviest kernel compilations in the build.It is still possible to enable nvcc static compilation through
NVTE_BUILD_LEGACY_STATIC_FUSED_SOFTMAXandNVTE_BUILD_LEGACY_STATIC_NORM, which then allow forNVTE_DISABLE_NVRTC=1to be used during runtime.Build time results:
Measured on RTX 6000 Ada, CUDA 12.8, single arch sm_89, 32-core host. AOT = -DNVTE_BUILD_LEGACY_STATIC_{FUSED_SOFTMAX,NORM}=ON (old behavior); NVRTC = default.
Per TU build time
scaled_masked_softmax.cuscaled_upper_triang_masked_softmax.cuscaled_aligned_causal_masked_softmax.culn_fwd_cuda_kernel.culn_bwd_semi_cuda_kernel.curmsnorm_fwd_cuda_kernel.curmsnorm_bwd_semi_cuda_kernel.cuBinary size
libtransformer_engine.soTotal build time
JIT compilation cost
layernorm_fwdlayernorm_bwdrmsnorm_fwdrmsnorm_bwdscaled_masked_softmax_fwdscaled_masked_softmax_bwdscaled_upper_triang_softmax_fwdscaled_upper_triang_softmax_bwdscaled_aligned_causal_softmax_fwdFixes # (issue)
Type of change
Changes
Please list the changes introduced in this PR:
rtc_dispatch.cppto allow NVRTC to work with the registry used by norms. This is the largest chunk of new code.Checklist: