vLLM介绍

vLLM是伯克利大学LMSYS组织开源的大语言模型高速推理框架,旨在极大地提升实时场景下的语言模型服务的吞吐与内存使用效率。vLLM是一个快速且易于使用的库,用于 LLM 推理和服务,可以和HuggingFace 无缝集成。vLLM利用了全新的注意力算法「PagedAttention」,有效地管理注意力键和值。

vLLM 的特点和优势:

  • 采用了 PagedAttention,可以有效管理 attention 的 keys、values
  • 吞吐量最多可以达到 huggingface 实现的24倍,文本生成推理(TGI)高出3.5倍,并且不需要对模型结构进行任何的改变

1 PagedAttention

1.1 背景
  • LLM 的推理,最大的瓶颈在于显存。
  • 自回归模型的 keys 和 values 通常被称为 KV cache,这些 tensors 会存在 GPU 的显存中,用于生成下一个 token。
  • 这些 KV cache 都很大,并且大小是动态变化的,难以预测。已有的系统中,由于显存碎片和过度预留,浪费了60%-80%的显存。
1.2 实现 受到操作系统中,虚拟内存和分页经典思想的启发
  • PagedAttention 允许在不连续的内存空间中存储连续的 keys 和 values。 具体来说,PagedAttention 会将每个序列的 KV cache 划分为块,每个块包含固定数量 tokens 的 keys 和 values。 在注意力计算过程中,PagedAttention 内核有效地识别并获取这些块。
  • 分块之后,这些 KV cache 不再需要连续的内存,从而可以像在操作系统的虚拟内存中一样,更灵活地对这些 KV cache 进行管理。
  • PagedAttention 对于显存的利用接近理论上的最优值(浪费比例低于4%)。通过对显存进行更好的管理,可以使得单次可以使用更大的 batch size,从而进一步利用 GPU 的并行计算能力。

2 vLLM 离线推理流程

vLLM 整体框架:
在这里插入图片描述
其中的关键技术点包括:

  • KVCache 显存优化
  • PagedAttention
  • Continuous Batching
2.1 LLM 和 LLM Engine

LLM 是对 LLM serving 部分的封装,也是核心部分。首先它会初始化这个类。初始化过程中大部分参数都会被用来构造 EngineArgs,这是一个 dataclass,封装了 Engine 的初始化参数。然后构建 LLM Engine。一个 LLM 只有一个 LLM Engine,所以它就是对 Engine 再包一层。不过按照作者的这个设计意思,LLM Engine 也可以单提出来使用。

初始化 LLM Engine 时候会先调用 create_engine_configs 将 EngineArgs 分解成 ModelConfig,CacheConfig, ParallelConfig 和 SchedulerConfig。其中:

  • ModelConfig 包括了对 model 和 tokenizer 的定义,dtype 和随机数 seed 以及是否用 pretrained weights 还是 dummy weights 等。
  • CacheConfig 包括 block_size(每个 block 多大), gpu_utilization(GPU 利用率,后面 allocate 的时候占多少 GPU)和 swap_space(swap 的空间大小)。默认 block_size=16,swap_space=4GiB。
  • ParallelConfig 包括了 tensor_parallel_size 和 pipeline_parallel_size,即张量并行和流水线并行的 size,由于我们是单卡,这两个都是 1。
  • SchdulerConfig 包括了 max_num_batched_tokens(一个 iteration 最多处理多少个 tokens),max_num_seqs(一个 iteration 最多能处理多少数量的 sequences)以及 max_seq_len(最大生成多长的 context length,也就是一个 sequence 的最长长度,包含 prompt 部分和 generated 部分)。

然后对于每个 device(也即每张卡 / 每个 rank)创建一个 Worker。Worker 是运行 model 的单位。一个 Engine 管理所有的 workers。同时给这个 engine 创建它的 scheduler,以及初始化这个 engine 的 KV cache。

2.2 workers

Worker 是对单个 GPU 的抽象。

Engine 通过调用 _run_workers(“<method_name>”, *args, get_all_outputs, **kwargs) 来在 所有 workers 上执行方法。如果 get_all_outputs 设成 True,那么它会将所有 workers 的返回结果包装成 List 来返回。否则,它只会返回第一个 worker 的结果,并且 assert 所有 workers 的输出都是一样的。在实际执行中主要会调用如下方法(方法名, get_all_outputs=False/True):

  • profile_num_avaiable_block,True:通过一次 “试运行” 来 profile peak memory。 每张卡的 blocks 个数可能不同(显存不同),所以需要 get all outputs。由于 vLLM 使用一个中心化的管理单元,因此我们会对 profile 出来的 blocks 个数取 min。
  • init_cache_engine,False:初始化 cache engine。由于返回 None,所以不需要 get all outputs。
  • execute_model ,False:执行模型。这里虽然是分布式 inference,但是最后 output 都会被 reduce,所以 get all outputs 也设成 False 就好了。

Worker 初始化阶段会初始化模型和一些 distributed 相关的东西。

2.3 Cache Engine

用于管理 KV Cache 的单元。

初始化时候,它先根据之前 profile 的数据(cpu/gpu blocks数)来 allocate cache。然后再给 caching 操作初始化一个 CUDA Stream,以及给每一个 layer 初始化一个 cuda event 来用做 stream synchronization。

在 vLLM 里,每个 key block 的 shape 是 [num_heads, head_size // x, block_size, x],其中 x 是 16 // dtype 的大小。也就是说 fp32 时 x=4,fp16 时 x=8。每个 value block 的 shape 是 [num_heads, head_size, block_size]。

在分配 cpu cache 时候,默认是会用 pin memory 的(除非在 WSL)。

cache engine 里支持了其它两个操作:

  • copy。由专门的 cu 函数 copy_blocks 支持。
  • swap_in 和 swap_out。有点像操作系统里的 swap 概念。in 就是 cpu to gpu,out 就是 gpu to cpu。内部实现由专门的 cu 函数 swap_blocks 支持。

相关的 cu 函数,实现在 csrc/cache_kernels.cu 中:

  • swap_blocks(src, dst, block_mapping): for 一遍 block_mapping,对于每个 [src, dst] pair(block number to block number)做一个单 block 的 copy。支持 GPU to GPU(必须是同一个 GPU 上),GPU to CPU,CPU to GPU。
  • copy_blocks(key_caches, value_caches, block_mapping):这里的 mapping 是 int->list[int],也就是一个 src block idx 对应多个 dst block idx。copy 的过程用一个 global kernel 并行实现。
  • reshape_and_cache(key, value, key_cache, value_cache, slot_mapping)
  • gather_cached_kv(key, value, key_cache, value_cache, slot_mapping)
2.4 memory sharing
  • memory sharing 是 PagedAttention 的另一个关键特性。
  • 当用单个 prompt 产出多个不同的序列时,可以共享计算量和显存。
  • 通过将不同序列的 logical blocks 映射到同一个 physical blocks,可以实现显存共享。
  • 为了保证共享的安全性,对于 physical blocks 的引用次数进行统计,并实现了 Copy-on-Write 机制。
  • 这种内存共享机制,可以大幅降低复杂采样算法对于显存的需求(最高可下降55%),从而可以提升2.2倍的吞吐量。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ZKP价值链路的垂直整合

1. ZKP proof生命周期 从ZKP&#xff08;zero-knowledge proof&#xff09;生命周期&#xff0c;先看围绕ZKP的价值链路形成&#xff1a; 1&#xff09;User intent用户意图&#xff1a;以某用户意图为起点&#xff0c;如想要在某zk-rollup上swap某token、证明其身份、执行某…

java数据结构与算法刷题-----LeetCode405. 数字转换为十六进制数

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 分组位运算 分组位运算 这道题正常来说可以用转换7进制的思想来&…

加速度:电子元器件营销网站的功能和开发周期

据工信部预计&#xff0c;到2023年&#xff0c;我国电子元器件销售总额将达到2.1万亿元。随着资本的涌入&#xff0c;在这个万亿级赛道&#xff0c;市场竞争变得更加激烈的同时&#xff0c;行业数字化发展已是大势所趋。电子元器件B2B商城平台提升数据化驱动能力&#xff0c;扩…

算法学习18:动态规划

算法学习18&#xff1a;动态规划 文章目录 算法学习18&#xff1a;动态规划前言一、线性DP1.数字三角形&#xff1a;f[i][j] max(f[i - 1][j - 1] a[i][j], f[i - 1][j] a[i][j]);2.1最长上升子序列&#xff1a;f[i] max(f[i], f[j] 1);2.2 打印出最长子序列3.最长公共子序…

[从零开始学习Redis | 第九篇] 深入了解Redis数据类型

前言&#xff1a; 在现代软件开发中&#xff0c;数据存储和处理是至关重要的一环。为了高效地管理数据&#xff0c;并实现快速的读写操作&#xff0c;各种数据库技术应运而生。其中&#xff0c;Redis作为一种高性能的内存数据库&#xff0c;广泛应用于缓存、会话存储、消息队列…

MySQL - 基础三

11、事务管理 CURD不加控制&#xff0c;会有什么问题&#xff1f; 当客户端A检查还有一张票时&#xff0c;将票卖掉&#xff0c;还没有执行更新数据库时&#xff0c;客户端B检查了票数&#xff0c;发现大于0&#xff0c;于是又卖了一次票。然后A将票数更新回数据库。这是就出现…

09 flink-sql 中基于 mysql-cdc 的 select * from test_user 的具体实现

前言 这也是最近帮一个朋友看问题 遇到的一个问题 然后 引发了一下 对于 flink-sql 里面的一些 常规处理的思考, 理解 原始问题主要是 在测试库可以使用 flink-sql 可以正常同步, 但是 在生产环境 无法正常同步数据 这个问题 我们后面单独 记录一篇文章 测试用例 下载…

设计模式总结-外观模式(门面模式)

外观模式 模式动机模式定义模式结构外观模式实例与解析实例一&#xff1a;电源总开关实例二&#xff1a;文件加密 模式动机 引入外观角色之后&#xff0c;用户只需要直接与外观角色交互&#xff0c;用户与子系统之间的复杂关系由外观角色来实现&#xff0c;从而降低了系统的耦…

携程旅行 abtest

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章…

WindowsPowerShell安装配置Vim的折腾记录

说明 vim一直以来都被称为编辑器之神一样的存在。但用不用vim完全取决于你自己&#xff0c;但是作为一个学计算机的同学来说&#xff0c;免不了会和Linux打交道&#xff0c;而大部分的Linux操作系统都预装了vim作为编辑器&#xff0c;如果是简单的任务&#xff0c;其实vim只要会…

c/c++之编译链接

了解我们写的代码是如何转变成可执行文件.exe的是很有必要的&#xff0c;我们将这些底层的东西掌握清楚才能打好基础&#xff0c;筑高楼。 编译链接的全流程 我们平时写代码的文件是.c或者.cpp文件。这里面包括我们的代码&#xff0c;还有宏定义&#xff0c;引用头文件以及注…

齐护机器人方位传感器指南针罗盘陀螺仪

一、方位传感器原理及功能说明 齐护方位传感器是一款集成了三轴磁传感器芯片的方位传感器模块。适用于无人机、机器人、移动和个人手持设备中的罗盘&#xff08;指南针&#xff09;、导航和游戏等高精度应用。模块可以感应XYZ平面角度外&#xff0c;还可实现1至2的水平面角度罗…

Python--Django--说明

Django 是基于python 的 Web 开发框架. &nsbp;   Web开发指的是开发基于B/S 架构, 通过前后端的配合, 将后台服务器上的数据在浏览器上展现给前台用户的应用. &nsbp;   在早期, 没有Web框架的时候, 使用 Python CGI 脚本显示数据库中的数据. Web框架致力于解决一些…

考古:IT架构演进之IOE架构

考古&#xff1a;IT架构演进之IOE架构 IOE架构&#xff08;IBM, Oracle, EMC&#xff09;出现在20世纪末至21世纪初&#xff0c;是一种典型的集中式架构体系。在这个阶段&#xff0c;企业的关键业务系统往往依赖于IBM的小型机&#xff08;后来还包括大型机&#xff09;、Oracle…

后端灰度发布

在软件开发中&#xff0c;"灰度"通常指的是渐进式地将新功能、更新或改进引入到生产环境中&#xff0c;但只对一小部分用户或流量进行部署和测试的过程。这种方法允许开发团队在生产环境中逐步测试新功能&#xff0c;以确保其稳定性、可靠性和用户体验&#xff0c;同…

vscode+anaconda 环境python环境

环境说明&#xff1a; windows 10 vscodeanaconda anaconda 安装&#xff1a; 1、官网下载地址:Free Download | Anaconda 2、安装 接受协议&#xff0c;选择安装位置&#xff0c;一直next&#xff0c;到下面这一步&#xff0c;上面是将Anaconda 添加至环境变量&#xff0…

非关系型数据库--------------------Redis 群集模式

目录 一、集群原理 二、集群的作用 &#xff08;1&#xff09;数据分区 &#xff08;2&#xff09;高可用 Redis集群的作用和优势 三、Redis集群的数据分片 四、Redis集群的工作原理 五、搭建redis群集模式 5.1启用脚本配置集群 5.2修改集群配置 5.3启动redis节点 5…

自动驾驶涉及相关的技术

当科幻走进现实&#xff0c;当影视照进生活&#xff0c;无数次憧憬的自动驾驶&#xff0c;正在慢慢的梦想成真。小时候天马星空的想象&#xff0c;现在正悄无声息的改变着我们的生活。随着汽车电动化进程的加快&#xff0c;自动驾驶技术映入眼帘&#xff0c;很多人可能感觉遥不…

非关系型数据库------------Redis的安装和部署

目录 一、关系型数据库与非关系型数据库 1.1关系型数据库 1.2非关系型数据库 1.2.1非关系型数据库产生背景 1.3关系型非关系型区别 1.4客户访问时&#xff0c;关系型数据库与redis的工作过程 二、Redis 2.1redis简介 2.2Redis命中机制和淘汰机制 2.3Redis 具有以下优…

每天五分钟深度学习:深度学习中数据样本和标签的符号化表示

本文重点 在深度学习的研究与应用中&#xff0c;数据样本和标签的符号化表示是至关重要的一环。通过合理的符号化表示&#xff0c;我们可以将现实世界中的数据转化为计算机能够理解和处理的形式&#xff0c;从而为后续的模型训练和推理提供基础。本文将对深度学习中数据样本和…