浅谈语言模型推理框架 vLLM 0.6.0性能优化

在此前的大模型技术实践中,我们介绍了加速并行框架Accelerate、DeepSpeed及Megatron-LM。得益于这些框架的助力,大模型的分布式训练得以化繁为简。

然而,企业又该如何将训练完成的模型实际应用部署,持续优化服务吞吐性能?我们不仅要考量模型底层的推理效率,还需从请求处理的调度策略上着手,确保每一环节都能发挥出最佳效能。

本期内容,优刻得将为大家带来vLLM[1],一款高性能推理服务框架的相关内容。vLLM于近期推出了0.6.0版本[2]。那么,相比旧版本推出了什么新功能,又做了哪些优化呢?

优刻得模型服务平台UModelVerse现已同步上线vLLM0.6.0。仅需几步,即刻畅享新版vLLM带来的极速推理体验。文末为您带来详细的使用教程。

01

API服务端-推理引擎进程分离

推理服务框架需要考虑服务部署的两个要素:面向客户请求的服务端,以及背后的模型推理端。在vLLM中,分别由API服务端 (API Server)模型推理引擎 (vLLM Engine)执行相应任务。

1.1 进程共用 vs. 进程分离

根据旧版vLLM设计,负责处理请求的API服务端与负责模型推理的推理引擎,共用同一个python进程;

0.6.0版本将API服务端和推理引擎分离,分别由两个python进程运行。进程之间的信息交互由ZeroMQ socket进行传输 [3]。

图片

上:API服务端与推理引擎共用同一个python进程;
下:API服务端与推理引擎各自独用python进程。

API服务端需要承担一系列处理HTTP请求等任务。通过对旧版本的性能分析,vLLM团队发现API服务端消耗大量CPU资源

举个例子,在推理引擎端,轻负载下使用Llama3 8B模型推理生成1个token的耗时约为13ms;而相对应地,API服务端需要能够每秒处理76个token才能跟上推理引擎的速度。由于python GIL的存在,推理引擎还会与服务端争抢CPU资源。CPU端负载巨大无法及时处理计算,则会使得GPU端因等待CPU而产生空闲,无法充分利用性能[3]。

在0.6.0版本中,将API服务端与推理引擎端分离为两个进程后,两个进程可以各自专注于份内职责,而不会受GIL的影响。而在分离后,团队后续可以更好地对两端分别进行更细致的性能优化和打磨。

1.2 TTFT、TPOT和ITL

在进入测试对比前,先了解一下衡量语言模型服务推理效率通常参照的三个指标,即:

首个token响应时长 (Time to first token, TTFT)

每个token输出时长 (Time per output token, TPOT)

跨token延迟 (Inter-token latency, ITL)

TTFT顾名思义,就是从客户端发出请求后开始计时,直到服务端返回第一个输出token的耗时。过程中,由服务端收到请求后着手处理,交由调度器准备推理。推理引擎需要完成prefill任务。基于prefill得到的kv值,decode得到第一个输出token后返回。

而TPOT和ITL概念相对接近,表达的都是后续一连串decode的耗时。根据vLLM测试代码 [4],我们定义如下:

TPOT是在一个请求从发出后,不纳入TTFT的耗时 (主要是为了排除prefill耗时),到所有token全部decode完成并返回的整体耗时除以一共返回的token数量,即每个token输出的平均时长

而ITL是在计算每次请求返回部分token时所需的时长,即服务端每次decode后返回一个或一批token所需的时长。

举个例子,如果每次服务端返回1个token,则ITL耗时应与TPOT接近;而当每次服务端返回5个token,则ITL耗时应接近于5倍的TPOT耗时 (因为ITL计算单次的时长,而TPOT计算单token的时长)。

1.3 测试&对比

优刻得云主机上开展对比测试。

利用vLLM官方提供的benchmark_serving基准测试,我们可以模拟真实的客户端请求,从而对比vLLM 0.6.0与旧版vLLM (0.5.5)在进程分离上的优化导致的性能差异。关闭其他优化方法后,在保持其他参数不变的情况下,在opt-125m模型上开展测试。

在服务端,我们分别在0.6.0和旧版本上使用以下的参数:

    #vLLM 0.5.5(共用进程)
    vllm serve facebook/opt-125m \
    --max-model-len 2048 \
    --use-v2-block-manager

    #vLLM 0.6.0(分离进程)
    vllm serve facebook/opt-125m \
    --max-model-len 2048 \
    --use-v2-block-manager \
    --disable-async-output-proc #关闭0.6.0的新优化方法:异步输出处理。下文有详解~

而在客户端,我们统一采用以下脚本。我们模拟100个请求同时发出,请求数据随机取自ShareGPT v3数据集。

python vllm/benchmarks/benchmark_serving.py \
    --backend vllm \
    --model facebook/opt-125m \
    --tokenizer facebook/opt-125m \
    --request-rate inf \ #所有请求无间隔同时发送
    --num-prompts 100 \ #共100条请求发出
    --dataset-name sharegpt \
    --dataset-path dataset/ShareGPT_V3_unfiltered_cleaned_split.json \
    --sharegpt-output-len 1024 \
    --seed 42 #固定种子控制变量

经过测试,结果如下 (左旧版本0.5.5;右新版本0.6.0):

图片

进程分离以牺牲TTFT指标为代价 (笔者推测进程间ZeroMQ通信带来开销),测试整体时长(Benchmark duration)比进程共用快近14秒,提速约40%。该模型参数量较小,GPU压力较小,瓶颈主要在于CPU。进程分离消除了CPU争抢造成的开销。

02

多步调度(Multi-step scheduling)

在请求调度层面,vLLM 0.6.0的更新中引入了多步调度 (Multi-step scheduling)的方法 [2],使得请求处理的调度更高效。为了更好地理解多步调度的意义,我们简单了解一下vLLM调度器。

2.1 调度器 (Scheduler)

vLLM推理引擎LLMEngine中存在调度器 (Scheduler)的概念。调度器控制来自服务端的输入请求会以什么顺序送入模型执行推理。

对于一个输入请求,我们需要首先对输入的句子执行prefill计算,并基于prefill得到的kv值开展decode计算,即预测下一个token。而调度器的职责就是以合理的调度策略,安排模型执行prefill或是decode的顺序 (篇幅限制,具体调度细节这里不展开)。

2.2 单步调度 vs. 多步调度

在旧版vLLM中,每次调度器只会为下一次的模型推理安排优先顺序,即每次调度对应一次模型推理。该方法被称为单步推理;

0.6.0引入多步推理,每次调度器调度会安排接下来的多次模型推理,即每次调度对应n次推理。多步推理可以减少调度次数,降低CPU开销,从而让模型推理充分利用GPU资源,尽量保持运行。

图片

上:一次调度后执行1步推理;

下:一次调度后执行3步推理。

据vLLM团队测试,4张H100环境下运行Llama 70B,多步推理的吞吐量比单步推理提升了28%[3]。

2.3 测试&对比

利用上述基准测试,对比单步调度与多步调度的性能差异。这次我们统一使用0.6.0版本。在保持其他设置相同的情况下,设置服务端启动参数分别如下。而客户端方面设置与上文相同,在此不再赘述。

    #单步/多步调度
    vllm serve facebook/opt-125m \
    --max-model-len 2048 \
    --use-v2-block-manager \
    --disable-async-output-proc \ #关闭异步输出处理
    --num-scheduler-steps 1/10 #每次调度1步/10步

以下为测试结果 (左单步调度,右多步调度step=10):

图片

多步调度(step=10)的情况下,基准测试仅耗时7.69秒;而单步调度耗时21.68秒,整体速度上快近3倍。(由于opt-125m模型的参数量较小,计算瓶颈主要位于CPU端,因此对CPU端的优化效果极其显著;对于更大规模的模型,瓶颈位于GPU端,加速效果相对没有这么明显。)

使用NVIDIA Nsight systems [5]进一步分析profile (NVTX中绿色块表明执行调度)。多步调度中每个绿色块之间有10组CPU epoll_pwait和read,即执行10次GPU上的模型推理,并读取结果;而单步推理中每个绿色块之间仅有1组epoll_pwait和read,即1次模型推理。

图片

多步调度(step=10)

图片

单步调度(step=1)

细心的同学可能发现了,上述测试中,尽管多步调度的整体耗时降低了很多,但是ITL远大于单步调度。这是因为多步调度(step=10)将10步推理整合到了一起。

因此,ITL(69.87秒)正好约为10倍TPOT(7.41秒)。增加一场多步调度(step=5)的测试进行验证,可以看到ITL约为41.76秒,约5倍于TPOT的8.79秒。

图片

多步调度(step=5)

03

异步输出处理(ASync output processing)

在旧版vLLM中,GPU端模型推理输出token后,必须在CPU端对输出token进行处理并判断是否符合停止条件 (stopping criteria),从而决定是否继续推理,这个操作会产生时间开销;

新版vLLM引入了异步输出处理,使得模型推理和输出处理异步进行,从而重叠计算的时间[3]。

3.1 异步输出处理

在异步输出处理中,我们把模型输出从GPU端取到CPU端进行停止条件判定时,并不会让模型停止推理,等待判定结果从而导致空闲。在CPU端对第n个输出进行处理并判定是否停止的同时,我们在GPU端假设第n个输出尚不符合停止条件,并继续推理预测第n+1个输出。

这样的设计可能会使得每条请求都多了一次推理,造成些许耗时,但与GPU空闲等待所浪费的时间相比就显得很划算了。 

图片

上:不启用异步输出处理;下:启用异步输出处理。

据vLLM团队测试,4张H100环境下运行Llama 70B,异步输出处理的TPOT指标比禁用快了8.7%[3]。

3.2 测试&对比

我们对比启用和禁用异步输出处理的性能差异。在保持其他设置相同的情况下,设置服务端启动参数分别如下。vLLM 0.6.0中默认启用该功能,可以通过设置参数--disable-async-output-proc来手动关闭。

    #禁用/启用异步输出处理

    vllm serve facebook/opt-125m \
    --max-model-len 2048 \
    --use-v2-block-manager \
    --disable-async-output-proc #移除该参数则默认启用

以下为测试结果 (左禁用异步输出处理,右启用异步输出处理):

图片

异步输出处理可以获得一些细微的性能提升,主要体现在TPOT和ITL上,约5%左右,基本符合预期。

04

在优刻得UModelVerse体验新版vLLM

4.1 创建并启动服务

打开UCloud控制台 (https://console.ucloud.cn/),登录账号。点击左上角的“全部产品”,从中找到“模型服务平台 UModelVerse”

图片

点击进入后,点击左侧栏目中的“服务部署”,并点击“创建服务”

图片

进入界面后,设置想要使用的模型并添加服务名称后,在右侧选择合适的支付方式,并点击“立即购买”,系统自动跳转到支付页面。

图片

完成支付后,页面回到“服务部署”。可以看到我们购买的服务正处于“部署中”的状态,稍作等待......

图片

待状态转为“已上线”后,即可点击“访问”打开网页图形界面,或通过API调用。

图片

4.2 使用服务

4.2.1 通过网页图形界面

点击“访问”即可进入与chatbot的图形对话页面:

图片

4.2.2 通过API接口

当然,我们也可以通过API接口进行对话。以下是调用代码样例。调用的API参数可以在服务列表中找到。其中:

• API_KEY:即API Key

• BASE_URL:为API地址

• MODEL:为模型的名称

图片

图片

Python

from openai import OpenAI

API_KEY = 'aDZ39J204akIPPhmqQtLuf64CBA7ZbyQ0Ov88VzlPuBRjdvP' # API Key
BASE_URL = 'https://ai.modelverse.cn/uminfer-14e3pxj9lnfc/v1' # 模型URL
MODEL = "meta-llama/Meta-Llama-3.1-8B-Instruct" # 模型名

client = OpenAI(
    api_key=API_KEY,
    base_url=BASE_URL
)

# 调用模型生成文本
response = client.chat.completions.create(
    model=MODEL,  # 选择模型
    temperature=0.5, # 温度,模型输出结果的随机性
    max_tokens=512, # 最大tokens长度
    messages=[
        {"role": "user", "content": "你好呀,可以给我讲个笑话嘛?"},
    ]
)

# 获取并打印 AI 生成的回复
print(response.choices[0].message.content)

 【相关资料】

[1] vLLM: https://github.com/vllm-project/vllm

[2] vLLM Highlights: https://github.com/vllm-project/vllm/releases/v0.6.0

[3] vLLM v0.6.0: 2.7x Throughput Improvement and 5x Latency Reduction: https://blog.vllm.ai/2024/09/05/perf-update.html

[4] vLLM benchmark source code: https://github.com/vllm-project/vllm/blob/b67feb12749ef8c01ef77142c3cd534bb3d87eda/benchmarks/backend_request_func.py#L283

[5] NVIDIA Nsight Systems: https://developer.nvidia.com/nsight-systems

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

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

相关文章

初始 html

html 文件结构 html 标签是整个 html 文件的根标签(最顶层标签) head 标签中写页面的属性. body 标签中写的是页面上显示的内容 title 标签中写的是页面的标题 <html><head><title>这是一个标题</title></head><body></body> <…

springboot校园支付系统-计算机毕业设计源码36348

目 录 摘要 Abstract 1 绪论 1.1 研究背景与意义 1.2 开发技术和开发特点 1.3论文结构与章节安排 2 校园支付系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.…

The First项目报告:抗 MEV 交易的CoW Protocol什么?

2023年&#xff0c;当UNIswap推出UniswapX 时&#xff0c;市场迎接它的不是赞叹&#xff0c;而是一片争议。UniswapX被指抄袭 CoWSwap 和 1inch。Curve 官方称 1inch 和 CoWSwap 早已改变游戏规则&#xff0c;UniswapX 非首创。CoWSwap 强调其 Intent Based Trading 的先驱地位…

【Linux系列】 环境配置文件合并的艺术:从`.env`到`.env.combined`

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Fastadmin框架短视频系统视频知识付费源码

简介&#xff1a; FastAdmin框架短视频系统/视频知识付费源码/附带小说系统 系统视频支持包月、单独购买、观影卷等功能 源码附带小说系统 源码需要配置高服务器和VDN加速 图片&#xff1a; 下载地址&#xff1a;云盘下载 原文地址&#xff1a;Fastadmin框架短视频系统视…

计算机体系结构之多级缓存、缓存miss及缓存hit(二)

前面章节《计算机体系结构之缓存机制原理及其应用&#xff08;一&#xff09;》讲了关于缓存机制的原理及其应用&#xff0c;其中提出了多级缓存、缓存miss以及缓存hit的疑问。故&#xff0c;本章将进行展开讲解&#xff0c; 多级缓存、缓存miss以及缓存hit存在的意义是为了保持…

后端SpringBoot学习项目-用户管理-增删改查

最终代码结构 仓库地址 Entity文件 数据库表设计 entity层实现 文件创建 ● 创建entity文件夹 ● 在entity层创建Java类&#xff0c;名字为User (关键字不可使用) 代码实现 package com.example.drhtspringboot.entity;import com.baomidou.mybatisplus.annotation.IdT…

华为入围Linux 内核CVE 检视“五人团”,openEuler要再进阶?

背景&#xff1a;内核社区接管 Linux 社区漏洞发布 往年 Linux 内核漏洞发布存在来源不固定、覆盖不全面&#xff0c;有时发布无修复补丁的 CVE 从而形成 0-day 漏洞等问题&#xff0c;给 Linux 内核安全带来了不确定性&#xff0c;为了更规范化运作&#xff0c;2024 年 2 月 1…

【C语言指南】C语言内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C语言指南》 期待您的关注 引言 C语言是一种强大而灵活的编程语言&#xff0c;为程序员提供了对内存的直接控制能力。这种对内存…

12 Node.js API接口开发

八、API接口 8.1 json-server工具 1&#xff09;安装json-server npm i -g json-server2)示例 //students.json {"student":[{"id":1,"name":"sally","age":18,"gender":"女"},{"id":2,&…

前段时间我所在的公司收到了来自Nevicat的律师函

前段时间我所在的公司收到了来自Nevicat的律师函&#xff0c;至于原因嘛&#xff0c;大家懂的都懂。肯定是因为没有购买人家的正版软件&#xff0c;于是公司下令&#xff0c;所有人禁止继续使用Nevicat自行寻找其他sql工具&#xff0c;迫于无奈&#xff0c;在我使用了十几款主流…

【系统设计】理解带宽延迟积(BDP)、吞吐量、延时(RTT)与TCP发送窗口的关系:优化网络性能的关键

在设计和优化网络性能时&#xff0c;理解 带宽延迟积&#xff08;BDP&#xff09;、吞吐量、延时&#xff08;RTT&#xff09; 和 TCP发送窗口 之间的关系至关重要。这些概念相互影响&#xff0c;决定了网络连接的性能上限&#xff0c;尤其是在高带宽、高延迟的环境中&#xff…

微服务容器化部署实践(FontConfiguration.getVersion)

文章目录 前言一、整体步骤简介二、开始实战1.准备好微服务2.将各个微服务打包为镜像第一种第二种3. 将各个打包好的镜像,通过docker-compose容器编排,运行即可总结前言 docker容器化部署微服务: 将微服务容器化部署到 Docker 容器中是一个常见的做法,可以提高应用的可移…

如何监控员工上网行为?五大妙招轻松上手,员工上网监控全攻略!挖到宝啦!

如何监控员工上网行为&#xff1f; 员工的不当上网行为不仅有可能导致企业机密的泄露&#xff0c;还可能对工作效率造成显著影响。 因此&#xff0c;如何有效地监控员工的上网行为&#xff0c;已成为许多企业管理者关注的重点。 本文&#xff0c;将为您介绍五大妙招&#xff…

【C++ 算法进阶】算法提升十一 十二

目录标题 让字符串成为回文串的最少插入次数题目题目分析代码题目题目 字符子串 &#xff08;滑动窗口&#xff09;题目题目分析代码 最长连续子序列 &#xff08;头尾表&#xff09;题目题目分析代码 让字符串成为回文串的最少插入次数 题目 本题为为LC原题 题目如下 题目分…

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 三种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过 rpm 包安装&#xff0c;需具备基础概念及常规操作。 三、通过 gz 包安装&#xff0c;需具备配置相关操作。 --------…

6.1 软件测试:软件质量与测试

软件质量与测试 1、软价质量保证1.1 软件质量质量控制QC&#xff1a;QUALITY CONTROL质量保证QA:QUALITY ASSURANCE质量成本软件质量软件质量保证 1.2 软件评审1.3 软件可靠性 2、软件测试2.1 软件测试过程模型软件测试策略软件测试策略V模型回归测试软件测试策略原则软件测试策…

JavaEE进阶---SpringMVC(二)请求里面十种参数类型

文章目录 1.请求1.1接受单个参数的请求1.2多个参数的传递1.3传递对象1.4参数重命名1.5设置参数是非必传的1.6数组的请求方式1.7如何传递集合1.8传递json数据1.9获取url里面的参数1.10获取文件 1.请求 1.1接受单个参数的请求 下面的这个就是我们的项目代码&#xff0c;都是单个…

FIPS203 后量子安全ML-KEM(标准简读)

FIPS 203是美国国家标准与技术研究院&#xff08;NIST&#xff09;发布的关于模块格基密钥封装机制&#xff08;ML-KEM&#xff09;的标准&#xff0c;旨在提供一种能抵御量子计算机攻击的密钥建立方案。以下是对该文档的详细总结&#xff1a; 标准概述 目的与范围&#xff…

Android GPU纹理数据拷贝

在 Android 开发中读取纹理数据有以下几种方法&#xff1a; glReadPixelsImageReaderPBO&#xff08;Pixel BufferObject&#xff09; HardwareBuffer 1. glReadPixels glReadPixels 是 OpenGL ES 的 API&#xff0c;通常用于从帧缓冲区中读取像素数据&#xff0c;OpenGL ES…