从系统角度看大模型(LLM)与数据库(Database)

It is never too late to give up our prejudices.

封面的图片是大模型生成的,还不是很靠谱,请勿直接采信。

众所周知,大模型的训练(Training)和推理(Inferencing)是两个截然不同的阶段。大模型的训练与现有的其他系统都明显不同,大模型的推理系统及其服务化则与现有的其他系统更相似一些。推理服务既然是个系统,那么它需要考虑响应时间、吞吐量、资源利用率等常见的系统类指标。从响应时间角度看,推理系统中最基础的指标包括首 Token 时延(TTFT,Time To First Token)、输出 Token 时延(TPOT,Time Per Output Token)等。TTFT 对应于推理服务的 Prefill 阶段,TPOT 对应于推理服务的 Decode 阶段,这是 Transformer 大模型结构计算 Attention 以及一次一 Token 输出的特点决定的。实际上,很多交互式的系统都存在类似 Prefill 和 Decode 阶段(数据库领域喜欢说启动成本高),只不过没有大模型的推理服务这么明显。例如,在数据库中发起一个交互式 SQL 查询后,到系统返回第一条记录一般也会需要较长的时间,其后的记录很多时候可以流式的连续输出。

以数据库为代表的传统系统是运行在 CPU 上的,可以采用多进程、多线程、数据缓存、计划缓存、结果集缓存、批处理等等各种技术手段,来优化响应时间、吞吐量和资源利用率等系统指标。可是大模型是运行在 GPU(或其他各种非 CPU 芯片上)上的,需要适应 GPU 编程的特点和约束;例如,它没法做到类似 CPU 的多线程调度。大模型最基本的优化包括批处理,也就是同时处理多个 Prompt 的推理,要采取各种技巧把显存填满并且减少无效的计算。简单粗暴的把不同长度的 Prompt 按照最长的对齐显然不是高效的做法,因此需要利用 Transformer 结构中 Attention 计算的特点做 Chunked Prefill 等。系统一旦运行起来,大量会话的 Prefill 和 Decode 会同时存在,因此把 Prefill 与 Decode 批量摆到一起做计算也是必须的优化。此外,在一个大规模的服务中,把 Prefill 与 Decode 分开部署也是架构上自然的一类演进。批处理的另外一些优化思路是缓存,例如把同样的 Prompt 对应的推理结果给缓存起来,以存代算。大模型推理服务中存在大量重复的 System Prompt,会话过程中也存在很多重复的其他 Prompt 前缀。实际上,Attention 计算过程中也有很多重复的计算,这些都可以通过 KV Cache 缓存来加速。Cache 机制非常类似于传统系统的类似机制,只不过它主要存放在显存内。如果显存不够大,自然的想法是把它们分级,存放一部分到内存,甚至未来还可以放到其他介质分层中去。大模型的训练过程中存在很多通信路径需要优化,在推理过程中也存在一些通信路径可以优化。典型的情况包括 Prefill 与 Decode 分离之后的 KV Cache 如何跨卡或跨节点快速传输复用等。vLLM 等开源框架已经实现了上述的很多优化技术点。

反过来,如果数据库系统需要跑在 GPU 上,也得遵循硬件的限制,从大模型系统上借鉴一些解决思路和技巧;学术界和工业界也一直有各种尝试。从宏观架构上考虑,数据库要跑在 GPU 上还面临几个实际的约束。首先,AI 芯片并没有多少能够腾出来跑非 AI 的负载,毕竟当前其价格仍然不菲,拿来跑数据库非常不划算。能够拿来跑数据库或其他负载的应该是被淘汰或闲置的旧卡,做点废物利用。其次,AI 芯片的很大一部分浮点数算力,例如 FP16、FP8,不适合拿来跑非 AI 负载,因为这些系统要的至少是 FP64、FP32。最后,很多非 AI 负载需要频繁从内外存读写数据。将数据一次性加载到 GPU 上,然后疯狂的进行计算的场景还不太多。从这个意义上看,将 CPU、GPU 封装到一起,统一内外存访问的模式可能更容易促进传统负载与 AI 负载的结合。

Written on December 8, 2025