已开启
【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— Part 7 CLI 入口打通 #145
changzherui创建于  5月15日
changzherui
changzherui成员
5月15日 创建

Part 7 — CLI 入口打通

写 config_registry.py,把 scripts/train_lm.py 切到 ConfigManager,端到端跑 --module qwen3_5_v2 --config qwen3_5_v2_4b 命令。旧 yaml 路径仍是默认。


1. 目标

把"命令行 → HyperTrainer.Config → config.build() → trainer.train()"完整链路打通,达成 torchtitan 风格的"用户敲命令 → 并行模型 + 完整训练栈"4 步链路。

2. 任务边界

新文件 / 修改文件 内容
hyper_parallel/models/qwen3_5_v2/config_registry.py(新) 多个工厂函数(recipe),每个返回 HyperTrainer.Config:qwen3_5_v2_debugmodel / qwen3_5_v2_4b / qwen3_5_v2_4b_tp2_fsdp4
scripts/train_lm.py(改) 改为 mgr = ConfigManager(); config = mgr.parse_args(); trainer = config.build(); trainer.train(),自动识别 --module / yaml 两种模式

3. config_registry.py 示例

# hyper_parallel/models/qwen3_5_v2/config_registry.py
from hyper_parallel.config import (
    TrainingConfig, ParallelismConfig, ActivationCheckpointConfig,
)
from hyper_parallel.components.optimizer import OptimizersContainer
from hyper_parallel.components.dataloader import HuggingFaceTextDataLoader
from hyper_parallel.trainer.trainer_config import HyperTrainer

from .__init__ import qwen3_5_v2_spec_factory


def qwen3_5_v2_debugmodel() -> HyperTrainer.Config:
    return HyperTrainer.Config(
        model_spec=qwen3_5_v2_spec_factory("debugmodel"),
        optimizer=OptimizersContainer.Config(lr=8e-4),
        training=TrainingConfig(
            local_batch_size=8, seq_len=2048, steps=10,
        ),
        dataloader=HuggingFaceTextDataLoader.Config(dataset="dummy"),
        activation_checkpoint=ActivationCheckpointConfig(mode="selective"),
    )


def qwen3_5_v2_4b() -> HyperTrainer.Config:
    cfg = qwen3_5_v2_debugmodel()
    cfg.model_spec = qwen3_5_v2_spec_factory("4B")
    cfg.parallelism = ParallelismConfig(
        tensor_parallel_degree=2,
        data_parallel_shard_degree=-1,
    )
    return cfg


def qwen3_5_v2_4b_tp2_fsdp4() -> HyperTrainer.Config:
    cfg = qwen3_5_v2_4b()
    cfg.parallelism.tensor_parallel_degree = 2
    cfg.parallelism.data_parallel_shard_degree = 4
    return cfg

4. scripts/train_lm.py 改造(≈ 5 行)

改造前(现状,scripts/train_lm.py:39-47):

if __name__ == "__main__":
    args = parse_args(HyperTrainerConfig)
    discover_model_spec(args.model.name)
    trainer = LLMTrainer(args)
    trainer.train()

改造后:

from hyper_parallel.config import ConfigManager

if __name__ == "__main__":
    mgr = ConfigManager()
    config = mgr.parse_args()           # 自动识别 --module / yaml
    trainer = config.build()            # HyperTrainer(config) 或 LLMTrainer(legacy)
    trainer.train()

关键点:

  • ConfigManager.parse_args() 内部如果走旧 yaml 路径,返回的是经过 _legacy_to_trainer_config 后的 HyperTrainer.Config(M2)。
  • config.build() 即 HyperTrainer(config) —— 不论新旧 CLI 入口,都收口到 M5 的 HyperTrainer.__init__。
  • 旧 LLMTrainer 路径仍可手动调用:trainer = LLMTrainer(parse_args(HyperTrainerConfig)),方便回归对比。

5. 入口判定规则

ConfigManager.parse_args 的判定(M2 manager.py):

argv[0] 起始为 "--module"   →  新 tyro 路径
                                  └─ importlib.import_module(
                                       "hyper_parallel.models.<NAME>.config_registry")
                                  └─ tyro.cli(HyperTrainer.Config, default=loaded_recipe,
                                              args=剩余 CLI)

否则(argv[0] 是 yaml 路径) →  旧路径
                                  └─ parse_args(HyperTrainerConfig)    # 复用 :547
                                  └─ _legacy_to_trainer_config(legacy)

6. 与 torchtitan 接口差异说明

# 差异点 原因
1 train_lm.py 同时支持新 / 旧入口(不像 torchtitan 只有 --module 一种) 零破坏迁移,保护现网 yaml 用户
2 config_registry.py 模块名 qwen3_5_v2(带 _v2 后缀),torchtitan 是 llama3 等纯模型名 与现存 qwen3_5 并存,避免 spec 名字冲突
3 discover_model_spec 调用时机:tyro 路径里 _load_config 已经 importlib 完成发现 旧路径继续走 discover_model_spec

7. 开发步骤

步 内容 工期
1 写 config_registry.py 的 3 个 recipe(debugmodel / 4b / 4b_tp2_fsdp4) 0.5 d
2 改 scripts/train_lm.py(约 5 行) 0.5 d
3 写 e2e 系统测试 1 d

8. 验证标准

新建 tests/torch/st/qwen3_5_v2_cli/:

测试 命令 断言要点
test_cli_1card.py python scripts/train_lm.py --module qwen3_5_v2 --config qwen3_5_v2_debugmodel --training.steps=5 与同种子 yaml 路径 bit-exact
test_cli_8card.py torchrun --nproc_per_node=8 scripts/train_lm.py --module qwen3_5_v2 --config qwen3_5_v2_4b --parallelism.tensor_parallel_degree=2 --training.steps=10 与 yaml 路径 loss / grad_norm 容忍 1e-4
test_legacy_yaml.py python scripts/train_lm.py existing_qwen3_5.yaml 与 main 分支 0 差异
test_cli_override.py ... --module qwen3_5_v2 --config qwen3_5_v2_4b --training.steps=20 --optimizer.lr=1e-4 tyro 覆盖生效,最终 config.training.steps == 20 and config.optimizer.lr == 1e-4

通过门槛:

  • 4 个 ST 全绿。
  • 旧 yaml 入口行为 0 改动(与 main 分支 bit-exact)。

9. 工期 & 依赖

工期 2 天
依赖 M2 + M6
下游 M8
likedislike
changzheruichangzherui成员
5月15日 修改标题为 “hyper-parallel 支持torchtitan 风格 Module/Config —— M7 CLI 入口打通”,原标题为“hyper-parallel 支持torchtitan 风格 Module/Config —— M7”
changzheruichangzherui成员
5月15日 修改标题为 “【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— M7 CLI 入口打通”,原标题为“hyper-parallel 支持torchtitan 风格 Module/Config —— M7 CLI 入口打通”
changzheruichangzherui成员
5月25日 修改标题为 “【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— Part 7 CLI 入口打通”,原标题为“【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— M7 CLI 入口打通”
changzheruichangzherui成员
5月25日 修改了issue 的描述