FluidPD 让 LLM 服务在预填充与解码间自由流动,而不是等待 SLO 爆掉
静态比例在真实流量下撑破的那一刻,FluidPD 出现了。它不是给你加机器,而是教已经部署好的 Worker 自由选自己该干的活——临时的,把多余的预填充任务借给空闲的解码单元;久的,干脄把 Worker 直接掰弯,从预填充岗换到解码岗,甚至连模型都不用重载。作者在 Azure 真实 trace 跑出来的结果是:比起一成不变的 SGLang 配置,SLO 达标率直接被压上去 —— 但具体百分比,还是去原文看去吧,别信我在这儿胡诌。
什么场景下你会因为“预填太多 / 解码太少”或反之苦恼
说起 P/D 解耦架构,不少人第一时间想到的是“资源更好利用”。但利用率高、配置合理那是静态仿真里说的。线上是另一回事:一分钟你这里用户刚刷了一波长 Prompt,预填充段瞬间就炸了队列;十分钟后大家都进了打字机模式,只见高速输出,从预填充机器上飙出来的资源干着急。
传统方案有两个方向:
- 开更多 GPU,按最大可能配比划分 Worker;
- 靠 Autoscaler 看负载指标攒够 CPU/GPU 之后,再加实例。
结果呢?第一种浪费闲资源,第二种反应慢,更别说还有“需要准备备用显卡”的前提。还有人说“那就动态路由嘛”,可路由只解决任务在固定 Worker 间的派发问题,没法改机器的角色定位。
所以 FluidPD 出来的时候,有没有那么点“终于想到个办法”的感觉。
FluidToken:临时任务外借,不需要加卡
遇到短时间的预填充洪峰,解码 Worker 往往还坐着一段时间。FluidPD 做的第一件事是:允许少量预填充计算任务,借着解码 Worker 当前的空闲周期给算完——前提是这个“借”不是随意的,必须控制在一个可预测的范围之内。
这种处理方式并不追根到底,只能说是“压力暂时过大、顺手借个凳子”。关键点在于:借多少、借谁、借多久 都不是写死的,而是靠一个轻量的压力指标判断出来的。
FluidRole:长期角色转换,连模型都不用重启
如果压力持续了一会,比如连续几分钟都是预填充需求远高于解码,那“借位”就不太靠谱了。这时候 FluidPD 的另一个机制上场了:FluidRole。
它的思路很直接,但执行上可不简单:把已经运行的 Worker,从预填充角色直接调成解码角色,或者反过来。不用卸载模型,不用重启服务引擎。整个过程,耗时应该在分钟以内,远远比 Spin-up 新实例快。
缺点也明显:调换角色意味着要处理上下文切换、状态同步等琐事。但作者声称,在压力指标清楚反映“该转换了”之前,系统已经在背后默默准备好状态,就好像司机在红灯前就踩刹车一样。
压力指标如何运转
FluidPD 并没有使用常见的队列长度或 GPU 利用率这种“事后指标”。取而代之的是,它自己设计了两个“压力指数”:
- 一个用于衡量预填充侧面是否饱和;
- 另一个用于衡量解码侧面是否有余力。
这两个值不是从系统日志里提取的宏观平均数,而是结合了当前请求特性、Token 吞吐、调度延迟等要素综合计算出来的。目的是为了在问题变严重之前就介入。
举例来说,当预填充压力指数突然上升,而解码那边压力指数还维持在中等水平,系统就会判断:“现在借任务过去,或者干脆换角色,应该都行。”
与 SGLang 静态部署比起来,差距有多大
这篇论文跑测试用的场景是 Azure 上的真实 trace。他们没说用的是哪款模型,但强调测试过程中并没有额外添加任何 Worker。
结果自然而然就是:FluidPD 在多个 trace 场景下,都比固定配比的 SGLang 表现更好。至于提升了几个点百分比——你可以理解为“显著”,但具体是多少,我不会在这里随随便便写出来。你要真想知道,去 arXiv 翻原文,那才是“可核对”的来源。
怎么看待 FluidPD?
说实话,这种方向性的改进,看起来很像是我们常说的“软硬结合”。它没有革命性的硬件突破,也没有颠覆性的调度算法。但它确实让人感觉到不一样:
> 不需要更多的资源,就能应对更多的变数。
对于那些正在被“流量突变”折腰的团队来说,这可能值得一试。毕竟现实中很多服务不是缺机器,而是缺灵活性。
不过也别期望太高。FluidPD 目前还是个论文成果,还没看到正式开源的代码仓库。等落地以后再去下判断,才更靠谱。
小结一下思路
- P/D 解耦不是“一劳永逸”的架构,流量分布变了就容易出问题;
- FluidPD 靠两个机制应对不同情况:借位应付短期波动,换角色缓解长期失衡;
- 它的优势来源于“不加资源,但能更智能用已有资源”;
- 测试结论属实,但具体数字你得去看原文;
- 落地时间未定,先看看代码再说。
SLO 压上去具体是多少啊,单看“比原配置好”太不好意思当回事儿,咋和 SGLang 的默认 P:D 比例比啊?