ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

vLLM 深度调优:Prefill 与 Decode 的资源博弈与实战参数

vLLM 深度调优:Prefill 与 Decode 的资源博弈与实战参数 vLLM 深度调优Prefill 与 Decode 的资源博弈与实战参数一、推理的两个阶段理解瓶颈在哪很多团队部署 LLM 时只关注模型能不能跑起来不关注同时跑的时候哪个阶段在排队。结果并发一上来延迟飙升、吞吐骤降却说不清楚卡在哪。要定位问题先得把 LLM 推理拆成两个阶段——Prefill 和 Decode。Prefill 阶段是处理用户输入的过程。你把一段文字喂给模型模型要把整个输入过一遍计算出中间结果生成 KV 缓存。这个阶段的特点是计算密集、一次性完成、消耗大量 GPU 计算资源。Decode 阶段是逐字生成回复的过程。模型根据 Prefill 阶段产生的 KV 缓存一个字一个字往外吐结果。这个阶段的特点是内存密集、逐步进行、每次只生成一个 token。为什么这个区分如此重要因为 Prefill 吃算力Decode 吃内存——如果你的卡在 Prefill 阶段被占满Decode 就得等着反过来如果 KV 缓存占满了新的请求连 Prefill 都排不进来。理解了这两个阶段的资源冲突vLLM 的所有优化机制——连续批处理、Chunked Prefill、PagedAttention——本质上都是在解决这个冲突。二、PagedAttention分页管理 KV 缓存先看 vLLM 最核心的机制。传统推理框架为每个请求的 KV 缓存预留连续的显存空间但序列长度是动态增长的——预留少了不够用预留多了浪费。PagedAttention 把这个难题交给了分页KV 缓存被切成固定大小的页block按需分配、动态换入换出物理上不要求连续通过页表管理逻辑到物理的映射。这个设计带来的收益是立体的。其一显存碎片率大幅下降——不再为每个请求预留整块空间碎片率可以降到 5% 以下。其二内存利用率提升——只有实际用到的页占用显存同等显存能支撑的并发请求数大幅增加。其三支持 KV Cache 的精细管理——可以给不同请求分配不同大小的缓存优先保障重要请求。实验数据显示这一机制在 24GB 显存的 GPU 上可以支持同时处理上百个并发请求相比固定分配方案吞吐量提升数倍。但分页机制本身也有开销页表维护、换页调度需要配合量化与批处理优化来抵消——没有任何机制是免费的。三、Chunked Prefill解决大输入吃死整张卡Prefill 阶段的一个现实问题是当某个请求的输入特别长时它的 Prefill 计算会长时间独占 GPU把其他请求全部堵在后面——短请求的延迟因此被长请求拉爆。vLLM 的 Chunked Prefill 机制把长输入的 Prefill 计算切成多个 chunk交错地插入到 Decode 批处理中执行。效果是长请求的 Prefill 不再独占 GPU短请求的 Decode 可以穿插进行整体延迟分布更均匀。这背后是资源调度的精细权衡Preflight 计算可以抢占Decode 输出也可以被暂停关键是让 GPU 永远在有活干的状态。Chunked Prefill 的 chunk 大小是可配置的需要根据负载特征调优——chunk 太大独占效应还在chunk 太小调度开销上升。四、连续批处理与投机解码把 GPU 喂饱Decode 阶段的问题正好相反——每一步计算量小、访存量大GPU 算力利用率低。两个机制专门针对这个问题。连续批处理Continuous Batching把调度粒度细化到 token 级批处理不是等一批请求全部完成再换下一批而是请求生成完一个就释放一个新请求随时插入。GPU 计算单元始终保持高利用率不会出现一批长请求把 GPU 占住短请求全在排队的局面。实测中连续批处理能提升吞吐量 2-4 倍。投机解码Speculative Decoding的思路更巧妙用一个小的草稿模型draft model先快速生成下一段 token再用大模型一次性批量验证。验证通过的 token 直接采纳验证失败的从头重来。由于大模型验证多个 token 的批量计算比逐个生成更高效整体生成速度可以提升 1.5-2 倍。投机解码对草稿模型的选择有要求——草稿模型与目标模型的 token 分布越接近接受率越高收益越大。五、关键参数图谱每个参数管什么vLLM 的调优参数很多理解了它们的作用调优才有方向。gpu_memory_utilization控制为模型预留的显存比例默认 0.9。KV Cache 从预留显存中分配这个参数调高能增加 KV Cache 容量更多并发但会挤压其他用途的显存空间调低则相反。显存紧张时优先从这里找空间。max_model_len模型支持的最大序列长度输入 输出。它直接决定 KV Cache 的单请求上限设置过大如默认 32K会让 KV Cache 预留激增很多并发上不去的案例根源就在这里——按业务实际需求设置别让框架为永远用不到的长度预留显存。max_num_seqs单次批处理的最大请求数。调高能提升吞吐但会增大单批次的内存峰值和调度延迟调低能降低延迟波动但牺牲吞吐。需要配合压测数据折中。enable_chunked_prefill是否开启 Chunked Prefill混负载场景建议开启。tensor_parallel_size / pipeline_parallel_size张量并行和流水线并行的配置。单卡放不下的模型用张量并行需要 NVLink 等高带宽互联追求多卡吞吐用流水线并行。其他值得关注quantization量化方法、enforce_eager关闭 CUDA Graph 加速调试用、max_paddingspadding 控制等。六、实测调优流程从基线到最优参数调优不能拍脑袋要遵循基线 → 压测 → 调参 → 复测的循环。第一步起基线服务。用默认配置起服务确认功能正常记录基础指标。第二步构建压测负载。用真实业务请求混合长度、混合并发压测记录三个核心指标TTFT首 token 延迟用户感知的响应速度、TPOT每 token 生成时间吞吐的镜像指标、吞吐量每秒生成 token 数。压测负载一定要贴近真实——单一短请求的压测会严重高估系统能力。第三步逐个参数实验。一次只改一个参数观察指标变化。常见的调优顺序先收紧 max_model_len 到业务需求立竿见影地释放 KV Cache 空间→ 再调 gpu_memory_utilization 找到显存水位平衡点 → 然后调 max_num_seqs 观察吞吐与延迟的拐点 → 最后按需开启 chunked prefill 和投机解码。第四步验证稳定性。最优参数组合要在持续负载下跑足够久观察显存水位是否稳定、是否出现 OOM 或延迟毛刺。还要验证长尾场景——极端长输入、突发并发、模型升级后的回归。一个实际案例某团队部署 7B 模型默认配置下 24GB 显卡只能跑 8 并发延迟还波动剧烈。分析发现 KV Cache 预留过大、max_model_len 设成了 32K。把 max_model_len 压到 8K、gpu_memory_utilization 调到 0.85、max_num_seqs 从 256 调到 64 之后并发从 8 提升到 30P95 延迟反而下降了 40%——没换任何硬件全靠参数调优。七、常见误区与排查思路误区一并发上不去就加卡。先查显存账——KV Cache 预留是不是过大、max_model_len 是不是虚高、量化是不是还没做。多数并发问题在参数层就能解决。误区二只看平均延迟。平均延迟会被少数短请求拉低掩盖长尾问题。生产监控要看 P95/P99 延迟和延迟分布。误区三压测负载与真实负载脱节。单长度、单并发模式的压测结果没有参考价值——真实业务是混合负载。误区四改参数不验证效果。调了 gpu_memory_utilization 觉得应该有效——参数对效果的影响必须用压测数据验证否则就是碰运气。排查思路延迟高先看是不是 TTFT 高Prefill 排队查 max_num_seqs 和 batch 调度还是 TPOT 高Decode 慢查 KV Cache 命中、显存带宽吞吐低先看 GPU 利用率低是批处理或 Prefill/Decode 失衡高但吞吐低是显存带宽瓶颈OOM 先看显存账四块构成找出哪块爆了。八、结语vLLM 把推理优化的大部分机制做成了默认能力但能用默认配置和能榨出最优性能之间隔着一整套理解与调优的功夫。理解 Prefill 与 Decode 的资源博弈是这套功夫的起点掌握参数与指标的对应关系是调优的路线图坚持基线 → 压测 → 调参 → 复测的循环是落地的方法论。大模型推理没有银弹但路径是清晰的算清显存账、理解两阶段冲突、用 vLLM 的机制对症下药、用压测数据持续调优。沿着这条路走同样的硬件你大概率能服务多一倍的并发还让用户等得更少——这就是推理优化的价值。
返回列表