vLLM 实战

news2025/1/21 5:49:03

引言

随着人工智能技术的飞速发展,以及今年以来 ChatGPT 的爆火,大语言模型 (Large Language Model, LLM) 受到越来越多的关注。

为了实现 LLM 部署时的推理优化,全球各地有众多团队做出了各种优化框架。本文以加州大学伯克利分校开发的 vLLM 框架为例,进行实战探索。

1. 整体介绍

根据公开文档中的实验结果, vLLM 吞吐量比 Hugging Face Transformers 高出 24 倍,比 TGI 高出 3.5 倍。

9d35a62a785406f699cfed5a7c83405b.png

vLLM 整体框架如下图所示。

7af58aa829a2211a1878d63642dfdbad.jpeg

其中的关键技术点包括:

  • KVCache 显存优化

  • PagedAttention

  • Continuous Batching

笔者通过实际使用,认为该框架优点如下:

  • 调试方便: 主框架由 Python 实现,便于用户断点调试。

  • 系统设计工整规范: LLMEngine、Scheduler、Worker 结构清晰,初学者可以方便地理清脉络。

  • 推理速度快: 经过理论计算与实测, 8 卡 A100-40G 足以支持千人试用。

2. offline_inference 示例复现分析

(1) 调试环境配置

为方便复现,笔者制作了 dockerfile 用于编译 base 镜像,base 镜像把 vllm 的依赖库都安装好,基于 base 镜像直接再安装 vllm 库即可复现。

docker build -t vllm_ci-benchmark:base -f ci/docker/ci-benchmark-base.dockerfile .

docker build -t vllm_ci-benchmark:v1 -f ci/docker/ci-benchmark.dockerfile .

镜像是基于 nvidia/cuda:11.8.0-cudnn8-devel-ubuntu20.04 (95d242fe9108) (9.83GB) 制作而来,篇幅所限,此处只展示 ci-benchmark.dockerfile 内容。

FROM vllm_ci-benchmark:base

COPY . /code/vllm

RUN cd /code/vllm && \
    python3 -m pip install -e . && \
    rm -rf ~/.cache

而后基于 vllm_ci-benchmark:v1 镜像创建容器,配置 vscode 断点调试环境,便于跟踪 offline_inference 示例的全流程。

(2) 模型下载与复现

提前从 facebook/opt-125m 下载 pytorch_model.bin 格式的模型和源码文件夹,而后将 offline_inference 中的模型路径改为本地路径,复现结果如下图所示。

c2063a6ac3edc175cd98a065075c717d.png

(3) offline_inference 流程梳理

(a) Create sampling_params

根据用户设置,创建采样参数类对象 sampling_params,只指定 temperature=0.8, top_p=0.95 的情况下,其他默认值如下所示。

SamplingParams(n=1,
               best_of=1,
               presence_penalty=0.0,
               frequency_penalty=0.0,
               temperature=0.8,
               top_p=0.95,
               top_k=-1,
               use_beam_search=False,
               stop=[],
               ignore_eos=False,
               max_tokens=16,
               logprobs=None)

各参数的取值范围见 vllm/sampling_params.py 里相关 _verify_xxx 函数。

(b) Create an LLM

LLM 类对象的构造函数中,首先创建 EngineArgs 类对象 engine_args 如下。

EngineArgs(model='/bigdata/shared/models/huggingface/opt-125m',
           tokenizer='/bigdata/shared/models/huggingface/opt-125m',
           tokenizer_mode='auto',
           trust_remote_code=False,
           download_dir=None,
           use_np_weights=False,
           use_dummy_weights=False,
           dtype='auto',
           seed=0,
           worker_use_ray=False,
           pipeline_parallel_size=1,
           tensor_parallel_size=1,
           block_size=16,
           swap_space=4,
           gpu_memory_utilization=0.9,
           max_num_batched_tokens=2560,
           max_num_seqs=256,
           disable_log_stats=True,
           quant_mode=None)

然后基于 engine_args ,构造 LLM 类内核心变量 llm_engine ,最后添加一个类内计数器 request_counter。

self.llm_engine = LLMEngine.from_engine_args(engine_args)
self.request_counter = Counter()

(c) Generate

LLM.generate 的处理过程中,核心操作分为两步。

第一步是调用 LLM._add_request ,通过 LLM.llm_engine.add_request 将用户传入的请求添加到请求列表中,添加完后,请求列表 LLM.llm_engine.scheduler.waiting 中内容如下。

[ \
    SequenceGroup(request_id=0, sampling_params=SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, temperature=0.8, top_p=0.95, top_k=-1, use_beam_search=False, stop=[], ignore_eos=False, max_tokens=16, logprobs=None), num_seqs=1),
    SequenceGroup(request_id=1, sampling_params=SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, temperature=0.8, top_p=0.95, top_k=-1, use_beam_search=False, stop=[], ignore_eos=False, max_tokens=16, logprobs=None), num_seqs=1),
    SequenceGroup(request_id=2, sampling_params=SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, temperature=0.8, top_p=0.95, top_k=-1, use_beam_search=False, stop=[], ignore_eos=False, max_tokens=16, logprobs=None), num_seqs=1),
    SequenceGroup(request_id=3, sampling_params=SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, temperature=0.8, top_p=0.95, top_k=-1, use_beam_search=False, stop=[], ignore_eos=False, max_tokens=16, logprobs=None), num_seqs=1)
]

第二步是调用 LLM._run_engine,通过 LLM.llm_engine.step(),转到 LLM.llm_engine._run_workers 函数中进行处理。

LLM.generate 的处理过程中,LLMEngine, Scheduler, Worker 协作配合,LLMEngine 负责总控,Scheduler 负责调度,Worker 负责执行,脉络清晰,其设计思路很值得学习借鉴。

3. 总结

vLLM 框架通过 PagedAttention 等关键技术,在多 batch 推理时,与传统 Hugging Face Transformers 框架相比,大幅提高了推理速度和吞吐量。

本文针对 vLLM 框架的 offline_inference 示例进行了复现与梳理分析,接下来准备进一步深入探索 PagedAttention 等特性。受限于笔者知识水平,文中可能会存在某些理解身上的偏差,欢迎各位大佬进行交流,共同进步。

ad80048d69b436b6f874a14bc5bc1316.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言之基础绘图

文章和代码已经归档至【Github仓库:https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 R语言 也可获取。 文章目录 1. 函数 plot( )2.直方图和密度曲线图3.条形图4. 饼图5. 箱线图和小提琴图6. 克利夫兰点图7. 导出图形小结 R 的基础绘图系…

大模型开发05:PDF 翻译工具开发实战

大模型开发实战05:PDF 翻译工具开发实战 PDF-Translator 机器翻译是最广泛和基础的 NLP 任务 PDF-Translator PDF 翻译器是一个使用 AI 大模型技术将英文 PDF 书籍翻译成中文的工具。这个工具使用了大型语言模型 (LLMs),如 ChatGLM 和 OpenAI 的 GPT-3 以及 GPT-3.5 Turbo 来…

【通用消息通知服务】0x4 - 目前进展 阶段复盘

【通用消息通知服务】0x4 - 阶段复盘 达成 基本的API已经写完✍️了(消息查看发送, 模板crud,终端crud,发送渠道crud,计划crud,计划执行查看)拆分server, executor, planner三个入口, 方便针对性水平扩展整体架构初步形成,通过队列实现了事件驱动模型和消息订阅发…

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【六】

😀前言 本篇博文是关于Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【六】,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章…

Apache RocketMQ 5.0 消息进阶:如何支撑复杂的业务消息场景?

作者:隆基 一致性 首先来看 RocketMQ 的第一个特性-事务消息,事务消息是 RocketMQ 与一致性相关的特性,也是 RocketMQ 有别于其他消息队列的最具区分度的特性。 以大规模电商系统为例,付款成功后会在交易系统中订单数据库将订单…

三---开关稳压器

通过控制系统反馈,当电压上升时通过反馈降低,当电压下降时通过反馈升高;形成一个控制环路;控制电路:PWM(脉宽调制),PFM(频率控制方式),移相控制方…

2023开学季有哪些电容笔值得买?平价电容笔推荐

在日常生活中,这支电容笔的使用范围很广,不管是和电脑、IPAD、手机一起使用,都可以说是一种很好的办公工具。首先要弄清楚自己的需求,再根据自己的需求来挑选合适的商品。苹果的Pencil有一种独特的重力压感,让人在上面…

【MTK平台】根据kernel log分析wifi scan的时候流程

一 概要: 本文主要讲解根据kernel log分析下 当前路径下(vendor/mediatek/kernel_modules/connectivity/wlan/core/gen4m/)wifi scan的时候代码流程 二. Log分析: 先看Log: 2.1)在Framework层WifiManager.java 方法中,做了一个标记,可以精准的确认时间 这段log可以…

基于Qt5开发图形界面——WiringPi调用Linux单板电脑IO

Qt5——WiringPi Qt5WiringPi示例教程 Qt5 Qt是一种跨平台的应用程序开发框架。它被广泛应用于图形用户界面(GUI)开发,可以用于构建桌面应用程序、移动应用程序和嵌入式应用程序。Qt提供了丰富的功能和工具,使开发人员可以快速、高…

企业内部搭建wiki的意义大吗?到底有何价值体现?

内部Wiki也叫做企业Wiki,是员工可以存储、共享和协作创作的地方,将企业内部员工知识共享集中到一个地方,并且相关内容与其他团队成员协作完成,它可以包含企业内部的各种知识,从操作指南到培训手册,再到客户…

ipad有必要用手写笔吗?开学季实惠的电容笔推荐

iPad平板的机型经过了一次又一次的升级,增加了更多的功能,如今已有了与笔记本电脑匹敌的能力。而到了如今,科技的发展,iPad也从一个娱乐工具,变成了一个集学习、画画、办公于一体的强大工具。为了提高生产效率&#xf…

Linux内核学习(十二)—— 页高速缓存和页回写(基于Linux 2.6内核)

目录 一、缓存手段 二、Linux 页高速缓存 三、flusher 线程 Linux 内核实现了一个被叫做页高速缓存(page cache)的磁盘缓存,它主要用来减少对磁盘的 I/O 操作。它是通过把磁盘中的数据缓存到内存中,把对磁盘的访问变为对物理内…

比较器DATESHEET参数

失调电压的理解 Input Offset Voltage 理想情况下,如果运算放大器的两个输入电压完全相同,则输出应为0V。但运放内部两输入支路无法做到完全平衡,导致输出永远不会是0,具体见图1所示。此时保持放大器负输入端不变,而在…

火绒能一键修复所有dll缺失吗?教你快速修复dll文件

关于dll文件的缺少,其实大家应该都是不陌生的吧,毕竟只要是经常使用电脑的人,那么它就一定碰到过各种各样的dll文件缺失,因为很多程序都是需要dll文件来支撑的,如果dll文件丢失了,那么一些程序就会启动不了…

新版白话空间统计(27):从离散点到密度图

点的密度是点分析中一个很重要的方向,有大量的点数据的空间表达,基本上都是通过密度图来进行体现的,比如百度热力图: 又或者是交通车流量热力图: 空间点密度分析,把海量离散的点,变成高度抽象的…

Tableau可视化进阶实践-1

各类地图 符号地图特点 填充地图特点 多维地图特点 混合地图特点 符号地图 特点 符号化:符号地图以符号的形式表示信息,使用不同的符号来代表不同的地理要素或特定的地理信息。这种符号化的方式可以简化地理信息的表达,使人们更容易理解和识…

基于ssm+vue斗车车辆交易系统源码和论文

基于ssmvue斗车交易系统源码和论文082 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次…

一个程序员眼中的API调用(淘宝/天猫/1688/拼多多API)

在程序员眼中,API调用是一种重要的编程概念,它允许开发人员通过预先定义好的接口和规范,调用其他应用程序或服务的功能。API调用是现代软件开发中不可或缺的一部分,它使得开发人员能够快速构建出复杂的应用程序,同时避…

电子电路原理题目整理(1)

电子电路原理题目整理(1) 最近在学习《电子电路原理》,记录一下书后面试题目,答案为个人总结,欢迎讨论。 1.电压源和电流源的区别? 电压源在不同的负载电阻下可提供恒定的负载电压,而电流源对于…

升讯威在线客服系统的并发高性能数据处理技术:具体化视图

我在业余时间开发维护了一款免费开源的升讯威在线客服系统,也收获了许多用户。对我来说,只要能获得用户的认可,就是我最大的动力。 最近客服系统成功经受住了客户现场组织的压力测试,获得了客户的认可。 客户组织多名客服上线后&a…