Skip to content

Bring back SLN cuda kernel and use provider options to switch to standard implementation - #15660

Merged
gh-yewang merged 18 commits into
mainfrom
wangye/sln_revert
May 2, 2023
Merged

Bring back SLN cuda kernel and use provider options to switch to standard implementation#15660
gh-yewang merged 18 commits into
mainfrom
wangye/sln_revert

Conversation

@gh-yewang

Copy link
Copy Markdown
Contributor

Description

Motivation and Context

perf drop in some models

@gh-yewang
gh-yewang marked this pull request as ready for review April 25, 2023 01:15
@gh-yewang
gh-yewang requested a review from yufenglee April 25, 2023 01:31
Comment thread docs/ContribOperators.md Outdated
Comment thread include/onnxruntime/core/providers/cuda/cuda_provider_options.h Outdated
Comment thread onnxruntime/python/onnxruntime_pybind_state_common.h Outdated
Comment thread onnxruntime/core/session/provider_bridge_ort.cc Outdated
Comment thread onnxruntime/python/tools/transformers/convert_generation.py Outdated
@gh-yewang
gh-yewang marked this pull request as draft April 28, 2023 18:23
@gh-yewang gh-yewang changed the title Bring back SLN cuda kernel and use attribute "strict" to switch to standard implementation Bring back SLN cuda kernel and use provider options to switch to standard implementation Apr 28, 2023
@gh-yewang
gh-yewang marked this pull request as ready for review May 1, 2023 16:57
@gh-yewang
gh-yewang requested a review from tianleiwu May 1, 2023 19:53

@yufenglee yufenglee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@yufenglee

Copy link
Copy Markdown
Member

we need to add this to transformer optimization document.

@gh-yewang
gh-yewang merged commit 391f897 into main May 2, 2023
@gh-yewang
gh-yewang deleted the wangye/sln_revert branch May 2, 2023 01:35
@gh-yewang

Copy link
Copy Markdown
Contributor Author

we need to add this to transformer optimization document.

will send out another PR

ShukantPal pushed a commit to ShukantPal/onnxruntime that referenced this pull request May 7, 2023
tianleiwu added a commit that referenced this pull request May 27, 2026
…28682)

## Description

Use fp32 accumulation in SkipLayerNormalization,
SkipSimplifiedLayerNormalization, and EmbedLayerNormalization CUDA
kernels to avoid overflow and improve numerical accuracy when processing
fp16/bf16 data.

The original implementation accumulated mean and variance statistics in
the input data type (fp16/bf16), which can overflow for large hidden
sizes or when input values have large magnitude. This change promotes
all intermediate accumulation (mean, variance, normalization math) to
fp32, matching the approach used by TensorRT-LLM's LayerNorm kernels.

## Motivation

- fp16 has limited range (max ~65504) and precision (10-bit mantissa).
Accumulating `x²/ld` across thousands of elements in fp16 easily
overflows or loses precision.
- bf16 has even less precision (7-bit mantissa), making accumulation
errors more severe.
- The fix is straightforward: cast to float before accumulating, compute
normalization in float, cast back to the output type.

## Key Changes

| File | Change |
|------|--------|
| `layer_norm.cuh` | Changed `LayerNorm`, `SimplifiedLayerNorm`,
`LayerNormSmall`, `SimplifiedLayerNormSmall` to accept and operate on
`float` for thread_data, epsilon, mu, rsigma. Removed unused
`KeyValuePairSum` overloads for half/bfloat16. |
| `skip_layer_norm_impl.cu` | Changed `SkipLayerNormKernel` and
`SkipLayerNormKernelSmall` to accumulate in fp32
(`cub::KeyValuePair<float, float>`). Removed `maybe2half` helper (no
longer needed). |
| `embed_layer_norm_impl.cu` | Changed epsilon from `T` to `float`,
accumulation to use `float` thread_data. |
| `profile_skip_layer_norm.py` | New profiling script for nsys-based
kernel timing analysis. |
| `profile_skip_layer_norm.sh` | Shell wrapper for running nsys
profiling. |
| `parse_nsys.py` | Utility to parse nsys SQLite output and extract CUDA
kernel timings. |

## Performance Results

Profiled on NVIDIA GPU with nsys (B=1, seq_len=2048, fp16 data, 200
iterations, skip first 5 warmup):

| Hidden Size | fp16 accum (μs) | fp32 accum (μs) | Regression |
|---|---|---|---|
| 768 | 3.81 | 3.81 | **0.0%** |
| 1024 | 4.22 | 4.22 | **0.0%** |
| 4096 | 13.01 | 13.03 | **+0.15%** (noise) |
| 8192 | 28.94 | 28.94 | **0.0%** |

**No measurable performance regression.** The kernel is
memory-bandwidth-bound, so fp32 arithmetic is completely hidden behind
memory latency.

## Testing

- Existing unit tests pass (SkipLayerNorm, EmbedLayerNorm ops).
- Profiling scripts added for reproducible performance measurement:
  ```bash
  cd onnxruntime/test/python/transformers
nsys profile -o sln_fp16 --export=sqlite python
profile_skip_layer_norm.py --mode fp16 --warmup 5 --repeat 100
  python parse_nsys.py sln_fp16.sqlite --skip-first 5
  ```
  
## Related PRs

#28442
#15660
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants