vLLM:给大模型提提速

vLLM:给大模型提提速

    • 提出背景
      • 迭代级调度
      • 细粒度批处理机制
      • PagedAttention算法、KV缓存管理器、分布式执行

 


提出背景

论文:https://dl.acm.org/doi/pdf/10.1145/3600006.3613165

代码:https://github.com/vllm-project/vllm

文档:https://vllm.readthedocs.io/en/latest/getting_started/quickstart.html

在未优化的系统中,每个请求的KV缓存被存储在连续的内存空间中。

当这些请求动态增长和缩减时,系统很难精确地预测每个请求所需的最大内存大小。

这导致了大量的内部碎片化(预留的内存未被完全使用)和外部碎片化(由于连续内存的需求,可用内存块被分散,不能被有效利用)。

在这里插入图片描述
它突出了三种类型的内存浪费—预留、内部碎片和外部碎片。这些浪费阻止了内存的有效使用,导致无法为其他请求提供空间。

图中的标记(如"four"、“score”、“and”、"seven"等)代表它们自己的KV缓存。

由于为最大潜在序列长度预留了内存,以及由于内存碎片化,导致并非所有内存插槽都得到有效利用,造成了内存空间的浪费。

例如,如果系统为每个请求预留了足够存储2048个令牌的空间,但实际上大多数请求只生成了几百个令牌,那么剩余的内存就浪费了。

同时,由于内存是连续预留的,其他较短的请求也无法利用这些未使用的内存空间。

  • PagedAttention算法:灵感来源于操作系统中的虚拟内存和分页技术,PagedAttention算法将请求的KV缓存分割成块,每个块包含固定数量的令牌的注意力键和值。

    这种方法使得KV缓存的管理更加灵活,类似于操作系统的虚拟内存。

    为了解决这个问题,我们引入了PagedAttention算法。

    该算法将KV缓存分割成多个块(页),每个块只存储固定数量的令牌信息。

    这样,当一个请求需要更多的令牌存储时,系统只需分配更多的块,而不是预留一个巨大的连续空间。这大大减少了内部和外部碎片化。

    例如,如果一个请求初始只生成了200个令牌,系统只需要分配足够存储这200个令牌的块。

    如果请求继续生成更多令牌,系统可以根据需要继续分配更多的块。

    这种方式使得内存利用率大大提高,也允许系统更灵活地管理不同请求的内存需求。

    之所以采用这种子解决方案,是因为KV缓存的动态增长和缩减特性以及其对连续内存空间的需求造成了内存碎片化。

  • vLLM系统:在PagedAttention的基础上构建的一个高吞吐量的分布式LLM服务引擎,采用块级内存管理和预先请求调度,实现了KV缓存内存的近零浪费。

    之所以开发vLLM系统,是为了克服现有服务系统在KV缓存管理上的效率低下问题,特别是内存碎片化和无法利用内存共享的机会。

自回归式生成的效率问题:每个翻译请求都需要模型逐个生成翻译后的词汇,依赖于前面所有词汇的上下文。

由于这种生成方式的顺序性,每次只能处理一个词汇,导致GPU的并行计算能力得不到充分利用,同时内存受限也成为瓶颈。

请求多样性:来自不同用户的请求在长度和复杂度上差异巨大,从简单的病症查询到需要深入分析的研究论文摘要。

如果按照传统批处理方式处理,短请求可能需要等待长请求完成,影响用户体验。

迭代级调度

应用场景:为了提高GPU的利用率并减少内存束缚,我们采用迭代级调度技术。

在处理翻译请求时,系统不是在整个批次完成后才开始处理新的请求,而是在每次迭代生成一个词后,就检查是否有请求已完成。

完成的请求会从当前批次中移除,同时加入新的请求。

这种方法使得新请求能够在下一个迭代就开始处理,大大减少了用户等待的时间。

想象你在一家快餐店工作,你负责制作汉堡。每个汉堡都需要按顺序添加配料:首先是面包底,然后是生菜,接着是汉堡肉,最后是面包顶。客人的订单(即请求)随时都在到来,而且每个客人可能要的汉堡数量不同。

如果你每次只为一个客人制作完所有汉堡后,才开始处理下一个客人的订单,那么后来的客人就需要等很长时间。特别是在忙时,等待时间会变得非常长。

传统处理方式(不使用迭代级调度):

  • 方式:你等待直到有5个客人的订单后,再开始同时为这5个客人制作汉堡。
  • 但是,你得等待最后一个客人的所有汉堡做完,才能开始新一轮的订单处理。
  • 问题:早到的客人需要等待后到客人的汉堡完成,导致不必要的延迟。

改进的处理方式(迭代级调度的比喻):

  • 方式:你开始制作第一轮的5个客人的汉堡,但在每完成一步(比如加完生菜)后,就检查是否有客人的全部汉堡都完成了这一步。
  • 如果是,那这个客人的订单就可以先出去,不用等其他客人的订单完成。
  • 同时,如果有新的客人来了,你就把他们的订单加入到下一步的制作中。
  • 优势:这样做的好处是,每个客人的汉堡可以更快完成,不需要等所有人的都做完才开始出餐。这样就大大减少了客人的等待时间。

假设客人A的订单先完成了加生菜的步骤,而此时客人B的订单刚刚到达。

按照改进的方式,你可以立即把客人A的订单向前推进到下一步(加汉堡肉),同时把新来的客人B的订单加入到加生菜的步骤中。

这样,每个订单都在它准备好进行下一步时立即进行,而不是等待所有订单都达到相同的处理点。

通过这种方法,每个客人的订单都能更快地完成,快餐店能够更高效地处理高峰时期的订单压力,客人满意度也因为等待时间的缩短而提高。

细粒度批处理机制

应用场景:为了应对请求长度差异大的问题,我们采用了细粒度批处理机制。

通过这种机制,系统能够根据每个请求的实际长度动态调整处理批次,避免了为了匹配最长请求而对其他请求进行不必要的填充。

这不仅提升了计算效率,也减少了内存的浪费。

PagedAttention算法、KV缓存管理器、分布式执行

vLLM的系统架构:

在这里插入图片描述

想象你在一个图书馆里负责把书放回书架上。

图书馆非常大,有成千上万本书。

每本书必须放回它特定的区域,但是这些区域在空间上并不是连续的。

这就像LLM服务中的KV缓存管理问题。

  • 使用PagedAttention: 就像你把书分成几堆,每堆书放在一个可以轻松到达的小车上。

    当一个区域的书架满了或者需要在另一个区域放书时,你可以推动小车到那个区域。

    这就是分页机制,让你不必一次性找到一个巨大的连续空间来存储所有书籍,而是可以根据需要动态地移动小车(页)。

在这里插入图片描述

PagedAttention算法的示意图,其中注意力键和值向量存储在非连续的内存块中。

"forth"查询向量指出了该算法如何从物理内存中不连续存储的不同块中检索键和值向量。

  • KV缓存管理器: 假设你有一个助手,他通过无线耳机告诉你哪些书需要放回哪些区域。

    你不需要记住所有书的位置,只需跟随指令行动。

    这就像KV缓存管理器,它根据中央调度器的指令,在GPU工作器上管理物理KV缓存。

  • 分布式执行: 现在,假设图书馆不仅大,而且分布在几栋楼中。

    你和你的同事需要分工合作,确保所有的书都能正确归位。

    每个人负责一栋楼,但大家通过无线耳机相互协调,确保整个图书馆的运作顺畅。

    这就像vLLM的分布式执行策略,使得即使是非常大的模型也可以在多个GPU上有效执行。

通过这种方式,vLLM可以在有限的GPU内存中,以更高的效率处理更多的请求,提高了LLM服务的吞吐量和响应速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/549570.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试算法-48-二叉树的锯齿形层序遍历

题目 给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 示例 1: 输入:root [3,9,20,null,…

电话机器人语音识别用哪家更好精准度更高。

语音识别系统的选择取决于你的具体需求,包括但不限于识别精度、速度、易用性、价格等因素。以下是一些在语音识别领域表现较好的公司和产品: 科大讯飞:科大讯飞是中国最大的语音识别技术提供商之一,其语音识别技术被广泛应用于各…

ASP.NET通过Appliaction和Session统计在人数和历史访问量

目录 背景: Appliaction: Session: 过程: 数据库: Application_Start: Session_Start: Session_End: Application_End: 背景: 事件何时激发Application_Start在调用当前应用…

VSCode创建用户代码片段-案例demo

示例 - 在线生成代码片段 Vue3代码片段 {"vue3": {scope": "javascript,typescript,html,vue","prefix": "vue3","body": ["<template>","$1","</template>",""…

到底什么时候该使用MongoDB

NoSQL是什么 NoSQL &#xff1a; Not Only SQL , 本质也是一种数据库的技术&#xff0c;相对于传统数据库技术&#xff0c;它不会遵循一些约束&#xff0c;比如 &#xff1a; sql 标准、 ACID 属性&#xff0c;表结构等。 NoSQL分类 类型应用场景典型产品Key-value存储缓存&…

算法第三十天-矩阵中移动的最大次数

矩阵中移动的最大次数 题目要求 解题思路 网格图 DFS 从第一列的任一单元格 ( i , 0 ) (i,0) (i,0) 开始递归。枚举往右上/右/右下三个方向走&#xff0c;如果走一步后&#xff0c;没有出界&#xff0c;且格子值大于 g r i d [ i ] [ j ] grid[i][j] grid[i][j]&#xff0c;则…

车载电子电器架构 - 网络拓扑

车载电子电器架构 - 网络拓扑 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎,出门靠…

Unity InputField实现框自适应内容简便方法

要实现InputField框自适应输入内容&#xff0c;除了通过代码进行处理&#xff0c;还可以是使用以下简便的方法。 1、创建InputField组件&#xff1a;右键->UI->Input Field -TextMeshPro。 2、把Input Field Settings中的Line Type设置为Multi Line Newline模式&#x…

自然语言处理: 第十七章RAG的评估技术RAGAS

论文地址&#xff1a;[2309.15217] RAGAS: Automated Evaluation of Retrieval Augmented Generation (arxiv.org) 项目地址: explodinggradients/ragas: Evaluation framework for your Retrieval Augmented Generation (RAG) pipelines (github.com) 上一篇文章主要介绍了R…

vue中判断是否使用自定义插槽

在封装自定义组件时&#xff0c;需要判断使用者是否使用了插槽<slot"aaa">&#xff0c;如果没有则使用一个组件中默认的值&#xff0c;反之就用传入的内容<template name"aaa"></template>,实现如下&#xff1a; <div class"lin…

使用树莓派 结合Python Adafruit驱动OLED屏幕 显示实时视频

关于OLED屏幕的驱动&#xff0c;在之前我已经写过很多篇博文&#xff1a; IIC 协议 和 OLED_oled iic-CSDN博客 香橙派配合IIC驱动OLED & 使用SourceInsight解读源码_香橙派5 驱动屏幕-CSDN博客 这两篇博文都是通过模拟或调用IIC协议来使用C语言驱动OLED屏幕&#xff0c;现…

Tomcat:Session ID保持会话

目录 前言 ​一、部署环境 二、部署nginx反向代理服务器 三、部署tomcat服务器1 四、部署tomcat服务器2 五、客户端测试&#xff08;Session ID不断变动&#xff09; 六、配置Session ID会话保持 七、客户端测试&#xff08;Session ID保持&#xff09; 前言 此次实验…