打开网易新闻 查看精彩图片

新钛云服已累计为您分享877篇技术干货

打开网易新闻 查看精彩图片

打开网易新闻 查看精彩图片

推理占已部署 AI 系统机器学习成本的 90%,因此推理优化成为研究领域的一个新兴话题也就不足为奇了。IDC 估计全球企业将在 2025 年投资 3070 亿美元用于 AI 解决方案,并且这一数字预计将逐年 aggressive 增长。

理解工作负载

与训练不同,自回归语言模型的推理只涉及前向传播,其本身又分为两个不同的阶段:预填充 (prefill) 和解码 (decode)。每个阶段都有独特的工作负载特征——预填充倾向于计算密集型,消耗系统能够获取的每一盎司浮点算术能力,然后是解码,这主要受内存带宽的限制。

预填充和解码阶段的计算复杂度都随着每个额外 token 呈二次增长。预填充很容易在 GPU 之间并行化——当请求到达模型 API 时,所有提示 token 都提前已知。解码阶段引入了 Transformer 多头注意力机制,并且必须计算所有先前 token 的注意力状态——包括任何提示和生成的响应。这使得推理服务的部署复杂化,因为上下文长度正在迅速增长以适应更大的代码库、更长的文档和检索增强生成。KV 缓存是将与提示中的 token 序列对应的计算出的键和值权重保存起来以备后用,然后在后续提示中使用时进行检索,以避免计算成本(GPU 小时)并减少从提交提示请求到第一个响应 token 之间的时间(time-to-first-token,或 TTFT)。

vLLM 和 LMCache 中的缓存块

vLLM 采用分层方法进行 KV 缓存。首先,它检查 GPU 内存中是否存在缓存块,如果发生缓存未命中,它将继续检查 CPU 内存,如果再次发生缓存未命中,它将尝试通过任何配置的 KV 连接器检索缓存块。LMCache 通过这个 KV 连接器接口与 vLLM 协同工作——vLLM 发送或请求缓存块,LMCache 负责存储或流式传输它定位到的缓存块。vLLM 还引入了 分页注意力 (Paged Attention) 技术,该技术将提示分解为固定大小的 token 序列,称为块,默认情况下为 16 个 token。LMCache 默认使用更大的 256 个 token 块, presumably 是为了减少管理对许多块的引用的开销,并更好地分摊每个块的传输开销。存储领域的人员,不熟悉 token 作为空间和 IO 的测量单位,可能会自然而然地想知道这转换为以字节表示的块大小是多少。每个 token 的字节数是模型相关的,因为它是模型的隐藏大小、键值头数量、隐藏层数量、头维度和数据类型大小的乘积。对于 Qwen3-32B 这样的模型,这大约是 62.5 MiB。如果您想了解任何给定模型或 token 数量所需的 KV 空间量,LMCache 的文档页面上提供了一个方便的 KV 缓存计算器(https://docs.lmcache.ai/getting_started/kv_cache_calculator.html)。

内容可寻址 KV 存储

vLLM 和 LMCache 都计算表示块的 token 序列的哈希值,并将其用作缓存块标识符。这意味着 vLLM 将通过 kv 连接器接口传递它感兴趣的缓存块的哈希值,LMCache 将返回一个位掩码,指示它可以提供哪些缓存块。在后台,LMCache S3 连接器将对每个块标识符(token 序列的哈希值)进行 GetObjectAttributes 调用,对于每个存在的块,它将翻转掩码中对应的位。这种方法的优点在于不需要持久化缓存块映射,并且当多个 vLLM+LMCache 实例在不同主机上运行时,无需进行协调。事实上,根本不需要配置 [LMCache 控制器](https://docs.lmcache.ai/kv_cache_management/index.html)。这种设计还允许灵活的逐出:存储系统可以通过生命周期配置实现基于时间的过期,任何已删除的块只需注册为未命中。最终,您可以获得完全弹性的内容可寻址 KV 缓存块存储,并支持灵活的逐出。任何熟悉 Ceph 的人都会真正欣赏计算数据位置而不是执行查找的概念。

检索缓存快

我们通过使用 Ceph 测试 LMCache 的原生 S3 连接器开始探索 LMCache,因为它为大多数现有环境提供了可访问的入口点。LMCache 中原生 S3 连接器的另一个吸引力在于它利用了 AWS 通用运行时库 (CRT),这意味着客户端连接池中的连接将多路复用到对象存储 FQDN 的 DNS 响应中返回的端点。缺点是 AWS 通用运行时库在 Python 中只支持 recv_filepath 和 send_filepath,这限制了 LMCache 将 GetObject 调用的响应正文直接流式传输到 LocalCPUBackend 分配的页锁定内存缓冲区的能力。为了解决这个限制,连接器在挂载到 /dev/shm 的 tmpfs 上预分配和 mmap 文件(每个并发请求一个),这样 CRT 客户端就可以传递内存映射文件的文件描述符,然后从其对应的缓冲区 memcpy 到用于 DMA 传输到 GPU 的页锁定 LocalCPUBackend 缓冲区。这是一种巧妙地解决 aws-crt-python 大部分限制的方法,但要实现真正的零拷贝,还需要对绑定进行更改。

在对原生 S3 连接器进行了一些初步测试后,[LMCache PR](https://github.com/LMCache/LMCache/pull/1939) 引起了我们的注意,因为它利用了 NVIDIA 推理传输库 (NIXL)。这个 PR 引入了直接将 S3 数据读取到页锁定 NIXL 缓冲区的能力,绕过了 /dev/shm 上的文件和相关的内存复制。它还引入了一个存在缓存,以消除用于确定给定序列是否存在缓存块的冗余 GetObjectInfo 请求。我们之前已经试验过 NIXL obj 插件并运行了一些基本的 nixlbench 测试。我们发现 NIXL obj 插件本身需要一个预分配的对象键池,并且它需要 LMCache 控制器或 Dynamo KVBM 来维护每个缓存块的设备 ID、偏移量和长度信息。与其他 NIXL 插件不同,obj 插件只能将单个缓存块写入每个设备 ID(与对象键 1:1 映射),因为 S3 等对象 API 不支持写入任意偏移量。所有这些都在 PR1939 中得到了解决,因为它没有使用对象键池和跟踪缓存块元数据,而是保留了 LMCache 原生 S3 连接器的内容可寻址方法。NIXL 唯一剩下的缺点是它使用了 S3Client 而不是 S3CrtClient,后者支持跨 S3 端点的多路径。

超大规模AI部署

凭借十多年为 Ceph 存储系统选择硬件的经验,我们对要构建什么样的系统才能最大限度地提高吞吐量有了一些想法,同时也借鉴了 Meta 和 OpenAI 等主要 AI 从业者的选择。Meta 对 Open Compute 项目的贡献——[Yosemite V3.5](https://www.opencompute.org/documents/yosemite-v3-5-platform-design-specification-v1-2-pdf) Sierra Point 服务器平台。YV3.5 机箱占用 3 个 OU,可以填充 6 个 Sierra Point 刀片。与传统的企业刀片系统不同,YV3.5 平台没有集成以太网交换机,而是每个 Sierra Point 刀片都有一个 OCP 3.0 插槽,用于直接到主机的网络连接。我们想要一个系统,它是 YV3.5 和 Sierra Point 的精神继承者,它利用了尖端处理器设计和光刻技术的优势。在考察了众多 OEM 厂商的服务器产品后,有一款系统引起了我们的注意,那就是 Supermicro X14 2U 4 节点 GrandTwin 后置 IO。

打开网易新闻 查看精彩图片

Supermicro X14 2U 4 节点 GrandTwin 后置 IO

每个节点:

  • 1 个 Intel Xeon 6 6740E 96C/96T,205W

  • 16x16GB DDR5-6400

  • 1 个 Broadcom 57608 2x200GbE

  • 6 个 2.5 英寸 Kioxia CM6-R,7.68TB Gen4 NVMe SSD

  • RAID1 2 个 480TB NVMe(启动)

该系统用于使用 IBM Storage Ceph 8.1 为 AI 解决方案提供高带宽全闪存对象存储。

打开网易新闻 查看精彩图片

Supermicro Gaudi 3 AI 服务器 SYS-822GA-NGR3

  • 2 个 Intel Xeon 6 6960P 72C/144T

  • 24x 64GB DDR5-6400

  • 8 个 Gaudi 3 HL-325L 加速器

  • 最多 8 个 2.5 英寸 Gen5 NVMe SSD

  • 扩展网络:21 个 200GbE Gaudi 网卡

  • 2 个 Broadcom 57608 1x400GbE

该系统用于结合 vLLM 和 LMCache 运行推理工作负载,利用 Intel 的 Gaudi 3 加速器。

打开网易新闻 查看精彩图片

Supermicro GPU A+ 服务器 AS -8125GS-TNMR2

  • 1 个 AMD EPYC 9654 96C/192T

  • 24x 96GB DDR5-4800

  • 8 个 AMD MI300X 加速器

  • 最多 8 个 2.5 英寸 Gen5 NVMe SSD

  • 扩展网络:4x400GbE

  • 存储和 GPU 扩展网络:4 个 NVIDIA MT28908 ConnectX-6 200GbE

该系统用于结合 vLLM 和 LMCache 运行推理工作负载,利用 AMD 的 MI300X 加速器。

打开网易新闻 查看精彩图片

SSE-T7132S - 400Gb 以太网交换机

  • 32 个 QSFP-DD 400GbE,或 64 个 QSFP56 / 128 个 QSFP28 带分支线缆

  • 25.6Tb/s 交换容量

  • SONiC OS

  • 支持 RoCEv2/RDMA 和 PFC

主机配置

  • 在 BIOS 中设置性能配置文件

  • 将 tuned 配置文件设置为 network-latency

tuned-adm profile network-latency

  • 所有主机都配置了 mode 802.3AD,xmit_hash_policy = Layer3+4

Ceph 配置

OSD服务

    - /dev/disk/by-path/pci-0000:89:00.5-pci-10002:04:00.0-nvme-1

存储池配置

我们决定在初始化 RGW 服务之前预创建 RGW 的元数据和数据存储池。

ceph osd pool application enable default.rgw.buckets.non-ec

RGW服务

此 RGW 服务配置将在 4 台主机的每台主机上创建 4 个 RGW 实例,其中一个集中器绑定到主机 IP 地址的 80 端口。

  concentrator_monitor_user: admin

流量管理

像许多应用程序一样,LMCache 期望一个单一的 S3 端点。为了最大限度地提高到存储集群的带宽,我们决定利用 [Hashicorp Consul 和 CoreDNS](https://ceph.io/en/news/blog/2025/consul-lb1/) 返回多个 DNS 记录,以响应我们选择的对象 FQDN 查询。如前所述,这与 LMCache 原生 S3 连接器使用的 AWS CRT 库完美配合。

Consul

/etc/consul.d/consul.hcl

]

CoreDNS

/etc/coredns/Corefile

}

测试 DNS 负载均衡

为了验证基于 Hashicorp Consul 和 CoreDNS 的方法是否正常运行,我们可以测试我们选择的对象 FQDN 的 DNS 解析。请注意,我们看到了 4 条记录返回,这正是我们想要的。

;; MSG SIZE  rcvd: 163

基线性能

为了在引入 vLLM 和 LMCache 之前建立存储集群的基线性能,我们使用 **elbencho**(https://github.com/breuner/elbencho) 评估了性能,从 Gaudi3 GPU 主机生成负载并将其定向到 Ceph S3 端点。我们使用了 62MB 的块大小来匹配 LMCache 持久化的 KV 缓存块的预期大小。这表明我们能够将连接多路复用到每个主机上的集中器端点,并从单个主机驱动大量的 S3 流量,最高达到近 60 GB/s。

打开网易新闻 查看精彩图片

vLLM

在我们测试时,vLLM 生产堆栈不支持我们的端到端工作流程,因此我们创建了定制的 vLLM 容器镜像,其中包含了 LMCache 开发版本,包括一个包含了最新 **vllm-gaudi** 开发的用于我们测试的镜像。

AMD 容

  • vLLM:

  • LMCache:

  • NIXL:

Gaudi 容器

  • vLLM:

  • LMCache:

  • NIXL:

下面您将找到我们用于同时运行 vLLM 和 LMCache 的配置文件和命令行参数。

.aws/credentials

preferred_transfer_client = crt

lmcache-ceph.yaml

  s3_file_prefix: "test"

lmcache-nixl-ceph.yaml

    bucket: lmcache

lmcache-dram.yaml

blocking_timeout_secs: 100

启动 vLLM

       --tensor-parallel-size 2

对于 Gaudi3 加速器测试,我们设置了以下额外的环境变量:

VLLM_EXPONENTIAL_BUCKETING=False

基准测试

我们希望描述在各种上下文长度下,Ceph 远程存储 100% 缓存命中率的 TTFT 减少情况,并将其与计算预填充进行对比。为此,我们选择了 LMCache 的 [long_doc_qa.py](https://github.com/LMCache/LMCache/blob/dev/benchmarks/long_doc_qa/long_doc_qa.py)。我们开发了以下 TTFT 数据收集方法:

  1. 启动 vLLM

  2. 运行 long_doc_qa.py 并记录热身轮的 TTFT(计算预填充结果)

  3. 重启 vLLM

  4. 运行 long_doc_qa.py 并记录热身轮的 TTFT(远程存储 KV 缓存命中结果)

  5. 停止 vLLM

  6. 从远程存储中移除缓存块

通过在步骤 3 中重启 vLLM,我们确保结果不会因 GPU HBM 或 CPU 内存中的 KV 缓存而产生偏差;通过停止 vLLM 并从远程存储中移除缓存块,我们确保每个后续上下文长度不会从先前上下文长度的远程存储 KV 缓存中受益。通过这种方法,除了我们希望在步骤 4 中测量其好处的远程存储 KV 缓存之外,所有 KV 缓存在每次测试开始时都是冷的。

long_doc_qa.py 示例命令行

      --output results/ttft_${L}.out

结 果

Intel Gaudi 3 结果

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

AMD MI300X 结果

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

Intel Gaudi3 和 AMD MI300X 加速器都显著降低了 TTFT,最大测量速度提升了 23 倍。这项测试还说明了 KV 缓存如何比使用张量并行化将预填充分散到系统中多个 GPU 更能减少 TTFT,并且结合这些技术可以提供最低的 TTFT。值得指出的是,除了减少 TTFT,前缀缓存还通过节省 GPU 周期用于解码而获得额外价值——可能会减少每个输出 token 的时间 (TPOT)。

接下来是什么?

我们与 Red Hat 的 llm-d 团队分享了我们的结果,并已开始与他们合作,通过将 Ceph 与 KV 缓存建立为 一条成熟的路径来实现 KV 缓存的商品化。我们相信我们的方法可能是最易于访问的,因为它使用标准的 S3 等对象协议、标准的 TCP/IP 网络,适用于来自不同供应商的各种加速器,并且因为 Ceph 对象通过 OpenShift Data Foundation 和 IBM Fusion 普遍部署在 OpenShift 集群中。我们的下一阶段测试将利用 llm-d,将 GPU 主机作为工作节点,并探索更复杂的场景,如 PD 分离和缓存混合。

如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。

原文: https://ceph.io/en/news/blog/2025/vllm-kv-caching/

 使用 vLLM、LMCache 和 Ceph 进行 KV 缓存
打开网易新闻 查看更多视频
使用 vLLM、LMCache 和 Ceph 进行 KV 缓存