vLLM 源码阅读 - 整体执行流程概览 (part1)
说明:基于 vLLM v0.7.3,commit id:
ed6e9075d31e32c8548b480a47d1ffb77da1f54c (HEAD, tag: v0.7.3)
PagedAttention
提出:解决 KV Cache 不连续导致的利用率不高问题。
KV Cache 利用率不高的问题:(可参考 pagedattention paper)
- 事先不知道请求的长度(prompt + output),如果提前分配过大的空间会导致浪费,产生内部碎片(internal fragmentation);过小又无法分配给其他请求,产生外部碎片(external fragmentation)。
- 无法共享空间,如 beam search 等解码算法会针对一个请求生成多个输出,现有系统无法使多个输出共享一个 prompt。
原理
vLLM 推理
推理的示例程序:
1 | from vllm import LLM, SamplingParams |
初始化流程
接口类 LLM
LLM 类的初始化:
1 | # entrypoints/llm.py |
构造 LLMEngine:
1 | # engine/llm_engine.py |
LLMEngine 类
LLMEngine
初始化:
1 | # engine/llm_engine.py |
LLMEngine
初始化流程涉及如下几个核心类或组件的初始化。
- executor, Worker 初始化
executor 初始化时序图如下:

executor 初始化:
1 | def _init_executor(self) -> None: |
Worker
初始化:
1 | # vllm/worker/worker.py |
- KV Cache 初始化
LLMEngine
初始化中,_initialize_kv_caches
函数执行 KV Cache 的初始化,具体如下:
2.1 先计算可用的 GPU、CPU blocks 数量
1 | # vllm/worker/worker.py |
计算 cache_block_size:
1 | # vllm/worker/cache_engine.py |
2.2 初始化 KV Cache
1 | # vllm/worker/worker.py |
CacheEngine
预先分配 KV Cache:
1 | # worker/cache_engine.py |
- Scheduler 初始化
会初始化一个 BlockSpaceManager
用于管理实际的 KV Cache 的分配。
1 | # vllm/core/scheduler.py |
LLM 接口 generate 整体逻辑
generate 的逻辑流程:
- for-loop 每个 prompt、sampling_param,并将 prompt、sampling_param 作为 request 参数添加给
llm_engine
的 request pool。
a. input_processor 做一些输入 prompt 的处理;
b. 将处理过的 prompt (tokens) 封装成Sequence
,seq 再封装进SequenceGroup
;
c. 将封装成的seq_group
append 到scheduler
的waiting
队列,以待后续处理任务的使用。
上述流程涉及的关键代码:
1 | # entrypoints/llm.py |
Sequence
和 SequenceGroup
类关系图如下:

- 然后调用
self._run_engine()
进行实际的调度和推理。
1 | # entrypoints/llm.py |
llm_engine
调用step
,scheduler
负责调度,model_executor
负责实际的推理。