NInfer 分页 KV 缓存实现原理:页、副本与地址空间如何高效管理长上下文
NInfer 分页 KV 缓存实现原理页、副本与地址空间如何高效管理长上下文【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninferNInfer 是一个面向单 GPU 的高性能推理引擎其分页 KV 缓存用固定 64 token 的页面、Device/Host 双副本和独立地址空间来管理长上下文显存。这篇文章带你完整理解 NInfer 分页 KV 缓存是如何做到长上下文不爆显存、前缀可以共享、推理不搬数据的。1️⃣ 为什么长上下文绕不开 KV 缓存管理Transformer 推理时每生成一个新 tokenAttention 都要回看前面所有 token 的 Key/Value即 KV 缓存。上下文越长KV 缓存越大——一个 27B 级别模型跑 128K 上下文KV 缓存可能达到数十 GB。如果按每条请求分配一整块连续显存的传统方式管理会遇到三个经典问题传统连续分配的问题后果显存内部碎片申请 100GB 实际只用了 60GB无法多请求共享前缀相同系统提示词重复 prefill浪费算力扩容需要搬迁上下文增长时整块 KV 要拷贝卡顿明显NInfer 的答案借鉴了操作系统虚拟内存的分页思想把 KV 切成小页面用逻辑页 → 物理页的映射表间接寻址。核心实现位于 src/core/paged_kv_cache.h 与 src/core/paged_kv_storage.h设计合同见官方文档 docs/maintainer/paged-kv-cache.md。上图是 NInfer CLI 的多模态测试样本模型要看懂山间小屋并回答图中数字24。这类多模态长上下文请求正是分页 KV 缓存需要伺候好的典型负载。2️⃣ 核心概念一页读懂页、池、地址空间NInfer 把管理 KV拆成了三层独立概念各管各的粒度概念通俗理解NInfer 中的设定页PageKV 的最小分配单位固定P64个 token 一页池Pool互相隔离的显存仓库启动时固定Main/MTP/Draft 各用一个池地址空间Address Space每条序列自己的门牌号序列逻辑连续物理可不连续页的大小为什么是 64文档 paged-kv-cache.md 解释得很清楚64 恰好对齐 Attention 的 32/64-key 计算 tile 与 128-token 的 prefill 分块同时让 block table 元数据足够小。页面边界不等于语义边界——有效 frontier 可以落在页内任意 token 位置这一点保证了按 token 精确的截断与回滚。池为什么按类型隔离不同生命周期的 KV 绝不能混仓Main Text 池目标模型全注意力层的 K/VMTP 池 / Draft Full 池投机解码MTP、DFlash后端的辅助 KV各自独立 frontier、独立提交、独立裁剪。池内只收同 frontier、同生命周期、同页大小的数据面K、V、量化 code、scale 面共享同一个页组 ID。固定大小的页组意味着没有变长碎片也无需显存压缩整理。3️⃣ 物理页怎么分配租约、预留与 block table每个池内部区分三种容量的状态这也是active 请求不被挤占的保证已分配页lease 已预留页reservation 全局可用页 池总容量预留Reservation为某条 active 序列锁定的未来额度不会被其他请求抢走租约Lease预留落地为真实物理页后的持有凭证带 generation 代号防止释放后被旧句柄误用Block table每条 active 序列租用一行把逻辑块号 → 物理页号批量发布到 GPU 上的固定矩阵block_tables[N_logical, C]。decode 每步通常只在跨越页边界时才申请一个新页尾页还有空位时分配器完全不用干活——这是长上下文 decode 不掉速的关键之一。批量预留接口见 reserve_device_kv_page_bundle。4️⃣ 副本机制显存装不下就沉到主机内存长上下文的另一个杀手锏是Device/Host 双副本Device 副本用消费端原生的页平面布局供 Attention kernel 直接读Host 副本是紧凑打包布局存放在启动时固定的 pinned 内存 arena见 src/core/host_kv_arena.h。迁移遵循严格的发布顺序预留目标位置 → 拷贝整页 → 校验内容 epoch 与覆盖范围 → 发布新副本 → 才释放旧副本。拷贝期间两端都被 pin 住任何时刻都只有一个有效副本对外可见。Inactive 的上下文如会话缓存可以整体沉到 Host 内存把显存腾给 active 请求激活时再按需搬回——这就是上下文缓存能同时容纳更多并发会话的底气。5️⃣ 前缀共享与写时复制一份 KV 服务多条请求多个请求共享同一系统提示词时重复计算 prefill 是最浪费的。NInfer 的共享策略分两档Move私有延续源 checkpoint 没有其他引用时地址空间直接过户零拷贝Fork COW共享前缀frontier 之前的完整页只增加不可变引用大家共享同一份物理页只有当要写入的页被多方共享时才对页内的部分尾页做一份私有拷贝Copy-on-Write后续追加只写私有尾页。以P64、checkpoint frontier 1000 为例前 15 个完整页被共享第 16 页里的 40 个已提交 token 复制进私有尾页。frontier不向下取整到 960——分配粒度与 token 级有效性彻底解耦。这套逻辑落在 src/models/qwen3_5/program/storage/kv_store.h 的 LogicalKVPage 与 KVAddressSpace 存储中。6️⃣ 地址翻译kernel 如何不搬数据地读页Attention kernel 从不接触分配器它拿到的只是一个非拥有视图PagedKVLayerView平面张量 一行 block table定义见 src/core/paged_kv_cache.h。地址翻译就三步逻辑块号 position 6 页内偏移 position 63 物理页 block_table[逻辑块号]随后按固定的页内平面顺序算出元素地址即可。由于页大小固定为 64翻译可以退化成移位和掩码在 page/tile 粒度算一次、内层循环复用。整个 growing-cache 路径不经过任何攒成连续 KV的 gather 拷贝——分页不引入任何与上下文长度成正比的中间搬运这就是直接分页执行的性能红利。消费端契约见 include/ninfer/ops/softmax_attention.h 与 include/ninfer/ops/kv_cache_append.h。7️⃣ 一页省多少量化存储对容量的杠杆分页管的是怎么放量化管的是每页放多少。NInfer 的 KV 池支持多种封闭存储 profile布局解析见 paged_kv_storage.h以 D256 每 token/每头 的物理占用为例KV Profile每 token/head 的 KV 占用相对 BF16BF161024 B1.0xINT8-G64528 B≈0.52xFP8-E4M3FN-row256516 B≈0.50xK8V4非对称402 B≈0.39xNVFP4-G16288 B≈0.28x同样的显存预算下NVFP4 能让可用页数量翻倍以上长上下文容量随之放大——分页机制保证了这些不同字节宽度的页组在同一个框架里被同等地分配、共享与迁移。8️⃣ 一张表总结长上下文高效管理的五个支点支点做法效果分页分配固定 64-token 页组 block table无碎片、无需整理、页边界不碰语义容量三态已分配 / 已预留 / 全局可用 分账active 请求额度不被缓存策略偷走双副本Device/Host 整页迁移 epoch 校验上下文缓存下沉显存留给活跃请求共享 COWMove / Fork / 部分尾页私有化相同前缀零重复 prefill直接分页执行移位翻译、无 gather 拷贝kernel 不搬数据decode 稳定高速写在最后NInfer 的分页 KV 缓存本质上把操作系统的虚拟内存哲学搬进了 GPU 推理逻辑上连续、物理上离散、共享靠引用、写入靠租约。理解页、副本、地址空间这三层分离之后你会发现长上下文推理引擎里最复杂的显存账目其实是被这套严格的粒度划分管得井井有条。 想继续深入可以阅读分页 KV 设计合同docs/maintainer/paged-kv-cache.md资源调度与上下文缓存docs/maintainer/resource-scheduling-and-context-cache.md设备端池与租约实现src/core/paged_kv_cache.cppHost 副本 arenasrc/core/host_kv_arena.cpp程序级逻辑页与地址空间src/models/qwen3_5/program/storage/kv_store.h【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninfer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →