Commit e0b2b97
authored
[CUDA]: Split-K2 QMoE SwiGLU GEMV kernel (#29167)
### Description
Add a CUDA QMoE Split-K2 two-pass FC1 interleaved-SwiGLU GEMV
implementation for supported fp16 INT4 decode-shaped workloads. The
first pass computes two K-split partials into QMoE workspace using the
selected GEMV accumulator type, and the second pass reduces the partials
in fp32, applies optional bias, and writes the SwiGLU output for FC2.
FC2 stays on the existing `moe_gemv_kernel` path.
The route now uses two binary environment controls.
`ORT_MOE_GEMV_FP32_ACCUM=1` enables fp32 accumulation, and
`ORT_MOE_GEMV_SPLITK2_SWIGLU=1` enables Split-K2. Both default to `0`.
| Accumulation control | Split-K2 control | Route |
|---|---|---|
| unset or `0` | unset or `0` | fp16 accumulation, single-kernel FC1
SwiGLU |
| unset or `0` | `ORT_MOE_GEMV_SPLITK2_SWIGLU=1` | fp16 accumulation,
Split-K2 FC1 SwiGLU |
| `ORT_MOE_GEMV_FP32_ACCUM=1` | unset or `0` | fp32 accumulation,
single-kernel FC1 SwiGLU |
| `ORT_MOE_GEMV_FP32_ACCUM=1` | `ORT_MOE_GEMV_SPLITK2_SWIGLU=1` | fp32
accumulation, Split-K2 FC1 SwiGLU |
This PR also:
- keeps Split-K2 narrowly gated to fp16 INT4 interleaved-SwiGLU GEMV
with activation/bias scale type matching the activation type;
- adds QMoE workspace plumbing for the Split-K2 partials;
- updates the focused QMoE profiler and Nsight wrapper with matching
`--fp32-accum` and `--splitk2-swiglu` controls;
- adds focused benchmark coverage that explicitly forces the Split-K2
route under the fp16-default policy;
- documents the routing policy, measurements, binary knobs, and future
autotune direction.
### Motivation and Context
GPT-OSS-20B single-token decode spends visible time in the QMoE FC1
interleaved-SwiGLU GEMV path. Split-K2 improves FC1 parallelism by
splitting the K dimension and reducing the partials in a lightweight
second pass.
Under the fp32-accumulation route, Split-K2 reduced FC1 kernel work from
about `21.42 us` to `17.59 + 2.39 = 19.98 us` in Nsight, and repeated
CUDA-graph GPT-OSS decode pairs showed about `+0.9%` to `+1.6%`
throughput improvement. A later 3-pair CUDA-graph run averaged
`332.099536 tok/s` for Split-K2 versus `327.857928 tok/s` with Split-K2
disabled (`+1.29%` throughput, `-1.28%` latency), with no MMLU smoke
regression signal.
After the normal fp16 QMoE GEMV path changed to fp16 accumulation by
default, the single-kernel fp16 route became faster on the focused
GPT-OSS, Qwen3.6-35B-A3B, and Gemma4-26B-A4B helper configurations. The
fp16 Split-K2 variant is still kept because it is faster than the fp32
Split-K2 route in those focused runs and may be selected by future
per-shape autotuning.
### Validation
- Built and synced CUDA provider:
- `cmake --build /home/tianlei/onnxruntime/build/cu130/Release --target
onnxruntime_providers_cuda --parallel $(nproc)`
- Lint/format:
- `lintrunner -a ...`
- `git diff --check`
- Focused CUDA test:
- `ORT_QMOE_GEMV_BENCHMARK=1 pytest -q
onnxruntime/test/python/transformers/test_qmoe_cuda.py::TestQMoEGemvBenchmark::test_splitk2_swiglu_decode_latency`
- result: `1 passed`
- Focused GPT-OSS helper route checks:
- default fp16: valid output, `ORT_MOE_GEMV_SPLITK2_SWIGLU=0`, latency
`0.062995 ms`
- fp16 accumulation with Split-K2: valid output,
`ORT_MOE_GEMV_SPLITK2_SWIGLU=1`, latency `0.063945 ms`
- fp32 accumulation without Split-K2: valid output,
`ORT_MOE_GEMV_SPLITK2_SWIGLU=0`, latency `0.071311 ms`
- fp32 accumulation with Split-K2: valid output,
`ORT_MOE_GEMV_SPLITK2_SWIGLU=1`, latency `0.071726 ms`
- Nsight route verification:
- default fp16 dispatched `moe_gemv_interleaved_swiglu_kernel` and
`moe_gemv_kernel`
- fp16 accumulation with Split-K2 dispatched
`moe_gemv_splitk_partials_kernel`,
`moe_gemv_splitk_reduce_swiglu_kernel`, and `moe_gemv_kernel`
- fp32 accumulation without Split-K2 dispatched the single FC1 SwiGLU
kernel and FC2
- fp32 accumulation with Split-K2 enabled dispatched Split-K2
partial/reduce kernels and FC2
- Additional focused helper checks, all with valid output:
- Qwen3.6-35B-A3B: fp16 Split-K2 `0.049207 ms`, fp16 single-kernel
`0.047403 ms`, fp32 Split-K2 `0.052055 ms`
- Gemma4-26B-A4B: fp16 Split-K2 `0.053503 ms`, fp16 single-kernel
`0.050732 ms`, fp32 Split-K2 `0.059571 ms`
- 1000-sample `match_mmlu` smoke on GPT-OSS-20B INT4 QMoE:
- Split-K2 route: `0.8380`
- Split-K2 disabled: `0.8350`1 parent 7e8fc29 commit e0b2b97
9 files changed
Lines changed: 559 additions & 15 deletions
File tree
- docs/contrib_ops/cuda
- onnxruntime
- contrib_ops/cuda/llm/moe_gemm
- test/python/transformers
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
989 | 989 | | |
990 | 990 | | |
991 | 991 | | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
992 | 1013 | | |
993 | 1014 | | |
994 | 1015 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
979 | 979 | | |
980 | 980 | | |
981 | 981 | | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
| 1052 | + | |
| 1053 | + | |
| 1054 | + | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
982 | 1145 | | |
983 | 1146 | | |
984 | 1147 | | |
| |||
0 commit comments