LLM大模型:推理优化-vLLM显存使用优化

   1、众所周知,transformer架构取得了巨大的成功,核心原因之一就是attention的引入。当年那篇论文的名称就叫attention is all you need,可见attention机制在transformer中的巨大作用!attention的计算示意图如下:

         

  同一个sequence中,每个token的q会和其他所有token的k求内积,得到相似度,然后作为各自v的权重,最终把每个带权重的v相加,就得到了该token的v向量,举例: “我喜欢吃水果,比如苹果、菠萝、西瓜、梨、李子等”。水果的q要和其他所有token的k求内积,结果作为v的权重,最后叠加所有token的v就是水果这个token的最终v向量; 很明显,这里的水果代指的是苹果、菠萝、西瓜、梨、李子,所以正常情况下,水果q和苹果、菠萝、西瓜、梨、李子这些token的k很接近,那么内积的值就比较高,意味者权重大,最终水果v中包含苹果、菠萝、西瓜、梨、李子这些token的v就多,也就是水果v中包含的主要信息就是苹果、菠萝、西瓜、梨、李子这些token的v[其他token的v在水果v的值很小,可以忽略不记];这就是attention的精髓所在:每个token都会根据context调整自己的v值,达到“千人千面”的效果!这也是区分“苹果”到底是可以吃的水果还是电子产品的方法;后续如果有新token加入,现有token之间的q、k内积不需要重新计算了,让新token的q乘以现有token的k,然后用同样的方法更新新token的v向量即可,这就是所谓的kv cache!以13B模型为例,推理时的显存耗费大致如下:

        

   所有parameters占用26GB(应该是FP16,一个参数占用2byte,13B参数占用26GB),kv cache大约占用了12GB、30%的显存;这两大块显存中,parameters占用是刚性的,只要参数量不减少,这个部分显存是没法节约的!剩下的就是kv cache了,用vllm官网的话说:As a result, efficiently managing the KV cache presents a significant challenge. We find that existing systems waste 60% – 80% of memory due to fragmentation and over-reservation. kv cache浪费了60%~80%的显存,原因如下:

  • 预分配显存,但不会用到;比如根据max token = 512,就分配存放512个token的显存,但实际可能第200个token时回答就结束了,剩下的312个token存放空间全浪费
  • 预分配显存,但暂时没用到;比如刚开始分配512个空间,但token是一个一个生成的,刚开始是用不了512个token的,只有等到生成快结束时才会用完512的存储空间
  • 显存之间的间隔碎片,不足以预分配给下个文本生成。

   以上问题导致了kv cache方式对显存的实际利用只有20%~40%,怎么提升显存利用率了?

  2、记得以前学操作系统时,内存管理是非常重要的一个核心功能。内存是有限的,但是用户想要运营的app是无限的,怎么尽可能提高内存利用率,让有限的内存满足用户无限的需求了?

  (1)page:为了减少内存浪费,需要把内存切分成N个小分,有app需要的时候就提供多个小分内存供其使用,每一小分就是一个page,大小为4KB. 同理,为了节约显存的使用,也可以人为把显存切分成多个小块,每个小块在需要的时候才分配。

           

   如上图所示:显存被切分为多个block,每个block最多存放4个token。block按需分配,就算浪费,最多控制3个token的空间!官方的数据:In practice, this results in near-optimal memory usage, with a mere waste of under 4%. This boost in memory efficiency proves highly beneficial: It allows the system to batch more sequences together, increase GPU utilization, and thereby significantly increase the throughput as shown in the performance result above. 采用小的block按需分配内存,浪费降到了4%;

   (2)内存浪费的问题解决了,碎片化怎么办了?搞IT的人都直到的基本数据结构:链表!这种数据结构相比数组,不需要连续的内存,只需要下一个数据节点的内存地址即可,所以链表完全可以被使用在碎片化的内存中存放数据;对于碎片化的显存,可以采用同样的思路充分利用起来,方案如下:

        

   建立一个映射表block table,记录logical kv cache block和physical kv cache block之间的对应关系;physical kv cache block之间可以是不连续的、碎片化的,但只要正确的位置被记录在block table,程序在读取的时候就能找到正确的数据

   (3)block 共享:离线部署大模型上线后,为了和用户需求对齐,需要收集用户的个人偏好,然后通过DPO的方式微调,所以同一个prompt,可能会生成2~3个不同的答案,让用户选择最喜欢的那个!问题又来了:同时生成2~3个答案,怎么提升速度了?

  假如promt是“the future of artificial intelligence is”,回答有两个,如下:

   

   显存分配和使用如下:prompt相同部分存放的block共享,后续的生成一旦发生分歧,变得不一样,那么开始分配新的block,两个回答分别在新的block中存储,这就是copy on wirte!

        

   3、官方的效果数据:In our experiments, vLLM achieves up to 24x higher throughput compared to HF and up to 3.5x higher throughput than TGI.

          

   4、具体实操,vllm官方已经提供了现成的API直接调用即可:

from vllm import LLM, SamplingParamsprompts = ["怎么用IDA打开二进制文件?","frida hook失败了怎么办?","sql map怎么查找sql注入点?","怎么逆向app和服务器之间的通信协议?",
]sampling_params = SamplingParams(temperature=0.8, top_p=0.95, max_tokens=512)
llm = LLM(model="/root/huggingface/secgpt", trust_remote_code=True)
outputs = llm.generate(prompts, sampling_params)# Print the outputs.
for output in outputs:prompt = output.promptgenerated_text = output.outputs[0].textprint(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

 

 

参考:

1、https://blog.vllm.ai/2023/06/20/vllm.html  官方介绍

2、https://www.bilibili.com/video/BV1kx4y1x7bu/?spm_id_from=333.337.search-card.all.click&vd_source=241a5bcb1c13e6828e519dd1f78f35b2    怎么加快大模型推理?10分钟学懂VLLM内部原理,KV Cache,PageAttention

3、https://aibyhand.substack.com/  AI by hand

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

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

相关文章

sql拦截器的应用

问题:在实际开发当中,日志log的打印无法直接对sql层出现的问题进行整而概之的显示,使得开发中对sql层的具体变动无法直观的查看。当出现sql层方法报错后,需要不断地打log逐条分析错误,再进入sql层分析问题。 解决方案:利于mybatis的sql拦截器工具进行对sql的拦截以及日志…

vite+vue3+ts+pinis搭建项目框架

一:使用 vite 快速创建脚手架 1.创建新项目 命令行输入后,依次选择vue -> typescript。1 yarn create vite vite_vue3_typescript_pinia_template --template2.cd 到项目文件,安装依赖,启动项目1 # 进入项目文件夹 2 cd vite_vue3_typescript_pinia_template 3 # 安装依…

抖音私信卡片制作教程,使用W外链创建抖音/快手/小红书卡片

在数字营销和社交媒体日益繁荣的今天,利用外部链接(W外链平台)为抖音平台创建卡片已成为一种有效的推广手段。抖音卡片不仅可以直接将观众导向目标网页或产品,还能提高用户的参与度和品牌的曝光度。下面,我们将详细介绍如何使用W外链平台创建抖音卡片。 一、了解W外链平台…

GMSSL2.x编译鸿蒙静态库和动态库及使用

一、编译环境准备 1.1 开发工具 DevEco-Studio下载。 1.2 SDK下载 ​ 下载编译第三方库的SDK有两种方式,第一种方式从官方渠道根据电脑系统选择对应的SDK版本,第二种方式通过DevEco-Studio下载SDK。本文只介绍通过DevEco-Studio下载SDK的方式。安装SDK到本地根据SDK安装位置…

自定义测试器

测试器测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,使用”is”关键字来进行测试。{% set name=ab %} {% if name is lower %} <h2>"{{ name }}" are all lower case.</h2> {% endif %}测试器本质上也是一个函数,它的第一个参数就是待…

Invalid or unexpected token

异常:原因: js代码中可能符号错误,如括号没有关闭、半角全角、 本次的原因是双引号没有关闭

minix 文件系统

来自:https://in1t.top/2020/05/04/minix-1-0-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/ 下一个模块将是 fs(file system) 文件系统模块,在开始阅读源码之前,先对 Linux 0.11 中使用的 Minix 1.0 文件系统有个大致的概念,这对之后的代码阅读会有很大的帮助 文件系统是操作系统…

栅格地图

在ROS中,地图是非常基本的元素,特别对于2D激光SLAM而言,栅格地图可以说是必不可少的元素。机器人在需要前往目标点时,需要在栅格地图中找到一条合适的路径从当前点到达目标点,这部分内容在move_base中有了详细的接口,可以直接调用并返回路径。但是作为一名工程师,不仅要…

VA02/VA03增加alv

项目背景:搞备库单(新建一种类型的销售订单),备库单不出货(通过排程明细类别控制,也需要新增),正式销售订单创建时,备库单分配数量给正式SO,SO的排程明细类别也是新增的(不跑MRP), 创建后,如果备库单已有库存,则从备库单直接自动调拨库存到正式SO上,还有其它的一…

Folding Strip

第一次在考场中做出来的E题,rank也是来到了20,纪念一下,一定要相信自己呀 构造方法见官方题解,证明见下: 对于原始串\(s\),如果第一个(从左往右数)相同交界不折,选择折后面的交界,那么根据决策包容性,我们可以折一下第一个相同交界,答案不会更差,如下 如果不折第一…

【matplotlib】生成各种图表

一、场景工作中,可能需要使用脚本分析各种数据,并生成图表二、工具matplotlibhttps://matplotlib.org/stable/install/index.html三、安装python -m pip install -U pip python -m pip install -U matplotlib 四、生成图表 1、折线图import matplotlib.pyplot as plt# 准备数…