执行摘要
- 一句话:提取分配逻辑到新文件 allocation.py 和 allocation_sizing.py
- 推荐动作:推荐精读,该 PR 展示了大规模机械重构的实践:通过 AST 搬迁工具确保纯搬迁可重现,并用清晰的提交结构(prep + move + postpare)管理重构链。对关注代码组织和模块拆分的读者有参考价值。
功能与动机
将分配逻辑从 common.py 这个大杂烩中提取出来,使分配入口点和大小计算集中在专用模块中,便于理解和维护并行变体,为后续解耦做准备(PR body: 'Lightweight extraction of the allocation entry points ... out of the mem_cache/common.py junk drawer')。
实现拆解
步骤 1. 创建 allocation.py
新建文件 python/sglang/srt/mem_cache/allocation.py,从 common.py 搬入 write_cache_indices、get_last_loc、get_last_loc_torch、alloc_token_slots、_compute_dsv4_state_lens、alloc_paged_token_slots_extend、alloc_req_slots、_alloc_page_size 等函数,保持逻辑完全一致。
步骤 2. 创建 allocation_sizing.py
新建文件 python/sglang/srt/mem_cache/allocation_sizing.py,搬入 get_alloc_len_per_decode、get_alloc_reserve_per_decode、get_req_to_token_extra_context_len 三个分配大小计算辅助函数。
步骤 3. 精简 common.py
从 common.py 中删除已搬迁的函数和不再需要的导入(如 support_triton、is_pin_memory_available、maybe_write_dsv4_* 等),仅保留剩余的工具函数(kv_to_page_indices、free_swa_out_of_window_slots、release_kv_cache 等)。
步骤 4. 更新消费方导入
更新所有引用这些函数的模块的 import 路径:
schedule_batch.py:alloc_for_decode、alloc_for_extend 改从 allocation 导入,get_alloc_reserve_per_decode 改从 allocation_sizing 导入。
pool_configurator.py:get_alloc_len_per_decode 改从 allocation_sizing 导入。
eagle_utils.py:相关函数改从 allocation 和 allocation_sizing 导入。
dsv4_allocator.py、kv_cache_configurator.py、dflash_info_v2.py:仅调整导入路径。
步骤 5. 后处理调整
使用已导入的 get_server_args() 替代 get_global_server_args(),更新调试工具 pr_fix_toggle.py 中的路径字符串指向 allocation_sizing,并降低 get_global_server_args 的 ratchet baseline 至 279。
无测试行为变更;测试文件仅更新导入路径。
关键文件:
python/sglang/srt/mem_cache/allocation.py(模块 缓存层;类别 source;类型 core-logic;符号 write_cache_indices, get_last_loc, get_last_loc_torch, alloc_token_slots): 新文件,核心分配入口点(write_cache_indices, get_last_loc, alloc_token_slots 等)搬迁至此,是 PR 最主要的新模块。
python/sglang/srt/mem_cache/allocation_sizing.py(模块 缓存层;类别 source;类型 core-logic;符号 get_alloc_len_per_decode, get_alloc_reserve_per_decode, get_req_to_token_extra_context_len): 新文件,集中存放分配大小计算逻辑,包括 spec decode 的 page-aligned 计算。
python/sglang/srt/mem_cache/common.py(模块 缓存层;类别 source;类型 dependency-wiring;符号 write_cache_indices, get_last_loc, get_last_loc_torch, get_alloc_len_per_decode): 精简后的 common.py 仅保留非分配工具函数,是提取操作的目标文件。
python/sglang/srt/managers/schedule_batch.py(模块 调度器;类别 source;类型 dependency-wiring): 主要消费方,导入从 common 改指向 allocation 和 allocation_sizing。
python/sglang/srt/speculative/eagle_utils.py(模块 投机解码;类别 source;类型 dependency-wiring): 投机解码模块,同时引用 allocation 和 allocation_sizing 中的函数。
关键符号:write_cache_indices, get_last_loc, get_last_loc_torch, alloc_token_slots, _compute_dsv4_state_lens, alloc_paged_token_slots_extend, alloc_req_slots, _alloc_page_size, get_alloc_len_per_decode, get_alloc_reserve_per_decode, get_req_to_token_extra_context_len
评论区精华
唯一 review 来自 gemini-code-assist[bot]:指出 allocation.py 中 alloc_req_slots 函数在 tree_cache 可能为 None 时调用 supports_mamba() 可能导致 AttributeError。但该问题在原始代码中已存在,非本次引入。作者未回应(或已通过合并解决)。
- tree_cache 为 None 时的潜在 AttributeError (correctness): 该问题在原始代码中已存在,本次搬迁未引入新风险;作者未予回应或已通过后续合并解决。
风险与影响
- 风险:本次变更为纯提取,无行为变更,风险极低。主要风险在于导入路径重写是否完全正确;PR 提交时作者通过了机械搬迁验证(byte-for-byte reproduce),且 CI 聚合测试(#28636)覆盖了主要路径,但未提供专门测试。
- 影响:对用户无影响。对开发者:模块职责划分更清晰,便于后续添加新的分配变体;所有消费方导入已更新为指向新模块。
- 风险标记:纯提取无行为变更, 导入重写需验证
关联脉络
- PR #29432 Fix bookkeeping fields not encapsulated with real allocations in normal alloc, PD pre-alloc, DFlash and EAGLE: 同一作者在同一重构系列中提交的后续 PR,进一步封装记账字段,与本 PR 的模块划分紧密相关。
参与讨论