2. vLLM基础架构:核心组件与PagedAttention原理

大家好,我是你们的运维老手。今天我们来聊聊vLLM的骨架——它的核心架构。

说实话,我第一次接触vLLM时,也被它那一堆组件搞晕过。但后来我发现,只要抓住三个核心组件,整个系统就清晰了:Scheduler(调度器)、Block Manager(块管理器)、KV Cache Manager(KV缓存管理器)

2.1 核心组件概览

先看一张整体架构图,我习惯把vLLM比作一个高效的物流仓库:

vLLM核心架构图 用户请求 Scheduler(调度器) 请求排队、批处理、优先级调度 Block Manager 物理块分配、逻辑块映射 KV Cache Manager 缓存分配、淘汰策略、内存管理 PagedAttention 引擎 分页注意力计算、非连续内存访问 生成结果 调度决策 内存状态

这张图我画了好几次才满意。你看,请求从顶部进来,先经过Scheduler,然后Scheduler会跟Block Manager和KV Cache Manager打交道,最后交给PagedAttention引擎去计算。

2.2 Scheduler(调度器)

Scheduler是vLLM的大脑。它的工作说白了就是:决定谁先算,谁后算,以及怎么算最划算

我在生产环境里遇到过一个问题:当并发请求突然飙升时,Scheduler如果处理不好,整个系统就会像堵车一样。vLLM的Scheduler有几个关键策略:

  • FCFS(先来先服务):基础策略,但容易导致长请求阻塞短请求
  • 优先级调度:可以给某些请求打标签,让它们插队
  • 动态批处理:把多个小请求合并成一个批次,提高GPU利用率

核心要点:Scheduler会维护一个等待队列和一个运行队列。每次调度时,它会从等待队列中取出请求,检查当前GPU内存是否足够。如果不够,它会触发KV Cache的淘汰机制。

2.3 Block Manager(块管理器)

Block Manager是vLLM的"仓库管理员"。它管理着GPU上的物理内存块。

你想想看,传统方式下,每个请求都要分配一整块连续内存。但vLLM不一样——它把内存切成固定大小的块(block),每个块通常16KB或32KB。

Block Manager的核心职责:

  • 物理块分配:从GPU显存中划出一块块固定大小的区域
  • 逻辑块映射:维护一个映射表,记录逻辑块对应哪个物理块
  • 碎片整理:当请求结束后,回收物理块,减少内存碎片

我的经验:我曾经遇到过一个坑——block size设置得太小(4KB),导致映射表太大,反而占用了不少显存。后来我改成32KB,性能提升了约15%。所以block size不是越小越好,要根据你的模型大小和显存容量来调。

2.4 KV Cache Manager(KV缓存管理器)

KV Cache Manager是vLLM的"记忆管家"。它管理着Transformer计算过程中产生的Key和Value缓存。

为什么需要它?因为大模型生成文本时,每个token都要计算注意力。如果不缓存,每次都要重新算前面的所有token,那效率就太低了。

KV Cache Manager的工作流程:

  1. 当请求开始处理时,为每个层分配KV缓存空间
  2. 每生成一个新token,把新的K、V追加到缓存中
  3. 当请求结束时,释放缓存空间
  4. 如果内存不足,触发淘汰策略(比如LRU)
缓存策略 原理 适用场景
LRU(最近最少使用) 淘汰最久没被访问的缓存 通用场景,实现简单
LFU(最不经常使用) 淘汰访问频率最低的缓存 请求模式稳定的场景
FIFO(先进先出) 淘汰最早进入的缓存 对延迟不敏感的场景

注意:KV Cache是显存消耗的大头。我见过一个7B模型,如果batch size开到64,KV Cache能吃掉20GB以上的显存。所以监控KV Cache的使用率,是运维vLLM的重中之重。

2.5 请求处理流程

好了,三个核心组件都认识了。现在我们把它们串起来,看看一个请求从进来到出去,到底经历了什么。

我习惯把这个流程分成四个阶段:

  1. 预处理阶段:请求到达Scheduler,进行tokenize、padding等操作。Scheduler检查当前GPU内存是否够用。
  2. 调度阶段:Scheduler决定是否立即处理,还是排队等待。如果内存不足,它会通知KV Cache Manager进行淘汰。
  3. 计算阶段:Block Manager分配物理块,KV Cache Manager分配缓存空间,然后交给PagedAttention引擎计算。
  4. 后处理阶段:生成结果,释放资源,返回给用户。

这里有个细节:vLLM用的是连续批处理(continuous batching)。什么意思呢?就是当一个请求生成完最后一个token时,它不会等整个批次都结束,而是立即把空出来的位置让给新请求。这样GPU利用率能提高不少。

2.6 PagedAttention原理

终于到了最核心的部分——PagedAttention。这个名字你可能听着耳熟,因为它借鉴了操作系统的分页内存管理思想。

传统注意力机制的问题是什么?它要求K、V矩阵在内存中是连续的。但连续内存很容易产生碎片,而且分配大块连续内存很慢。

PagedAttention的解决方案:把K、V矩阵切成小块(page),每个page可以放在任意物理位置。就像操作系统的虚拟内存一样,逻辑上连续,物理上可以分散。

具体来说:

  • 每个page包含固定数量的token的K、V值(比如16个token)
  • 维护一个页表(page table),记录逻辑页到物理页的映射
  • 计算注意力时,通过页表找到物理位置,然后读取数据

PagedAttention的优势

  • 几乎零内存碎片——小块分配,灵活回收
  • 支持内存共享——多个请求可以共享相同的KV page(比如beam search场景)
  • 更高的GPU利用率——连续批处理配合分页,让显存不再成为瓶颈

我记得有一次,一个客户抱怨说他们的推理服务总是OOM。我一看,他们用的是传统注意力实现,每个请求预分配了最大长度的连续内存。换成PagedAttention后,同样的显存,并发量从4提升到了16。这就是分页的魅力。

2.7 小结

嗯,这一章内容不少。我们来捋一下:

  • Scheduler:大脑,负责调度决策
  • Block Manager:仓库管理员,负责物理块分配
  • KV Cache Manager:记忆管家,负责缓存管理
  • PagedAttention:核心算法,用分页思想解决内存碎片问题

这四个东西配合起来,才构成了vLLM高效推理的基础。下一章我们会深入Prometheus监控指标,看看怎么把这些组件的状态实时抓出来。


公众号:蓝海资料掘金营,微信deep3321