显存碎片化的隐形杀手:为何长期运行后频频 OOM

在 AMD Instinct GPU 上部署 vLLM 推理服务时,许多工程师都遇到过一种“玄学”现象:服务刚启动时一切正常,显存占用平稳,吞吐量达标;但运行数天甚至数小时后,即便请求量没有显著增加,服务却突然崩溃,报出 HIP out of memoryMalloc failed 错误。重启服务后,问题立刻消失,仿佛什么都没发生过。这种间歇性的显存溢出(OOM),往往不是模型变大或并发突增导致的,而是显存碎片化在长期运行中逐渐累积的恶果。

与 NVIDIA CUDA 生态成熟的内存管理器不同,ROCm 栈在长时间高负载下的内存回收机制表现得更为敏感。特别是在 vLLM 利用 PagedAttention 技术动态管理 KV Cache 时,如果底层驱动无法高效合并释放的小块显存,就会形成大量无法被复用的“内存空洞”。随着时间推移,这些空洞越来越多,虽然总空闲显存看似充足,但连续的大块内存申请却无法满足,最终触发 OOM。

PagedAttention 在 ROCm 底层的分配困境

vLLM 的核心优势在于其 PagedAttention 机制,它将 KV Cache 切分为固定大小的 Block,按需分配给序列。在理想情况下,这种细粒度管理能极大提升显存利用率。然而,在 AMD ROCm 7.x 环境下,这一机制面临着特殊的挑战。

ROCm 的内存分配器(基于 HIP API)在处理高频次、小尺寸的内存申请与释放时,策略相对保守。当 vLLM 不断创建和销毁 Block 以应对动态批处理(Continuous Batching)时,底层驱动会频繁调用 hipMallochipFree。问题在于,释放后的显存块往往不会立即物理合并回大的空闲池,而是留在自由列表中等待特定大小的再次申请。

随着推理服务的持续运行,请求序列长度的随机性导致 Block 的生命周期各不相同。短序列快速释放 Block,长序列则长期占用。这种不均匀的释放模式,使得显存空间中充斥着大量不连续的、大小为 block_size * element_size 的空闲片段。当新的长序列到来,需要分配一连续的 Block 表或较大的临时缓冲区时,分配器无法找到足够大的连续地址空间,尽管此时 rocm-smi 显示的总空闲显存可能还有几 GB。这就是典型的“外部碎片化”问题,也是 AMD 平台上 vLLM 长期运行稳定性的主要瓶颈。

关键参数调优:Block Size 与内存策略

针对上述碎片化成因,最直接的工程化手段是调整 vLLM 的内存块大小参数 --block-size。这个参数决定了 PagedAttention 管理显存的最小粒度,直接影响碎片的产生频率和大小。

默认情况下,vLLM 通常使用 16 作为 block size。在 AMD Instinct MI300 等大显存卡上,较小的 block size 虽然能提高细粒度利用率,但也加剧了碎片化的风险。因为更小的块意味着更多的分配/释放操作,以及更细碎的闲置空间。对于主要处理中长文本的业务场景,尝试将 --block-size 调整为 32 甚至 64,可以显著减少内存管理的元数据开销,并降低产生微小碎片的概率。较大的块使得释放后的空间更容易被后续的大请求复用,从而延缓碎片累积的速度。

此外,--gpu-memory-utilization 参数的设置也至关重要。许多用户为了最大化容量,将其设置为 0.95 甚至更高。这在短期测试中或许可行,但在长期运行中极为危险。预留过少的显存余量(Headroom),会让分配器在面对碎片化时毫无缓冲空间。建议将该值控制在 0.85 至 0.90 之间,特意留出 10%-15% 的物理显存作为“碎片整理区”和突发峰值的缓冲带。这部分未分配的显存虽看似浪费,实则是保障服务长期不崩溃的安全垫。

运维层面的缓解策略与监控实践

除了参数调优,制定合理的运维策略也是应对显存碎片化的必要手段。鉴于当前 ROCm 驱动在自动碎片整理方面的局限性,定期重启服务是最简单且有效的“硬重置”方案。

通过监控数据可以发现,显存碎片率通常随运行时间呈线性或指数上升。建议在 Prometheus + Grafana 监控体系中,不仅关注显存使用总量,更要自定义指标追踪 hipMemGetInfo 返回的最大可用连续块大小与总空闲大小的比值。一旦该比值低于阈值(例如 0.6),或服务连续运行超过预设窗口(如 72 小时),即触发自动滚动重启。这种主动式的维护能有效清除累积的碎片,将服务状态重置到最佳点。

在代码层面,若具备二次开发能力,可探索替换默认的 HIP 内存分配器。社区中有部分实践尝试集成 jemalloc 或针对 GPU 优化的自定义分配器来拦截 malloc/free 调用,通过预分配大池(Memory Pool)的方式减少直接对驱动的频繁请求。虽然这增加了架构复杂度,但对于对稳定性要求极高的生产环境,这是一条值得深入的技术路径。

综上所述,AMD GPU 上的显存碎片化问题并非无解。通过理解 PagedAttention 与 ROCm 驱动的交互机制,合理调整 block-size 与显存预留比例,并结合监控数据实施定期的重启策略,我们完全可以在享受 AMD 高性价比算力的同时,构建出稳定可靠的大模型推理服务。

200小时GPU算力已就位,快来领取:https://marketing.csdn.net/questions/Q2604140858304426315?utm_source=AIpaper
在这里插入图片描述

Logo

免费领 200 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐