Day 30 · M1 总复习:一页笔记、20 道全月自测、错题本汇总与 M2 预告
把 M1 四周加加餐周压成一页:W1 的账本、W2 的计时与 profiler、W3 的实测屋顶、W4 的环境流水线、加餐周的硬件与数值地基。然后合上笔记做 20 道全月自测,把三十天的错题按形状、单位、异步、标称、计费五类归根,对照 Day 0 的目标逐条打勾,最后写 M2 的预告。
Archive
32posts
把 M1 四周加加餐周压成一页:W1 的账本、W2 的计时与 profiler、W3 的实测屋顶、W4 的环境流水线、加餐周的硬件与数值地基。然后合上笔记做 20 道全月自测,把三十天的错题按形状、单位、异步、标称、计费五类归根,对照 Day 0 的目标逐条打勾,最后写 M2 的预告。
拿真实招聘要求对照 Day 0 定的路线:样本从哪来、有多不完整,JD 里反复出现哪些词,哪些是路线图已经覆盖的、哪些是缺口。由此在路线图上加了六个勾,记下薪资快照和四条必须正视的限制。不改骨架,只补缺口。
A100 宣传页写 624 TFLOPS,Day 5 用的却是 312;同样叫 A100 80GB,SXM 和 PCIe 的带宽差 5%,ridge point 一个 153 一个 161;NVLink 和 PCIe 差十倍。把规格表上每个会骗人的数字过一遍,最后把小时价换算成每一百万 token 多少钱,看 batching 在账单上是多大的杠杆。
一个 kernel 是怎么被切成几千个 block 撒到 SM 上跑的,warp 为什么是 32,stream 为什么是有序队列,以及每次 launch 都要付的那笔固定税有多大。把 Day 11 在 timeline 上看到的 gap 追到它的物理来源,顺手给 M5 的 Triton 铺好路。
前面四周所有的「× 2 字节」都默认了 fp16。今天把这 16 个位拆开看:几位给符号、几位给指数、几位给尾数,换一种分法就是另一个格式。然后回答两个实际问题:为什么 T4 跑 bf16 会出事,以及把权重压到 8 位、4 位之后 decode 上限从 150 tok/s 变成多少。
前四周一直在说「算力」和「带宽」,今天把这两个词拆开看里面的零件:算力是多少个 SM 里多少个 tensor core 每个时钟做多少次乘加,带宽是一座五层的存储金字塔里最底下那一层。312 TFLOP/s 和 2039 GB/s 这两个数,今天要能从零件表里亲手算出来。
把 W4 五天的工程活压成一张能打勾的清单:开机前、开机后、收尾三段,每项对应哪个脚本、哪条计费事实。然后做路线图 W4 的五道验收题,把这周三篇文章里口径不一致的地方统一掉,最后整理错题本。W4 结束时的标准只有一句:一条命令起环境,跑完自己消失,钱花在哪一眼可查。
把每一次开机都变成一行记录:日期、实验名、卡型、小时价、时长、花费、一句结论。启动和销毁脚本自动记账,一段 Python 汇总本月,再把小时价换算成每个实验多少钱、每百万 token 多少钱。答不出「这个月花了多少、花在哪」就是看板没做好。
忘记关机是这条路上预算失控的唯一原因,而它不会因为「这次一定记得」而消失。给三种不同的失败方式各配一道保险:任务结束脚本自己销毁实例,GPU 空闲太久看门程序销毁实例,前两层都失效时账户余额兜底。每一层写出来、跑一遍,验收是故意跑完一个任务,然后看实例自己消失。
把「开机之后手工装环境」这件事变成一个幂等的脚本:装依赖、拉代码、配 token、预热模型、打印 nvidia-smi。每一步都计时,找出最慢的那一步。验收标准只有一条:从实例启动到能跑第一行 GPU 代码,全自动,不超过 5 分钟。
租来的机器是一次性的,销毁之后盘上的一切都没了。今天把 RunPod 和 Vast 的几种存储在 stop 和 delete 时的命运搞清楚,算一笔「存着」和「重下」哪个便宜的账,然后给代码、模型权重、实验结果三类东西各定一个去处,画成决策树。
W4 第一天,从免费 Colab 换到按秒计费的租卡。两家平台怎么选、便宜的可中断实例到底便宜在哪、选哪张卡要先算显存再看价,以及第一次 SSH 进去必须做的三件事。全程只充 10 到 20 美元。
把测带宽、测算力、画 roofline、扫 batch、对比标称这五天压成一页笔记:每一步的公式、预期区间和坑放在一起。合上笔记做路线图 W3 的五道验收题,再把这周最容易测错的地方一条条摊开。屋顶从这周起是自己测的,不是抄的。
把 Day 13、14 测出来的带宽和算力跟规格表并排放,算清标称值是怎么来的、实测为什么差那一截。再给每种 kernel 算一遍算术强度,标到 roofline 上:大矩阵乘能碰到屋顶,elementwise、softmax、norm 这些永远贴着斜线的底部,而这正是 M5 要写 fused kernel 的全部理由。
把 batch 开到 1、4、16、64、128,测 decode 每步时间,算吞吐,标到 Day 15 的 roofline 上。W1 预测 batch 到 ridge 附近才碰屋顶,今天要看这条曲线实际在哪弯、为什么弯——弯的原因不是 FLOP 追上了带宽,是 KV cache 的字节跟着 batch 一起涨。
把 Day 13 测出的带宽、Day 14 测出的算力换掉标称值,用 matplotlib 画出自己这张卡的 roofline,再把 Day 9 的 TPOT 换算成图上的一个点。屋顶从此是自己测出来的,不是宣传页上抄来的。
昨天测了斜线,今天测屋顶。用大方阵矩阵乘法把 T4 真正能算多快测出来:FLOPs = 2MNK 除以时间。坑比带宽多:矩阵不够大打不满、fp32 的标称是另一个数、fp16 要真走 tensor core 才对得上 65 TFLOPS、A100 的 624 是稀疏值。顺手算出方阵多大才跨过 ridge point。
W3 开工。标称 320 GB/s 是纸面数字,今天用一次最简单的逐元素加法,把 T4 真正能搬多快测出来,再把这个实测值装回 Day 5 的 decode 下限公式里。顺手踩清三个坑:字节只算读没算写、张量小到落进 L2、没 synchronize。
第一周算账,第二周对账。把 Day 7 到 Day 11 压成一页:计时怎么做才是真的、TTFT 和 TPOT 各自的下限、比值怎么读、profiler 里的 kernel 名怎么对回模型、gap 占比怎么算。然后合上笔记做路线图 W2 的五道验收题,把这周会犯的错一条条摊开。
Day 1 读到的第三种瓶颈 overhead-bound,今天在 Perfetto 的 timeline 上亲眼看到它:GPU 那一行的空白。算清 decode 一步为什么有三百个小 kernel、CPU 为什么发不过来,再看加大 batch 时空白怎么缩,以及两种真正的治法。
计时器只给一个数,profiler 给每个 kernel 的名字和时长。今天把 Day 9 那个比值拆开:一步 decode 里 GPU 真正在跑的是哪几个 kernel,各对应模型的哪一部分,CPU 那边又在干什么。
一次 generate 的耗时里藏着两个性格完全不同的数:首 token 时间和后续每 token 时间。今天把它们拆开,各自算出理论下限,然后用一个比值回答 W1 那张表能不能信。
CPU 把 kernel 扔进队列就往下走,GPU 在后面慢慢干。不加 synchronize,perf_counter 测到的是「派活的时间」,不是「干完活的时间」,能差几个数量级。今天把这件事画成时间线,对比两种正确的计时法,把 Day 7 的计时代码改成以后一年都用的最终版。
W1 一行代码没写,今天开始写。在 Colab 的免费 T4 上加载一个 1.1B 的模型跑通 generate,搞清第一次为什么慢好几倍,再把连续十次运行的延迟方差压到 10% 以内。这周所有实测数字的可信度,从今天的 warmup 开始。
把第一周所有公式和数字压成一页,合上笔记做完五道验收题,再把这周犯过的错一条条摊开。算不出数字就是没过,跟读了几篇文章没关系。
把 7B 模型推理时的显存拆成四项算清楚,再用一次除法算出 decode 的物理上限。最后引出整条路线最重要的一个数:ridge point ≈ 153。附五张卡的 ridge point 对照、量化和 KV cache 读取怎么改这张图。
把 Day 2 数出来的参数量变成两个能算的数:模型跑一遍要做多少次运算,以及 decode 时为了不重算而缓存下来的 k、v 占多少显存。算完会发现 batch 一大,缓存比权重本身还大。附六个模型的 KV cache 对照表和一段从 config.json 自动算账的代码。
把注意力机制拆到能手算的粒度:三个向量各干什么、权重怎么来的、加起来的到底是什么。用一个 3 token、head_dim 2 的例子把整张注意力矩阵算完,再接一段能跑的 numpy。顺带搞清模型为什么只能一个 token 一个 token 地生成,以及这件事怎么直接引出 prefill、decode 和 KV cache。
不靠任何公式表,只用「矩阵形状 = 输入长度 × 输出长度」一条规律,把 Llama-2-7B 的 6.74B 参数从头数到尾,再算出它在 fp16 下占多少显存。同一套算法顺手对账 13B、Llama-3-8B 和 TinyLlama-1.1B。
读 Horace He 的 Brrrr。一段代码跑得慢,只可能卡在三个地方:算力、显存带宽、调度开销。今天学的是怎么判断卡在哪一个,判错了后面所有优化都是白干。附判定流程图、三段式时间线和一个可以在 Colab 上跑的小实验。
开工前把三件事写死:为什么选 AI Infra 而不是 AI 应用层,为什么先攻推理不碰分布式训练,以及 12 个月每一段要交出什么东西。这一篇是整个 365 天系列的地图,也是三个月后动摇时要回来读的那一篇。
One FLOP per byte. That single ratio explains why a batch-size-1 decode step uses under one percent of an A100, and why most "make it faster" instincts are aimed at the wrong resource.