Skip to content

feat: add gdr load mode#851

Open
lixin010 wants to merge 2 commits intomainfrom
feature/load_gdr
Open

feat: add gdr load mode#851
lixin010 wants to merge 2 commits intomainfrom
feature/load_gdr

Conversation

@lixin010
Copy link
Copy Markdown
Collaborator

@lixin010 lixin010 commented Apr 1, 2026

No description provided.

@lixin010 lixin010 requested a review from LLLLKKKK as a code owner April 1, 2026 10:04
@LLLLKKKK
Copy link
Copy Markdown
Collaborator

LLLLKKKK commented Apr 1, 2026

Code Review: PR #851 — feat: add gdr load mode

Author: lixin010
Review version: v1
Head SHA: 18695ab
Verdict: LGTM

Summary

添加 GDR (GPU Direct RDMA) 权重加载模式和启动时间线追踪:

  1. GDR 加载模式: 新增 LoadMethod.FASTSAFETENSORS_GDR,通过 fastsafetensorscopier_type="gdr" 实现 GPU Direct RDMA 加载,跳过 SHM 中转
  2. _resolve_load_method 重构: 将加载方法解析从 _load_weight 中提取为独立方法,load_weights 统一调度所有加载路径(SCRATCH/CONVERTED/FST/FST_GDR)
  3. StartupTimeline: 新增启动时间线追踪工具(157 行),记录各阶段耗时(MODULE_INIT、WEIGHT_LOAD、ENGINE_START 等),支持跨进程时间戳传递和报告输出
  4. is_sp_model 标记: 区分主模型和 speculative 模型的加载阶段
  5. LoadMethod.CONVERTED: 新增显式枚举值替代隐式的 is_ft_style_weight 判断

评价

重构方向正确,加载路径更清晰。GDR 模式通过 copier_type 参数切换,改动最小化。StartupTimeline 对排查启动性能问题有价值。

P2 Suggestions

1. fastsafetensors_weights_iterator 参数语义变更

-    def fastsafetensors_weights_iterator(self, device: str, use_tqdm_on_load: bool):
+    def fastsafetensors_weights_iterator(self, device: str, use_gdr: bool):

参数从 use_tqdm_on_load 改为 use_gdr,但 use_tqdm_on_load 被硬编码为 True。如果有外部调用方依赖原参数语义,需要确认兼容性。

2. StartupTimeline 使用全局类变量存储状态

StartupTimeline 通过类变量 _phases_timestamps 存储状态,在多进程场景下每个进程有独立副本(spawn 模式)。ProcessLaunchTimestamp 通过参数传递解决了跨进程时间同步,设计合理。

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

🤖 AI Code Review — PR #851

PR 概述

Title: feat: add gdr load mode
Author: lixin010
规模: 11(GitHub) files, +261/-49

核心目标

本 PR 包含两个独立功能:

  1. 新增 GDR(GPU Direct RDMA)权重加载模式,通过 fastsafetensorscopier_type="gdr" 实现直接从存储到 GPU 的权重传输
  2. 新增 StartupTimeline 启动耗时追踪框架,在各启动阶段埋点并通过 KMonitor 上报指标

改动逻辑拆解

GitHub 开源仓库变更(主要代码)

1. GDR 加载模式(Commit 1: feat: add gdr load mode)

  • rtp_llm/model_loader/load_config.pyLoadMethod 枚举新增 CONVERTED(原 ft-style 路径的显式命名)和 FASTSAFETENSORS_GDR
  • rtp_llm/model_loader/loader.py:将原 _load_weight 拆分为 _resolve_load_method(纯决策)+ load_weights 中的 dispatch 逻辑。_load_from_fastsafetensor 新增 use_gdr 参数
  • rtp_llm/utils/database.pyfastsafetensors_weights_iterator 参数从 use_tqdm_on_load 改为 use_gdr,内部将 use_shm=True 替换为 copier_type="gdr"|"shm"use_tqdm_on_load 硬编码为 True。新增 PerExpertParallelLoader import 和 stacked_key_config 支持

2. 启动耗时追踪(Commit 2: feat: report startup timeline)

  • rtp_llm/utils/startup_timeline.py:新增文件,定义 StartupPhase 枚举、StartupTimeline 单例类、startup_phase context manager
  • rtp_llm/__init__.py:记录 MODULE_INIT 阶段耗时
  • rtp_llm/start_server.py:主进程入口埋点
  • rtp_llm/start_backend_server.py:backend server 进程和 rank 进程启动埋点,函数签名变更
  • rtp_llm/server/backend_manager.py:distributed server、NCCL 初始化、DeepEP 初始化埋点
  • rtp_llm/model_factory.py:engine 创建埋点,is_sp_model 标记
  • rtp_llm/models/base_model.py:模型加载埋点
  • rtp_llm/config/model_config.py:新增 is_sp_model 字段

Checklist 检查结果

通用原则

软件工程原则

检查项 结果
SRP ❌ PR 混合了两个独立功能(GDR 加载 + 启动 timeline),应拆分
OCP ✅ 新增 LoadMethod 枚举值,不修改已有枚举行为
LSP ✅ 不涉及继承变更
ISP
DIP
DRY
KISS
YAGNI

架构审视

检查项 结果
抽象边界 ✅ StartupTimeline 作为独立 util 模块,边界清晰
依赖方向
状态完整性 ✅ StartupTimeline 单例 per-process,符合多进程架构
错误语义 ✅ startup_phase 在 finally 中记录,异常不影响
可观测性 ✅ 通过 KMonitor 上报,改善了可观测性
可演进性
可运维性

测试

检查项 结果
新功能有对应测试 ❌ 两个新功能均无测试
删除的测试有等价替代 ✅ 无删除测试
边界 case 覆盖 ❌ 无测试
分布式改动有多卡测试 ❌ 无测试

代码质量与文档

检查项 结果
无关改动分离 ❌ GDR 加载和 StartupTimeline 是两个独立功能,混在一个 PR
mega-PR 拆分 ✅ 规模不大
Commit 原子性 ✅ 两个 commit 各自对应一个功能
Commit message 准确性
PR description 说明动机和设计 ❌ PR body 为空
日志频率控制 ✅ 仅在启动阶段打印

领域检查

A. 兼容性与配置

检查项 结果
1.1 Breaking Change 兼容处理 start_backend_server 签名变更破坏 main() 调用(见 P0-1);fastsafetensors_weights_iterator 参数语义变更(见 P1-1)
1.2 默认值变更
1.12 模型变体配置传播 is_sp_model 仅用于 timeline 标记
1.32 可选依赖 lazy import ✅ KMonitor 在 report() 内 lazy import

B. 正确性与逻辑

检查项 结果
逻辑错误 main() 调用 start_backend_server(None) 缺少必需参数(见 P0-1)
边界 case
死代码
状态标志生命周期

C. 线程安全与并发 — 全部 ✅

D. 性能 — 全部 ✅

E. 分布式 — 全部 ✅

F. 跨平台 — 全部 ✅

G. 语言与框架特有

检查项 结果
1.8 Python 变量安全 ❌ Python 3.9 类型注解语法不兼容(见 P1-2)
1.17 重命名全局搜索 fastsafetensors_weights_iterator 参数语义变更,旧调用方未全部更新(见 P1-1)

H. 测试与 CI

检查项 结果
1.5 测试覆盖 ❌ 无测试

I. 代码质量

检查项 结果
1.4 代码风格统一 ❌ 拼写错误 main_enrty_time(见 P2-1)

Review 意见

问题

  1. start_backend_server 签名变更破坏 main() 入口 [P0]

    start_backend_server 的签名从 (global_controller, py_env_configs, pipe_writer=None) 变为 (global_controller, py_env_configs, process_launch_time, pipe_writer=None),其中 process_launch_time 是必需的位置参数。

    start_backend_server.py 末尾的 main() 函数仍然是:

    def main():
        return start_backend_server(None)

    这只传了一个参数(global_controller=None),缺少 py_env_configsprocess_launch_time,调用时会抛出 TypeError

    同样,start_server.py 的 debug 路径:

    start_backend_server(global_controller, py_env_configs, None)

    这里 None 会被解释为 process_launch_time(可以工作),但 pipe_writer 缺失(默认 None,也可以工作)。这个调用点恰好不会报错,但语义上 None 从原来的 pipe_writer=None 变成了 process_launch_time=None,需要确认是否有意为之。

    建议:将 process_launch_time 改为带默认值的关键字参数 process_launch_time: Optional[ProcessLaunchTimestamp] = None,或修复 main() 函数。

  2. fastsafetensors_weights_iterator 参数语义变更未同步旧调用方 [P1]

    CkptDatabase.fastsafetensors_weights_iterator 的第二个参数从 use_tqdm_on_load: bool 变为 use_gdr: bool,语义完全不同。

    当前代码库中 loader.py 的旧版本(未被 PR 修改的基线代码)在 _load_from_fastsafetensor 中调用:

    all_tensors = self._load_config.database.fastsafetensors_weights_iterator(
        device, True
    )

    这里 True 原意是 use_tqdm_on_load=True,但在 PR 后会被解释为 use_gdr=True,导致所有 fastsafetensors 加载路径都意外启用 GDR 模式。

    虽然 PR 中 loader.py 的 diff 重构了这个调用路径(通过 _resolve_load_method 分发),但需要确认 BaseDatabase 的其他子类或外部调用方是否也使用了旧签名。

    建议:使用关键字参数调用以避免位置参数语义混淆,或在 BaseDatabase 基类中同步更新接口声明。

  3. Python 3.9 不兼容的类型注解语法 [P1]

    startup_timeline.py 中大量使用了 Python 3.10+ 的类型注解语法:

    • float | None(应为 Optional[float]
    • dict[str, str](应为 Dict[str, str]
    • "StartupTimeline | None"(应为 Optional["StartupTimeline"]

    如果项目需要支持 Python 3.9(容器内使用 3.10,但开源用户可能使用 3.9),这些语法会导致 TypeError 在 import 时。

    建议:在文件顶部添加 from __future__ import annotations,或改用 typing 模块的 Optional/Dict 等类型。

  4. 缺少测试覆盖 [P1]

    两个新功能均无测试:

    • GDR 加载模式:_resolve_load_method 的分支逻辑、FASTSAFETENSORS_GDR 路径
    • StartupTimeline:mark_phasestartup_phase context manager、report 方法、跨进程 timestamp 传递

    建议:至少为 _resolve_load_method 添加单元测试覆盖各分支,为 StartupTimeline 添加基本的 mark/report 测试。

小问题

  1. 拼写错误 main_enrty_time [P2]
    ProcessLaunchTimestamp.main_enrty_time 应为 main_entry_time。这个拼写错误会传播到 KMonitor 上报的 tag 中("main_start_time": str(int(cls._get_instance().process_launch_timestamp.main_enrty_time))),影响监控数据的可读性和查询。

  2. PR 混合两个独立功能 [P2]
    GDR 加载模式和 StartupTimeline 是两个完全独立的功能,建议拆分为两个 PR,便于独立 review、回滚和 bisect。

  3. PR description 为空 [P2]
    PR body 为空,缺少动机说明和设计描述。对于新增加载模式和监控框架这样的功能,应说明 GDR 的使用场景、性能预期、以及 StartupTimeline 的设计决策。

  4. force_clean_cuda_memory 行为变更 [P3]
    原代码中 force_clean_cuda_memory() 仅在非 ft-style 路径调用,重构后在所有加载路径后都会调用。这是一个行为变更,虽然可能是有益的(ft-style 路径也能受益于显存清理),但应在 commit message 中说明。

  5. metirc 拼写错误 [P3]
    startup_timeline.py 第 131 行 metirc = kmonitor.register_gauge_metric(...) 应为 metric

整体评价

PR 包含两个独立功能:GDR 加载模式和启动耗时追踪。GDR 加载的核心逻辑(_resolve_load_method 拆分 + copier_type 切换)设计合理,将加载方法决策与执行分离是好的重构方向。StartupTimeline 框架设计简洁,per-process 单例 + context manager 的模式适合多进程架构。

但存在一个 P0 问题:start_backend_server 签名变更破坏了 main() 入口,会导致直接调用 start_backend_server.py 时 crash。此外 Python 3.9 兼容性和缺少测试也需要关注。

存在阻塞/重要问题,不建议合入

@LLLLKKKK
Copy link
Copy Markdown
Collaborator

Code Review — PR #851: feat: add gdr load mode

审查日期: 2026-04-14 | 变更: +261 / -49, 11 文件, 2 commits | CI: 功能测试 FAILED


变更概览

  1. GDR 加载模式: 新增 FASTSAFETENSORS_GDR 加载方式,通过 copier_type="gdr" 启用 GPU Direct RDMA 加载。重构 _load_weight_resolve_load_method
  2. 启动 Timeline 上报: 新增 StartupTimeline 单例,在启动各阶段埋点计时,通过 KMonitor 上报 rtp_startup_latency 指标。

P1-1: force_clean_cuda_memory() 行为变更

rtp_llm/model_loader/loader.py — 旧代码中 force_clean_cuda_memory() 仅在非 ft-style 路径调用,新代码对所有加载方式(包括 CONVERTED/ft-style)都执行。需确认是有意为之还是重构遗漏。

P1-2: copier_type 参数依赖 fastsafetensors 版本

rtp_llm/utils/database.pyuse_shm=True 改为 copier_type="shm"/"gdr",旧版本 fastsafetensors 不支持此参数会直接 TypeError。建议明确最低版本要求或添加 fallback。

P1-3: 缺少测试覆盖

无任何测试变更。StartupTimeline 无单元测试,GDR 加载路径无集成测试,_resolve_load_method 分支覆盖缺失。CI 功能测试已 FAILED (run 34173930)。

P2-1: 拼写错误 main_enrty_time

startup_timeline.py:40ProcessLaunchTimestamp.main_enrty_time 应为 main_entry_time

P2-2: start_backend_server 签名变更

新增必选参数 process_launch_time 插入在 pipe_writer 之前,可能影响其他调用方。建议设默认值 None

P2-3: CONVERTED 静默回退 AUTO

_resolve_load_method 中用户指定 CONVERTED 但权重非 ft-style 时静默回退 AUTO,应打 warning。

P2-4: record.tags 未合并到 metric 上报

report()WEIGHT_LOAD 阶段的 load_method tag 被丢弃,无法区分 GDR vs SHM 耗时。

P3: 其他

  • metircmetric (startup_timeline.py:131)
  • float | None 等 PEP 604 语法与项目 Optional[float] 风格不一致
  • 多处 f-string 无变量插值

级别 数量
P1 3
P2 4
P3 3

整体:功能方向合理,代码结构清晰。主要风险在 force_clean_cuda_memory 行为变更和 fastsafetensors API 兼容性。建议补充测试并确认 CI 失败原因。

Generated by Claude Code Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants