执行摘要
该PR修复了在启用重叠调度(extra_buffer)和结构化JSON输出时,因闭包持有GPU张量引用而导致的VRAM泄漏。通过及时释放关键张量,解决了内存持续增长直至OOM的问题,提升了系统稳定性,建议关注其内存管理策略。
功能与动机
根据Issue #20640,在生产环境中使用Qwen3.5模型时,启用extra_buffer并请求结构化输出会导致VRAM缓慢但持续增长,几小时后引发OOM错误。此问题仅在两个条件同时满足时触发:重叠调度激活并创建闭包,以及基于语法的结构化输出分配vocab_mask。修复旨在消除这一内存泄漏,确保资源高效利用。
实现拆解
- scheduler.py:在
launch_batch_sample_if_needed方法中,添加代码将batch_result.delay_sample_func设为None,并清理logits_output.next_token_logits,以断开闭包对张量的引用。
python
batch_result.delay_sample_func = None
if batch_result.logits_output is not None:
batch_result.logits_output.next_token_logits = None
- model_runner.py:在
_preprocess_logits方法中,设置sampling_info.vocab_mask = None,在应用掩码后立即释放GPU张量。
python
sampling_info.vocab_mask = None
这些改动共同确保张量在不再需要时被及时回收,防止内存累积。
评论区精华
审核讨论中,hnyls2002提出疑问:"为什么VRAM会持续增长而不是仅延迟一轮释放?" Cishoon解释:"在tp_worker.py中,重叠调度创建的delay_sample_func闭包捕获了forward_batch和logits_output,导致张量保持引用。" 双方最终确认修复方案合理,无进一步争议。
风险与影响
- 风险:变更仅涉及引用置空,核心逻辑未变,但若下游代码错误依赖已释放张量(如
vocab_mask),可能引发异常;缺少单元测试覆盖具体泄漏场景。
- 影响:直接解决了生产环境OOM问题,提高了系统可靠性;影响范围限于重叠调度和结构化输出场景,对普通用户无影响,但优化了整体内存管理。
关联脉络
此PR独立修复了特定内存泄漏,未在近期历史PR中发现直接关联(如PR 20625涉及中间件bug,PR 20862为扩散模型功能)。它反映了在异步调度中管理GPU张量生命周期的重要性,可能为类似内存优化提供借鉴。
参与讨论