1. 大模型推理过程

  • prefill 阶段: 用户提出问题后, 大模型将问题tokenize, 变成一系列tokens, 然后计算每个token 对应的K, V 矩阵, 放入kv cache 中, 这里是可以并行计算的。
  • decode 阶段。 基于输入迭代的输出下一个token. 这里是串行化的。自回归的模式, 即每个token, 要用到前面所有的token 的 K V 。

2. 大模型推理优化Naive Batching 提出

用户会发送非常多的推理请求, 如果串行处理这些用户的请求, 如果用户的问题的tokens 数量较小, 无法充分利用GPU并行处理能力。
使用naive baching. 当用户请求到达时, 不立即处理, 而是积累到一定请求后,按批次处理。
存在问题:

  1. 初始预分配的序列空间未知。
  2. 内部碎片:每个请求对应的生成序列长度不同, decode 阶段有些请求已经完成, batch 中有效请求数量减少。但是显存没有释放, 导致GPU利用率低。

3. continuous Batching 提出

不申请最大显存,而是动态申请 当前需要的显存。
当某请求任务完成后, 系统动态从批次中删除, 并释放对应的显存,当有新请求时, 先单独执行prefill , 这样可以复用已经完成的请求的显存。

缺点: continuous Baching新的请求会复用旧的释放的空间。 但是如果新的请求token 数量很大, 超过了某个释放的旧的显存空间,只能把新的请求不进行处理。 但是如果,有多个释放了的旧的显存空间 他们的总的空间超过了新的请求需要的空间呢?这个时候continous Baching 还是无法处理

4. PagedAttention 提出

传统KV 缓冲的缺点:

  1. 初始预分配的序列空间未知
  2. 内部碎片:每个请求对应的生成序列长度不同, decode 阶段有些请求已经完成, batch 中有效请求数量减少。但是显存没有释放, 导致GPU利用率低。
  3. 外部碎片:相邻请求间的碎片。因为KV缓冲 必须占用连续内存, 所以会造成外部碎片
    在做parallel sampling 和 beam search 时, 可能会生成多种输出序列, 这些序列有共同的前缀,理论上是可以 KVcache 共享的,但是传统的KV cache 要求内存连续, 这些前缀的KV cache 无法共享。 需要paged attention 解决。

5.Paged Attention 原理

写的不错的博客
https://aijishu.com/a/1060000000458185

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐