Kalypso:打破算子物化壁垒,关系型LLM推理实现4.57倍提速

Kalypso: Relational LLM Serving

论文原文 ↗ 论文发布 解读发布 解读:AI前沿分享

Kalypso:打破算子物化壁垒,关系型LLM推理实现4.57倍提速 论文图示

在大模型作为非结构化数据处理基础设施的浪潮下,数据库领域正在经历一场深刻的范式迁移。文本检索、实体抽取、多表关联和属性转换等经典数据库操作,逐渐被封装成由提示词驱动的“语义算子”(Semantic Operators)——比如通过自然语言过滤低质评论、抽取临床病历的核心指标,或者跨表比对两份法律合同的条款一致性。为了承载这类复杂查询,以 Lotus、Palimpzest 为代表的语义查询处理系统(SQPS)应运而生。

ArXiv URL:https://arxiv.org/abs/2607.23815v1

然而,当前的系统架构存在一条隐蔽而高昂的鸿沟。上层的语义查询系统虽然掌握着全局查询计划(Query Plan),但优化重心往往局限在如何用小模型做代理过滤、如何剪枝调用次数;而下层的现代大模型推理引擎(如 vLLM、SGLang、TGI)则是典型的“以请求为中心”(Request-centric),对上层算子之间的拓扑依赖关系毫无感知。查询系统按照传统的“算子逐个执行”(Operator-at-a-time)方式物化中间结果,推理引擎则将每个输入元组当成彼此孤立的推理请求。这种割裂直接导致昂贵的键值缓存(KV Cache)在上游算子完成后被迅速逐出,当下游算子再次处理同一文本时,又不得不重新做一遍计算量巨大的上下文预填(Prefill)。

来自马萨诸塞大学阿默斯特分校(UMass Amherst)的研究团队在论文《Kalypso: Relational LLM Serving》中提出了破局方案。该研究定义了“关系型 LLM 推理”(Relational LLM Serving)这一全新抽象层,并构建了名为 Kalypso 的执行系统。Kalypso 既不修改上层语义查询的数学定义,也不侵入改变模型的生成精度,而是通过打破算子之间的物化边界,以流式流水线(Pipelining)调度和自适应显存感知控制,让中间元组的 KV Cache 在有限显存中直接流转到下游算子。基准测试表明,在同等调用参数与模型精度下,Kalypso 相比现有方案实现了高达 4.57 倍的端到端查询耗时缩减。

割裂的现状:为何前缀缓存在查询系统中频繁失效?

要理解 Kalypso 的价值,首先需要厘清大模型语义查询的执行本质。在处理非结构化文本时,一个典型的查询计划往往由级联算子组成。例如,一个“过滤 $\rightarrow$ 映射”(Filter $\rightarrow$ Map)流程:输入一张学术论文表,Filter 算子负责判断论文是否属于阿尔茨海默病研究,通过筛选的论文接着送入 Map 算子提取核心实验结论。

在这两个连续的算子中,提示词(Prompt)通常由三部分构成:系统指令(System Prompt $S$)、论文正文(Tuple Content $C(t)$)以及具体的任务指令($I_{\mathrm{filter}}$ 或 $I_{\mathrm{map}}$)。不难发现,输入文本 $[S \mid C(t)]$ 在逻辑上是完全一致的前缀。现代推理引擎普遍支持自动前缀缓存(Automatic Prefix Caching, APC),理论上,只要 Filter 处理过该元组,其对应的 KV Cache 就可以被紧随其后的 Map 算子直接命中,Map 算子只需要针对差异化的后缀 $I_{\mathrm{map}}$ 进行极少量的增量 Prefill。

但在现实系统中,这一理想假设几乎必然落空。由于现有的 SQPS 普遍采用整体物化机制,系统必须等待整张数据表的所有行全部跑完 Filter 算子,才会将过滤后的结果集合并打包送入 Map 算子。在数据量庞大或文本篇幅较长时,后续元组在执行 Filter 算子时会源源不断产生新的 KV Cache,受限于物理 GPU 显存上限,推理引擎内部的 LRU 或类似淘汰机制会迅速将先前算好的前缀逐出显存。当 Map 算子终于开始执行时,面对的又是一片已经被清空的缓存,只能退化为代价高昂的全局全量重算。

这就暴露出以请求为中心的推理引擎的核心缺陷:底层引擎无法识别“哪些请求属于同一个元组的后续阶段”,因而只能一视同仁地根据局部的请求到达时间来淘汰缓存;而上层系统虽然知道算子依赖,却放任中间结果落盘物化,错失了流水线执行(Pipelining)带来的缓存复用窗口。

关系型 LLM 推理:将查询图下沉到调度层

Kalypso 的核心理念是引入“关系型 LLM 推理”抽象层,将其置于高级查询系统与底层通用推理引擎之间。它既向上暴露能够定义复杂语义算子与查询图的 API,又向下直接接管推理任务的分发时序与 GPU 显存分配。

在 Kalypso 中,一个静态的左深查询树(Left-deep query plan)首先被解析器划分为多个执行流水线(Pipeline)。阻塞型算子(如全局排序或全表聚合)作为流水线的自然边界;而在同一个流水线内部,算子序列进一步根据笛卡尔积算子(如 Semantic Join)划分为连续的阶段(Stage)。

每个 Stage 由一个或多个按顺序作用于单条元组的非阻塞算子组成。Kalypso 的最小调度单元被定义为任务(Task),即“在某一个特定元组上执行某个 Stage”。当一个 Task 在上游完成计算并产出合格的中间元组时,Kalypso 不会将其留在内存中等待整批数据就绪,而是立即将产出的中间元组推进到下游 Stage 的等待队列,或者与右表组合生成依赖任务(Dependent Tasks)。

通过这种流式推进,属于同一元组的下游计算请求能够在极短的时间间隔内被推送到底层推理引擎,从而使上游刚刚计算完成的 KV Cache 前缀在还未被覆盖之前,就能被下游算子无缝复用。

显存感知的在线调度:并发度与淘汰压力的动态平衡

然而,仅仅实现朴素的流水线推进并不能自然解决问题,反而会引出一个更加棘手的在线调度困境:在物理显存容量严格受限的前提下,流水线算子依赖与 KV Cache 驻留时间高度耦合

为了维持 GPU 计算核心(SM)的高利用率,调度器必须维持足够的元组并发度;但并发度一旦过高,在途(In-flight)算子所持有的显存总和就会瞬间击穿显存预算,底层引擎被迫发生未经计划的 Cache 逐出,下游算子依然拿不到预期的缓存命中;反之,如果调度器过度保守,严格限制上游算子的并发数,由于算子过滤的选择率(Selectivity)和关联膨胀率(Fan-out)在运行前完全是未知的,上游产出稍有波动,下游阶段就会迅速陷入无活可干的“饥饿”(Starvation)状态,导致 GPU 空转。

为了破解这一矛盾,Kalypso 设计了一套自适应显存感知调度算法。系统为每个 Stage 分配一个动态调整的显存预算配额。调度器为每个进入执行态的 Task 预估其所需的显存开销,并维护两道安全水位线:

\[\mathit{high}_{s} = \alpha \cdot \frac{\mathit{budget}_{s}}{\mathit{minBudget}_{s}}, \qquad \mathit{low}_{s} = \beta \cdot \frac{\mathit{budget}_{s}}{\mathit{minBudget}_{s}}\]

其中 $\alpha$ 与 $\beta$ 为调节系数。当某个 Stage 内部在途任务消耗的显存达到高水位线时,调度器会暂停吸纳该 Stage 的新输入,防止过量积压导致缓存溢出;而当在途显存回落到低水位线以下时,再恢复拉取任务以补充算力。

更为关键的是跨阶段的动态预算转移机制。在查询执行过程中,如果下游 Stage 发生饥饿(等待队列排空且无在途任务),算法会认定当前瓶颈在于上游供给不足,下游 Stage 会主动将自身的部分显存预算转移给直接上游;若上游同样处于饥饿状态,该转移逻辑会递归向源头传递,直到找到有积压任务的 Stage,扩大其并发配额以快速生成数据。反之,当下游积压严重而上游仍在高速生产时,预算会被反向归还,限制上游的扩张。这种基于实时吞吐波动的在线弹性调度,在不需要预知数据分布的前提下,维持了整条流水线在显存临界点上的高吞吐平衡。

显存预测、固定与死锁解脱

在底层实现上,精确的显存控制必须直面大模型生成的不确定性。与传统关系型数据库可以通过固定 Schema 算出每行字节数不同,大模型在 Decode 阶段究竟会吐出多少个 Token 在执行前是无法确定的。

Kalypso 的显存管理器为此引入了弹性配额预估与重试闭环。针对特定算子,系统会基于静态元数据和历史运行数据为 Task 设定一个预估 Token 预算。如果大模型实际生成的 Token 数量超出了初始预算,推理引擎会暂停并抛出显存超限信号,Kalypso 则会根据实际输出长度动态扩大预算,将任务重新加入调度队列进行重试。

此外,为了确保依赖任务能够百分之百利用上游 Cache,系统支持显存固定(Pinning)策略:在上游任务完成且所有下游依赖任务全部执行完毕之前,强制通知引擎锁定其 KV Cache 块不可被换出。然而,显式锁定在多算子并发时极易引发经典的资源循环等待,最终诱发死锁。

Kalypso 对此设置了细致的死锁检测与恢复保护:调度器会周期性轮询底层 Serving 引擎的内部状态,一旦发现系统存在处于就绪等待状态的 LLM 请求,但整个 GPU 上没有任何正在运行(Running)的推理请求,即可判定系统遭遇死锁。一旦捕捉到死锁信号,Kalypso 会瞬间解开所有已固定的内存块,并将策略降级为基于优先级的“虚拟固定”(Virtual Pinning),允许底层引擎在紧急时刻按照标准规则逐出部分 Cache 以打破僵局,待管线疏通后再平滑切回。这种软硬结合的防御机制,保证了在极端负载与异常长尾输出下系统仍具备工业级的执行健壮性。

实验评测:长文本与显存极限制约下的真实表现

为了验证架构的有效性,研究团队在一台配备 4 张 NVIDIA RTX Pro 6000 GPU(共 96 GB 高速显存)、AMD EPYC 9575F 处理器及 300 GB 内存的高规格服务器上部署了 Kalypso,底层依托 vLLM(v0.13.0rc4)与 Triton 后端,选用 Llama-3.3-70B-Instruct 作为基准模型,并在多卡间启用张量并行(Tensor Parallelism)。对比基准涵盖了目前学术界与工业界最具代表性的语义查询处理系统 Lotus 与 Palimpzest。

测试选取的四类典型负载覆盖了多样化的算子拓扑结构与长短文本分布:

  1. FEVER:事实核查任务,包含文本过滤与标签判断的多阶段流水线;

  2. MEDEC:医学错误纠正任务,包含针对医疗文本的高选择率复杂过滤;

  3. BioDEX:生物医学实体匹配,侧重于专业文献的高维特征抽取;

  4. ContractNLI:法律合同蕴含推理,包含两阶段操作,单篇合同平均长度达到 2145 个 Token,且每个合同需与 17 条假设进行笛卡尔关联匹配(Semantic Join),随后执行属性提取(Map)。

端到端延迟测试表明,Kalypso 在所有评测工作负载中均展现出显著的性能优势。在 LLM 实际调用总次数基本持平(误差仅来自模型采样的固有随机性)的前提下,性能加速完全源于执行效率的提升。

提升最为惊艳的场景出现在长文本跨阶段复用的 ContractNLI 任务中。由于长达两千余 Token 的合同文本需要在 Join 谓词判定和后续 Map 算子中被反复调用 17 次以上,基线系统由于算子割裂物化,每次关联都在做极其沉重的上下文 Prefill,甚至连引入了轻量代理过滤模型的 Lotus 也被频繁的重算拖垮。而 Kalypso 凭借流水线传递,将这块巨大的 KV Cache 牢牢锁定并就地复用,端到端耗时从 Palimpzest 的 2373.4 秒大幅压缩至 1062.4 秒,实现 2.23 倍提速;面对 Lotus 的 4854.0 秒基线,更是斩获了高达 4.57 倍 的加速比。

更值得关注的是系统在显存资源敏感度实验中的抗压表现。研究人员通过人工限制分配给 vLLM 的显存比例,将可用 KV Cache 容量从充裕的 190.6 GB 逐步阶梯式压缩至极度苛刻的 38.6 GB。在显存被压缩近 80% 的极端环境下,缺乏查询感知的基准系统出现了严重的性能崩溃:Lotus 在 MEDEC 负载上的延迟飙升了 44%,Palimpzest 激增了 29%;而 Kalypso 得益于自适应的高低水位控制与动态 Stage 预算平移,在同一任务下的延迟仅微增 9%(从 464.3 秒轻微浮动至 507.3 秒)。即便在庞大的 ContractNLI 负载下,Kalypso 在显存缩减过程中整体执行时间始终稳定被压制在 1348.3 秒以内,充分印证了显存感知调度算法在应对真实物理显存瓶颈时的刚性防御能力。

走向数据系统与大模型推理的协同演进

Kalypso 的实践表明,单纯在应用层优化查询代数,或者单纯在底层优化通用注意力机制,都无法充分释放大模型在复杂数据处理场景中的潜力。过去几十年数据库系统所积累的经典思想——算子流水线、内存准入控制、执行图感知——在进入大模型时代后并没有过时,反而在昂贵的显存与算力约束下迸发出了全新的生命力。

将“以请求为中心”的机械式 LLM 服务,演进为“以算子关系为中心”的协同式 LLM 服务,是支撑未来智能数据湖仓、自主智能体工作流(Agentic Workflows)以及复杂 RAG 系统的关键一步。随着模型上下文窗口的持续膨胀和非结构化数据规模的井喷,让底层推理引擎真正“看懂”业务查询图,或将成为大模型基础设施演进的一条必然路径。