mindspore-ai / mindspore-ai/hyper-parallel
【RFC】hyper-parallel 支持torchtitan 风格 Module/Config —— Part 7 CLI 入口打通
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.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 |
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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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