AI Infra学不完学不完

最近读了腾讯写的文章,简单自己做了下总结和理解,又有了新的输入,不愧是腾讯👍

一、学到的核心知识

1. 大模型推理的两大基石

  • Continuous Batching(连续批处理):传统批处理要求一个 batch 内所有请求"同时开始、同时结束",但 LLM 输出长度不可预测,会浪费 GPU。vLLM 把调度粒度从 request level 下沉到 token level——每一步看哪些请求"差几个 token",就调度几个 token,把短请求填进 batch 的空隙里。
  • Paged Attention:传统做法一次为请求申请全部显存,碎片严重;Paged Attention 仿照操作系统的页表,KV Cache 按固定 block_size(默认 16)分块,用 block_table 维护虚拟→物理块映射,按需分配。代价是 block 间访存不再连续会有 L2 Cache miss,但用少量访存带宽换大幅吞吐提升,整体是赚的。

2. Prefill vs Decode 的本质差异

  • Prefill:一次性处理完整 prompt,QKV_Proj/O_Proj/MLP 全是稠密 GEMM,算力密集 (Compute-bound)
  • Decode:自回归每次只算 1 个 token,矩阵乘退化成矩阵向量乘 (GEMV),瓶颈在读权重和 KV Cache 的访存带宽 (Memory-bound)
  • Continuous Batching 的真正价值:通过 token 级调度让多请求复用模型权重,把 Decode 阶段的 GEMV 重新变回 GEMM,摊薄权重访存开销。

3. FlashAttention:通过 Online Softmax(维护 Running Max 和 Running Sum + 动态缩放因子)解除全局数据依赖,把 Q·K → Softmax → ·V 融合成一个 CUDA Kernel,在 SRAM 里分块完成计算,不再把 N×N 中间矩阵写回 HBM,是打破内存墙的关键。

4. 一些工程细节也很有趣

  • RoPE 不实时算 sin/cos,而是引擎启动时预计算 cos_sin_cache——SFU 算超越函数吞吐只有 FP32 ALU 的 1/4,用几 MB 的小表换掉每次 forward 几百万次调用,空间换时间
  • Fused QKV 和 Fused Gate/Up 都是把多个 Linear 按列拼起来,一次宽 GEMM 替代多次窄 GEMM,减少 Kernel Launch。
  • TP 切分时 QKV/Gate-Up 走 Column Parallelism,O_Proj/Down_Proj 走 Row Parallelism(最后 AllReduce 聚合)——理解了 shape 流,TP 一下就懂了。

二、个人理解

读完最大的震动是:大模型推理的数学其实并不深奥,难的全是工程 Trade-off

Paged Attention 牺牲访存连续性换显存利用率,FlashAttention 用重计算换 IO,最后一层 MLP 明明可以只算最后一个 token 但 vLLM 选择"老老实实全算一遍"——每一个决策都是物理极限下的权衡,没有"最优解"只有"在当前硬件约束下最划算的解"。

另一个收获是看到了 Attention 为什么是大模型的命门:其他模块都能通过 Continuous Batching 摊薄访存,只有 Attention 因为 KV Cache 不能跨请求共享 + 计算随上下文长度线性膨胀,始终无法均摊。这就解释了为什么 DeepSeek MLA、Linear Attention、Flash-Decoding 这些工作都在围绕 KV Cache 做文章——根因都在这里。

"AI Infra 的东西真的多,根本学不完"特别有共鸣。比起 Agent 圈里不断重命名的"上下文工程""harness 工程",AI Infra 这边每个名词背后都有扎实的数学和工程支撑。下一步我打算啃 FlashAttention 论文 + MLA 原理,把这篇当作整个 Infra 知识树的索引。

原文指路:AI Infra入门干货总结:大模型是如何高效推理的 ·

alt

全部评论

相关推荐

在我来鹅之后,接到的第一个完整大需求就是需要编写一个skill,之前的实习也写过一些skill,但是在我的理解中skill就是跟提示词没差,把你需要的目标全写上就好了,所以第一次mr我提交了一个超过1200行的md,被mt打了回去,为了完成这个需求,我又赶紧请教了我身边的大神同学,获取一些写skill的经验,将原先1200行的md进行了对应的references拆封,又通过我朋友教我的验证机制验证这个skill的效果,最后完成了我的第一个需求。正好前两篇文章给大家分享了写好的用来包装简历的skill,那么今天来给大家分享怎么去写一个好的,可以实际用来工作的skill,摆脱只会写提示词的尴尬。构建 Skill 的五个步骤Step 0:先写 EvalsEval(Evaluation,评估)是一套结构化的、可重复运行的测试用例集,用来判断 Skill 的表现是否符合预期。它不是泛指"测试一下",而是开发 Skill 的前提条件。一个典型的 Skill eval 集至少包含三类用例:- 正例(Positive):用户说“帮我看一下这个 PR 能不能合”,验证 Skill 应该被加载- 负例(Negative):用户说“帮我把代码格式化一下”,验证 Skill 不该被加载——路由别跑偏到不该触发的地方- 边界(Edge):“这个 PR 改了一行日志,要不要审”,验证边界情况下的路由行为正例和负例都要写,而且负例往往比正例更值钱——误触发是 Skill 路由的头号失败模式。Eval 不只是测一次。Perplexity 的 eval 分三个层次:如下图每种都要在 GPT、Claude Opus、Claude Sonnet 不同的 orchestration 模型上分别跑——Sonnet 和 GPT 的 Skill 行为差异很大,只在一种模型上过了不够。没有 evals,你改 description 就是在盲改,一个新 Skill 也可能悄悄搞坏已有的十个 Skill。Step 1:写 Description(最难的一行)description 是路由触发器,不是文档。写好它不需要关心 Skill 的内容,只需要关心能不能在正确的时间加载、有没有意外触发到不应该触发的地方——误触发是头号失败模式,每加一个 Skill 都有可能让其他 Skill 变差。糟糕的 description 描述 Skill 做什么,好的 description 说什么时候加载。举个监控 PR 的例子:不要写这个 Skill 做什么,要写工程师感到焦虑时会说什么——"babysit"、"watch CI"、"make sure this lands"。快速检查清单:- 以"Load when…"开头- 控制在 50 词以内- 描述用户意图,最好来自真实查询- 不总结工作流程Step 2:写 Body跟同事讲工作流程和跟 LLM 讲工作流程完全是两回事。对几乎任何面世超过一年的软件工具,只要提名字,模型已经知道怎么用。所以跳过模型已经懂的部分。不用写出每一步命令。比如不要写 git log → git checkout main → git checkout -b clean-branch → git cherry-pick commit。写 "Cherry-pick the commit onto a clean branch. Resolve conflicts preserving intent. If it can't land cleanly, explain why." 模型在后者上表现好得多,尤其是事情不按预期走的时候。太规定的指令比灵活的指令更脆弱。然后聚焦 gotchas 和反例,它们是最高信噪比的内容。每次 Agent 搞砸了就加一条,gotcha 会自然地累积起来。条件逻辑或内容太重的东西移出 SKILL.md,放到 accessory file 里渐进加载。Step 3:用层级结构- scripts/ —— 确定性逻辑,模型不用每次重新发明- references/ —— 重型文档,条件触发才读("如果 API 返回非 200,读 api-errors.md")- assets/ —— 输出模板,模型直接复制填充- config.json —— 首次运行设置,问一次保存下来对于极其复杂的 Skill,进一步考虑是否应该拆成一组 Skill,用 depends: 声明加载关系。Step 4:迭代切分支出来,在无 Skill 的状态下跑 hero query(核心用户场景查询),建 eval 集,反复调。提交 review 时最好一个 changeset 里自带 eval 集。Description 里的小词改动对路由影响很大,甚至会 spillover(溢出)到其他 Skill,所以这些在 Step 5 之前做完。Step 5:发布大家快把这5步实行起来,成为写skill专家吧!
AI了,我在打一种很新的...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务