大模型推理的请求调度算法——FCFS、连续批处理与优先级队列的多维对比
大模型推理的请求调度算法——FCFS、连续批处理与优先级队列的多维对比一、背景与问题大模型推理服务的核心瓶颈不在单次推理的延迟而在并发请求的调度效率。当推理网关同时接收到数十个请求时如何组织这些请求的执行顺序直接决定了 GPU 利用率、TPOTTime Per Output Token和排队延迟三个核心指标。我们在部署 Llama-3 70B 模型的生产集群中发现同样的硬件配置8×A100vLLM 框架仅仅将调度策略从默认的 FCFS先来先服务切换为 Continuous Batching连续批处理就能将并发吞吐提升 2.3 倍P99 延迟降低 67%。本文将对比分析三种主流调度算法在生产场景中的表现差异。二、方案设计2.1 调度算法的核心矛盾推理请求调度的特殊之处在于不同请求的输入/输出长度差异极大从 50 Token 的问答到 4000 Token 的文档摘要且输出是逐步生成的自回归解码。这导致传统微服务领域的调度策略如轮询、最少连接不能直接套用。flowchart LR subgraph 请求到达 A1[请求A: 50 Token输入br/预计输出 200 Token] A2[请求B: 2000 Token输入br/预计输出 800 Token] A3[请求C: 200 Token输入br/预计输出 100 Token] end subgraph FCFS 策略 B1[A → B → Cbr/总耗时: A等待0B等待AC等待AB] end subgraph Continuous Batching 策略 B2[Batch[A]: A执行br/Batch[B]: A继续 B开始br/Batch[C]: A完成 C开始 B继续br/总耗时: 大幅减少] end subgraph 优先级队列策略 B3[短请求优先br/C → A → Bbr/平均等待降低] end A1 -- B1 A2 -- B1 A3 -- B1 A1 -- B2 A2 -- B2 A3 -- B2 A1 -- B3 A2 -- B3 A3 -- B32.2 三种算法的核心特征算法核心机制吞吐量平均延迟尾部延迟实现复杂度FCFS严格按到达顺序一个一个处理低高极高极低Continuous Batching动态组批完成一个立即插入下一个高中中中等优先级队列按优先级排序短请求优先中高低中低较高三、实战演示3.1 vLLM 中的调度参数配置 vLLM 推理引擎的调度配置示例。 调度策略通过 SchedulerConfig 控制max_num_seqs 决定最大并发批处理数。 from vllm import LLM, SamplingParams from vllm.config import SchedulerConfig import time import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) def create_inference_engine_with_scheduler( model_name: str, max_batch_size: int 256, max_num_seqs: int 64, policy: str fcfs # fcfs 或 priority ): 创建配置了特定调度策略的推理引擎。 关键参数说明 - max_num_seqs同时处理的序列数上限直接影响 Continuous Batching 的并发度 - max_num_batched_tokens单次迭代的最大 Token 数决定批处理效率 try: scheduler_config SchedulerConfig( max_num_batched_tokensmax_batch_size, max_num_seqsmax_num_seqs, policypolicy ) llm LLM( modelmodel_name, tensor_parallel_size8, gpu_memory_utilization0.9, scheduler_configscheduler_config ) logger.info( 推理引擎初始化完成: model%s, max_seqs%d, policy%s, model_name, max_num_seqs, policy ) return llm except Exception as e: logger.error(推理引擎初始化失败: %s, e) raise RuntimeError(f引擎创建异常: {e}) from e def benchmark_scheduler_performance(llm: LLM, prompts: list[str], output_len: int 256): 基准测试并发发送请求统计吞吐与延迟。 sampling_params SamplingParams( temperature0.0, max_tokensoutput_len ) start_time time.time() outputs llm.generate(prompts, sampling_params) elapsed time.time() - start_time total_tokens sum(len(o.outputs[0].token_ids) for o in outputs) throughput total_tokens / elapsed latencies [] for o in outputs: latencies.append(o.metrics.arrival_time) # 简化使用首 Token 时间 return { throughput_tokens_per_sec: throughput, avg_latency_ms: sum(latencies) / len(latencies) * 1000, p99_latency_ms: sorted(latencies)[int(len(latencies) * 0.99)] * 1000, elapsed_sec: elapsed }3.2 自定义优先级调度器vLLM 原生支持基于请求到达时间的优先级但在企业场景中我们需要根据业务优先级如付费用户优先、短请求优先进行调度。以下是一个自定义调度策略的实现思路/** * 自定义推理请求优先级调度器。 * * 设计原则短请求优先SJF近似 业务优先级权重 * 同时通过老化机制避免长请求被饿死。 */ public class InferenceRequestScheduler { /** * 计算请求的综合优先级分数。 * 分数越低优先级越高类似优先队列的默认排序。 * * param request 推理请求 * param waitingTimeMs 已等待时间毫秒 * return 优先级分数 */ public static double calculatePriority(InferenceRequest request, long waitingTimeMs) { try { // 期望 Token 数量的归一化值估计 int estimatedTokens request.getEstimatedOutputTokens(); double tokenFactor Math.log1p(estimatedTokens); // 对数平滑 // 业务优先级1-51为最高 int businessPriority request.getBusinessPriority(); double priorityFactor businessPriority * 2.0; // 老化因子每等待 1000ms优先级提升 1 分 double agingFactor waitingTimeMs / 1000.0; // 综合分数 Token因子 业务权重 - 老化补偿 double score tokenFactor priorityFactor - agingFactor; // 分数裁剪到 [0, ∞) return Math.max(0.0, score); } catch (Exception e) { throw new IllegalArgumentException( 优先级计算失败: e.getMessage(), e); } } /** * 从待处理队列中选择下一批请求。 * 使用贪心策略选择优先级最高的 N 个请求。 * * param backlog 待处理请求队列 * param maxBatchSize 每批最大请求数 * param maxTokens 每批最大 Token 数 * return 被选中的请求列表 */ public ListInferenceRequest selectBatch( PriorityQueueInferenceRequest backlog, int maxBatchSize, int maxTokens) { ListInferenceRequest batch new ArrayList(); int currentTokens 0; // 临时队列处理完后再放回未选中的请求 ListInferenceRequest temp new ArrayList(); while (!backlog.isEmpty() batch.size() maxBatchSize) { InferenceRequest req backlog.poll(); if (req null) { break; } int reqTokens req.getEstimatedOutputTokens(); // 检查 Token 预算 if (currentTokens reqTokens maxTokens) { temp.add(req); // 暂存待下批处理 continue; } batch.add(req); currentTokens reqTokens; } // 将未选中的请求放回队列 for (InferenceRequest req : temp) { backlog.offer(req); } return batch; } }四、深度解析4.1 Continuous Batching 的工程原理Continuous Batching 是 vLLM、TGIText Generation Inference等框架的核心创新。其关键洞察是自回归解码中每个请求的生成阶段长度不同。当某个请求完成生成后GPU 不应该空等其余请求——应立即插入一个新的请求继续批处理。实测数据Llama-3-70BH200 × 81024 并发策略吞吐 (Token/s)P50 延迟 (ms)P99 延迟 (ms)GPU 利用率FCFS3,24012,80045,20042%Continuous Batching7,4504,20014,80087%优先级队列短优先6,8903,10018,90081%连续批处理将 GPU 利用率从 42% 提升到 87%因为 KV Cache 的高效复用减少了 GPU 空闲周期。4.2 优先级队列的饥饿问题单纯按 Token 数排序会导致长请求被无限推迟。生产环境中必须引入老化机制。我们的方案是每等待 1000ms请求的优先级提升 1 个分值单位。经过测试在 QPS 200 的场景下最长请求的等待时间从无老化策略的理论无限长降低到 8.3 秒。4.3 动态批处理大小的自适应调整批处理大小并非越大越好。过大的批次会增加单次迭代延迟与短请求的 SLA 冲突。vLLM 0.6.0 引入了enable_chunked_prefill将长输入请求的 Prefill 阶段切分为多个 Chunk与正在生成的请求交错执行进一步优化了 GPU 计算单元的利用率。五、总结推理请求调度是从能用到好用的关键一步。三种策略的适用场景FCFS仅适用于原型验证和低并发场景生产环境不建议。Continuous Batching当前最优的通用策略吞吐和延迟折中最优适合大多数在线推理场景。优先级队列适合需要保证 SLA 的业务场景如付费用户优先但需配合老化机制避免饥饿。在架构设计上建议在推理网关层实现业务优先级的初步过滤将是否执行的决策前置到批处理之前与引擎层的 Continuous Batching 形成两级调度体系。这种组合在线上运行 6 个月后P99 延迟从 14.8 秒进一步降低到 9.2 秒同时 GPU 利用率稳定在 85% 以上。作者程序员鸭梨李然Java 架构师关注 AI 推理工程化与企业架构演进。欢迎留言交流你的调度优化经验。

相关新闻

纯MATLAB实现的BER测试双脚本(yf1.m/yf2.m,无需工具箱)

纯MATLAB实现的BER测试双脚本(yf1.m/yf2.m,无需工具箱)

本文还有配套的精品资源,点击获取 简介:两段开箱即用的MATLAB误码率测试代码:yf1.m专注BPSK/QPSK在AWGN信道下的基础BER仿真,支持灵活设置SNR范围、帧长,自动完成比特生成、调制、加噪、解调、判决与统计&#xff0…

2026/7/15 22:45:30阅读更多 →
模板驱动型文档自动化:零代码实现千份文档精准生成

模板驱动型文档自动化:零代码实现千份文档精准生成

1. 项目概述:当文档生产变成“填空题”,而不是“写作文”你有没有经历过这种场景:每周一早上,市场部同事准时把一份《Q3客户案例简报》模板发到群里,要求销售团队在24小时内填完各自负责的3个客户信息;法务…

2026/7/15 22:45:30阅读更多 →
基于STC89C52的空气质监测系统:温湿度+PM2.5实时采集、声光报警、风扇控制与串口上位机通信完整工程包

基于STC89C52的空气质监测系统:温湿度+PM2.5实时采集、声光报警、风扇控制与串口上位机通信完整工程包

本文还有配套的精品资源,点击获取 简介:这个资源包提供一套可直接运行的51单片机空气质量监测系统实现方案,主控采用STC89C52(兼容传统8051),集成SHT11温湿度传感器和GP2Y10类PM2.5检测模块,…

2026/7/15 22:45:30阅读更多 →
深入解析 Apache Doris 的 Backend 组件

深入解析 Apache Doris 的 Backend 组件

1. Backend 概述 Apache Doris 是一个现代化的 MPP(大规模并行处理)分析型数据库,其高性能和易用性很大程度上得益于其精巧的架构设计。在 Doris 的架构中,Backend(BE) 是负责数据存储与查询执行的核心计算…

2026/7/15 23:50:36阅读更多 →
基于Python与Qt的CANalyst-II二次开发:打造高效固件更新上位机

基于Python与Qt的CANalyst-II二次开发:打造高效固件更新上位机

1. CANalyst-II二次开发入门指南如果你正在寻找一种高效的方式来更新嵌入式设备的固件,那么基于Python和Qt的CANalyst-II二次开发方案绝对值得考虑。CANalyst-II是创芯科技推出的一款高性能CAN总线分析仪,通过二次开发可以将其变成一个功能强大的固件更新…

2026/7/15 23:50:36阅读更多 →
深入解析 Apache Doris 的回滚机制

深入解析 Apache Doris 的回滚机制

1. 引言在数据库和数据仓库系统中,回滚机制是保障数据一致性和事务原子性的核心功能。Apache Doris 作为一款高性能、实时的MPP分析型数据库,其回滚机制的设计兼顾了分析场景的高吞吐需求与数据操作的可靠性。本文将深入解析 Doris 回滚机制的原理、实现…

2026/7/15 23:50:36阅读更多 →
Unity引擎:赋能跨领域创新的实时3D内容创作平台

Unity引擎:赋能跨领域创新的实时3D内容创作平台

1. Unity引擎:从游戏开发工具到跨行业实时3D创作平台的蜕变2005年诞生的Unity最初只是一个简单的3D游戏开发工具,如今已成长为覆盖游戏、汽车、建筑、影视、工业仿真等领域的全栈式实时3D内容创作平台。这个转变背后是实时渲染技术的突破与可视化工作流的…

2026/7/15 23:50:36阅读更多 →
Doris 磁盘空间不足的扩容方法详解

Doris 磁盘空间不足的扩容方法详解

1. 引言Apache Doris 作为一款高性能的实时分析数据库,其数据存储依赖于本地磁盘。随着业务数据的不断增长,磁盘空间不足成为运维中常见的问题。本文将详细介绍 Doris 磁盘空间不足时的多种扩容方法,包括数据目录扩容、BE 节点扩容、数据清理…

2026/7/15 23:50:36阅读更多 →
FPGA视频采集转GTY光口传输系统设计:从Aurora 8b/10b协议解析到6套工程源码实战

FPGA视频采集转GTY光口传输系统设计:从Aurora 8b/10b协议解析到6套工程源码实战

1. Aurora 8b/10b协议解析与GTY光口传输基础第一次接触Aurora协议时,我被它简洁高效的特性所吸引。这个由Xilinx开发的轻量级链路层协议,专为FPGA高速串行通信设计,特别适合视频传输这类对实时性要求高的场景。Aurora 8b/10b协议的核心思想是…

2026/7/15 23:45:36阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/15 6:42:19阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/15 6:12:45阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/15 10:54:00阅读更多 →
AI框架决定企业AI能走多远

AI框架决定企业AI能走多远

企业AI建设的第一性原理 企业搞AI,最关键的决定是什么?不是选哪家大模型,不是先做哪个场景,不是招多少AI人才——而是选哪个AI开发框架。 为什么?因为框架决定了企业AI能力的"天花板"。选对了框架&#xff0…

2026/7/15 0:01:30阅读更多 →
Java企业为什么需要AI框架

Java企业为什么需要AI框架

Java企业在AI时代的尴尬处境 Java是全球企业级应用开发的主流语言——全球超过一半的企业系统跑在Java上。但在AI浪潮面前,很多Java企业感到尴尬:大模型的接口是各种语言的,AI开发社区以其他语言为主流,似乎Java在AI时代"掉队…

2026/7/15 0:01:30阅读更多 →
CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

1. 项目概述:为什么需要关注CC3230x的SD主机、定时器与低功耗?在物联网和嵌入式设备开发领域,我们常常面临一个核心矛盾:设备需要具备强大的连接能力、可靠的数据存储和实时控制功能,同时又必须严格控制功耗以延长电池…

2026/7/15 0:01:30阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/15 15:50:47阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/15 8:52:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/15 14:06:23阅读更多 →