如何从头开始构建您自己的 LLM 运行时

如果您曾经想自己实际构建一个 LLM 推理运行时 — 打包自己的权重、拥有每个障碍、捕获自己的 CUDA 图表 — 这就是 H100 上的旅程。逐步浏览名为 annotated-llm-runtime 的小型运行时,以及产生大部分注释的三个错误。如何从头开始构建自己的 LLM 运行时一文首先出现在 Towards Data Science 上。

来源:走向数据科学
  • 这篇文章的内容是:逐步浏览 NVIDIA H100 (`sm_90`) 上的 Qwen2.5-Coder-7B-Instruct 从头开始​​的 CUDA 推理运行时 — 每个热路径都注释了原因,而不仅仅是内容。
  • 运行时今天做了什么:贪婪的图层令牌匹配在 ≤4096 上下文中通过 H100,稳态解码约为每个令牌约 16.7 毫秒(约 60 tok/s),对于 512 个令牌提示,第一个令牌延迟约为 128 毫秒。
  • 使其他一切都有意义的一个数字:急切解码约为 119 毫秒/令牌。将解码包装在捕获的 CUDA 图中,将其压缩至约 17 毫秒/令牌。 7 倍的胜利——相同的内核,只是更少的驱动程序。
  • 三个 bug 完成了大部分教学:warp 专用分支内的 __syncthreads() 是未定义的行为(并且会破坏 KV 页尾处的 softmax),CUDA 图不是可选的,并且 prmt.b32 在 Hopper 上击败 __dp4a 用于门/上/下 GEMV 形状 - 尝试并删除了 INT8 激活路径。
  • llama.cppi 是参考实现,而不是竞争对手:在同一 GPU 类上使用 Q4_K_M 提交 b3040 时,相同的 pp512/tg128 协议发布约 43 ms TTFT 和约 4.95 ms/token 解码。它是检查你自己的构建是否合理运行的标尺。
  • TL;DR 放在前面,这样您就可以留下要点:如果您曾经想自己实际构建一个 LLM 推理运行时 — 打包自己的权重、拥有每个障碍、捕获自己的 CUDA 图表 — 这就是在适用于 Qwen2.5-Coder-7B 的 NVIDIA H100 (Hopper,sm_90) 上的旅程。您将对 warp 专门化、TMA、__syncthreads() 产生强烈的看法,并且 CUDA 图不是一个额外的好处,而是一个必需品。本文介绍了一个名为 annotated-llm-runtime 的小型 LLM 运行时(大约有两打 CUDA/C++ 源文件,每个热路径都注释了原因,而不仅仅是内容)以及产生大部分注释的三个战争(比喻)故事。

    Github Repo(稍后将在整个帖子中大量使用):https://github.com/AnubhabBanerjee/Annotated-LLM-Runtime

    1. 为什么要构建自己的 LLM 运行时?