优化Qwen3 - FP8模型L40S卡性能提升18%

我在之前的博客中介绍了自己写的 SM89 上的 FP8 Blockwise GEMM CUDA kernel。后来看到 Qwen3 官方文档中的 H20 卡上的性能测试数据,本文仿照 Qwen3 文档的测试方法,对新 Kernel 进行更多 Qwen3 FP8 模型在 L40S 的对比性能测试。

总结放最前

对下面的速度指标可以有几个观察:

  1. 新 Kernel 平均提升性能 18%。依照 Qwen3 官方的测试用例,平均下来新 Kernel 对端到端推理的性能优化幅度是 18%。
  2. 速度优化的比例随着模型参数的增加先升后降。大概是因为最小模型的参数量太小,调度占比更高;而更大的模型参数量太大,访存占比升高。
  3. A3B 的模型优于 4B 的模型。但我在更多的测试后发现,A3B 仅在 batch_size 2 以下性能优于 4B,在超过 2 以后,A3B 的性能曲线增长远不如 4B 的性能曲线。我的测试在 L40S 上,4B 的最大吞吐大约是 A3B 的 1.7 倍,8B 的最大吞吐大约是 A3B 的 1.4 倍。这大概是因为 A3B 模型计算时需要更多的显存带宽。
  4. 新 Kernel 下 L40S 的平均吞吐是 H20 的 56% (triton:47%)。可以用作单卡运行 Qwen3 模型时,L40S 和 H20 的性价比大略预估。

下面是具体的测试环境和测试数据:

1. 测试环境

硬件使用的是 NVIDIA L40S,评测的每个模型都跑在 1 张 L40S 卡上。Docker 使用的是 SGLang 的开发镜像:lmsysorg/sglang:dev。

SGLang 和 SGL-Kernel 可以根据我的这篇博客中介绍的方法自行编译,或者从下面链接下载我编译好的 Python wheel 包: https://github.com/solrex/sglang/releases/tag/sm89-fp8 然后通过下面命令安装:

pip install sgl_kernel-0.1.5-cp39-abi3-linux_x86_64.whl
pip install sglang-0.4.6.post5-py3-none-any.whl

2. 测试设置

SGLang 的测试设置基本与 Qwen3 官方的测试设置相同,启动参数主要设置了这些。因为下面测试的 batch size 只有 1,所以 --cuda-graph-max-bs 只设置了 8,正常批量压测时最好设置到 64 以上。

python3 -m sglang.launch_server --model-path MODEL_PATH --tp 1 --allow-auto-truncate --enable-mixed-chunk --context-length 40960 --enable-torch-compile --torch-compile-max-bs 8 --cuda-graph-max-bs 8 --port ****

使用以上方式启动,使用的是默认的 FP8 Blockwise Triton Kernel;如果希望使用新的 CUDA 实现的 FP8 Blockwise Kernel,只需要在启动前增加环境变量:

export SGLANG_SUPPORT_CUTLASS_BLOCK_FP8=1

所以后面的测试,主要是比较 Triton 和 CUDA 实现的 FP8 Blockwise GEMM Kernel 的性能区别。

指标中加上“triton”前后缀的,即为 Triton Kernel 的指标;指标中加上“cuda”前后缀的,即为我新实现的 CUDA Kernel 的指标。

3. 准确率速测

首先测一下新 Kernel 的实现是否有严重的问题,这里使用 SGLang 代码库中的 benchmark/gsm8k 进行一下速测。速测有 512 token 截断,测试 500 条,仅用于粗略比较是否有 bug,不能充分说明模型的能力差距。

速测命令如下,通过 port 将请求发送给不同的模型:

python3 bench_sglang.py --num-questions 500 --port ****
模型triton-准确率cuda-准确率
Qwen3-0.6B-FP841.0%43.4%
Qwen3-1.7B-FP869.0%68.8%
Qwen3-4B-FP885.4%86.2%
Qwen3-8B-FP892.0%92.2%
Qwen3-14B-FP889.2%86.2%
Qwen3-32B-FP880.8%83.8%
Qwen3-30B-A3B-FP890.6%88.2%

可以看到我写的 CUDA Kernel 在准确率上与官方的 triton Kernel 没有明显的差距。

4. 性能测试结果

为了与 Qwen3 官方的性能指标进行对齐,我采用了完全相同的请求参数,即:batch_size 固定为 1,生成长度固定为 2048,输入长度使用 1、6144、14336、30720,速度指标使用 (输入+输出)/时间。

Qwen3 官方如此设置大概是为了照顾 Transformers 库,但这种测试方式并不常见。batch_size 为 1 很难测出来最大吞吐,30K 的输入长度在业务场景下也不算常见,最终指标受 prefill 影响很大。为了显示生成的性能,我增加了一列平均 ITL 指标。

指标列说明:

  • 输入:输入的长度,单位是 token;
  • H20:Qwen3 官方文档中 H20 的速度,单位是 tokens/s;
  • L40S-triton:L40S 上 SGLang 官方 triton FP8 blockwise GEMM 实现的速度,单位是 tokens/s;
  • L40S-cuda:L40S 上替换为我实现的 CUDA Kernel 实现的速度,单位是 tokens/s;
  • 速度提升的百分比:L40S-cuda / L40S-triton - 100%
  • ITL-triton:SGLang 官方 triton 实现下生成每个 token 的平均间隔,单位是毫秒 ms;
  • ITL-cuda:我的 CUDA 实现下生成每个 token 的平均间隔,单位是毫秒 ms;

4.1 Qwen3-0.6B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
1458.03250.36303.09+21.1%3.983.28
61441572.95805.75936.57+16.0%4.944.24
143362689.081270.001427.09+12.0%6.265.57
307203819.861773.351918.70+8.0%8.978.28

4.2 Qwen3-1.7B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
1333.90148.35197.24+32.9%6.735.05
61441198.20518.43661.93+27.7%7.696.01
143362095.61877.281071.52+22.1%9.087.43
307203165.321356.381576.85+16.2%11.7410.07

4.3 Qwen3-30B-A3B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
1155.55102.83117.38+14.2%9.708.49
6144551.34377.75426.18+12.8%10.549.34
14336945.13680.58757.84+11.4%11.7010.50
307201405.911133.151238.20+9.3%14.0512.85

4.4 Qwen3-4B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
1200.6175.19103.18+37.2%13.289.67
6144662.26278.90370.24+32.8%14.3110.76
143361066.23498.17638.03+28.1%16.0212.50
307201467.71821.341002.76+22.1%19.4215.90

4.5 Qwen3-8B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
1150.2553.4766.56+24.5%18.6915.00
6144516.64202.20248.00+22.7%19.7516.10
14336859.92371.91447.97+20.5%21.4717.82
307201242.24641.60751.65+17.2%24.8821.23

4.6 Qwen3-14B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
197.1134.2039.30+14.9%29.2225.46
6144342.95130.36148.56+13.9%30.6526.89
14336587.33246.01278.15+13.1%32.4828.72
30720880.72441.62492.80+11.6%36.1732.40

4.7 Qwen3-32B-FP8 (SGLang sm89-fp8 branch)

输入H20L40S-tritonL40S-cuda速度提升ITL-tritonITL-cuda
146.1715.9518.31+14.8%62.7054.59
6144165.7161.3670.13+14.3%65.1456.98
14336287.60117.39133.28+13.5%68.0959.96
30720436.59FAILFAIL