feat: interleave CPU KV cache pages across NUMA nodes - #1399
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces NUMA node interleaving for CPU KV cache pages in lightllm/utils/kv_cache_utils.py by implementing interleave_pages_across_numa_nodes and helper functions. The feedback highlights two critical issues with the mbind syscall implementation: first, the hardcoded SYS_MBIND syscall number (237) is specific to x86_64 and will cause failures on aarch64 architectures; second, passing 65 as maxnode when nodemask is a 64-bit c_ulong leads to an out-of-bounds read of stack memory, potentially causing mbind to fail with EINVAL.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
补了 reviewer 要的端到端结果,PR description 里有完整配置和三组数据。
三组配对 throughput 的平均改善是 3.18%,95% CI [-2.74%, 9.10%]。也就是说,这个 workload 下每组方向一致,并且页落点已经确定性稳定,但 n=3 还不足以把 E2E 收益表述成统计显著。 两条 syscall review finding 已在 |
CPU KV cache 的共享内存由 prefault 线程首次触碰,物理页落点取决于当时的线程调度。多 Socket 上连续 cache 分块可能集中到单个内存控制器,GPU 并发 load/offload 的带宽和运行间波动都会受影响。
这个改动提供可选的 NUMA interleave 策略:在 prefault 前对 SHM VMA 设置
MPOL_INTERLEAVE,并对每个 attacher 的 VMA 设置相同策略。策略只影响后续缺页,不迁移已分配页。该功能现在默认关闭,未配置时继续使用 first-touch。需要显式设置:
export LIGHTLLM_ENABLE_NUMA_INTERLEAVE=1才会调用
mbind。单 NUMA、不支持的架构或mbind失败时也会安全回退到 first-touch。旧的LIGHTLLM_DISABLE_NUMA_INTERLEAVE已移除,环境变量统一在envs_utils.py管理。E2E
在一台双 NUMA、8×RTX 5090 机器上(GPU 0-3 在 N0,4-7 在 N1),用 InternLM2.5-7B-chat BF16、TP8 对比:
4c42ffd2(当时的开关语义为 A 设置LIGHTLLM_DISABLE_NUMA_INTERLEAVE=1、B 默认启用;当前版本的等价配置为 A 默认、B 设置LIGHTLLM_ENABLE_NUMA_INTERLEAVE=1)lightllm:v1.5.3-main-9565289-cu130每个服务实例先分别 seed 两套前缀,再按 set-1→set-2→set-1→set-2 发送 64 个 timed requests。变体外层做 3 组 ABBA,共 12 次独立服务启动、768 个 timed requests。
6 次 A/B run 的中位数:
三组 throughput 配对结果都为正,平均改善 3.18%;n=3 的 95% CI 为 [-2.74%, 9.10%],因此这是方向一致的 E2E 收益,但样本量不足以声称统计显著。
768/768 个 timed requests 都命中服务端 CPU cache,没有错误。6 次 B run 的 64 GiB 映射均精确落在 N0/N1 各 8,388,608 页;A 的 N0 占比在 33.4% 到 76.9% 之间。试跑期间发现
--ipc=host会遗留 SysV SHM,相关数据已排除;正式结果在每次启动前检查可用内存、每次退出后回收对应 SHM。DMA microbenchmark
同一台机器上,用普通 4K 页测 pinned SHM 的 GPU DMA,每组 3 轮 ABBA:
interleave 的
numa_maps每次都是精确 50/50;first-touch 的运行间波动明显更大。E2E 收益小于 DMA 微基准,符合 CPU cache 恢复只是请求链路一部分的预期。最新精度回归
在当前 head
227e76de上完成以下全量回归,LIGHTLLM_ENABLE_NUMA_INTERLEAVE均未设置,用于验证默认 first-touch 路径。Qwen3.5-0.8B CPU cache + linear attention
GSM8K 全量 1,319 条,在同一服务生命周期连续执行两次:
两轮 strict accuracy 完全一致,CPU cache 分配、prefault、attach、pinned-memory 注册及全命中路径均正常,没有 cache 异常。
Qwen3-VL-8B-Instruct
MMMU validation 全量 900 条:
两个模式 900 条请求均完成并保存逐样本结果。3/900 条原始响应不同,只有 1 条影响正确性;ViT separation 的 438/900 与上一轮回归完全一致,属于单样本运行间波动,没有 visual proxy、AFS、请求或评测错误。
权限与降级行为
另一个双 NUMA、8×H200 的容器环境启用了 Docker seccomp,且没有
CAP_SYS_NICE。在显式启用 interleave 的诊断中,mbind、set_mempolicy和get_mempolicy均返回EPERM;cpuset 允许的内存节点为0-1,因此失败来自容器安全策略,而不是无效 nodemask。当前默认关闭配置不会调用
mbind,上述最新回归日志中没有mbind/EPERM。显式启用但受限时会记录 warning 并安全回退到 first-touch;若需要在该容器覆盖成功路径,应增加CAP_SYS_NICE或使用允许 NUMA policy syscall 的定制 seccomp profile。pre-commit 的 Black、Flake8 检查通过。