mindspore-ai / mindspore-ai/hyper-parallel

【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— Part 7 CLI 入口打通

Open
#724 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
53
Forks
63
Avg merge
23h 45m
Merged PRs (30d)
63

Description

Part 7 — CLI 入口打通

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


1. 目标

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

2. 任务边界

新文件 / 修改文件 内容
hyper_parallel/models/qwen3_5_v2/config_registry.py(新) 多个工厂函数(recipe),每个返回 HyperTrainer.Configqwen3_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

schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 145
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/145

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading M2's ConfigManager in manager.py and the current entry point in scripts/train_lm.py, then inspect the existing qwen3_5_v2 model factory. Add the three recipes and wire both --module and legacy YAML paths through the CLI. Run the four tests under tests/torch/st/qwen3_5_v2_cli/; done means all pass while legacy YAML behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, pytorch, yaml
Domain
cli, distributed-systems, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
56/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.