↓ 跳过正文

111qqz

ML Infra Engineer | ex-ICPCer@HUST

最近的文章

从投机解码到 Rand5 模拟 Rand7:跨越十年的拒绝采样直觉

上一篇理清了 Prefill 和 Decode 的因果链之后,我开始翻 Decode 阶段的加速方案。结论已经很清楚了:在单请求、小 Batch 的典型场景下,Decode 阶段是 memory-bound 的——每生成一个 token 就要把整个模型权重从显存搬一遍,计算单元大部分时间在等数据(Batch 较大或模型结构不同时,瓶颈也可能转向 compute-bound,但单次请求的延迟优化场景下 memory-bound 是常态)。

PagedAttention:为什么 KV Cache 需要自己的内存管理系统?

前一篇写完之后,KV Cache 在我脑子里的形象已经变了——它不再是一次 forward 里的临时中间量,而是一个跨多轮存活、随 Decode 持续增长、每个请求各自独立的状态。 但"知道它是有状态的"和"知道怎么管它"是两件事。当我开始想具体的内存管理问题的时候,发现事情比想象的复杂。

从一次 Forward 到持续生成:LLM Inference 为什么不一样?

最近在从传统模型 Serving 转向 LLM Inference,一个让我停下来想了很久的问题是:为什么 LLM 的推理系统看起来和我之前熟悉的那套完全不一样? 我之前做推荐模型和 CV 模型的部署,排序模型的 Serving 架构虽然在工程上也有不少复杂性(远程 embedding 读取、稀疏参数缓存等),但核心计算模式不难概括:一个请求进来,跑一次 forward,返回结果。LLM Serving 里冒出来一大堆新概念——推理要分成 Prefill 和 Decode 两个阶段,中间要维护 KV Cache,请求调度要做 Continuous Batching,显存管理要用 PagedAttention——我花了些时间才把它们背后的因果链串起来。

从 Dense FFN 到 MoE:Router、Token Dispatch 与 Grouped GEMM

·5127 字·11 分钟
上一篇 MoE 笔记把架构家族理了一遍——稀疏、稠密、Soft MoE,gate 在前还是在后,决定了算力形态和适用场景。 但那篇有一段伪代码一直让我不太舒服: 1for prob, idx in zip(topk_probs.unbind(1), topk_idx.unbind(1)): 2 out += prob.unsqueeze(1) * self.experts[idx](x) 逻辑上没问题。但想象一下真实场景:一个 batch 有几千个 token,每个 token 选 2 个 expert,就是上万个 token-expert 计算任务。用 Python for loop 逐个调 expert 的 forward,GPU 利用率会低得离谱。