VLLM是伯克利大学LMSYS组织开源的大语言模型高速推理框架,通过PagedAttention技术、连续批处理和优化CUDA内核,显著提升模型推理吞吐量和内存效率。其架构包含LLMEngine、Worker、Cache Engine和Scheduler等组件,支持多种模型和硬件。VLLM具有高吞吐量、内存效率高、易用性强等优势,适用于在线服务、批量推理和研究实验等场景,为大语言模型的高效部署提供了强大支持。
一、VLLM 是什么
VLLM 是伯克利大学 LMSYS 组织开源的大语言模型高速推理框架,旨在极大地提升实时场景下的语言模型服务的吞吐量与内存使用效率。它通过创新的技术和优化策略,有效管理计算资源,为大语言模型的高效运行提供了强大支持。VLLM 利用全新的注意力算法「PagedAttention」,对注意力键和值进行高效管理,其核心理念在于通过优化内存管理和资源调度,提升大语言模型部署和执行的效率。
二、VLLM 的技术原理
2.1 KV Cache 机制
所有生成式大模型,例如 GPT、GLM、LLaMA、Qwen 等,底层均采用 Decoder 结构。该结构类似于 Encoder,但在底层运用 Multi - head Self - Attention 机制,涉及 K(Key)、Q(Query)、V(Value)矩阵运算。与 Encoder 不同的是,解码器在计算 Q 乘以 K 转置后,会添加一个 Mask Matrix,以此确保每个词仅受其前面词的影响,进而实现 Causal Attention。
在 K-Q-V 计算过程中,后续词会用到前面词的 K 和 V 矩阵。因此,在推理时,若能存储前面词的 K 和 V 值,便无需重新计算,这大大提升了推理速度,是典型的 “用空间换时间” 策略。然而,KV Cache 自身会占用大量 VRAM。举例来说,如果大模型占用 59% 的 VRAM,KV Cache 可能会占用另外 31%,所以如何合理利用这部分 VRAM 至关重要。
2.2 Page Attention 技术
为解决 KV Cache 占用大量 VRAM 的问题,VLLM 引入了 Page Attention 技术。具体做法是,VLLM 将 KV Cache 划分为多个小块(pages),并依据用户输入 token 的数量,动态分配这些小块的空间。未被占用的空间可供其他任务使用,从而避免了显存浪费。例如,当用户输入的句子较短时,VLLM 只会分配必要的 KV Cache 空间,而非预分配整个缓存空间,这使得其他任务能够共享剩余的 VRAM 资源。
2.3 连续批处理(Continuous Batching)
连续批处理是 VLLM 的另一项关键技术。它允许新请求在旧请求完成时立即加入批次,从而减少 GPU 的空闲时间,提高了 GPU 的利用率。在实际应用中,例如聊天机器人每分钟可能会收到数千个查询,其中许多查询存在相似之处。借助 VLLM 的连续批处理技术,聊天机器人可以将相似的词元字符串存储在短期记忆(KV 缓存)中,并发送一个 “翻译请求”,而非针对每个相似查询都发送单独请求。通过批量处理类似查询,能够有效提高吞吐量并优化内存分配。
2.4 优化后的 CUDA 内核
VLLM 集成了高效的 CUDA 内核,如 FlashAttention 和 FlashInfer,对注意力机制的计算进行优化。这些优化后的 CUDA 内核能够加速矩阵运算,减少计算瓶颈,并且支持多种解码算法,如并行采样、束搜索等。在长序列和复杂解码任务中,相比传统框架,VLLM 的性能可提升 2 - 4 倍。
三、VLLM 架构剖析
3.1 LLMEngine 和 AsyncLLMEngine
- LLMEngine**:作为 VLLM 的核心推理引擎,负责处理输入、执行模型推理、调度请求以及生成输出。其工作流程涵盖输入处理、模型执行(可能分布在多个主机和 / 或 GPU 上)、调度和输出处理。在输入处理阶段,使用指定的分词器对输入文本进行分词;调度过程中,会选择在每个步骤中处理的请求;模型执行环节,管理语言模型的执行,包括跨多个 GPU 的分布式执行;输出处理时,将语言模型生成的 token ID 解码为人类可读的文本。LLMEngine 的代码位于 vllm/engine/llm_engine.py。**
- AsyncLLMEngine:该类是 LLMEngine 的异步封装,基于 asyncio 创建一个后台循环,持续处理传入的请求。AsyncLLMEngine 专为在线服务场景设计,能够处理多个并发请求,并将输出流式传输给客户端。OpenAI 兼容的 API 服务器使用的便是 AsyncLLMEngine,还有一个演示 API 服务器作为更简单的示例,代码位于 vllm/entrypoints/api_server.py,其代码在 vllm/engine/async_llm_engine.py 中。
3.2 Worker
Worker 是运行模型推理的进程,VLLM 遵循常见做法,使用一个进程控制一个加速器设备,如 GPU。例如,若采用大小为 2 的张量并行和大小为 2 的流水线并行,总共会有 4 个 Worker。Worker 通过它们的 rank 和 local_rank 来标识,rank 用于全局协调,而 local_rank 主要用于分配加速器设备以及访问本地资源,如文件系统和共享内存。每个 Worker 都有一个模型运行器对象,负责加载和运行模型,模型执行的许多逻辑都在此处,如准备输入张量和捕获 cudagraphs。
3.3 Cache Engine
每个 Worker 拥有独立的 Cache Engine,负责管理 GPU 上的 KV Cache 存储。Cache Engine 的作用是最大化批次大小,其可利用的空间为 GPU 内存减去模型权重和中间激活后的剩余部分。通过这种方式,能够更高效地利用 GPU 内存资源,提升模型推理的性能。
3.4 Scheduler
Scheduler 动态决定每一步执行预填充(Prefill,处理提示词)还是解码(Decode,生成下一 token),这一决策基于请求优先级,例如优先处理被换出的请求。通过合理的调度策略,能够提高系统整体的运行效率,确保高优先级请求能够得到及时处理。
3.5 API 和接口
- Python 接口:LLM 类提供了主要的 Python 接口,用于进行离线推理,即无需使用单独的模型推理服务器即可与模型交互,使用起来简单易用。
- CLI 和 API 服务器:VLLM 支持命令行接口和 OpenAI 兼容的 REST API,方便进行部署和查询。这种兼容性使得开发者可以无缝迁移现有的基于 OpenAI API 的应用,降低了应用迁移和部署的成本。
3.6 配置管理
VLLM 使用 VllmConfig 类封装所有配置,支持深度层次的类结构,这使得在扩展新功能时变得更加容易。例如,若要添加一个仅涉及模型运行器的新功能,只需在 VllmConfig 类中添加一个新的配置选项。由于传递的是整个配置对象,模型运行器可以直接访问该选项,而无需更改引擎、Worker 或模型类的构造函数来传递新的配置选项。
四、 vLLM 调度器结构与主要组件
在 vLLM 中,调度器的结构设计围绕任务的状态管理和内存资源的优化利用展开。为此,它将任务划分为不同的状态队列,并通过缓存管理和内存调度来保证任务处理的高效性。下面详细介绍调度器的核心组成部分:waiting、running 和 swapped 三个状态队列的作用及设计。
图 1: vLLM 调度器结构图
vLLM 调度器依赖三个状态队列来管理任务的不同阶段:
waiting 队列:waiting 队列用于存放新加入的任务或已完成预填充阶段但等待解码的任务。调度器会从 waiting 队列中取出任务,判断其是否可以分配资源,如果资源允许,则将其移至 running 队列。
running 队列:running 队列包含当前正在处理的任务,通常是在解码阶段。调度器会根据当前资源情况和任务优先级,决定是否抢占任务,将其暂时移出 GPU 以腾出资源。抢占的任务会被转移到 swapped 队列中。
swapped 队列:swapped 队列用于存放因资源不足而被暂时从 GPU 移至 CPU 的任务。调度器会定期检查 swapped 队列,如果资源允许,则将任务重新加载到 GPU,继续运行。
相关实现在vllm/engine/scheduler.py中。
- 初始化与请求队列的管理
调度器的初始化和请求队列管理是 vLLM 高效运行的关键。这部分主要实现在 vllm/engine/scheduler.py 中的 Scheduler 类。
Scheduler 的初始化过程集中在解析配置项、创建 BlockSpaceManager 和初始化状态队列,以确保调度器能够动态、高效地管理多任务请求。初始化过程中涉及三个主要配置:
scheduler_config:包含调度器行为相关的设置,如任务优先级、调度策略等。
cache_config:定义内存分配策略、GPU 与 CPU 缓存的使用等。
lora_config(可选):用于配置 LoRA 模型的特定要求,如并行度和内存需求。
每个新请求在进入调度队列前需要被解析并转换成 SequenceGroup 实例。这一步骤的关键在于为请求分配适当的 token 数、调度优先级、资源需求等信息,然后将其分配至 waiting、running 或 swapped 队列。
SequenceGroup:一个请求可能包含多个序列(如生成任务的多个解码路径)。SequenceGroup 用于管理请求的多个序列,并跟踪该组序列的状态。
add_seq_group 方法:将一个新请求包装为 SequenceGroup,并添加到 waiting 队列。
一个新请求在进入调度器后,会首先经过 add_seq_group 的包装流程,生成 SequenceGroup 实例,并加入 waiting 队列。假设一个请求需要生成文本的多种可能性,调度器会解析该请求并通过 add_seq_group 将其加入等待队列,等待资源分配。
- 调度流程与任务分配策略
vLLM 的调度系统设计堪称一件精妙的艺术品。它通过精心设计的状态转换机制,优雅地解决了大规模并发请求下的资源调度难题。在 vllm/engine/scheduler.py 的 Scheduler 类中,调度器通过 _schedule 方法作为总指挥,协调着整个系统的运转。
调度器会根据当前系统负载和请求特征,自适应地选择最优的调度策略。在标准场景下使用 _schedule_default,而在需要处理大批量请求时,则会切换到专门优化的 _schedule_chunked_prefill 模式。这种灵活的策略选择确保了系统在不同负载下都能保持最佳性能。
整个调度过程可以优雅地分为三个阶段:
预填充阶段(Prefill Phase)
这是请求处理的第一个关键阶段。当新请求到达时,调度器首先评估其资源需求,包括所需的 KV Cache 空间和计算资源。系统会为请求生成初始的注意力缓存,为后续的解码做好准备。这个阶段就像是为任务搭建舞台,布置好所有必要的道具。
解码阶段(Decode Phase)
这是生成过程的核心阶段。调度器在这个阶段需要精确地分配计算资源,确保每个请求都能得到持续的服务。通过细粒度的资源管理,系统能够在保证响应速度的同时,最大化 GPU 利用率。解码阶段的任务会被放入 running 队列,接受调度器的持续监控和管理。
交换阶段(Swap Phase)
为了处理资源竞争,调度器实现了优雅的任务交换机制。当系统资源紧张时,调度器会识别优先级较低的任务,将它们暂时转移到 CPU 内存(swapped 队列),为急需资源的高优先级任务让路。这种动态调度机制确保了系统资源的最优利用,同时保证了服务质量。
这三个阶段通过精密的协作,构成了一个流畅的任务处理管道。调度器通过维护 waiting、running 和 swapped 三个队列的状态平衡,实现了类似操作系统页面调度的高效内存管理。每个阶段都配备了完善的监控和容错机制,确保了整个系统的稳定性和可靠性。
值得一提的是,vLLM 的调度系统还实现了优先级抢占、动态批处理等高级特性,这些机制共同保证了系统在高负载下依然能够提供稳定且高效的服务。整个调度过程就像一场精心编排的交响乐,每个组件都恰到好处地配合,共同奏响高性能服务的乐章。
3.1 scheduler 调度生命周期
图 2: vLLM 调度器状态队列示意图
3.2 _schedule_default调度逻辑
_schedule_default方法是 vLLM 调度系统的指挥中心,它通过精心设计的流程来协调各类请求的处理。让我们逐步解析这个复杂而优雅的调度过程:
(1) 预算初始化与资源盘点
这就像交通管理员在早高峰前先统计可用车道和当前道路占用情况。系统会创建一个预算对象,记录最大可处理的 token 数和序列数,并统计当前正在运行的任务占用的资源。
(2) 优先级调度策略
这类似于交通管理系统的优先车道管理。系统优先处理已被交换出去的紧急任务,就像先让救护车通行。如果没有紧急任务,则开始处理新到达的请求。当采用优先级策略时,还会考虑是否需要让高优先级任务抢占资源。
(3) 解码任务调度
这就像管理正常行驶的车辆。只有在处理完紧急情况后,系统才会调度常规的解码任务。如果道路通畅(没有任务被抢占或交换出),还会尝试让一些临时停靠的车辆(被交换出的任务)重新上路。
(4) 状态更新与队列管理
这类似于实时更新交通状态。系统会更新各个队列的状态:被抢占的任务回到等待队列,新的任务进入运行队列,需要暂时让路的任务进入交换队列。
(5) 结果整合与输出
最后,系统会生成一份完整的调度报告,包含了所有需要执行的操作:哪些任务要执行,哪些内存块需要交换,以及各类统计信息。这就像交通指挥中心生成的实时路况报告,为下一个调度周期提供决策依据。
通过这种精密的调度机制,vLLM 能够在保证公平性的同时,最大化系统的吞吐量和响应速度。整个过程就像一个训练有素的交通指挥系统,让每个请求都能得到恰当的处理,保证了整个服务的高效运转。
3.3 预填充阶段的精密编排
预填充阶段就像一个精心设计的入场管理系统,需要确保每个请求都能得到合适的处理。让我们通过几个关键步骤来理解这个过程:
(1) 初始检查与资源评估
这就像检票员在入场时检查门票。系统首先确认每个等待组只包含一个提示序列,然后计算需要处理的新token数量,区分哪些需要重新计算(uncached),哪些可以直接使用缓存(cached)。
(2) 容量限制检查
这类似于场馆的容量管理。如果一个请求太大(token数超过限制),就像一个太大的团队无法进入会场一样,系统会将其标记为"已忽略",并移出等待队列。
(3) 内存分配评估
这就像检查场地是否有足够的座位。系统会评估是否有足够的内存块来容纳这个请求。如果暂时没有空间(LATER),就等待下次尝试;如果永远无法容纳(NEVER),则将请求标记为无法处理。
(4) LoRA 资源管理
这类似于特殊设备的分配管理。如果请求需要使用LoRA(一种特殊的模型适配技术),系统会检查是否还有可用的LoRA槽位。如果没有,该请求会被暂时搁置。
(5) 预算控制
这就像控制场地的实时容量。系统会严格监控已分配的资源是否达到上限,包括总token数和序列数,确保不会超出系统的处理能力。
(6) 资源分配与状态转换
这是最后的入场阶段。当所有检查都通过后,系统会正式为请求分配资源,将其状态更新为"运行中",并记录相应的资源使用情况。
(7) passed_delay均衡
模型在做推理时,waiting 队列中是源源不断有 seq_group 进来的,一旦 vLLM 选择调度 waiting 队列,它就会停下对 running/swapped 中 seq_group 的 decode 处理,转而去做 waiting 中 seq_group 的 prefill,也即vLLM 必须在新来的 seq_group 和已经在做推理的 seq_group 间取得一种均衡:既不能完全不管新来的请求,也不能耽误正在做推理的请求。_passed_delay 就是用来做这个判断的。
prev_prompt 和 prev_time 用于记录上一个请求的执行时间,从而动态计算 last_prompt_latency 以调整调度速率。这种延迟控制机制可以防止过度调度,减少 GPU 负载。
当延迟条件满足时,_schedule_prefills 会获取 waiting 队列中第一个请求的 token 数量,并通过 _get_num_new_tokens 方法来确定这个请求所需的 token 数量。随后,该 token 数量与 _get_prompt_limit 限制值进行比较,以确保请求不会超出模型的最大 token 负载。
若 can_allocate 返回 AllocStatus.LATER,表明当前 GPU 资源不足,调度器将等待下次机会;若返回 AllocStatus.NEVER,则说明该请求太大无法分配,调度器将忽略该请求并将其移出等待队列。
(8) 资源分配与状态转换
allocate 函数通过 block_manager 的内存管理功能,为请求在 GPU 上分配所需的内存空间,从而确保其可以顺利进入解码阶段。
通过这种细致的分层管理,vLLM能够高效地处理大量并发请求,既确保了资源的最优利用,又保证了每个请求都能得到公平的处理机会。整个预填充阶段就像一个精密的入场管理系统,通过多重检查和平衡机制,确保系统的稳定运行和最佳性能。
3.4 解码阶段的精密调度
解码阶段是 vLLM 处理请求的核心环节,就像一条高效的生产线,需要精确地控制每个环节的运转。让我们深入理解这个复杂而优雅的过程:
(1) 初始化与缓存清理
这就像生产线开始新的班次前的准备工作。系统会清理所有临时状态,为新一轮调度做好准备。通过使用对象池(cache)来复用对象,避免频繁创建新对象带来的性能开销。
(2) 资源评估与任务获取
这类似于生产线上的任务评估。系统会检查每个正在运行的任务组,评估其资源需求。特别的是,在解码阶段我们不需要考虑缓存的 tokens,因为它们在预填充阶段就已经处理完毕。
(3) 异步处理保护
这就像生产线上的安全检查点。当使用异步处理器时,系统会检查序列长度是否超出限制,以防止内存溢出。这种保护机制确保了系统的稳定性。
(4) 资源竞争处理
这类似于生产线上的资源调度。当资源不足时,系统需要决定哪些任务需要暂时让出资源。它会优先选择优先级较低的任务组作为"牺牲者",就像在繁忙时段将部分生产线暂时切换到更紧急的订单。
(5) 抢占执行与状态转换
这就像生产线上的任务切换。系统会根据具体情况决定是将任务暂存(swap out)还是标记为需要重新计算(recompute)。这种灵活的处理机制确保了资源的最优利用。
(6) 任务调度与资源分配
这类似于生产线上的实际加工过程。系统会为任务分配所需的资源槽位,并根据任务类型(预填充或解码)设置不同的处理参数。解码任务通常每次只处理一个 token,而预填充任务可能会批量处理多个 tokens。
(7) 资源统计更新
这就像生产线上的资源使用统计。系统会实时更新资源使用情况,包括已批处理的 tokens 数量和运行中的序列数。当启用分块处理时,还需要额外更新序列数统计。
通过这种精密的调度机制,vLLM 能够在保证公平性的同时,最大化系统的吞吐量和响应速度。整个解码阶段就像一条精心设计的智能生产线,通过灵活的资源调度和任务管理,确保了系统的高效运转。
3.5 交换阶段的精密调度
交换阶段是 vLLM 内存管理的关键环节,就像一个智能仓储系统,需要在 CPU 和 GPU 内存之间灵活调度资源。让我们深入理解这个复杂而精密的过程:
(1) 初始化与资源准备
这就像仓库管理员准备工作清单。系统会初始化各种任务列表,包括需要从 CPU 加载到 GPU 的内存块、需要复制的数据块,以及不同类型的任务组。
(2) 可行性评估
这类似于仓库管理员评估货物存放可能性。系统会检查是否有足够的 GPU 内存来容纳被交换出的任务。如果暂时没有空间(LATER)就等待下次机会,如果永远无法容纳(NEVER)则将任务标记为无法执行。
(3) LoRA 资源检查
这就像检查特殊设备的可用性。如果任务需要使用 LoRA 适配器,系统会检查是否有可用的 LoRA 槽位。如果没有,该任务会被暂时保留在交换队列中。
(4) 资源预算评估
这类似于评估仓库的剩余容量。系统会计算任务所需的资源,包括新序列数量和token数量,确保在预算范围内才进行调度。
(5) 执行交换操作
这就像实际执行货物搬运。系统会将任务从 CPU 内存移回 GPU,并为其分配必要的计算资源。这个过程包括数据传输和内存分配两个关键步骤。
(6) 任务分类与资源记录
这类似于货物分类入库。系统会根据任务类型(预填充或解码)将其放入相应的处理队列,并设置适当的处理参数。
(7) 资源统计更新
这就像更新仓库库存记录。系统会更新资源使用统计,包括已使用的token数量和序列数,确保资源使用始终在可控范围内。
通过这种精密的交换机制,vLLM 实现了 CPU 和 GPU 内存之间的高效协同,既保证了资源的充分利用,又确保了任务的连续性。整个交换阶段就像一个智能仓储系统,通过灵活的调度策略,实现了计算资源的最优配置。
- 资源管理与调度策略
4.1 预算管理系统设计
SchedulingBudget 类是 vLLM 资源管理的核心组件,它就像一个精密的预算管理系统,负责追踪和控制系统的资源使用。让我们深入理解它的设计:
(1) 核心资源指标
这就像企业的预算系统,定义了关键的资源限制:总预算(token_budget)、人员限制(max_num_seqs),以及当前的资源使用状况。系统通过这些指标来确保资源使用不会超出限制。
(2) 请求追踪机制
这类似于预算系统中的交易记录追踪。系统使用集合来记录已经处理过的请求ID,避免重复计算同一个请求的资源消耗。这种设计特别适合处理分布式环境下的资源统计。
(3) 调度可行性检查
这就像预算审批过程。在添加新的任务前,系统会检查是否有足够的资源来处理它。检查包括两个方面:
- token数量是否在预算范围内
- 序列数是否超过系统限制
- (4) 资源分配与回收
- 这类似于预算的分配和回收流程:
- add_num_batched_tokens:为新请求分配资源,同时记录请求ID避免重复计算
- subtract_num_batched_tokens:在请求完成或被中断时回收资源
- (5) 序列数管理
- 这就像人力资源管理系统,负责跟踪当前正在处理的序列数量:
- 添加新序列时会检查是否已经计入统计
- 移除序列时会相应减少计数
- (6) 资源状态查询
- 这类似于预算系统的报表功能,提供了查询当前资源使用状况的接口:
- 已使用的token数量
- 剩余可用的token预算
- 当前序列数等关键指标
- 通过这种精密的预算管理机制,vLLM 能够准确地追踪和控制系统资源的使用情况,确保系统在高负载下依然能够稳定运行。整个预算管理系统就像一个高效的企业财务系统,通过严格的资源控制和灵活的分配策略,实现了计算资源的最优利用。
4.2 优先级调度和抢占策略的精密实现
优先级调度和抢占机制是 vLLM 处理资源竞争的核心策略,让我们深入理解这个精密的调度过程:
(1) 队列初始化与优先级排序
这就像应急指挥中心的初始准备工作:
- 获取当前等待的请求队列
- 将运行中的任务按优先级排序
- 准备记录需要暂时撤离的资源
- 初始化强制抢占计数器
(2) 优先级反转检测
这类似于应急响应中的情况评估:
- 检查是否有等待中的请求
- 评估新请求的资源需求(序列数和token数)
- 准备进行优先级比较
(3) 抢占条件评估
这就像应急处理中的资源调配决策:
- 检查是否存在优先级反转(低优先级任务占用资源而高优先级任务等待)
- 评估是否有足够的资源来处理新请求
- 如果资源充足,则无需进行抢占
(4) 受害者选择与资源回收
这类似于应急情况下的资源重新分配:
- 选择优先级最低的运行中任务作为"受害者"
- 计算需要回收的资源数量
- 从预算中扣除这些资源
- 更新序列计数
(5) 抢占执行与状态转换
这就像执行应急预案:
- 执行实际的抢占操作,将任务从 GPU 移出
- 将被抢占的任务放回等待队列前端
- 记录抢占次数以进行监控
(6) 队列重排序与状态更新
这类似于应急处理后的现场恢复:
将触发抢占的请求放回等待队列
重新按优先级排序所有等待的请求
更新系统的队列状态
通过这种精密的优先级调度和抢占机制,vLLM 能够在资源竞争激烈的情况下,保证高优先级任务的及时处理,同时尽可能减少对低优先级任务的影响。整个机制就像一个高效的应急响应系统,通过合理的资源调配和任务管理,确保了系统的公平性和效率。
4.3 抢占机制的精密实现
vLLM 的抢占机制提供了两种处理模式:重新计算(Recompute)和交换(Swap)。这种灵活的设计让系统能够根据不同场景选择最优的处理策略。让我们深入理解这个精密的抢占过程:
(1) 抢占模式选择
这就像应急预案的选择过程:
- 默认情况下,系统会根据序列组的特征自动选择最优策略
- 对于单序列任务,优先选择重新计算模式,因为它的开销较小
- 对于多序列任务(如束搜索),由于当前不支持重新计算,会选择交换模式
(2) 用户自定义模式处理
这类似于应急响应中的人工干预:
- 系统允许用户指定特定的抢占模式
- 如果用户明确要求使用交换模式,系统会遵循这个选择
- 其他情况下默认使用重新计算模式
(3) 性能监控与警告机制
这就像系统的健康监控:
- 每50次抢占操作会触发一次警告
- 提醒管理员系统可能需要调整资源配置
- 建议增加GPU内存利用率或张量并行度来缓解抢占压力
- 记录累计抢占次数以便跟踪系统状态
(4) 抢占执行
这类似于应急预案的实际执行:
重新计算模式:放弃当前进度,后续需要从头计算
交换模式:将数据暂存到CPU内存,保留计算进度
- 严格的错误检查确保只执行有效的抢占模式
- 通过这种精密的抢占机制,vLLM 实现了资源的灵活调度:
- 通过自动选择最优抢占模式,最小化性能开销
- 提供用户自定义选项,满足特定场景需求
- 内置监控机制,及时发现系统瓶颈
- 支持多种抢占策略,适应不同的任务特征
- 这种设计就像一个智能的应急处理系统,既能自动选择最优方案,又保留了人工干预的可能,同时通过持续监控确保系统的健康运行。
- vLLM 调度系统总结
vLLM 的调度系统是一个精心设计的多层次架构,通过多个协同工作的组件实现了高效的资源管理和任务调度。让我们从整体到细节来回顾这个系统。
5.1 核心架构设计
调度系统的基础建立在三个关键队列之上。waiting 队列负责存放新到达的请求,running 队列管理正在执行的任务,而 swapped 队列则暂存被交换出的任务。这种三队列设计为系统提供了灵活的任务状态管理能力,使其能够有效应对各种负载情况。
5.2 调度流程的精密编排
整个调度过程分为三个主要阶段,每个阶段都有其独特的职责。在预填充阶段,系统会对新请求进行资源评估,检查容量限制和内存可用性,同时进行 LoRA 资源管理,最后执行预算控制和资源分配。
进入解码阶段后,系统的重点转向管理运行中任务的资源使用。这包括处理异步任务和长度限制,执行资源竞争处理,以及维护任务状态和资源统计。
在交换阶段,系统负责在 CPU 和 GPU 内存间进行任务迁移。它会评估交换操作的可行性,执行数据传输和资源重分配,并及时更新系统状态和资源记录。
5.3 资源管理的创新机制
系统通过 SchedulingBudget 类实现了精确的资源控制。这个类不仅维护着 token 和序列数预算,还负责追踪请求级别的资源使用。它提供了完整的资源分配和回收机制,并通过实时监控确保系统资源的高效利用。
5.4 优先级调度与抢占策略
为了处理资源竞争,系统实现了两种抢占模式。Recompute 模式适用于单序列任务,因其开销较小而被优先选用。而 Swap 模式则适用于多序列任务,它能够保留计算进度,虽然开销较大但更适合某些特定场景。
这种灵活的抢占机制确保了高优先级任务能够及时获得资源,同时也保证了系统资源的最优利用和任务处理的连续性。通过精心的设计,系统在处理资源竞争时既保证了效率,又维护了公平性。
5.5 性能优化与监控
在性能优化方面,系统采用了多项创新机制。对象池的复用有效减少了内存分配开销,延迟控制机制避免了过度调度,而批处理优化则显著提高了系统吞吐量。同时,完善的实时监控和警告机制确保了系统运行的稳定性。
通过这些精密的设计,vLLM 的调度系统实现了资源的高效利用、任务的灵活管理、服务的可靠保障和性能的持续优化。这种多层次、多维度的调度架构,使 vLLM 能够在处理大规模并发请求时保持稳定高效的性能,为 LLM 服务提供了可靠的基础设施支持。
五、VLLM 的优势
1 高吞吐量
相比 Hugging Face Transformers,VLLM 的吞吐量可高出 8.5 - 24 倍,相比 TGI(Text Generation Inference)高 2.2 - 3.5 倍(测试于 LLaMA - 7B 和 LLaMA - 13B)。通过连续批处理技术,VLLM 能够动态调度请求,减少 GPU 空闲时间,从而显著提高了系统在单位时间内处理请求的数量,适用于高并发的应用场景,如聊天机器人、实时翻译等。
2 内存效率高
PagedAttention 技术的引入,使得 VLLM 能够有效减少内存浪费,支持更大批次和更长序列。与传统框架中预分配大量内存的方式不同,VLLM 的动态内存分配策略解决了内存囤积问题,能够根据实际需求灵活分配内存,提高了内存的使用效率,使得在有限的内存资源下能够处理更多的任务。
3 易用性强
VLLM 与 Hugging Face 模型无缝集成,支持 LLaMA、Mistral、Qwen 等主流模型。开发者只需几行代码,即可将这些模型部署到 VLLM 框架中,大大降低了使用门槛。同时,其提供的简单易用的 Python 接口和 OpenAI 兼容的 API,进一步方便了开发者进行模型推理和服务部署。
4 灵活性高
支持多模态、多硬件(NVIDIA、AMD、Intel、TPU 等),能够适应不同场景的需求。无论是在使用 NVIDIA GPU 的高性能计算环境,还是在使用其他硬件的特定场景中,VLLM 都能够发挥其优势,为不同的用户和应用场景提供灵活的解决方案。此外,其开源的特性(Apache 2.0 许可证),使得社区能够对其进行定制和快速修复,进一步增强了框架的灵活性和适应性。
5 可扩展性好
VLLM 支持从 7B 到 70B 模型的快速切换,仅需少量配置调整。在实际应用中,随着业务需求的变化,可能需要在不同规模的模型之间进行切换,VLLM 的这种可扩展性能够方便地满足这种需求,降低了模型升级和扩展的成本和难度。
六、以部署 DeepSeek 为例讲解 VLLM 安装部署步骤
1 环境准备
- 硬件要求:确保拥有支持 CUDA 的 NVIDIA GPU,例如 A100、V100 等,以充分发挥 VLLM 的性能优势。同时,配备足够的系统内存,因为大模型推理对内存需求较高。
- 软件依赖:安装 Python 环境,建议使用 Python 3.8 及以上版本。安装 PyTorch,需根据 GPU 型号和 CUDA 版本选择对应的 PyTorch 版本,可通过官方网站获取安装命令。例如,对于 CUDA 11.7 的环境,安装命令可能为:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117还需安装其他依赖库,可通过 VLLM 官方文档获取完整的依赖列表,并使用 pip 进行安装。例如:
pip install -r requirements.txt2 安装 VLLM
可以通过 pip 直接安装 VLLM 的稳定版本:
pip install vllm若希望获取最新的开发版本,也可以从 GitHub 仓库克隆代码并进行安装:
git clone https://github.com/vllm-project/vllm.git cd vllm pip install -e.3 下载 DeepSeek 模型
从 DeepSeek 官方网站或合法的模型存储库下载 DeepSeek 模型文件。确保下载的模型文件完整且符合 VLLM 的要求。下载完成后,将模型文件解压到指定的目录,例如/path/to/deepseek/model。
4 配置 VLLM
创建一个配置文件,例如config.py,用于指定 VLLM 的运行参数。在配置文件中,需要指定模型的路径、使用的 GPU 数量、是否启用量化等参数。以下是一个简单的配置示例:
from vllm import LLM, SamplingParams model_path = "/path/to/deepseek/model" llm = LLM(model=model_path, tensor_parallel_size=2) sampling_params = SamplingParams(temperature=0.8, top_p=0.95)在上述示例中,tensor_parallel_size=2表示使用 2 个 GPU 进行张量并行计算,可根据实际硬件情况进行调整。
5 启动服务
编写一个启动脚本,例如serve.py,用于启动 VLLM 服务并加载 DeepSeek 模型:
from vllm import LLM, SamplingParams model_path = "/path/to/deepseek/model" llm = LLM(model=model_path, tensor_parallel_size=2) sampling_params = SamplingParams(temperature=0.8, top_p=0.95) prompts = ["请描述一下春天的景色", "介绍一下中国的传统文化"] results = llm.generate(prompts, sampling_params) for prompt, result in zip(prompts, results): print(f"Prompt: {prompt}") print(f"Generated text: {result.outputs[0].text}")运行启动脚本:
python serve.py此时,VLLM 服务将启动,并使用 DeepSeek 模型进行推理,根据输入的提示生成相应的文本。
七、VLLM 的应用场景
1 在线服务
在聊天机器人领域,VLLM 的高吞吐量和低延迟特性使其能够快速响应用户的输入。例如,在大型客服聊天机器人系统中,每分钟可能会收到数千个用户咨询,VLLM 通过连续批处理技术,将相似的用户问题进行合并处理,减少了 GPU 的空闲时间,能够在短时间内生成准确的回复,提升用户体验。同时,其高效的内存管理机制确保在高并发情况下,系统依然能够稳定运行,不会因内存不足而导致服务中断。
2 批量推理
对于需要处理大量文本生成任务的场景,如内容创作平台生成文章摘要、机器翻译系统处理大量文档翻译等,VLLM 能够充分发挥其高性能推理的优势。通过合理配置多 GPU 环境,利用张量并行和流水线并行技术,VLLM 可以快速处理大规模的文本数据,提高批量推理的效率,降低处理时间和成本。
3 研究实验
在学术研究和模型开发过程中,研究人员需要频繁测试不同大语言模型的推理效果。VLLM 提供的简单易用的接口和对多种模型架构的支持,使得研究人员能够轻松部署和测试不同的模型。同时,其高效的推理性能可以加速实验进程,帮助研究人员更快地验证新的算法和想法,推动大语言模型领域的研究发展。
总结与展望
VLLM 作为一款高性能的大语言模型推理框架,通过创新的技术如 PagedAttention、连续批处理等,在吞吐量、内存效率等方面展现出了显著的优势。其灵活的架构设计和良好的兼容性,使其能够适应多种应用场景和硬件环境,为大语言模型的部署和应用提供了有力的支持。在未来,随着大语言模型技术的不断发展,VLLM 有望在以下几个方面进一步优化和拓展:
- 性能优化:持续改进算法,进一步提升在长上下文场景下的性能,例如通过优化注意力机制,减少计算复杂度,提高模型在处理长文本时的速度和准确性。
- 功能扩展:支持更多的模型架构,如编码 - 解码模型、Mamba 模型等,以满足不同应用场景对模型结构的多样化需求。同时,增强对多模态融合的支持,不仅仅局限于现有的文本、图像、音频、视频输入,探索更多模态数据的融合方式和应用场景。
- 硬件兼容性:进一步优化对低端硬件的支持,降低部署门槛,使更多用户能够在资源有限的环境中享受到高效的大语言模型推理服务。例如,通过优化内存管理和计算资源分配,提高在消费级 GPU 或集成显卡上的运行效率。
- 社区发展:随着开源社区的不断壮大,VLLM 将获得更多开发者的贡献和反馈。社区的力量将推动 VLLM 持续创新,快速修复漏洞,增加更多实用功能,进一步巩固其在大语言模型推理框架领域的领先地位。
最后
近期科技圈传来重磅消息:行业巨头英特尔宣布大规模裁员2万人,传统技术岗位持续萎缩的同时,另一番景象却在AI领域上演——AI相关技术岗正开启“疯狂扩招”模式!据行业招聘数据显示,具备3-5年大模型相关经验的开发者,在大厂就能拿到50K×20薪的高薪待遇,薪资差距肉眼可见!
业内资深HR预判:不出1年,“具备AI项目实战经验”将正式成为技术岗投递的硬性门槛。在行业迭代加速的当下,“温水煮青蛙”式的等待只会让自己逐渐被淘汰,与其被动应对,不如主动出击,抢先掌握AI大模型核心原理+落地应用技术+项目实操经验,借行业风口实现职业翻盘!
深知技术人入门大模型时容易走弯路,我特意整理了一套全网最全最细的大模型零基础学习礼包,涵盖入门思维导图、经典书籍手册、从入门到进阶的实战视频、可直接运行的项目源码等核心内容。这份资料无需付费,免费分享给所有想入局AI大模型的朋友!
👇👇扫码免费领取全部内容👇👇
部分资料展示
1、 AI大模型学习路线图
2、 全套AI大模型应用开发视频教程
从入门到进阶这里都有,跟着老师学习事半功倍。
3、 大模型学习书籍&文档
4、AI大模型最新行业报告
2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
5、大模型大厂面试真题
整理了百度、阿里、字节等企业近三年的AI大模型岗位面试题,涵盖基础理论、技术实操、项目经验等维度,每道题都配有详细解析和答题思路,帮你针对性提升面试竞争力。
6、大模型项目实战&配套源码
学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
👇👇扫码免费领取全部内容👇👇
这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】