25
2025
02
16:42:02

vLLM框架:认识大模型推理框架

       这两年是大模型盛行的黄金时代,各大优秀的大模型诸如GPT、LLM、QWen、Deepseek等层出不穷,不断刷新我们的认知;但是大模型都有一个共同的特点,都拥有非常惊人的参数量,小的都有上十亿的参数,大的更是可以有几千亿的参数,这么大的参数量就会带来一个新的问题,就是推理效率不如传统的深度学习模型,再有就是目前的大模型基本上都是基于transformer进行开发的,最大限制上下文token数会导致模型在显存的利用率上会有很大的缺陷,基于此,专门针对大模型推理优化的vllm架构应运而生,它凭借PagedAttention核心技术加速了大模型的推理速度。

一、vLLM框架深度解析

1. 框架定位与核心目标
  • 定位: 专为大规模语言模型(LLM)推理设计的高性能服务框架(如GPT-3/4、LLaMA等)。

  • 核心目标:

    • 解决传统推理框架的显存碎片化问题,提升吞吐量(Throughput)10-24倍。

    • 降低服务成本,支持高并发场景(如ChatGPT类应用)。

2. 核心技术:PagedAttention
  • 问题背景:

    • LLM推理时,KVCache显存占用量大且动态变化,传统连续内存分配导致碎片化。

    • 类似操作系统内存分页的痛点。

  • 创新设计:

    • 分块管理: 将KVCache划分为固定大小的块(如4MB),以“页表”形式动态分配。

    • 零碎片化: 块可非连续存储,避免预分配导致的浪费(传统方法浪费60-80%显存)。

    • 共享优化: 支持不同序列间块的共享(如提示词重复场景),显存占用减少55%+。

  • 技术类比:

    • 类似虚拟内存的Page Table机制,但针对GPU显存优化。

    • 与计算机视觉中显存池化技术(如CUDA Unified Memory)有思想共性。

3. 关键性能优势
  • 吞吐量对比:

    • 比HuggingFace Transformers高24倍,比FasterTransformer高3.5倍(官方基准测试)。

  • 显存利用率:

    • 最高可达99%,传统方法通常低于40%。

  • 延迟控制:

    • 首Token生成时间(Time-to-First-Token)优化显著,适合流式输出。

4. 性能对比数据
框架吞吐量 (tokens/s)显存利用率
HuggingFace4538%
Text Generation Inference11265%
vLLM107599%

二、 PagedAttention核心技术

       PagedAttention 是 vLLM 框架的核心创新,其设计灵感源自操作系统的虚拟内存分页机制,旨在高效管理大语言模型(LLM)推理过程中产生的 Key-Value Cache(KVCache)。以下从设计动机、原理、实现细节及对计算机视觉的启示四个层面深入解析。

1. 设计动机:KVCache 的显存管理困境
1.1 KVCache 的作用
  • 在 Transformer 的自回归生成中,每个解码步骤需重复计算历史 token 的 Key 和 Value 矩阵,导致计算冗余。

  • KVCache:缓存已生成 token 的 Key 和 Value 矩阵,避免重复计算,加速推理。

    • 例如:生成第 tt 个 token 时,直接复用前 t−1t−1 步的 KVCache。

1.2 传统方法的瓶颈
  • 连续显存分配:每个请求的 KVCache 需占用连续显存空间。

    • 问题1:显存碎片化:不同请求的 KVCache 因长度动态变化(如对话场景),释放后产生碎片,无法被新请求利用。

    • 问题2:过度预分配:为预防显存不足,通常按最大序列长度预分配显存(如 2048 tokens),实际利用率常低于 40%。

  • 显存浪费示例

    • 假设 GPU 显存为 40GB,单个请求实际需 1GB,但预分配 2GB → 最多支持 20 个并发请求。

    • 采用 PagedAttention 后,显存利用率提升至 90%+ → 支持 36 个请求,吞吐量提升 1.8 倍。

2. 核心原理:分块管理与页表机制
2.1 分块设计
  • 块(Block):将 KVCache 划分为固定大小的块(如 16 个 token 的 K/V 数据,块大小可调)。

    • 块内存储连续 tokens 的 Key 和 Value 矩阵。

    • 类似操作系统的内存页(Page),但针对 GPU 显存优化。

  • 块共享:不同序列可共享相同块(如多个用户询问相同提示词)。

    • 显存节省示例:10 个请求共享 1 个提示词块 → 显存占用减少 90%。

2.2 页表(Block Table)
  • 每个序列维护一个 逻辑页表,记录其 KVCache 块在物理显存中的位置。

    • 逻辑页表条目:[block_id, physical_block_address]

    • 物理块池:全局管理所有可用块,动态分配与回收。

  • 动态分配流程

    1. 序列生成新 token 时,检查当前块是否有空位。

    2. 若当前块已满,从物理块池申请新块,更新页表。

    3. 物理块池无可用块时,触发块淘汰策略(如 LRU)。

2.3 注意力计算优化
  • 分块注意力计算

    • 传统 Attention:

    • PagedAttention:将 K 和 V 按块加载,分块计算 QK^T,再聚合结果。

  • 计算示例

  • 假设 Query 长度为 1,Key/Value 被分为 4 个块:

    # python
    
    for block in key_blocks:
        scores += Q @ block.T
    final_output = softmax(scores) @ concatenated_value_blocks
3. 实现细节与性能优化
3.1 块大小选择
  • 权衡因素

    • 小块 → 灵活性高,但页表管理开销大。

    • 大块 → 管理简单,但可能浪费显存。

  • 经验:16 tokens/block(平衡碎片化与开销)。

3.2 物理块池管理
  • 空闲块列表:维护可立即分配的块。

  • 块回收策略

    • 引用计数:当多个序列共享块时,计数归零后回收。

    • LRU 淘汰:显存不足时,释放最近最少使用的块。

3.3 并行与锁机制
  • 多GPU支持:通过 NCCL 通信同步块状态。

  • 线程安全

    • 块分配/回收使用原子操作或细粒度锁。

    • 避免多线程竞争导致死锁。

4. 性能对比与实测数据
4.1 显存利用率提升
场景传统方法显存占用PagedAttention显存占用
单序列(长度 512)2.1 GB2.1 GB(无优势)
100并发序列(平均长度 300)210 GB(预分配)63 GB(动态分配)
4.2 吞吐量对比
  • 实验配置:A100 GPU,LLaMA-7B 模型,输入长度 512,输出长度 128。

    • HuggingFace Transformers:45 tokens/sec

    • vLLM + PagedAttention:1075 tokens/sec(提升 24 倍)

5. 传统方法导致过度预分配的原因解析

       为了深入理解传统方法为何会导致显存过度预分配,我们需要从 KVCache 的存储特性显存管理机制实际应用场景三个维度展开分析。以下通过类比、数学公式和实际场景示例详细说明;

1. KVCache 的存储特性
1.1 KVCache 的显存占用公式

对于 Transformer 模型的每一层,KVCache 的显存占用可表示为:

显存占用=2×b×s×h×d

  • b: 批处理大小(Batch Size)

  • s: 序列长度(Sequence Length)

  • h: 注意力头数(Number of Heads)

  • d: 每个注意力头的维度(Head Dimension)

以 LLaMA-7B 模型为例(h=32, d=128):

  • 单个请求的序列长度 s=512时,KVCache 占用的显存为:

    2×1×512×32×128=4,194,304 元素≈16.78 MB(float16)

  • 看似不大,但 并发请求数(b) 和 长序列(s) 会指数级放大显存需求。

2. 传统方法的显存分配逻辑
2.1 连续显存分配要求
  • 传统策略:为每个请求的 KVCache 预先分配最大可能长度的连续显存块。

    • 例如:假设最大允许序列长度为 smax=2048,则每个请求预分配:

      2×1×2048×32×128≈67.11 MB

    • 实际使用率:若请求的平均序列长度 savg=300,显存利用率仅为:

      3002048≈14.6%

2.2 显存碎片化的数学解释
  • 问题本质:显存分配/释放后,空闲空间被分割为不连续的小块,无法被新请求利用。

  • 碎片化示例

    • 假设 GPU 显存总容量为 M=40 GB

    • 已有两个请求分别占用了 2GB 和 1GB 的显存,随后释放。

    • 剩余显存:40−(2+1)=37 GB,但 最大的连续空闲块可能仅有 1GB(取决于释放顺序)。

    • 新请求需 1.5GB 连续显存 → 分配失败,尽管总剩余显存足够。

3. 过度预分配的根源
3.1 长尾效应与安全冗余
  • 长尾场景:少数请求需要极长序列(如 s=2048),但多数请求较短(如 s<500)。

  • 保守预分配:为确保所有请求都能完成,必须按 smax 预分配。

    • 若 E[s]=500, smax=2048:

    • 显存浪费率公式:

3.2 显存预留的“停车场悖论”
  • 类比:将显存比作停车场,每个请求是一辆车。

    • 传统方法:为每辆车预留最大可能车位(如可停卡车)。

    • 实际车辆:90% 是轿车,仅需小车位。

    • 结果:大量车位空间浪费,停车场无法容纳更多车辆。

  • 数学表达:设停车场总面积为 A,每辆卡车需面积 amax,轿车需 amin。

    • 传统方法最大车辆数:

    • 理想情况(无浪费):

    • 浪费率:

4. 传统方法 vs. PagedAttention 的显存利用率对比
4.1 传统方法显存分配
  • 显存占用公式

    Mtraditional=b×smax×c

    • c: 单个 token 的 KVCache 成本(如 LLaMA-7B 的 c≈0.033 MB/token)

  • 示例

    • b=100, smax=2048:

      Mtraditional=100×2048×0.033≈6,758 MB≈6.6 GB

4.2 PagedAttention 显存分配
  • 显存占用公式

    Mpaged=⌈b×E[s]\block_size⌉×block_size×c

    • block_size=16: 每个块存储 16 个 token 的 KVCache

  • 示例

    • b=100, E[s]=300, block_size=16:

      总块数=⌈100×300\16⌉=1,875 块

    • Mpaged=1,875×16×0.033≈990 MB≈0.97 GB

4.3 对比结果
方法显存占用利用率提升倍数
传统方法6.6 GB1x(基线)
PagedAttention0.97 GB6.8x

三、总结

       vLLM通过创新的显存管理机制,为LLM推理设定了新标准。对于计算机视觉工程师,其技术思路对视觉大模型优化具有借鉴意义,同时为视觉-语言多模态应用提供了高效的推理基座。建议关注其多模态扩展进展,并尝试将PagedAttention思想迁移到视觉模型的显存优化中。 




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/9149.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: