Chapter 12

案例:用 TorchTitan 训自定义架构

📌 commit af33f76把一个新模型加进 torchtitan/models/

TorchTitan 默认只支持 Llama 3 / DeepSeek-V3 / Mixtral 等几个模型。本章手把手加一个新模型(假设叫 MyArch)。

12.1需要写哪些文件

文件作用
torchtitan/models/my_arch/model.pynn.Module 实现
torchtitan/models/my_arch/args.py模型 config dataclass
torchtitan/models/my_arch/parallelize.pyTP / PP / FSDP plan
torchtitan/models/my_arch/__init__.py注册 + 暴露 build_model
train_configs/my_arch.toml跑配置

12.2model.py 骨架

# 标准 PyTorch nn.Module,不要任何分布式
class MyTransformerBlock(nn.Module):
    def __init__(self, cfg: MyArchArgs):
        super().__init__()
        self.attention = Attention(cfg)
        self.feed_forward = FeedForward(cfg)
        self.attention_norm = RMSNorm(cfg.dim)
        self.ffn_norm = RMSNorm(cfg.dim)
    def forward(self, x, freqs_cis):
        h = x + self.attention(self.attention_norm(x), freqs_cis)
        out = h + self.feed_forward(self.ffn_norm(h))
        return out

class MyModel(nn.Module):
    def __init__(self, cfg: MyArchArgs):
        super().__init__()
        self.embed = nn.Embedding(cfg.vocab_size, cfg.dim)
        self.layers = nn.ModuleDict({str(i): MyTransformerBlock(cfg) for i in range(cfg.n_layers)})
        self.norm = RMSNorm(cfg.dim)
        self.output = nn.Linear(cfg.dim, cfg.vocab_size, bias=False)
    def forward(self, ids):
        h = self.embed(ids)
        for layer in self.layers.values():
            h = layer(h, freqs_cis=...)
        return self.output(self.norm(h))

注意:写的是普通 PyTorch nn.Module,不要在这里搞 ParallelLinear。所有并行在 parallelize.py 注入。

12.3args.py

@dataclass
class MyArchArgs:
    dim: int = 2048
    n_layers: int = 16
    n_heads: int = 16
    vocab_size: int = 32000
    max_seq_len: int = 4096
    ...
    # 多种 flavor
    @classmethod
    def from_flavor(cls, flavor):
        return {
            "1B": cls(dim=2048, n_layers=16, n_heads=16),
            "7B": cls(dim=4096, n_layers=32, n_heads=32),
        }[flavor]

12.4parallelize.py

from torch.distributed.tensor.parallel import (
    ColwiseParallel, RowwiseParallel, parallelize_module
)
from torch.distributed.fsdp import fully_shard

def parallelize_my_arch(model, mesh, parallel_dims, config):
    # TP
    if parallel_dims.tp_enabled:
        tp_mesh = mesh["tp"]
        for layer in model.layers.values():
            plan = {
                "attention.wq": ColwiseParallel(),
                "attention.wk": ColwiseParallel(),
                "attention.wv": ColwiseParallel(),
                "attention.wo": RowwiseParallel(),
                "feed_forward.w1": ColwiseParallel(),
                "feed_forward.w2": RowwiseParallel(),
                "feed_forward.w3": ColwiseParallel(),
            }
            parallelize_module(layer, tp_mesh, plan)
        # embed / output 也要 TP
        parallelize_module(model.embed, tp_mesh, RowwiseParallel())
        parallelize_module(model.output, tp_mesh, ColwiseParallel())

    # AC
    if config.activation_checkpoint.mode != "none":
        for layer in model.layers.values():
            apply_ac_to_layer(layer, config.activation_checkpoint)

    # FSDP2
    if parallel_dims.dp_shard_enabled:
        dp_mesh = mesh["dp_shard"]
        for layer in model.layers.values():
            fully_shard(layer, mesh=dp_mesh)
        fully_shard(model, mesh=dp_mesh)

    return model

12.5__init__.py:注册

from .model import MyModel
from .args import MyArchArgs
from .parallelize import parallelize_my_arch

def build_my_model(args: MyArchArgs) -> MyModel:
    return MyModel(args)

# 在 torchtitan/models/__init__.py 里注册
from torchtitan.models.my_arch import build_my_model, MyArchArgs, parallelize_my_arch

MODELS_REGISTRY["my_arch"] = {
    "build_model_fn": build_my_model,
    "args_cls": MyArchArgs,
    "parallelize_fn": parallelize_my_arch,
}

12.6train_configs/my_arch.toml

[model]
name = "my_arch"
flavor = "7B"

[training]
batch_size = 1
seq_len = 4096
tensor_parallel_degree = 2
data_parallel_shard_degree = 4
...

12.7

torchrun --nproc_per_node=8 torchtitan/train.py \
    --job.config_file ./train_configs/my_arch.toml

能跑通就 OK。后续可以加新的 flavor、调 TP plan、加 PP 切层。

12.8注意事项

12.9这章你需要带走的