Skip to content
mumong's blog
Go back

vLLM 工具调研

梳理 vLLM 的核心架构、调度机制、PagedAttention 思路,以及 CPU 环境下的安装部署和基础使用方式。

本文由内部 DOCX 技术文档整理而来,已移除目录前的模板页与前置信息;正文内容、截图与操作步骤按博客阅读方式重新排版。

本文旨在介绍 vLLM 的核心概念、架构设计及其主要特性,帮助读者理解该工具在大语言模型(LLM)推理领域的重要性和创新点。vLLM 是一种专为优化大语言模型推理性能而设计的高效推理引擎,其通过内存管理优化、并行处理机制以及对多硬件环境的支持,为开发者和企业提供了低延迟、高吞吐的推理能力。本文希望通过深入解析 vLLM 的架构及其特性,展示其在提升推理效率、降低资源开销以及支持复杂应用场景中的独特优势,为需要高性能 LLM 推理的用户提供清晰的参考和指导。

本文档适用于了解vLLM

术语、缩略语解释

引用文件

https://zhuanlan.zhihu.com/p/681716326

了解vLLM

vLLM 是一个 LLM (Large Lanuage Model) 推理和部署服务库,它结合 iterative-level schedule (常被称为 continuous batching,该调度算法在Orca中首次被提出) 和 PagedAttention 注意力算法以提高服务的吞吐量。前者(iterative-level schedule)以单轮迭代的方式对用户的请求进行处理,即 LLM 生成一个 token 后会重新调度下一轮要处理的请求。后者(PagedAttention)受操作系统虚拟内存和分页思想启发,将原本连续的 KV cache 存储在不连续的空间,以避免 KV cache 带来的显存浪费。

vLLM 对外提供了 LLM 和 AsyncLLMEngine 接口,前者用于离线推理(offline inference),后者用于在线服务(online serving)。本文只提及 LLM 接口,对于 AsyncLLMEngine 接口的更多介绍请阅读 vLLM 用户文档。

vLLM 工具调研 图 1
图 1

上述为vllm的架构图。它的核心组件是 LLMEngine 类,外层接口类 LLM 和 AsyncLLMEngine 都是对 LLMEngine 的封装。 LLMEngine 有两个核心组件,分别是负责请求调度的 Scheduler 和负责模型推理的 Worker,前者从等待队列中选择接下来要处理的请求,后者负责使用模型对被调度的请求进行推理。

Scheduler 使用 iterative-level 策略对请求进行调度(选择要被处理的请求),被调度的请求在生成一个 token 后会被重新调度。得益于 itertive-level 策略,vLLM 能够在每一轮新的迭代时选择不固定数量的请求进行处理(即 batch size 每次都不一定相同),因此它能够尽可能多地处理请求。

请求的处理通常分为两个阶段,第一个阶段对 prompt 进行处理(也被称为填充阶段,后文使用填充阶段表示这一个阶段),生成 prompt KV cache 的同时生成第一个 token,第二个阶段是生成阶段,不断预测下一个 token。

目前对 iterative-level 的实现有两种方式,一种是区分填充阶段和生成阶段,另一种是不区分这两个阶段。具体而言,同一个 batch 里被处理的请求是否均处于同一个阶段(例如填充阶段或者生成阶段。vLLM 采用的 iterative-level 策略是区分两个阶段的(https://github.com/vllm-project/vllm/pull/658),即同一批被调度的请求要么都处于填充阶段,要么都处于生成阶段,这和 huggingface 的 TGI 推理库一致。而提出 iterative-level 策略的 Orca 系统是不区分这两个阶段的。

Scheduler 中有 3 个队列,waiting(接受到的新请求会先放入 waiting 队列)、running(被调度的请求)和 swapped 队列(swapped 队列用于存放被抢占的请求,即当请求处于生成阶段时,但由于空间的不足,需暂时将 running 队列中优先级低的请求移到 swapped 队列)。在调度时,Scheduler 会按照先到先处理(first come first served)的原则从 waiting 队列中选择请求放入 running 队列(注意,实际的调度包含更多细节,会在后续的文章中做更详细的介绍)。

此外,Scheduler 的另一个核心组件是 BlockSpaceManager,它主要负责块表的维护。

Worker 负责模型的执行。如果模型过大,可以将模型切分到多个 Worker 共同完成请求的处理。

假设模型有 4 层,现在有 4 张卡,可以设置 Tensor Parallel=4(注意:截止 v0.4.0,vLLM 还没有支持 Pipeline Parallel),则将模型切分为 4 份,每张卡存放模型的一部分。

vLLM 工具调研 图 2
图 2

Worker 的一个核心组件是 CacheEngine,它负责 KV cache 的初始化以及 KV cache 的相关操作。

下面以具体的示例演示 vLLM 的工作流。

Vllm的工作流如下

在初始化阶段,主要初始化 LLMEngine 中的 Scheduler 和 Worker 对象,Scheduler 的初始化主要是块表(block table)的初始化,Worker 的初始化包括模型的初始化以及 KV cache 的初始化,

vLLM 工具调研 图 3
图 3

调度和推理

假设 vLLM 接收到 3 个请求(记为 s0, s1, s2)并放入 waiting 队列中,它们的 prompt 分别为 "Hello, my name is"、"The future of AI is" 和 "The life is"。

接下来开始 vLLM 的调度和处理。

vLLM 的第一轮处理

假设 vLLM 在这一轮只能调度两个请求进行处理,那么根据先到先处理的原则,会从 waiting 队列中选择 s0 ("Hello, my name is") 和 s1 ("The future of AI is") 放入到 running 队列。对于 s0,Worker 生成的 token 为 Dustin,对于 s1,Worker 生成的 token 为 bright。同时,Worker 会将计算过程产生的 KV 值存储在 KV cache 中,

vLLM 工具调研 图 4
图 4

vLLM 的第二轮处理

由于 waiting 队列中还有一个请求 s2(The life is),因此,vLLM 在第二轮只会处理这一个请求,因为前面提到,vLLM 只会处理要么都是填充阶段的请求,要么都是生成阶段的请求。

vLLM 工具调研 图 5
图 5

vLLM 的第三轮处理

waiting 队列中没有要处理的新请求,所以会从 running 队列中选择此轮要处理的请求(这些请求均处于生成阶段)。但由于没有多余的空间,vLLM 只会选择 s0 和 s1 进行处理。经过多轮调度和推理,最终完成 3 个请求的处理,以上就是 vLLM 的工作流。

vllm的安装部署

vllm的安装异常艰辛,由于主要用于大模型的推理与部署因此强烈建议在装有gpu资源的linux系统上安装部署。下面给出使用cpu安装的方式。详细步骤参考https://vllm-zh.llamafactory.cn/getting_started/cpu-installation.html

下载源码

git clone https://github.com/vllm-project/vllm.git

下载依赖

sudo apt-get update -y
sudo apt-get install -y gcc-12 g++-12 libnuma-dev
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 10 --slave /usr/bin/g++ g++ /usr/bin/g++-12

安装需要的资源包

pip install --upgrade pip
pip install wheel packaging ninja "setuptools>=49.4.0" numpy
pip install -v -r requirements-cpu.txt --extra-index-url https://download.pytorch.org/whl/cpu

构建oneDNN库,由于要使用cmkae命令,需要cmake版本大于3.26

git clone -b rls-v3.5 https://github.com/oneapi-src/oneDNN.git
snap install cmake –classic
cmake -B ./oneDNN/build -S ./oneDNN -G Ninja -DONEDNN_LIBRARY_TYPE=STATIC \
-DONEDNN_BUILD_DOC=OFF \
-DONEDNN_BUILD_EXAMPLES=OFF \
-DONEDNN_BUILD_TESTS=OFF \
-DONEDNN_BUILD_GRAPH=OFF \
-DONEDNN_ENABLE_WORKLOAD=INFERENCE \
-DONEDNN_ENABLE_PRIMITIVE=MATMUL
cmake --build ./oneDNN/build --target install --config Release

最后构建vllm cpu后端

VLLM_TARGET_DEVICE=cpu python3 setup.py install
vLLM 工具调研 图 6
图 6

安装完成如上图所示,vllm已经安装到本地

vLLM 工具调研 图 7
图 7

Vllm的使用

参考上节安装部署好vllm后下面给出一个快速使用的例子,在python编程中通过import的方式引用vllm

from vllm import LLM, SamplingParams
# Sample prompts.
prompts = [
"Hello, my name is",
"The president of the United States is",
"The capital of France is",
"The future of AI is",
]
# Create a sampling params object.
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
# Create an LLM.
llm = LLM(model="facebook/opt-125m")
# Generate texts from the prompts. The output is a list of RequestOutput objects
# that contain the prompt, generated text, and other information.
outputs = llm.generate(prompts, sampling_params)
# Print the outputs.
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
vLLM 工具调研 图 8
图 8

执行后明显的可以看出,我们有一些prompt,经过推理后可以直接输出context,

vLLM 工具调研 图 9
图 9

下面详细分析这个快速示例的功能和意义,以及vllm在其中的关键作用。

首先import导入模块

之后定义了prompt为我们想让AI补全的内容句子。

然后设置了采样参数

sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

之后加载模型

llm = LLM(model="facebook/opt-125m")

总结

vLLM 的作用:

最后生成文本。

其中vllm的功能是

1. 高效推理框架

vLLM 的核心价值在于优化 LLM 的推理性能和资源使用:

2. 简化 LLM 部署

3. 降低成本

4. 支持生成式 AI 应用

vLLM 是一个高效的分布式推理框架,专注于优化大语言模型(LLM)的推理性能、内存管理和资源利用率。它通过动态批处理和 Lazy Tensor Parallelism 技术,显著降低了显存占用,提升了推理速度,使得超大规模模型在有限的硬件资源上运行成为可能。vLLM 的核心功能包括高性能推理、动态任务分配、灵活的硬件适配和多用户并发支持,为生成式 AI 应用(如文本生成、翻译、问答系统)提供了基础架构支持。在 AI 领域,vLLM 的意义在于推动 LLM 的普及,降低部署门槛,让企业和开发者以更低的成本和复杂度构建强大的 实时AI 应用。未来,vLLM 有望成为 AI 平台中的关键组件,通过支持更广泛的任务、多样化的模型和更高效的服务,为智能客服、创意生成、文档处理等领域提供不可或缺的底层支持,从而扮演 AI 服务的“加速引擎”角色。


Share this post on:

Previous Post
Kubeflow 安装部署与使用
Next Post
这个博客准备开始认真写了