LLM Theory 杂谈:我也不知道主题是什么,一些零碎的insight

softmax softmax的好处:平滑,稳定,和为1可以保证output的范数有界。如果和小于1就会让norm趋向0,因为自迭代系统会跌入局部吸引子(一个动力系统的insight)。 softmax本身就是sigmod的高维版本。soft本身就是改良sig在传统多分类的问题,然后导出的向量级别sig,本质上就是sig pro,sigmod本身假设多标签分类结果非唯一。 这就是标量化的坏处啊,看不到上下文,所以要向量化。向量化看不到上下文就要矩阵化,矩阵化看不到上下文就要张量化,然后并行计算就又要退回到向量化,那么就要用向量化逼近矩阵化。 模型表达能力在不断提高上下文阶数;系统实现又必须把高阶上下文拆成可并行的低阶块。优秀算法的本质,就是在这两者之间做近似、重排、分块和融合。 为什么一开始要叫softmax,它一开始被命名成这个是因为人们发现它可以让任何一个数稍微大一点就几乎接近1,所谓softmax,就是可微的max。 它的数学性质是,把差值相等转化成比例相等。 具体说说为什么soft是sig的扩展,因为sig是二分类,soft生成一个多分类的概率条,让他们自己进行博弈。

June 16, 2026 · 1 min

LLM System: 训练框架随笔 02 - Femtotron PP Schedule 模块重构日记

本篇目标: 为什么要重构 因为要支持vpp(interleave 1f1b) zerobubble dualpipe dualpipev,之前的只支持1f1b,gpipe。 从vpp思索stage的执行序 在gpipe和1f1b里面,一个stage就是一个rank,但如果加上vpp,一个rank上就很多虚拟的stage了。以前设计vpp的初衷就是,一个mb在等通信的时候可以让另一mb去做计算。我们给每个物理rank都绑定了一个executor和一个active queue,为了达成这种目的,我们必须保证两个虚拟stage的active在指令执行顺序没有依赖和申请的资源不会死锁,这样才能让virtual stage A的通信和virtual stage B的计算相互overlap。 那么上面说的这种overlap要怎么排布active才能实现呢?这个必须先定义边界。 从dual(奇美拉)思考stage的执行序 dual V的思想是让一个物理rank不会只绑定模型的一层,而是模型的某两层。这个和vpp的区别是,vpp的优化是不同mb不同时做通信and计算带来的掩盖效果吗,而dual的思想是一个rank可以做几个model layer进而降低了单任务的IDLE,pipeline从两个方向同时发任务,气泡少。可能带来的代价是任务切换带来的开销,但直觉上这部分开销不会很大。(加个TODO先,有空也会验一验) TODO: 验证 folded V / VPP 下更细粒度 action interleave 带来的 kernel launch、stream sync、activation memory 和 comm fragmentation 开销。 mb编码逻辑 随着foldv,dw分离,vpp的引入,mb的编码应该用一个结构体保存所有metadata而不是简单的id。 action之痛 做到vpp的时候,开始发现femtotron这套基于active-mb的扩展性不够好,在做dw分离的时候我把一个backward action拆成一个d action和一个w action,其实这个设计就给后面的复杂埋下了问题。或者说一开始femtotron的forward,backward,sfrb等设计就让这种设计注定变得不可扩展。因为如果一个schedule包含多种优化,一个action的含义必然是复杂的。 所以没办法,先研究一下megatron是怎么实现的。

June 15, 2026 · 1 min

LLM System: 训练框架随笔 01 - PP Schedule 为什么要做成非异步的

本篇目标: schedule要不要做成异步 gpipe的非异步调度 就是简单的做sf和rf,sf和rf之间依赖于torch.dist的api做阻塞同步。 在其他博客中也说这种静态调度和下发cpu指令差不多,按顺序一条条执行,执行完了整个程序就跑完了。 异步的问题 那为什么不直接把任务丢到下游(backward是上游)然后直接做下一个mb的计算呢,这样看起来还可以让sm利用率高。 搞成异步之后快的那个stage确实会更快推进,但是慢的那边会更慢。要么就是两遍差不多快,一样没有什么提升。 另外就是action memory的值会比较不确定。可能会非常大。而静态调度actionmemory的大小是可控的。 语义问题 如果搞成异步下发,那说明会有任务的积压,这些任务做了一半以后,checkpoint要按照哪个标准做记录呢?这也是很难做的。 静态调度的状态就是比动态调度状态更少。动态调度存储,加载,更新状态都会更难而且可能bound在控制流。 好处? 动态调度对慢节点的容忍度好,但是绝对不是pp schedule pipe里面的慢节点。因为llm场景每个mb的时间都差不多。就算是卡慢了也不会这样处理,直接换掉就行了。这种对慢节点的容忍度指的是对于一些异构的流程,比如说rl的几个步骤,以及搜推处理sparse数据等。但是这两个流程我都暂时不特别熟悉,后续还要继续学习。 如果做同步pipe,算子做还是框架做? 放在框架 那就是调用action之前barrier一下,因为这样涉及到多节点,所以启动开销会比较大,好处是位置浅好定位。 放在算子 那训练框架侧就只启动torch.dist的接口,torch.dist底下再接入通信算子库。算子内部barrer。这种问题是调用栈会很深,以及算子级更难定位,好处是算子层可以做更深度的优化,比如做smfree把单节点的mfu打上去。(不过还是那个问题,单节点mfu可能真高了,全局不好说) 那其实这里再给自己开个新todo,试试sm free的算子实现,用CE做通信,到时候跑训练看下效果。

June 10, 2026 · 1 min

LLM System: Training Schedule 01 - 训练框架中的 Schedule 算法

本篇目标: 问题背景 什么是schedule,这个词含义很广但是在训练框架这里一般考虑的是f和b任务之间的编排。 PP pp开几一般就是把所有layer除以几,然后每个就是一个stage的layer数量。一般按照layer切。 GPipe 有很多mb,每个mb要做很多stage(模型的layer或op,跨卡或跨机,这些都行),GPipe就是要等到所有的mb都做完他们自己的所有前向stage,然后开始反向stage。气泡比较多,此外因为前向和反向的layer是反过来的,所以对于一个mb来说,他做的这些stage里面做前向越早的那个stage,做反向越晚。也就是inflight越多。inflight越多就代表得保存中间的状态,占显存。所以2个肉眼可见的缺点一个是空泡另一个是inflight。 在 Perfetto 中打开 GPipe trace 如何实现一个GPipe呢?(底层组件假设已经分好了,我们只需要考虑怎么把任务排好发出来,底层组件的事情可以见后文如何实现一个调度器) 非常的简单,给每个stage执行的载体(GPU)从mb0下发到mbn就可以了。然后执行那个stage对应的layer的前向传播/反向传播。 1F1B 做F的预取,然后让F和B同时进行。中间的卡交替进行f和b。好处是inflight少,但是空泡不减。 在 Perfetto 中打开 1F1B trace 如何实现一个1F1B呢?也并非很难,假设我们的stage执行载体(GPU,虽然总是括号里写GPU但是某些场景不一定是GPU,目前为了便于理解先这么写) 有m个,那只需要给stage编号(这个编号代表第一次启动任务的顺序)为i的stage提前分配m-i+1个mb就行了,mb的序号是从0到m-i。 然后这样预填充完之后,只需要做简单的配对+交叉即可。因为是1f1b,所以只需要交替下发f和b任务,f和b任务对应的mb编号只需要匹配最近一次任务即可,如果是b则找最旧的未完成mb任务id让fb闭合,如果是f则找最新的未完成mb任务id+1。 interleaved 1F1B 也叫vpp,把一个stage再划分为几个虚拟stage,用interleave的形式排到几张卡上。这个场景为什么能减少bubble在我第一次理解的时候其实不是很直观,因为我思考的是,就算切细了那三角形的空泡依然存在,为什么空泡会少。所以就计算了一下size。只算开始部分的三角形空泡(结束时候是对称的就不管了)不计算的很细的话,我们看三角形空泡里面最长的部分,也就是最底下的那条,长度正比于每个f/b的时间*(pp-1),但这里要注意一个很容易想当然的问题,这里的pp是物理pp数,也就是真实的stage,而不是虚拟的stage。因为我们真实的stage数量一般和gpu数量一样,所以就算很多虚拟stage,一次填充到流水线的阶段也最多只有物理个gpu数。那切完以后f/b的t就变小了,显然空泡就小了。 这么解释不太直观,,最直观的其实是,让最底下的那个rank早启动。假设就是rank0到7,rank7得等好几个阶段才能启动,那就把阶段切细,然后启动的就快了。但是如果切得太细,跨rank(其实是stage)通信不能忽略,那就也不行。 然后写这个还想一个问题就是stage到底跨卡还是跨机还是跨什么东西,问了下ai说具体情况具体分析(等于没说)然后翻了下之前(未发布)的训练框架学习笔记,原则上stage没有跨什么东西的限制,但是在机内有高速互联的情况下一般是跨节点的。因为高速互联要留给tp。优先级tp>dp>pp因为我们假设tp每一层都开一次,那么tp的通信量是 $$ seq\_len \times batch\_size \times layer \times hidden $$dp没有layer这个维度肯定要少点。pp一般都可以overlap了。如果节点内没有高速互联是需要开pp的。 Chimera 最接近dualpipe的办法。 初始流水线:s0f-s1f-s2f-s3f-s3b-s2b-s1b-s0b。 Chimera主要减少了bubble,前面二者有bubble都是因为GPU来任务的时间难免有pipeline式的三角形空泡问题。但是三角形空泡来源一个先入为主的假设就是我们总假设只能gpu0开始做mb0stage0。如果让其他gpu也同时开始一个任务,三角形空洞就能补上很多。(拓展,Chimera只是同时走两段pipe,能不能更多的pipe,收益如何) 其实就是排两个交叉的流水线。依然要vpp把stage加倍。 假设原先4stage,vpp成8个。 s0 0 7 s1 1 6 s2 2 5 s3 3 4 就大概这样的。 如果纯做vpp的话是这样的: s0 0 4 s1 1 5 s2 2 6 s3 3 7 那为什么vpp的效果不如Chimera呢。可以观察一件事情,stage越“在时间上靠前”被下发做f的,在做b收口的时候越晚,占用的显存就越大。所以有一个直观的结论,不同stage的显存开销在时间上是不均匀的。最影响显存开销的就是f的第一stage-b的最后一个stage这一对。这一对fb启动最早释放最晚,所以我们如果多同时启动几个这样的f,就可以让显存开销在时间上更均匀,进而降低了显存需求量的峰值。我们做vpp的话很难让不同stage的显存分配量是均匀的,甚至还有可能让inflight叠加。 ...

June 8, 2026 · 1 min

LLM System: Transformer Engine 00 - 学习地图

这篇文章是 LLM System 系列里 Transformer Engine 子专题的第 0 篇,也是这个主题的学习入口。 我准备用这个系列系统学习 NVIDIA Transformer Engine。目标不是只会调用几个 te.* API,而是把 TE 放到大模型训练系统里理解:它为什么存在、如何利用 FP8 / FP4 和 fused kernel、怎么被 Megatron-LM 接入,以及后续如何用 profiler 分析和改进它。 0. 学习目标 这组笔记会围绕四件事展开: 1. TE 在 AI Infra 技术栈中的位置 2. TE 的核心加速策略:低精度、融合算子、Attention、MoE、通信重叠 3. Megatron-LM / Megatron-Core 如何接入 TE 4. 如何 benchmark、trace 并尝试改进 TE 1. 技术定位 Transformer Engine 不是训练框架,而是 NVIDIA 为 Transformer 训练/推理提供的高性能 building block 库。它大致位于训练框架和底层 CUDA/cuBLAS/cuDNN kernel 之间。 这一阶段要回答的问题: 1. TE 和 PyTorch AMP 的关系是什么? 2. TE 和 Megatron-LM 的边界在哪里? 3. TE 为什么不是一个完整训练框架? 4. TE 为什么不只是 FP8,而是 Transformer 优化库? 5. TE 在 AI Infra 技术栈里更靠近 compiler/runtime/kernel,还是更靠近 model framework? 2. 核心加速策略 核心加速策略先按五条线学习: ...

May 21, 2026 · 1 min

LLM System: PD 分离 00 - 学习地图

这篇文章是 LLM System 系列里 PD 分离子专题的第 0 篇,也是这个主题的学习入口。是笔者让gpt-5.5通过联网搜索帮自己制定的系统性学习方案。笔者会根据这个方案来确定如何学习PD分离的整套机制。目标不是先把所有论文细节读完,而是先建立一张可以持续填充的地图:该读什么、该推导什么、该写什么代码、最后应该能回答什么问题。 这个系列暂时围绕一个问题展开:为什么现代 LLM serving 系统越来越关心 prefill/decode disaggregation,也就是 PD 分离? 我希望自己最后能回答四个问题: 1. 为什么 prefill 和 decode 要分离? 2. 一个 workload 到底该配多少 P worker、多少 D worker? 3. KV cache 从 P 到 D 传输到底传了什么、代价多大? 4. vLLM / SGLang / Mooncake 里这件事具体怎么落地? 先说一个结论:**PD 分离不是一个“拆进程就能变快”的魔法优化。**它真正解决的是服务系统里的资源解耦问题:prefill compute、decode iteration、KV cache 生命周期、网络传输和调度策略,本来在 colocated serving 里被绑在一起;PD 分离试图把它们拆开,让不同阶段按照不同目标优化。 0. 心智模型 LLM 推理一个请求大致分成两段。 Prefill:一次性吃掉 prompt,生成整段 prompt 的 KV cache,并产出第一个 token。长输入时它更像大 GEMM,通常更容易把 GPU 算力吃满。它最直接影响的是 TTFT,也就是 time to first token。 ...

May 5, 2026 · 10 min

LLM Theory: MuP 01 - MuP 介绍

这篇文章是关于 LLM 预训练中 MuP / μP 的学习笔记,主要参考原论文 Tensor Programs V: Tuning Large Neural Networks via Zero-Shot Hyperparameter Transfer 和苏剑林的博客 《初探MuP:超参数的跨模型尺度迁移规律》。 问题背景 LLM 预训练的成本很高,因此我们通常不希望直接在目标规模的大模型上反复搜索学习率、初始化、权重衰减等超参数。一个自然想法是:先在同架构的小模型上调参,再把超参数迁移到大模型上。 MuP(Maximal Update Parametrization)的核心目标,就是让某些关键超参数在模型宽度变化时尽量保持稳定,从而支持从小模型到大模型的 zero-shot hyperparameter transfer。原论文把这个迁移范式称为 μTransfer。 因为苏老师的博客写得太简洁+深入浅出了,本文也不会重复去讲他讲的很完善的部分,而是对他的内容进行补充和完善。个人在读原博客的时候感觉到一些地方苏老师略过了一些思考过程,导致初次理解时会让人觉得有些跳跃。 正文 MuP问题的出发点很简单,模型是一个黑盒,因此想训练出一个好模型,无法避免地要做大量的尝试(也就是俗称的调参炼丹)。但对于大模型而言,尝试的时间&金钱&人力成本很高。MuP就是对传统的炼丹过程做了一个剪枝,通过数学推导证明了小模型上已经被验证的某些规律可以直接扩展到大模型上。 当然,上述的总结是比较泛化的,具体到实践中,肯定还会问几个问题:模型大小如何界定?哪些规律可以扩展?具体如何扩展?在展开具体方法之前笔者可以回答前两个问题,这里模型的大小用神经网络的宽度/隐藏层维度来量化。可扩展的规律主要指学习率的选择。因此MuP解决的具体问题是“在网络加宽的情况下,学习率应该如何跟随着隐藏层维度改变”。 MuP(朴素版) 这一节的MuP推导没有用到超过大一高数/线代的知识,也没有用到超过机器学习基本常识的知识。用一种非常简单的视角推导了MuP(虽然有些步骤不够严谨) 模型宽度的影响:无法尽善尽美的参数初始化 为什么要先讲参数初始化呢,因为参数初始化提供了一个最基础的视角,来定量描述“宽度影响稳定性”这件事。 前传和反传的最优参数初始化无法兼容。 高维的任意两个向量夹角都是几乎正交的,可以算一下任意向量和单位向量的夹角,这里不赘述。 所以苏剑林老师基于这点给了一个推论: 从$N(0,1/n)$ 中随机选取$n^2$ 个数,组成一个$n×n$ 的矩阵,这个矩阵近似为正交矩阵,且$n$ 越大,近似程度越好。 其实道理是一样的,列向量两两正交,就是正交矩阵。n越大,相当于维度越高,正交概率越大。每个向量里面的元素都是采样出来的,所以每个元素的值大约是sqrt(1/n),所以整个向量的模长平方就是$n * (sqrt(1/n))^2 = 1$ 正交矩阵有一个好的性质,就是它作用于一个向量时,不改变向量模长。神经网络是对一个输入向量做很多次变换, 得到一个输出向量。我们希望输入向量在变换为输出向量的游走过程中,能一直在一个球面上,也就是模长不变。因为这样 从直觉上可以大幅压缩向量遍历的空间。可以想象一下,在一个完整的高维空间里面找最优解,和在空间内的一个球面 找最优解显然是后者更容易。如果向量变换前后都在同一个球面上或者近似在一个厚度比较薄的球壳上,本文将这种性质称为“稳定性”。 所以最经典的初始化方式是推论里面的采样方式。上述结论也可以通过让变换前后的RMS相等来推导。如果引入了激活函数,初始化的值略有不同,但是推导逻辑类似。 前传和反传区别不大,都是矩阵乘。 $$ \frac{\partial \mathcal{L}}{\partial \boldsymbol{X}} \sim \frac{\partial \mathcal{L}}{\partial \boldsymbol{Y}} \boldsymbol{W}^{\top} $$主要的尺度变化也来自于$W$。输入和输出的维度不相等的时候,就找不到一个两全其美的采样方差。这是一个open的问题,苏老师在原文这里提出这个问题并不是为了直接解决这个问题,而是为了说明模型的宽度和中间层稳定性之间存在着直接的关系。 Loss的稳定性 在苏老师这篇MuP的博客中透露着一个隐含的insight:模型加宽带来的难度就是稳定性下降。(也许这个insight来自于训模型时候的经验)这个稳定性可以是Loss的稳定性,也可以是梯度的稳定性,还可以是每一层输出结果的稳定性。这里考虑了损失增量的稳定性。 文章中需要推导或注释的地方有两点,第一点是公式6如何近似,第二点是公式4如何得到公式7。 公式6的近似: $$ \Delta \mathcal{L}=\mathcal{L}(\boldsymbol{W}+\Delta \boldsymbol{W})-\mathcal{L}(\boldsymbol{W}) $$ 一阶泰勒近似: ...

May 4, 2026 · 4 min

LLM System: Transformer Engine 01 - 在 AI Infra 技术栈中的位置

本篇目标:了解 Transformer Engine 的技术定位,搞清楚它为什么存在,以及它和 PyTorch、cuBLAS、Megatron-LM 的边界。 基本接口 Layer 类定义接口非常直接,最表层的使用方式就是把 torch.nn 模块替换成 transformer_engine.pytorch 模块。 普通 PyTorch 写法: self.linear = torch.nn.Linear(hidden_size, 4 * hidden_size) TE 写法: import transformer_engine.pytorch as te self.linear = te.Linear(hidden_size, 4 * hidden_size) 量化上下文: from transformer_engine.pytorch import fp8_autocast with fp8_autocast(enabled=True): y = module(x) 进入 TE 的 FP8 上下文之后,TE 会围绕量化、反量化、fused path、tensor cache 和 backend 选择做一系列处理。相较于纯 PyTorch 计算图优化,TE 会拿到更多信息 tensor parallel、sequence parallel、FP8 recipe 等。这些额外信息给底层算子优化留下了空间。 这一点目前还是比较 general 层面 的认知,后面要继续顺着源码和 profiler trace 去验证。 TE 和 Megatron 的边界 Megatron-Core 负责模型并行、训练 loop、optimizer、activation checkpoint、MoE routing、pipeline schedule 和 config。 ...

May 21, 2026 · 1 min

LLM System: KV Cache 查询 01 - PagedAttention 原理

TODO: 这里写 PagedAttention 的核心抽象:block/page、block table、逻辑 token 到物理 KV block 的映射。 基础:tensor 级拆请求的形状(大量细节) 定义符号:$B$ 是 batch size,$T$ 是 seq_len,$D$ 是 token_dim,$d_q$ 是把 embedding token 投影到 $Q$ 后的维度。 推理框架拿到的请求是:\(R \in \mathbb{R}^{B \times T}\)。 $R_{b,t}$ 是一个最最基本的 token id 标量。 raw 请求经过 embedding lookup,做的操作是把这个 token 标量映射成一个高维向量。假设原先 token 是 1234 这个标量,现在就把 token 映射成 [0.1, 0.2, 0.3, 0.4] 这样的向量。 所以 $R$ 经过 embedding lookup 之后,得到:\(X \in \mathbb{R}^{B \times T \times D}\)。 因为我们目前只考虑推理场景,所以把 $W_Q$、$W_K$、$W_V$ 之类的矩阵当成固定的模型参数。 然后很多博客会直接写:\(Q = XW_Q\)。 ...

May 10, 2026 · 5 min

LLM Theory: MuP 02 - 推广到更 general 的 init setup

本文从训练模型要考虑的第一性原理(稳定性和速度)出发,探讨了 LLM 预训练中的初始化设定问题。 参考文献 MuP之上:1. 好模型的三个特征 https://spaces.ac.cn/archives/11605 https://spaces.ac.cn/archives/11647 https://spaces.ac.cn/archives/11729

May 6, 2026 · 1 min