Arganzheng's Blog

stay hungry, stay foolish

Transformer 与 LLM(01):Transformer 解剖与参数量

Transformer Anatomy and Parameter Count: From config.json to 8.03B

本文是《Transformer 与 LLM:结构、算量与数值》系列的第 1 篇(共七篇)。下一篇:前向的算量与访存量 做推理系统、训练基础设施或 kernel 的工程师,迟早会被问到这样的问题:这个模型有多少参数?一张 80 GB 的卡放得下吗?某个 GEMM 的 \(m, k, n\) 是多少?为什么 Llama 的 FFN 中间维度是 14336 这样一个看起来不整的数?这些问题的答案全部藏在一个几十行的 config.json 里,不需要下载权重,也不需要运行代码。 本篇要建立的是整个系列的分析对象:一个 decoder-only Transformer 里到底有哪些矩阵、每个矩阵的形状由哪个超参数决定、把它们加起来等于多少。它不讲 attenti...

Transformer 与 LLM:结构、算量与数值(总纲)

Transformers and LLMs for Infrastructure Engineers: Architecture, Arithmetic and Numerics

内容简介 《Transformer 与 LLM:结构、算量与数值》是一组共七篇的系列文章,面向不训练模型、但要为模型搭建训练与推理系统的工程师,以及想知道自己的模型在硬件上”花多少钱”的算法工程师。它讲的是大语言模型的成本结构:每一层做多少次乘加、读多少字节、存多少状态,这些数字由哪些超参数决定,以及各种结构上和数值上的改动如何改变这些数字。 它回答的问题是: Infra 工程师不训练模型,但必须知道自己在优化什么:这个模型的每一步算多少、读多少、存多少? Infra 工作的绝大多数决策——一张卡能不能放下这个模型、批要开到多大、KV cache 该留多少显存、量化到 INT4 能快多少、投机解码值不值得开、要不要为 MoE 上专家并行——答案都不在...

PyTorch 深度实践(10):PyTorch 的工程体系——一次改动如何安全地到达用户

The Engineering System of PyTorch: How a Change Travels Safely from Commit to Production

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第十篇(共十篇)。上一篇:分布式 PyTorch 前九篇讲的是 PyTorch 是什么、怎么运行:Tensor 怎么存、Autograd 怎么记、算子怎么分发、Kernel 怎么写、编译器怎么融合、性能怎么测、多卡怎么通信。每一篇都在描述一个已经存在、并且正确运行的系统。 这一篇换一个问题:它是怎么做到一直正确、一直可用的? PyTorch 有两千多个算子、每个算子有十几种 dtype、两个以上后端、无数种 shape 和 stride 组合,还要在 eager、torch.compile、Meta、Autograd、分布式等模式下行为一致。每天有几十个 PR 合入主干,每个 ...

PyTorch 深度实践(09):分布式 PyTorch

Distributed Training in PyTorch: Collectives, DDP, FSDP, TP, PP, CP and EP

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第九篇(共十篇)。上一篇:性能优化与调试 下一篇:PyTorch 的工程体系:一次改动如何安全地到达用户 前八篇都在一张卡上。第八篇末尾算过一笔账:Adam 训练下每个参数的静态显存是 16 字节,7B 参数的模型仅参数、梯度和优化器状态就要 112 GB,激活值还没算。一张 80 GB 的卡放不下。即使放得下,第八篇案例里那个 38M 参数的小模型在单卡上跑到 2207 samples/s 之后,GPU 已经饱和——再要快,只能加卡。 这一篇回答加卡之后的问题: 当一张卡放不下模型或跑不完数据时,PyTorch 如何把计算和状态切分到多个设备,并让通信与计算重叠? ...

PyTorch 深度实践(08):性能优化与调试

Performance Optimization and Debugging in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第八篇(共十篇)。上一篇:编译执行与图优化 下一篇:分布式 PyTorch 前面七篇建立了 PyTorch 的执行模型:Tensor 如何存储(第二篇),Autograd 如何记录反向(第三篇),算子如何分发到 Kernel(第五篇),编译器如何把多个算子融合成更少的 Kernel(第七篇)。每一篇都在某处留下一句”性能问题第八篇讨论”。 这一篇兑现这些承诺。它围绕一个问题展开: 如何判断一个 PyTorch 程序慢,以及如何定位它为什么慢? 这个问题比”如何让它变快”更基础。AI-Infra 工作中大量的性能优化失败,不是因为不知道优化手段,而是因为没有正确地测量,...

PyTorch 深度实践(07):编译执行与图优化

Compilation and Graph Optimization in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第七篇(共十篇)。上一篇:C++ 扩展与自定义算子 下一篇:性能优化与调试 前两篇讨论的是单个算子:第五篇解释一次 torch.add 调用如何经过入口、分发、执行;第六篇把一个自定义算子接入了同样的路径。无论原生还是自定义,每个算子都是独立走完这条路的。 这一篇把视角从单个算子拉远到一段程序。当我们写下: def f(x, weight, bias): y = x @ weight + bias if x.shape[0] > 64: return torch.relu(y) return torch.tanh(y) compi...

PyTorch 深度实践(06):C++ 扩展与自定义算子

C++ Extensions and Custom Operators in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第六篇(共十篇)。上一篇:Dispatcher 与算子系统 下一篇:编译执行与图优化 上一篇把算子系统拆成两个维度:开发者在构建时定义 → 注册 → 实现,用户在运行时入口 → 分发 → 执行,两者通过 Operator Table 交汇。那一篇站在使用者的角度观察原生算子 add。 这一篇换到开发者的位置:自己写一个算子,把它接入 PyTorch 的算子系统。 这是从“阅读框架”走向“扩展框架”的关键一步。AI-Infra 工作中大量的实际需求都落在这里:一个融合 Kernel、一个新硬件的后端适配、一个推理引擎的定制算子,最终都要经过同样的路径。 本文用一个刻意简单的算子...

PyTorch 深度实践(05):Dispatcher 与算子系统

The Dispatcher and Operator System in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第五篇(共十篇)。上一篇:nn.Module 与训练系统 下一篇:C++ 扩展与自定义算子 上一篇讨论了 nn.Module 与训练系统:Module 如何组织子模块、Parameter 和 Buffer,Optimizer 如何更新参数,DataLoader 如何把数据送入训练循环。 但当我们写下: z = x + y 到底是谁决定了这个操作对应哪个算子、x 和 y 位于哪个设备、当前是否需要 Autograd、最终应该调用哪个 Kernel? 这些问题属于 PyTorch 的算子系统(Operator System)。本文不会一开始分析复杂的 Attention,而是...

PyTorch 深度实践(04):nn.Module 与训练系统

nn.Module and Training Systems in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第四篇(共十篇)。上一篇:自动求导与动态计算图 下一篇:Dispatcher 与算子系统 上一篇讨论了 Autograd:Tensor 运算如何形成动态计算图,backward() 如何沿图传播梯度,以及梯度状态和计算图生命周期之间有什么关系。 但一个真实的模型不会只是几个散落的 Tensor 运算。它通常包含: 多层嵌套的网络结构; 需要训练的参数; 不参与梯度更新但属于模型状态的 Buffer; 优化器和优化器状态; 训练、验证和推理三种不同阶段; 数据集、采样器和 DataLoader; CPU 到 GPU 的数据搬运; checkpoi...

PyTorch 深度实践(03):自动求导与动态计算图

Autograd and Dynamic Computation Graphs in PyTorch

本文是《PyTorch 深度实践:从 Tensor 到深度学习运行时》系列的第三篇(共十篇)。上一篇:Tensor 与内存布局 下一篇:nn.Module 与训练系统 上一篇介绍了 Tensor 的核心模型:它不是一组孤立的数字,而是由 Storage、Shape、Stride、Storage Offset、dtype、device 和 layout 共同描述的一种数据抽象。 但 Tensor 只有数据和布局,还不能完成模型训练。训练还需要回答一个问题: 模型输出发生变化时,参数应该沿着什么方向、以多大的幅度变化? 这需要计算梯度。PyTorch 通过 Autograd 把数学上的求导过程变成了一个可以执行的运行时系统: Tensor 运算...

×