梳理 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的架构图。它的核心组件是 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 份,每张卡存放模型的一部分。
Worker 的一个核心组件是 CacheEngine,它负责 KV cache 的初始化以及 KV cache 的相关操作。
下面以具体的示例演示 vLLM 的工作流。
Vllm的工作流如下
在初始化阶段,主要初始化 LLMEngine 中的 Scheduler 和 Worker 对象,Scheduler 的初始化主要是块表(block table)的初始化,Worker 的初始化包括模型的初始化以及 KV cache 的初始化,
调度和推理
假设 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 的第二轮处理
由于 waiting 队列中还有一个请求 s2(The life is),因此,vLLM 在第二轮只会处理这一个请求,因为前面提到,vLLM 只会处理要么都是填充阶段的请求,要么都是生成阶段的请求。
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已经安装到本地
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}")
执行后明显的可以看出,我们有一些prompt,经过推理后可以直接输出context,
下面详细分析这个快速示例的功能和意义,以及vllm在其中的关键作用。
首先import导入模块
-
LLM: 用于加载大语言模型(LLM)的核心类。通过 LLM,可以加载模型、配置生成参数并处理推理任务。
-
SamplingParams: 用于控制模型生成时的采样策略,比如温度、top-p 等生成文本的质量和多样性参数。
之后定义了prompt为我们想让AI补全的内容句子。
然后设置了采样参数
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
-
temperature: 控制生成文本的多样性,值越低,生成的文本越保守;值越高,生成的文本越随机和多样化。
-
top_p: 实现核采样(Nucleus Sampling),控制生成时的词汇分布覆盖范围。0.95 表示模型会从概率质量占 95% 的词汇中采样。
之后加载模型
llm = LLM(model="facebook/opt-125m")
-
LLM 类实例化一个模型。
-
model=“facebook/opt-125m”:加载 Facebook 提供的 opt-125m 模型,这是一个小型的预训练大语言模型,用于文本生成。
-
通过 vLLM,模型可以直接从预定义的模型库中加载,也支持加载本地模型。
总结
vLLM 的作用:
-
提供简单的接口以加载和使用预训练模型。
-
在底层优化推理过程,包括显存管理和多任务批处理,使得推理高效且资源消耗低
最后生成文本。
其中vllm的功能是
1. 高效推理框架
vLLM 的核心价值在于优化 LLM 的推理性能和资源使用:
-
动态批处理:支持多个任务同时推理,最大化 GPU 和内存的利用率。
-
内存管理优化:使用 Lazy Tensor Parallelism,减少显存占用,支持大模型在有限资源下运行。
-
高吞吐量:通过智能的任务调度和并行计算,在多用户场景下保持高效响应。
2. 简化 LLM 部署
-
一键式加载模型:通过 LLM 类,开发者可以轻松加载流行的预训练模型(如 OPT、GPT 等),无需复杂的设置。
-
灵活硬件支持:兼容 GPU 和 CPU,支持分布式环境下的推理任务。
3. 降低成本
-
减少硬件需求:通过显存和计算优化,能够在中低端硬件上运行大语言模型,降低部署成本。
-
适合大规模部署:支持多用户并发请求处理,是 SaaS 服务和企业应用的理想选择。
4. 支持生成式 AI 应用
-
提供灵活的接口,适用于生成文本、回答问题、翻译、摘要等场景。
-
通过采样参数调节生成效果,满足不同场景需求(例如更精确或更创造性)。
vLLM 是一个高效的分布式推理框架,专注于优化大语言模型(LLM)的推理性能、内存管理和资源利用率。它通过动态批处理和 Lazy Tensor Parallelism 技术,显著降低了显存占用,提升了推理速度,使得超大规模模型在有限的硬件资源上运行成为可能。vLLM 的核心功能包括高性能推理、动态任务分配、灵活的硬件适配和多用户并发支持,为生成式 AI 应用(如文本生成、翻译、问答系统)提供了基础架构支持。在 AI 领域,vLLM 的意义在于推动 LLM 的普及,降低部署门槛,让企业和开发者以更低的成本和复杂度构建强大的 实时AI 应用。未来,vLLM 有望成为 AI 平台中的关键组件,通过支持更广泛的任务、多样化的模型和更高效的服务,为智能客服、创意生成、文档处理等领域提供不可或缺的底层支持,从而扮演 AI 服务的“加速引擎”角色。