Arganzheng's Blog

stay hungry, stay foolish

GPU Kernel 工程(06):Tensor Core、CUTLASS 与 CuTe

Tensor Cores, CUTLASS and CuTe: Programming the Matrix Units

上一篇用 CUDA Core 把 GEMM 的分块结构讲透了。回顾一下那个结构,因为本篇要做的事情就是把它”接”到另一种计算单元上: 一个 thread block 负责输出矩阵 \(C\) 的一个 \(BM \times BN\) 的 tile,沿 \(K\) 维以 \(BK\) 为步长循环; 每一步把 \(A\) 的 \(BM \times BK\) 子块和 \(B\) 的 \(BK \times BN\) 子块搬进 shared memory,全局读取量从 naive 的 \(2MNK\) 个元素降为 \(MNK \cdot (1/BM + 1/BN)\),\(BM = BN = 128\) 时减少 128 倍(\(2 / (2/128)\)); ...

GPU Kernel 工程(05):GEMM——从 naive 到分块

GEMM from Naive to Tiled: Reaching the Compute Ceiling on CUDA Cores

前四篇讨论的 kernel——elementwise、reduction、softmax、LayerNorm——有一个共同点:它们都是 memory-bound 的。每个元素读进来、算一两次、写回去,算术强度远低于 ridge point,优化的全部目标是”把 HBM 带宽用满”。做到了带宽的 80–90%,这类 kernel 就到头了。 GEMM 是这个系列的转折点。一个 4096×4096×4096 的矩阵乘法有 1374 亿次浮点运算,但三个矩阵合计只有 192 MiB(FP32)。它的算术强度是 elementwise 的几千倍,理论上应该被算力而不是带宽限制。但一个不加思考写出来的 GEMM kernel,跑出来的却是 FP32 峰值的百分之一二——它被...

GPU Kernel 工程(04):共享内存与 reduction——softmax、LayerNorm 与 online softmax

Shared Memory and Reductions: Softmax, LayerNorm and Online Softmax

上一篇的 elementwise kernel 有一个共同特征:每个线程只管自己的元素,线程之间不需要说话。把访存合并、向量化、grid-stride 做对,带宽就能推到 90% 以上。 这一篇进入需要线程协作的 kernel。RMSNorm 要先知道整行的均方才能缩放每个元素;softmax 要先知道整行的最大值和指数和才能归一化每个元素。”先算出一个整行的标量,再用它处理每个元素”——这个模式叫 reduction,它是所有 norm、softmax、loss、统计类算子的核心,也是 FlashAttention 内循环的一半。 总纲给这一篇的核心问题是: 一个 4096 维的 RMSNorm,读一次写一次,理论上是 memory-bound 的。为...

GPU Kernel 工程(03):访存合并与 elementwise kernel

Memory Coalescing and Elementwise Kernels: Hitting the Bandwidth Ceiling

上一篇写出了第一个 kernel:一个 BF16 的 y = x + b,每个线程处理一个元素。它能跑、结果正确,但没有回答”它跑得够快吗”。这一篇就回答这个问题,并把答案推到极限。 先把理论下界放在最前面,后面所有讨论都对着它算。BF16 的 y = x + b 对每个元素读 2 个 BF16、写 1 个 BF16,共 6 字节,做 1 次加法(1 FLOP): \[\text{算术强度} = \frac{1\ \text{FLOP}}{6\ \text{B}} \approx 0.17\ \text{FLOP/B}\] A100 SXM 80GB 的 HBM2e 带宽约 2.0 TB/s,BF16 Tensor Core 约 312 TFLOPS(均为公开...

GPU Kernel 工程(02):CUDA 编程模型与第一个 kernel

The CUDA Programming Model and Your First Kernel, Measured

上一篇建立了本系列的分析框架,用到的结论可以压缩成三个数字。GPU 的基本执行单位是 warp:32 个线程共用一个指令流,一条指令同时作用在 32 个数据上。以 A100 SXM 80GB 为默认分析对象(标称值):HBM2e 带宽约 2.0 TB/s,BF16 Tensor Core 算力 312 TFLOPS,两者相除得到 Roofline 的拐点(ridge point): \[\text{ridge} = \frac{312 \times 10^{12}\ \text{FLOP/s}}{2.0 \times 10^{12}\ \text{byte/s}} \approx 156\ \text{FLOP/byte}\] 算术强度低于 156 FLOP/b...

GPU Kernel 工程(01):GPU 为什么这样设计——硬件结构与 Roofline

Why GPUs Look the Way They Do: Architecture and the Roofline Model

这个系列要回答的问题是:一个 kernel 为什么快、为什么慢,以及如何把它写到接近硬件极限。要谈”极限”,先得知道极限在哪里。所以第一篇不写、也不运行任何完整的 kernel,只做一件事:把一块 GPU 拆开,看清它由什么组成、硬件如何把工作切成 warp 和 block 放到 SM 上、每个部分能以多快的速度搬数据和做乘加,然后把这些数字装进一个足够简单、又足够有用的模型——Roofline——用它回答: 在一块给定的 GPU 上,一段计算理论上最快能多快?1 有了这个答案,后面每一篇的工作就有了明确的目标:elementwise kernel 的目标是把 HBM 带宽吃满;GEMM 的目标是把 Tensor Core 吃满;attention 的目...

GPU Kernel 工程:从 CUDA 执行模型到 FlashAttention(总纲)

GPU Kernel Engineering, from the CUDA Execution Model to FlashAttention

内容简介 《GPU Kernel 工程:从 CUDA 执行模型到 FlashAttention》是一组共十篇的系列文章,面向已经理解 PyTorch 运行时、准备向下进入 GPU 执行层的工程师,系统讲解如何读懂、写出和优化运行在 GPU 上的 kernel。 它回答的问题是: 一个 kernel 为什么快、为什么慢,以及如何把它写到接近硬件极限?1 站在框架和推理系统的层面看,kernel 始终是一个黑盒:Profiler 告诉你”这个算子是 memory-bound 的”,论文告诉你”FlashAttention 把 HBM 流量压下去了”,推理引擎的文档告诉你”用了 PagedAttention 所以显存碎片少了”。这些结论是对的,但它们都建立...

多模态(10):系列总结与通关自测

Multimodal Models: Series Recap and Final Self-Test

九篇正文回答了两个问题:图片、视频、语音怎么进入一个语言模型,以及图像与视频的生成为什么是另一套数学。前五篇是理解线——编码器学到什么、几百个向量怎么进 LLM、训练分几个阶段、声音怎么变成 token、怎么听与说;第六到八篇是生成线——去噪为什么等于学分布、三种视角为什么是同一件事、怎么把这套数学变成 SD / FLUX;第九篇是交汇——图像能不能像文本一样 token 化后自回归地生成,理解与生成能不能用一个模型。 本文不讲新内容,做三件事:把九篇压成一张表与九段回顾,把贯穿九篇的几条线拎出来,然后给一套三段式的通关自测——判断与计算、跨篇综合、面试题。各篇末尾的自测检验的是”这一篇读懂了没有”,这里检验的是”九篇能不能连起来用”。第九篇末尾的”系列总结”一节...

多模态(09):自回归图像生成与统一模型

Autoregressive Image Generation and Unified Understanding-Generation Models

两条线在这里交汇。理解线把图片编码成连续向量送进 LLM;生成线从噪声出发去噪。中间有一条被绕过的路:把图片像文本一样离散化成 token,然后用 LLM 的方式——next-token prediction——生成它。这条路在 2021 年的 DALL-E(第一代)与 VQGAN 上就走通了,之后被扩散模型的质量压过;2024 年因为两个原因回来:一是 LLM 的 scaling 与基础设施太成熟,”把一切变成 token 然后用同一个 Transformer”的诱惑太大;二是统一模型——一个模型既理解图片又生成图片——需要生成侧能与 LLM 共享结构,而扩散是另一套。 自回归图像生成的第一个问题是怎么离散化:VQ-VAE 的码本、它的坍缩问题、无码本的 FSQ...

多模态(08):Latent diffusion、DiT 与文生图配方

Latent Diffusion, DiT and How Text-to-Image Models Are Built

前两篇的数学在二维点云和 \(32^2\) 的 CIFAR 上就能跑;要生成 \(1024^2\) 的图,中间隔着三个工程决定。在哪个空间做扩散——像素空间的 \(1024 \times 1024 \times 3\) 太大,Latent Diffusion 先用一个 VAE 把图压到 \(128 \times 128 \times 4\)(或 16 通道),扩散在 latent 上做,48 倍的压缩让训练与采样都进入可行区间。用什么网络——2022 年是 U-Net,2023 年 DiT 证明 Transformer 在扩散上同样遵循 scaling law,2024 年 SD3 与 FLUX 用 MMDiT 让文本与图像 token 在同一个 Transform...

×