CUTLASS
3 秒看懂
CUTLASS 是 NVIDIA 开源的 C++ 模板库,提供在 NVIDIA GPU 上实现高性能矩阵乘法(GEMM)及相关线性代数运算的可组合构建模块。 它不是面向终端用户的库(如 cuBLAS),而是面向内核开发者——让你像搭积木一样,从寄存器→共享显存→全局显存逐层组装出 Tensor Core 加速的高效 GEMM 内核。可以说,CUTLASS 是 NVIDIA GPU 高性能计算内核的”零件工厂”。
3 分钟产业解释
为什么 CUTLASS 重要?
在 AI 推理/训练的算力栈中,矩阵乘法(GEMM / GEMV)占据了绝大部分计算量。NVIDIA 自家的 cuBLAS 是闭源黑盒,无法定制。当产业界需要:
- 针对特定精度(FP8、INT4、FP4 等新格式)快速适配 GEMM 内核;
- 针对特定算子融合(GEMM + bias + activation)优化;
- 针对非标准矩阵形状(如 MoE 中稀疏专家的小 batch GEMM)定制调度;
就需要在 cuBLAS 之下的层级进行编程。CUTLASS 正是这个层级的标准工具。
产业位置
┌──────────────────────────────────────────┐
│ 应用层: PyTorch / TensorFlow / JAX │
├──────────────────────────────────────────┤
│ 框架层: cuDNN / cuBLAS / TensorRT │ ← NVIDIA 官方闭源库
├──────────────────────────────────────────┤
│ 内核库层: CUTLASS / Triton / FlashAttention │ ← 开源,可定制
├──────────────────────────────────────────┤
│ 编程层: CUDA C++ / PTX │
├──────────────────────────────────────────┤
│ 硬件层: SM / Tensor Core / TMA │
└──────────────────────────────────────────┘
关键洞见:FlashAttention、FlashDecoding、各种 FP8 GEMM kernel、乃至 NVIDIA TensorRT 内部的部分内核,其底层都大量复用了 CUTLASS 的构建模块。它实质上是 NVIDIA GPU 上高性能线性代数内核的”标准零件库”。
15 分钟专家深入
一、设计哲学:分层可组合(Hierarchical Composability)
CUTLASS 的核心设计理念是将 GPU GEMM 的计算映射到存储层次结构的每一层,每一层提供模板化的构建块:
| 层级 | 对应硬件 | CUTLASS 构建块(2.x 术语) | 职责 |
|---|---|---|---|
| 线程级 (Thread) | 寄存器文件 | Mma::Operator | 一条指令完成的小矩阵乘(映射到 Tensor Core 指令) |
| Warp 级 (Warp) | 寄存器 + warp 内同步 | Mma::Policy 的 warp tile | 组织多个线程级 operator,形成 warp 级 tile |
| CTA 级 (CTA / Threadblock) | 共享显存 (SMEM) | Mma::Base / Epilogue | 从全局显存加载 tile 到 SMEM,执行 warp 级 MMA,写回结果 |
| Device 级 (Device) | 全局显存 | Gemm::Device / 隐式 grid 调度 | 将整个矩阵分 tile,调度多个 CTA 并行执行 |
每个层级都可以被替换——你可以换一种数据加载策略、换一种 epilogue 融合、换一种 tile 调度,而不需要重写整个内核。这就是”可组合”的含义。
二、CUTLASS 2.x vs 3.x(CuTe)
| 维度 | CUTLASS 2.x | CUTLASS 3.x(含 CuTe) |
|---|---|---|
| 布局抽象 | 基于预定义的 Layout 模板(RowMajor / ColumnMajor 等) | CuTe 张量布局代数:用 layout algebra 组合描述任意数据排列 |
| 编程风格 | 较重的模板嵌套,“选型”式配置 | 更轻量的 composable 式编程,layout + algorithm 解耦 |
| Hopper 特性支持 | 有限 | 完整支持:TMA、warpgroup MMA、cluster scheduling |
| 代码量 | 相对成熟稳定 | CuTe 组件引入后,内核代码量显著缩减(社区反馈约缩减 30-50%)[社区经验估算] |
| 代表版本 | CUTLASS 2.x(约 2020-2022) | CUTLASS 3.x(约 2023 起) |
CuTe (CUDA Templates) 是 CUTLASS 3.x 中引入的布局代数核心。它把 GPU 上的张量数据布局抽象为数学上的 layout function(offset → coordinate 映射),支持 layout 的 composition、complement、divide 等代数运算,使得开发者可以用极少量代码描述复杂的数据搬运与分块逻辑。
三、关键内核流程(以 GEMM C = A × B 为例)
┌─────────────────────────────────────────────────────────┐
│ Device-level Grid │
│ 将 M×K (A) 和 K×N (B) 分成多个 tile │
│ 每个 CTA 负责一个 M_tile × N_tile 的输出 tile │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ CTA / Threadblock │ │
│ │ │ │
│ │ 1. Prologue: 从 Global → SMEM 加载 A_tile, B_tile│ │
│ │ (Ampere+: cp.async; Hopper+: TMA) │ │
│ │ │ │
│ │ 2. Mainloop: 沿 K 维度迭代 │ │
│ │ ┌──────────────────────────────────────┐ │ │
│ │ │ * Ampere及之前: │ │ │
│ │ │ SMEM → Registers (ldmatrix) │ │ │
│ │ │ Tensor Core MMA (mma.sync) │ │ │
│ │ │ * Hopper+: │ │ │
│ │ │ SMEM 直接由 wgmma 指令读取 │ │ │
│ │ │ 累加到寄存器中的 accumulator │ │ │
│ │ │ 预取下一轮 tile 到 SMEM (double buffer)│ │ │
│ │ └──────────────────────────────────────┘ │ │
│ │ │ │
│ │ 3. Epilogue: 寄存器 → Global 写回 │ │
│ │ 可融合 bias、activation、type conversion 等 │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
关键优化手段:
- Double/Triple Buffering:SMEM 加载与计算重叠,隐藏全局显存延迟。
- cp.async(Ampere+):异步拷贝,绕过寄存器直达 SMEM。
- TMA(Hopper+):硬件张量内存加速器,自动处理多维 tile 的地址计算与异步搬运。
- Warpgroup MMA(Hopper+):4 个 warp 协作执行一条 wgmma 指令,输出更大的 tile。
- Cluster-level Scheduling(Hopper+):CTA Cluster 内共享 SMEM,实现跨 CTA 数据复用。
四、支持的数据类型与 Tensor Core 映射
| 数据类型 | 首次支持的 GPU 架构 | Tensor Core 指令族 | 备注 |
|---|---|---|---|
| FP16 (FP16×FP16→FP32) | Volta (SM70) | mma.sync | 最成熟路径 |
| BF16 | Ampere (SM80) | mma.sync | |
| TF32 | Ampere (SM80) | mma.sync | FP32 输入截断为 19-bit |
| INT8 | Turing (SM75) | mma.sync | 推理量化常用 |
| INT4 | Turing (SM75) | mma.sync | CUTLASS 2.0 已支持 |
| FP8 (E4M3 / E5M2) | Hopper (SM90) | wgmma | 训练+推理关键精度 |
| FP4(实验性) | Blackwell (SM100) | wgmma / 未充分公开 | CUTLASS 3.x 逐步适配 |
以上”首次支持”指 CUTLASS 库中的适配情况,与 NVIDIA GPU 硬件 Tensor Core 指令首次出现的代际一致,但具体版本号以 [NVIDIA CUTLASS GitHub Release Notes] 为准。
五、CUTLASS 3.x 在 Hopper(SM90)上的关键特性
- TMA(Tensor Memory Accelerator):硬件单元,通过描述符(descriptor)一次配置即可异步搬运任意多维 tile,取代 Ampere 时代软件循环 cp.async。
- wgmma(Warpgroup MMA):一条指令让 4 个 warp(128 线程)协作完成一个大 tile 矩阵乘,输出 tile 尺寸可达 64×256(取决于数据类型)。
- Distributed Shared Memory(DSMEM):Cluster 内 CTA 可直接读取彼此的 SMEM,无需经过全局显存,用于减少数据搬运。
- 异步流水线(Async Pipeline):硬件级 barrier 支持 TMA load → MMA compute → epilogue store 的多级流水线完全异步执行。
技术原理(最深)
核心机制:Threadblock / CTA Tile 的计算-访存映射
CUTLASS 内核设计的核心问题是:如何将一个 M×N×K 的 GEMM 映射到 GPU 的存储层次,使得 Tensor Core 始终有数据可算。
Tile 分解示意
矩阵 A: M × K 矩阵 B: K × N
┌────┬────┬────┐ ┌────┬────┐
│ T00│ T01│ T02│ │ T00│ T01│
├────┼────┼────┤ ├────┼────┤
│ T10│ T11│ T12│ │ T10│ T11│
├────┼────┼────┤ ├────┼────┤
│ T20│ T21│ T22│ │ T20│ T21│
└────┴────┴────┘ └────┴────┘
每个 tile: M_tile × K_tile 每个 tile: K_tile × N_tile
CTA (i,j) 负责输出 tile C[i][j] = Σ_k A[i][k] × B[k][j]
沿 K 维度累加, 每次加载一对 (A_tile, B_tile)
Warp 级 Tile 与线程级 Tile
在一个 CTA 内部,warp tile 和 thread tile 进一步细分:
CTA tile (例: 128×256×32, 以 FP16 为例)
├── Warp tile 0 (64×64×32) [4 个 warp]
├── Warp tile 1
├── Warp tile 2
└── Warp tile 3
每个 warp tile 由多个线程级 operator 组成
线程级 operator 映射到 Tensor Core mma.sync 指令
(如 m16n8k16 for FP16 on Ampere)
关键参数选择的影响
| 参数 | 增大效果 | 减小效果 | 约束 |
|---|---|---|---|
| CTA Tile M/N | 更高计算/访存比(算术强度↑) | SMEM 占用↓,可并行 CTA 数↑ | 受 SMEM 容量限制 |
| CTA Tile K | 每轮迭代数据复用↑ | SMEM 占用↑ | 受 SMEM 容量限制 |
| Warp Tile | 减少 warp 间同步 | 单 warp 寄存器压力↑ | 受寄存器文件大小限制 |
| Stages(流水线深度) | 更好隐藏内存延迟 | SMEM 占用↑ | 受 SMEM 容量限制 |
“Arithmetic Intensity”(算术强度) 是 GEMM 性能的核心衡量:
Arithmetic Intensity = 2×M×N×K / (数据搬运字节数)
理想 GEMM: 接近 2×M×N×K / ((M×K + K×N + M×N) × bytes_per_element)
当 M,N 足够大时趋近于计算/带宽比
当算术强度 > GPU 的 FLOPS/Bandwidth 比时,GEMM 为 compute-bound;否则为 memory-bound。CUTLASS 的 tile 选择与 double buffering 策略就是为了尽可能将内核保持在 compute-bound 区域。
Hopper wgmma 指令的微架构细节
wgmma.mma_async.sync.aligned.m64nNk{16,32}.f16.f16 ...
- 执行 warp: 4 个 warp (warpgroup, 128 线程)
- 操作数来源: SMEM(A 和 B 均可直接从 SMEM 读取)
- 输出: 寄存器(distributed across warpgroup)
- 异步执行: 发射后可继续执行后续指令,通过 barrier 同步
- 关键优势: 不再需要 ldmatrix 将 A/B 从 SMEM 装入寄存器再做 MMA
→ 直接从 SMEM 读操作数,减少寄存器压力
这就是 CUTLASS 3.x Hopper 内核能实现更大 tile、更少寄存器溢出的硬件基础。
技术演进史
| 时间 | 版本/事件 | 关键里程碑 |
|---|---|---|
| 2017-2018 | CUTLASS 1.0 | 首次开源,Volta Tensor Core 支持(FP16),基础 GEMM 模板 |
| 2019 | CUTLASS 2.0 | 重大重构,支持 Turing INT8/INT4,引入 epilogue 融合 |
| 2020-2021 | CUTLASS 2.x 逐步成熟 | 陆续加入 Ampere BF16/TF32/INT8 支持,cp.async 支持;社区广泛采用,FlashAttention v1 首版使用 CUTLASS 构建块 |
| 2023 | CUTLASS 3.0 + CuTe | 全新布局代数,Hopper SM90 完整支持(TMA、wgmma、cluster) |
| 2023-2024 | CUTLASS 3.x 持续迭代 | FP8 GEMM 模板成熟,Blackwell SM100 初步适配,Grouped GEMM 优化 |
| 2024-2025 | 社区生态爆发 | FlashAttention-3、各种 FP8 推理引擎、MoE 内核均基于 CUTLASS 3.x |
具体版本号时间线以 [NVIDIA/cutlass GitHub releases] 为准,上表为近似标注。
技术路线对比(量化表)
| 维度 | CUTLASS | cuBLAS(闭源) | Triton(OpenAI) | 手写 CUDA/PTX |
|---|---|---|---|---|
| 编程抽象级别 | 中(C++ 模板) | 低(API 调用) | 中高(DSL) | 最低 |
| 可定制性 | ⭐⭐⭐⭐⭐ | ⭐(黑盒) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 峰值性能 | 接近 cuBLAS(部分场景持平或超越) | ⭐⭐⭐⭐⭐ 基准线 | 通常 80-95% cuBLAS [社区基准估算] | 取决于开发者水平 |
| 开发效率 | 中等(模板元编程学习曲线陡峭) | 高(一行 API) | 高(Python 级别) | 最低 |
| 新硬件适配速度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐(依赖后端) | ⭐⭐⭐⭐⭐ |
| Tensor Core 利用 | 完整控制 | 完整但不透明 | 通过后端映射,控制力有限 | 完整控制 |
| 生态规模 | 大(GitHub 数千 star) | 最大(NVIDIA 官方) | 大且快速增长 | 分散 |
| 典型使用者 | FlashAttention、TensorRT 内核开发者 | 一般用户 | 研究者、快速原型 | 极少数专家 |
| 开源 | ✅ BSD 3-Clause | ❌ | ✅ MIT | N/A |
关键判断:
- 极致性能 + 可定制 → CUTLASS
- 快速原型 + Python 生态 → Triton
- 不想折腾 → cuBLAS/cuDNN
- CUTLASS 与 Triton 并非完全竞争:Triton 后端可生成 CUTLASS 风格的内核,两者生态互补。
上下游
上游(CUTLASS 依赖什么)
硬件:
NVIDIA GPU (Volta/Turing/Ampere/Hopper/Blackwell)
└── Tensor Core 指令集 (mma.sync / wgmma / ...)
└── SMEM / 寄存器文件 / TMA 硬件单元
软件:
CUDA Toolkit (nvcc / nvrtc / PTX)
C++ 模板元编程 (C++17 标准)
cmake 构建系统
下游(谁在用 CUTLASS)
直接消费者:
├── FlashAttention 系列 (Tri Dao) ← 使用 CUTLASS 构建块实现 fused attention
├── NVIDIA TensorRT (部分内核) ← [NVIDIA 未充分公开具体比例]
├── xFormers (Meta)
├── vLLM / SGLang 等推理引擎 ← 通过 FlashAttention 间接依赖
├── 各种 FP8/INT4 量化内核 ← 社区开源项目广泛使用
└── 各大 AI 芯片公司对标参考 ← 软件栈 benchmark baseline
间接消费者:
PyTorch / JAX 用户 → 通过上述框架间接使用 CUTLASS 内核
关键指标
| 指标 | 说明 | 参考量级 |
|---|---|---|
| GEMM 效率 | 实际 TFLOPS / 硬件峰值 TFLOPS | 高手优化后可达 80-95%+ [取决于矩阵形状和精度] |
| SMEM 占用 | 单 CTA 使用的共享显存量 | 典型 48KB-228KB(取决于 tile size 和 stages) |
| 寄存器压力 | 每线程寄存器数 | 受限于 255 reg/thread(默认),可通过 maxrregcount 调节 |
| Occupancy | SM 上活跃 warp / 最大 warp 比 | CUTLASS 可精细调控,典型 50-100% |
| 支持的矩阵形状 | M, N, K 范围 | 从极小(如 MoE 的 M=1 token batch)到极大(数十万维度)均有优化路径 |
| 模板编译时间 | CUTLASS 内核的编译耗时 | 较长(分钟级),这是 C++ 模板元编程的固有代价 |
| 编译产物大小 | 单内核 PTX/SASS 大小 | 取决于 tile 配置,通常数十 KB |
供需与市场数据
CUTLASS 本身的”市场”
CUTLASS 是开源免费工具库,没有直接的商业营收。但其产业影响力体现在:
-
NVIDIA 生态护城河:CUTLASS 深度绑定 NVIDIA GPU 指令集(Tensor Core ISA),竞争对手(AMD ROCm / Intel oneAPI)需要类似工具但缺乏同等成熟度的开源替代品。AMD 的 composable_kernel (CK) 是类比项目,但社区采用度和生态成熟度与 CUTLASS 有差距 [定性判断]。
-
间接影响的市场体量:全球 AI 推理/训练市场中,绝大多数工作负载运行在 NVIDIA GPU 上。CUTLASS 作为底层内核基础设施,其优化直接影响每 FLOP 的实际吞吐。保守估算,基于 NVIDIA GPU 的 AI 计算市场年规模在 [数百亿美元级别,具体参考 NVIDIA Data Center 财报],CUTLASS 的性能优化间接影响该市场中 GEMM 密集型工作负载的效率。
人才供需
- CUTLASS 开发者极度稀缺:需要同时精通 CUDA 编程、GPU 微架构、C++ 模板元编程、线性代数算法。全球能独立编写 CUTLASS 级别内核的工程师估计在 [千人量级,定性估算]。
- 薪资溢价:具备 CUTLASS 经验的工程师在 AI 基础设施领域的薪资通常显著高于一般 CUDA 开发者 [行业经验估算]。
代表公司与资本映射
| 维度 | 代表 | 说明 |
|---|---|---|
| 核心开发方 | NVIDIA (NVDA) | CUTLASS 由 NVIDIA 硬件团队维护,是其 CUDA 生态的关键组成部分 |
| 重度使用者 — 大厂 | Meta (META)、Google (GOOGL)、Microsoft (MSFT) | 内部推理优化团队广泛使用 CUTLASS 定制内核 |
| 重度使用者 — 推理创业 | xAI、Together AI、Anyscale 等 | 使用/定制 CUTLASS 内核优化推理吞吐 |
| 开源 AI 推理框架 | vLLM、SGLang、TensorRT-LLM | 间接依赖 CUTLASS(通过 FlashAttention 等) |
| 竞争对标 | AMD (AMD) composable_kernel | AMD 的类比方案,生态成熟度较低 |
| 竞争对标 | OpenAI Triton | 更高层抽象的 DSL 路线,与 CUTLASS 互补 |
投资含义:
- CUTLASS 强化了 NVIDIA CUDA 生态的开发者锁定效应——当整个高性能内核生态都基于 CUTLASS 构建,切换到其他硬件平台的成本极高。
- 这种”软生态壁垒”与 CUDA 的硬件指令集优势叠加,构成 NVIDIA 在 AI 算力市场最深的护城河之一。
投资逻辑
核心论点
-
CUTLASS 是 NVIDIA AI 生态软壁垒的重要组成部分:不是直接盈利产品,但它使得 NVIDIA GPU 上的高性能计算形成了”标准零件”生态,极大地增加了替代成本。
-
新精度格式(FP8/FP4)的快速适配能力是竞争武器:每当 NVIDIA 推出支持新数据类型的硬件(如 Hopper FP8、Blackwell FP4),CUTLASS 通常能快速提供高质量的 GEMM 内核模板,使得整个软件栈能迅速跟进,而竞争对手需要更长时间适配。
-
MoE(Mixture of Experts)等新架构对 GEMM 内核的新需求:MoE 推理涉及大量小 batch GEMM + routing 逻辑,Grouped GEMM 等 CUTLASS 特性正好满足此类需求。随着 MoE 成为大模型主流架构,CUTLASS 的 Grouped GEMM 能力愈发关键。
风险
- Triton 的崛起:如果 Triton 在更多场景下能自动达到 CUTLASS 水平的性能,开发者可能转向更易用的 DSL,削弱 CUTLASS 的直接影响力(但此时 Triton 的后端可能仍然产出类似 CUTLASS 风格的内核)。
- AMD composable_kernel 的追赶:如果 AMD 硬件在性价比上具备竞争力且 CK 生态成熟,部分用户可能迁移。
常见误读纠偏
误读 1:「CUTLASS 就是开源版 cuBLAS」
纠偏:两者层级不同。
- cuBLAS 是面向用户的应用级库——你调用
cublasGemmEx(),得到结果,不关心内部实现。 - CUTLASS 是面向内核开发者的零件库——你用它组装出 GEMM 内核,可以精确控制 tile 大小、数据搬运策略、epilogue 融合逻辑等。
- cuBLAS 的部分内核实现可能确实使用了 CUTLASS 组件 [NVIDIA 未充分公开具体比例],但两者不是等价关系。把 CUTLASS 比作”乐高积木”,cuBLAS 比作”用乐高搭好的成品车”更准确。
误读 2:「CUTLASS 性能不如 cuBLAS」
纠偏:在充分调优的场景下,CUTLASS 内核可以达到甚至超越 cuBLAS 的性能——因为它给了开发者更多的优化自由度(如自定义 epilogue 融合可以省去额外 kernel launch)。但”开箱即用”性能取决于开发者水平,cuBLAS 对常见形状的自动调优(auto-tuning)更成熟。结论:CUTLASS 的理论性能上限 ≥ cuBLAS,但实际性能下限取决于使用者。
误读 3:「CUTLASS 只支持 GEMM」
纠偏:CUTLASS 同样支持 卷积(Conv2d/Conv3d)、Grouped GEMM、Ranked K Reduction 等操作。但 GEMM 确实是最核心和最成熟的部分,社区使用中 GEMM 相关内核占绝大多数。
误读 4:「CUTLASS 和 Triton 是竞争关系,二选一」
纠偏:两者互补大于竞争。
- Triton 擅长快速原型和Python 级别的自动内核生成;
- CUTLASS 擅长极致性能调优和硬件特性深度利用;
- 实际项目中,常见策略是用 Triton 快速实现,对性能关键路径的内核用 CUTLASS 重写。
- Triton 的后端在某些场景下也可能生成类似 CUTLASS 模式的 PTX 指令序列。
学习路径
入门(1-2 周)
- 阅读 NVIDIA CUTLASS GitHub Wiki 的 [Quick Start] 和 [Key Abstractions] 文档
- 跑通 CUTLASS 示例目录中的
00_basic_gemm,理解 tile 配置 - 对比同一 GEMM 用 cuBLAS vs CUTLASS 的代码量和可调参数差异
进阶(1-3 月)
- 学习 CUTLASS 2.x 的
Gemm::Device→Gemm::Kernel层级,理解 threadblock tile 选择 - 阅读 CUTLASS Profiler 文档,理解不同 tile 配置的性能差异
- 研究 FlashAttention 源码中如何使用 CUTLASS 构建块
专家(3-6 月+)
- 学习 CuTe 布局代数(Layout Algebra),理解
Layout::compose、Layout::complement等操作 - 研究 CUTLASS 3.x Hopper 内核(
SM90_64x128x32_F16...系列),理解 TMA + wgmma 流水线 - 尝试编写自定义 Epilogue(如 GEMM + LayerNorm 融合)
- 对比 CUTLASS 与 AMD composable_kernel 的设计理念差异
推荐资源
- 代码仓库:
github.com/NVIDIA/cutlass(含大量 example 和 profiler) - 博客:NVIDIA Developer Blog 上的 CUTLASS 系列文章
- 演讲:GTC 相关 session(搜索”CUTLASS”或”CuTe”)
- 论文:CUTLASS 团队在相关学术会议上的技术报告(如有)
一句话总结
CUTLASS 是 NVIDIA GPU 上高性能线性代数内核的”标准零件库”——分层可组合、硬件深度绑定、开源可定制,构成 NVIDIA AI 算力生态的重要软件护城河。