Arganzheng's Blog

stay hungry, stay foolish

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...

多模态(07):扩散模型(下):score matching、flow matching 与 classifier-free guidance

Diffusion II: Score Matching, Flow Matching, Noise Schedules, and Classifier-Free Guidance

上篇用 DDPM 的语言把扩散模型讲了一遍:加噪、猜噪声、逐步去噪、DDIM 跳步。这一篇讲另外两种看同一件事的方式——score matching(网络学的其实是”概率密度上升最快的方向”)与 flow matching(网络学的是”从噪声到数据的速度场”,SD3 与 FLUX 用的就是它)——它们的推导与记号完全不同,读起来像三个东西,实际上训练的是同一个网络、只是参数化不同;看清它们在哪一步汇合,读任何一篇扩散论文都不会再迷路。然后讲两个所有文生图模型都依赖的技术:噪声调度(哪些噪声水平该多学)与 classifier-free guidance(\(w = 7.5\) 到底在做什么)。 全篇继续用上篇那个二维的两个月牙 toy:分数场可以画成箭头图、flo...

多模态(06):扩散模型(上):DDPM——加噪、去噪与「预测噪声」

Diffusion I: DDPM — Forward Noising, Reverse Denoising, the ELBO, and DDIM

生成线的数学从这里开始。语言模型的生成是”下一个 token 的分类”——目标函数是交叉熵,采样是逐个 token;图像生成走了另一条路:从纯噪声出发,一步步去噪,几十步后得到一张图。这条路在 2020 年由 DDPM 确立、2021 年被 score-based SDE 统一、2023 年被 flow matching 简化,三种视角各有一套推导与记号,读起来像三个不同的东西——实际上它们训练的是同一个网络、只是参数化不同。 扩散模型分上下两篇。上篇(本篇)只讲 DDPM——最早、也最容易从零看懂的那个视角:怎么把一张图一步步加噪成纯噪声(前向),怎么训一个网络把噪声一步步去掉(反向),为什么训练目标最后化简成”猜出加进去的噪声”这么一句话,以及 DDIM 怎么...

×