vLLM 介绍与使用

发布时间: 更新时间: 总字数:5243 阅读时间:11m 作者: IP上海 分享 网址

vLLM 是一个用于大型语言模型 (LLM) 推理加速的开源库,它以其卓越的性能和易用性而闻名。vLLM 的核心优势在于其创新的PagedAttention算法,该算法有效解决了传统注意力机制在处理长序列时内存碎片化的问题,从而显著提高了吞吐量和降低了延迟。

介绍

vLLM 的主要特点包括:

  • 高吞吐量和低延迟: 归功于 PagedAttention 算法,vLLM 能够高效地管理注意力键值 (KV) 缓存,从而实现业界领先的推理性能。
  • 高效的内存利用率: PagedAttention 借鉴了操作系统中的分页思想,使得 KV 缓存的内存分配更加灵活和高效,避免了内存浪费。
  • 易于使用: vLLM 提供了简单直观的 API,用户可以轻松地集成到现有项目中。
  • 广泛的模型支持: vLLM 支持 Hugging Face Transformers 库中的绝大多数流行模型。
  • 分布式推理: 支持在多个 GPU 上进行模型推理,进一步提升性能。
  • 流式输出: 能够像 ChatGPT 一样实时生成和返回文本。

当前不支持 CPU(vLLM primarily focuses on GPU acceleration, native and optimized CPU support for vLLM is not its core offering)

PagedAttention

随着大型语言模型(LLM)的不断发展,它们在处理长序列输入时面临着巨大的内存挑战。传统的注意力机制需要存储所有键(Key)和值(Value)向量,这被称为KV Cache。当序列长度增加时,KV Cache 会迅速占用大量显存,成为 LLM 推理效率的瓶颈。PagedAttention 正是为了解决这个问题而诞生的。

什么是 PagedAttention?

PagedAttention 是 vLLM(一个高效的 LLM 推理和服务引擎)中引入的一项创新技术,它借鉴了操作系统中虚拟内存和分页的思想来管理 KV Cache。

在传统的注意力机制中,KV Cache 是连续存储的,这意味着即使序列中途有填充(padding)或分批处理(batching)导致的空间浪费,这部分内存也无法被其他序列利用。PagedAttention 打破了这种限制,它将 KV Cache 分割成固定大小的块(blocks),这些块可以不连续地存储在内存中。

PagedAttention 的核心原理

PagedAttention 的核心原理可以概括为以下几点:

  1. KV Cache 分块: PagedAttention 将每个序列的 KV Cache 划分为多个固定大小的块。每个块包含特定数量的令牌(tokens)的键和值向量。
  2. 块表(Block Table): 对于每个序列,PagedAttention 维护一个逻辑块表。这个块表记录了该序列的逻辑块与实际存储在显存中的物理块之间的映射关系。
  3. 按需分配: 只有当模型处理到新的令牌时,才会在显存中按需分配新的物理块来存储对应的 KV Cache。
  4. 共享和复用: PagedAttention 允许不同序列共享相同的物理块。当多个序列拥有共同的前缀时(例如,在批处理推理或 Beam Search 中),它们可以共享这些前缀对应的 KV Cache 块,从而显著减少内存占用。
  5. 内存碎片优化: 通过将 KV Cache 分块并允许不连续存储,PagedAttention 有效地减少了内存碎片化,提高了显存利用率。

PagedAttention 的优势

PagedAttention 技术为 LLM 的推理带来了显著的优势:

  • 显著提高显存利用率: 这是 PagedAttention 最主要的优势。通过避免 KV Cache 的内存碎片和实现块共享,它大大减少了显存的占用,使得在相同硬件条件下可以处理更长的序列或更大的批次。
  • 支持更长的上下文窗口: 由于显存利用率的提高,LLM 可以处理更长的输入序列,从而更好地理解和生成长篇文本。
  • 提高吞吐量: 更高的显存利用率意味着可以并行处理更多的请求,从而显著提高 LLM 服务的吞吐量。
  • 动态批处理(Dynamic Batching): PagedAttention 与动态批处理相结合,可以更有效地管理请求,进一步优化资源分配。
  • 支持高效的 Beam Search: 在 Beam Search 中,不同的候选序列可能共享相同的前缀。PagedAttention 允许这些共享前缀的 KV Cache 块被高效地复用,极大地提高了 Beam Search 的效率。

总之,PagedAttention 技术通过引入类似操作系统虚拟内存管理的方式,彻底改变了 LLM KV Cache 的管理方式。它有效地解决了 LLM 在处理长序列时面临的内存瓶颈,显著提高了显存利用率、吞吐量,并使得 LLM 能够处理更长的上下文。这项技术是 vLLM 之所以能够提供高性能 LLM 推理服务的关键之一,也为未来 LLM 的进一步发展奠定了基础。


Continuous Batching (连续批处理)

LLM 连续批处理(Continuous Batching),也称为动态批处理(Dynamic Batching),是一种旨在显著提高大型语言模型(LLM)推理吞吐量和效率的关键技术。传统上,LLM 推理采用静态批处理,即在每个推理步骤中将固定数量的请求打包在一起。然而,这种方法在处理可变长度的序列和请求到达不规律的情况下效率低下。

为什么需要连续批处理?

在理解连续批处理之前,我们需要了解传统批处理的局限性:

  • 填充(Padding)浪费: 传统批处理通常需要将较短的序列填充(pad)到批次中最长序列的长度,以确保所有序列的计算量一致。这导致了大量的计算资源浪费,因为填充的部分并不包含有效信息。
  • 低 GPU 利用率: 当请求到达不规律或序列长度差异大时,静态批处理可能导致批次未完全填充,从而降低 GPU 利用率。
  • 高延迟: 对于需要快速响应的实时应用,等待积累足够的请求来填充一个批次会引入额外的延迟。

连续批处理的工作原理

连续批处理的核心思想是动态地管理和调度 GPU 上的请求,以最大化其利用率并减少不必要的等待和填充。它通常结合了以下几种关键机制:

  1. 请求队列和动态批次构建:

    • 所有传入的请求都会被放入一个等待队列。
    • 调度器会根据 GPU 的当前负载、可用内存以及序列长度等因素,动态地从队列中选择请求来构建批次。这意味着批次的大小不再是固定的,而是根据实际情况调整。
    • 与传统批处理不同,连续批处理不会等待整个批次完成推理才开始下一个批次。相反,一旦一个请求的推理完成,它就会被从批次中移除,并立即为新的请求腾出空间。
  2. 注意力键值(KV)缓存共享:

    • LLM 在生成每个 token 时都会计算注意力机制中的键(Key)和值(Value)。这些 KV 张量通常会被缓存,以便在生成后续 token 时重用,避免重复计算。
    • 连续批处理利用了 KV 缓存的共享机制。当多个请求在 GPU 上并行处理时,它们的 KV 缓存可以被有效地管理和复用,减少内存占用并提高计算效率。
    • 即使请求的长度不同,每个请求的 KV 缓存也会独立存储,只占用实际需要的内存空间。
  3. 预测性调度和并行化:

    • 通过预测每个请求的生成长度(或最大生成长度),调度器可以更智能地分配 GPU 资源。
    • 不同的请求可以并行地在 GPU 上运行,即使它们处于生成过程的不同阶段。例如,一个请求可能正在生成第 5 个 token,而另一个请求可能正在生成第 50 个 token。

连续批处理的优势

  • 显著提高吞吐量: 这是连续批处理最主要的优势。通过减少填充和提高 GPU 利用率,它可以处理更多的并发请求。
  • 降低平均延迟: 请求不再需要等待完整的批次,一旦进入就可能被处理,从而缩短了平均等待时间。
  • 提高 GPU 利用率: 减少了 GPU 的空闲时间,确保计算资源得到更充分的利用。
  • 更好的内存管理: 通过动态管理 KV 缓存,连续批处理可以更有效地利用 GPU 内存,从而允许更大的模型或更多的并发请求。
  • 处理可变长度序列更高效: 避免了对短序列进行不必要的填充,从而节省了计算资源。

常见实现的框架

目前,一些流行的 LLM 推理框架已经内置或正在积极开发对连续批处理的支持,例如:

  • vLLM: 一个专门为 LLM 离线和在线推理优化的库,其核心特性就是高效的连续批处理(PagedAttention)。
  • TensorRT-LLM: 英伟达的 LLM 优化库,也支持动态批处理和 KV 缓存优化。
  • DeepSpeed-Mii: 微软 DeepSpeed 团队的推理优化库,也提供了相关的批处理优化功能。

vLLM 支持的模型格式

vLLM 主要支持 Hugging Face Transformers 格式的模型。这意味着只要是 Hugging Face Hub 上可用的模型,并且能够通过 Transformers 库加载,vLLM 通常都能够对其进行加速推理。

具体来说,这包括但不限于以下类型的模型:

  • 因果语言模型 (Causal Language Models): 如 Llama、GPT 系列 (GPT-2, GPT-NeoX)、Mistral、Gemma、Falcon 等,这些模型通常用于文本生成、问答、摘要等任务。
  • 编码器-解码器模型 (Encoder-Decoder Models): 虽然 vLLM 主要优化的是解码器模型的推理,但一些编码器-解码器模型的解码部分也可以受益。
  • 多模态模型: 一些基于 Transformer 架构的多模态模型(如某些视觉语言模型)的文本生成部分也可以通过 vLLM 进行加速。

重要提示: vLLM 不支持 ONNX、TensorRT 等特定推理引擎的优化格式,它直接加载 Hugging Face 的模型权重和配置文件。当您准备使用 vLLM 时,请确保您的模型是通过 transformers 库的 AutoModelForCausalLM.from_pretrained() 等方法加载的标准 Hugging Face 格式。


安装

要运行 vLLM,您首先需要安装它。

pip install vllm

接下来,我们以一个简单的文本生成任务为例,展示 vLLM 的基本用法。

Kubernetes

示例

示例 1:基本文本生成

from vllm import LLM, SamplingParams

# 1. 初始化 LLM 模型
# 这里我们以 "meta-llama/Llama-2-7b-chat-hf" 为例,您可以替换为其他支持的模型
# 如果是本地模型,可以直接指定模型路径,例如:model="/path/to/your/model"
llm = LLM(model="meta-llama/Llama-2-7b-chat-hf")

# 2. 定义采样参数
# temperature: 控制生成文本的随机性,值越高越随机
# top_p: 控制核采样(nucleus sampling),只考虑概率累积和达到 top_p 的词
# max_tokens: 生成的最大 token 数量
sampling_params = SamplingParams(temperature=0.7, top_p=0.95, max_tokens=100)

# 3. 准备输入提示
prompts = [
    "Hello, my name is",
    "The capital of France is",
    "Tell me a short story about a dragon.",
]

# 4. 生成文本
outputs = llm.generate(prompts, sampling_params)

# 5. 打印结果
for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

运行说明:

  • 首次运行 LLM(model="...") 时,vLLM 会自动从 Hugging Face Hub 下载模型权重和配置文件。这可能需要一些时间,具体取决于您的网络速度和模型大小。
  • model 参数可以指定 Hugging Face Hub 上的模型名称,也可以是本地模型文件的路径。
  • SamplingParams 允许您微调文本生成行为。

示例 2:使用 GPU 数量和量化模型

vLLM 也支持在多个 GPU 上运行,并且可以加载量化模型以减少显存占用和提高推理速度(如果模型提供了量化版本)。

from vllm import LLM, SamplingParams

# 初始化 LLM 模型,指定使用2个GPU进行张量并行,并加载4比特量化模型(如果可用)
# device_map="auto" 也可以用于自动分配 GPU
llm = LLM(
    model="meta-llama/Llama-2-7b-chat-hf", # 替换为实际支持量化的模型或路径
    tensor_parallel_size=2,  # 使用2个GPU进行张量并行
    dtype="auto",            # 自动选择数据类型,或指定如 "bfloat16", "float16"
    quantization="awq"       # 如果模型支持 AWQ 量化,可以这样指定
)

sampling_params = SamplingParams(temperature=0.7, top_p=0.95, max_tokens=100)

prompts = [
    "Explain the concept of quantum entanglement.",
    "Write a poem about the beauty of nature.",
]

outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

运行说明:

  • tensor_parallel_size 参数用于指定使用的 GPU 数量。
  • quantization 参数可以指定量化方法,例如 "awq""gptq" 等,前提是模型本身支持这些量化。使用量化模型可以显著降低显存需求。
  • 在运行这些示例之前,请确保您的环境中安装了相应的 PyTorch 版本和 CUDA 驱动,以便 vLLM 能够正确地利用 GPU 进行计算。

离线推理 vs 在线服务

在 vLLM 中,offline inference (离线推理)online serving (在线服务) 代表了两种不同的使用模式和应用场景,它们在设计目标、交互方式和优化侧重上有所区别。

Offline Inference (离线推理)

离线推理通常指的是在非实时、批量处理的场景下运行模型。

  • 交互方式:
    • 直接通过 vLLM 的 Python API(使用 vllm.LLM 类)进行调用。
    • 用户提供一个或一批输入(prompts),模型一次性处理这些输入并返回结果。
    • 没有 HTTP 服务器层,通常在脚本或程序中直接执行。
  • 设计目标:
    • 最大化吞吐量 (Throughput):目标是在给定时间内处理尽可能多的请求或生成尽可能多的 token。
    • 批量处理 (Batch Processing):非常适合处理大量预先准备好的数据,例如生成数据集、对文档进行批量摘要、预计算静态内容等。
  • 应用场景:
    • 数据生成和扩充。
    • 离线分析和报告。
    • 内容预处理。
    • 模型基准测试 (benchmarking)。
  • 特点:
    • 通常不需要低延迟,更关注整体处理效率。
    • 可以利用 vLLM 的 PagedAttention 等优化技术,实现高效的批处理和显存管理。
    • 通常通过 Python 脚本直接调用,无需启动额外的服务进程。

Online Serving (在线服务)

在线服务通常指将模型部署为一个可访问的服务,以实时响应单个或少量并发请求。

  • 交互方式:
    • 通过 vLLM 提供的OpenAI 兼容的 HTTP API 服务器进行调用(使用 vllm serve 命令启动服务)。
    • 客户端(如聊天机器人、Web 应用)通过 HTTP 请求向服务器发送 prompts,并实时接收生成的响应。
    • 支持流式输出 (streaming output),即模型生成一个 token 就返回一个 token,而不是等待整个响应生成完毕。
  • 设计目标:
    • 低延迟 (Low Latency):目标是尽快响应每个单独的请求,确保用户体验流畅。
    • 高并发 (High Concurrency):需要能够同时处理多个用户的请求,即使请求是异步到达的。
    • 可用性 (Availability):作为一个服务,需要保证其稳定运行和可用性。
  • 应用场景:
    • 聊天机器人和对话系统。
    • 实时问答系统。
    • Web 应用程序的后端服务。
    • API 集成。
  • 特点:
    • vLLM 的在线服务通过Continuous Batching (连续批处理) 技术来优化效率,即使是单独的请求,也会在后台尽可能地进行批处理,以提高 GPU 利用率。
    • 提供了标准化的 API 接口(如 OpenAI API),便于集成到各种应用中。
    • 通常需要长时间运行的服务进程。

区别

特征 Offline Inference (离线推理) Online Serving (在线服务)
调用方式 Python API (vllm.LLM 类) HTTP API Server (OpenAI 兼容)
目的 批量处理,最大化吞吐量 实时响应,最小化延迟,支持高并发
数据流 批量输入,批量输出 单个或少量并发请求,实时或流式输出
部署形式 通常作为脚本或程序的一部分执行 作为独立的 HTTP 服务持续运行
典型场景 数据预处理、离线分析、基准测试 聊天机器人、实时问答、Web 应用后端

虽然两者在实现上都受益于 vLLM 的底层优化(如 PagedAttention),但它们针对不同的工作负载类型进行了优化,选择哪种模式取决于你的具体需求:如果你需要对大量数据进行批处理,使用离线推理更合适;如果你需要为用户提供实时交互式体验,则在线服务是首选。

参考

  1. https://docs.vllm.ai/
  2. https://github.com/vllm-project/vllm
  3. https://hub.docker.com/r/vllm/vllm-openai/
  4. https://docs.vllm.ai/en/v0.9.1/models/supported_models.html
  5. https://docs.vllm.ai/en/v0.9.1/serving/distributed_serving.html
  6. https://docs.vllm.ai/en/v0.8.4/deployment/k8s.html
本文总阅读量 次 本站总访问量 次 本站总访客数
Home Archives Categories Tags Statistics