拓冰建站拓冰建站
首页 / 资讯中心 / 正文

如何理解 vLLM 请求调度:负载均衡与资源分配实战指南

如何理解 vLLM 请求调度负载均衡与资源分配实战指南【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllmvLLM 是一个高吞吐、省内存的大模型推理引擎它的请求调度子系统直接决定了高并发下的负载均衡与资源分配效果。下面以一个请求的完整旅程为主线拆解 vLLM 连续批处理原理、分块预填充、KV 缓存管理、抢占机制并给出 vLLM 调参建议。为什么请求会排队从一个高并发场景说起想象一个在线客服场景白天高峰每秒涌进 200 个提问每个问题几百到几千 token要求首 token 尽量快出。此时 GPU 面临两道硬约束每步计算预算有限一个调度步最多处理固定数量的 tokenmax_num_batched_tokens来多少请求都塞不进去KV 缓存容量有限每个请求生成的每个 token 都要占用 KV 缓存块显存只够装下有限数量的请求。请求到达速度 处理速度时排队是必然的。调度的艺术不在于消灭排队而在于谁先进批、谁被挪走、谁被重新计算都要让 GPU 不空转、让重要请求不被饿死。这就是 vLLM 负载均衡的核心职责——把有限的计算 token 预算和KV 缓存块这两类资源在源源不断的请求之间做动态分配。一次请求在 vLLM 里的完整旅程从等待队列到运行队列新请求进入引擎后并不立刻被计算而是先挂在**等待队列waiting**上。调度器每个推理步都会做一次决策先看正在运行的请求能不能继续跑它们每步各需要 1 个新 token再把剩下的 token 预算分给等待队列里的新请求。一个请求被录取进当前批次需要同时满足两个条件条件含义对应参数计算预算够本步剩余 token 额度 ≥ 该请求还需预填充的 token 数max_num_batched_tokens内存块够KV 缓存空闲块 ≥ 该请求要用的块数还要扣掉预留水位block_size、水印两个条件都满足请求从等待队列移入运行队列running拿到 KV 缓存块开始预填充预填充完成后进入逐 token 解码直到生成结束符或达到长度上限释放全部资源。这条主路径的代码位于 调度器源码 与 KV 缓存管理器。WAITING→RUNNING→SWAPPED 状态流转经典生命周期里出现过SWAPPED状态V0 引擎会把请求的 KV 缓存换出到主机内存请求挂起等待换回。V1 引擎把这条路径收敛了——请求状态枚举中只有 WAITING、RUNNING、PREEMPTED 和若干 FINISHED 变体见 请求状态定义被抢占的请求直接释放 KV 块、回到等待队列重新排队。也就是说V1 默认走重新计算路线换出/换入作为可选策略保留在抢占逻辑中。对调度的影响是V1 的抢占代价更可控代价是预填充要重算一遍。连续批处理让 GPU 不再空等静态批处理 vs 连续批处理静态批处理的规则是一锅端凑满一批等最慢的请求做完整批结束新请求只能干等下一批。批内请求长短不一时先完成的请求对应的 GPU 算力就被白白浪费。连续批处理Continuous Batching把批次从静态概念变成动态窗口维度静态批处理vLLM 连续批处理批的边界固定整批同进同出每个推理步都可变化请求完成时机等整批结束谁完成谁立即出批新请求进入必须等下一批完成的槽位立即让出GPU 利用率受最慢请求拖累接近满负荷实现上调度器每步重新组合批次完成的请求移出等待队列里够格的请求补入。这个批次持久化、成员动态换血的机制是 vLLM 高吞吐的来源之一。分块预填充如何避免长请求霸占GPU没有分块时一个 32k token 的长请求做预填充会独占一个完整的推理步期间其他请求一个 token 都出不来首 token 延迟TTFT雪上加霜。分块预填充Chunked Prefill的做法是把长预填充切成若干片每步只处理其中一片片大小受max_num_batched_tokens约束剩下的片留在等待队列里排队与短请求、解码请求交错执行。效果是长请求不再一步独吞预算短请求的 TTFT 得到保护预填充compute-bound与解码memory-bound天然混批GPU 算力和访存都被利用得更充分在 V1 引擎中只要设置了max_num_batched_tokens分块预填充就是默认行为调度器按剩余预算逐请求切分。调度器如何决定先处理谁优先级与先到先服务等待队列本身就是一个小调度器。vLLM 提供两种入队/出队策略见 请求队列实现策略队列结构出队规则适用场景FCFS默认双端队列严格先到先服务公平性优先的通用服务PRIORITY堆heapq先比优先级再比到达时间混合了 VIP 与普通流量的场景优先级策略下请求自带一个priority数值数值越小越优先同优先级内仍按到达时间排序保证公平底线# 优先级队列的排序键伪代码 order_key (priority, arrival_time) # priority 小者优先同级按到达先后注意优先级只影响等待队列的出队顺序不会跳过 KV 缓存的容量检查——再高优先级的请求块不够也进不了批。多队列负载均衡调度器同时维护三条流水线每个推理步按固定顺序做负载均衡运行队列优先保障已入批请求每步 1 token 的解码需求保证已开始的请求尽快完成等待队列在剩余 token 预算内按策略出队新请求做分块预填充被抢占/换出请求资源宽裕时回收重新进入等待队列。这种先保存量、再收增量的顺序是多队列负载均衡的关键它让解码延迟ITL稳定同时让新请求尽快上手。若某步预算不够运行队列中的请求会被从后往前选出替罪羊抢占把资源让给等待队列里的请求——这是调度器内置的动态再平衡手段。KV 缓存与内存管理块式分配与块大小权衡vLLM 的 KV 缓存不连续分配而是切成固定大小的块默认 16 个 token/块按需分配类似操作系统的分页内存——这正是 PagedAttention 的思想详见 Paged Attention 设计文档。块大小是一个典型的精度 vs 开销权衡块大小优点代价小如 16内存碎片少多请求混排更灵活块数多管理元数据与注意力 kernel 的间接开销略高大如 32/64管理开销小每请求尾部浪费最多一个块显存利用率下降块大小在 缓存配置 中指定通常保持默认即可只有在显存极度紧张、想榨出几个百分点利用率时才值得实验。水印机制避免频繁换页空闲块刚好够新请求但请求跑起来又要占块——这种临界状态会引发连环抢占。为此 KV 缓存管理器引入水印watermark为等待/被抢占请求的准入额外预留watermark × 总块数个空闲块作为安全垫。准入判断可以简化为可用块 空闲块 − 已运行请求的预留块 准入条件新请求需要块 水印块 ≤ 可用块V1 实现中水印默认为 0即不额外预留见 KV 缓存管理器 中的watermark_blocks计算。当观察到刚放进一个请求就触发抢占的锯齿状行为时把水印调成 0.01~0.05 这类小值用一点容量换稳定往往划算。Swap 与抢占内存告急的两套方案显存不够时调度器必须挑请求腾地方有两种腾法方案做法恢复成本额外开销Swap换出把请求 KV 缓存搬回主机内存资源宽裕时换回继续一次 PCIe 拷贝占用主机内存长上下文时拷贝量大Recompute重算直接释放该请求的 KV 块请求回到等待队列重新做一遍预填充浪费算力但实现简单、内存零占用选择建议上下文短几千 token 内时重算比拷贝更快V1 引擎默认也走重算上下文极长且主机内存充裕时换出能保住已经算好的结果。被抢占多少次、是否被反复踢出都可以从指标中追踪num_preemptions计数器记录在请求对象上。前缀缓存与 LRU 驱逐大量请求共享相同前缀系统提示词、Few-shot 样例、多轮对话上文时逐块重算是纯浪费。前缀缓存Automatic Prefix Caching按块对内容做哈希内容相同的块只算一次、被引用计数共享命中时预填充直接跳过这部分 token功能说明见 前缀缓存文档。配套的回收策略是LRU 驱逐空闲块池中记录每块最后被引用的时间需要腾块时优先淘汰最久没被访问的块。LRU 的直觉很直接——最近被用过的块更可能再次命中所以最后才轮到它。命中率与驱逐行为可通过PrefixCacheStats见 KV 缓存指标观测。面向场景的调参实践核心参数分两类vLLM 调参先分清调度类还是缓存类分组参数作用默认量级调度类max_num_batched_tokens每步 token 预算上限控制吞吐/延迟平衡数千随引擎版本调度类max_num_seqs单批最大并发请求数数百调度类scheduling_policyfcfs/priorityfcfs缓存类block_sizeKV 缓存块大小16缓存类watermark准入预留比例0缓存类enable_prefix_caching是否开启前缀缓存视场景参数定义与校验逻辑见 调度器配置 与 引擎参数文档。高并发短请求目标是吞吐最大化、TTFT 稳定参数方向理由max_num_batched_tokens调大短请求预填充便宜预算放大可混入更多请求max_num_seqs调大并发上限放宽减少批内排队空位enable_prefix_caching开系统提示词共享收益大抢占模式重算上下文短重算比换出更快watermark观察锯齿后设 0.01~0.05防止临界准入引发连环抢占长序列生成目标是保长上下文可用、控好显存水位参数方向理由max_num_seqs调小长序列单请求吃块多限并发防 OOMmax_num_batched_tokens适中偏小给分块预填充留余地避免单步被一个长请求吃光watermark适当抬高长请求准入波动大安全垫更值抢占模式换出主机内存充裕时重算 32k 上下文的代价远高于拷贝滑动窗口模型支持时启用直接压缩 KV 占用监控与持续优化调参前先看数据。vLLM 内置 Prometheus 指标导出覆盖请求延迟TTFT / ITL / E2E、批大小、KV 缓存使用率、前缀缓存命中率、抢占次数等使用方式见 监控指标文档GPU 侧细粒度瓶颈可用 profiling 文档 中的方法定位。持续优化建议盯住三个信号抢占次数持续增长→ 容量不足优先加显存/降并发其次再调watermark前缀缓存命中率偏低→ 检查请求前缀是否真的稳定或块大小是否导致哈希边界错位TTFT 长尾明显→ 大概率长请求预填充干扰确认分块预填充生效并下调max_num_batched_tokens。结语vLLM 的请求调度可以浓缩为一句话在每步固定的 token 预算和有限的 KV 缓存块之间为源源不断的请求做动态、公平且可抢占的分配。连续批处理让 GPU 不空等分块预填充让长请求不霸占优先级队列让重要请求不饿死水印与 LRU 让内存告急时系统抖得尽量小。理解了这条主线再回头看max_num_batched_tokens、block_size、watermark这些参数它们就不再是玄学旋钮而是这条主线上的具体阀门。【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门