01 · 架构总览
1. 设计目标
把「纯文本 / 视觉多模态 / 全模态(语音)」三套模型统一到一套代码里,按能力分层:
core/只放与模态无关的纯 Transformer 组件,可被任意模型复用。models/把core组件拼装成成品模型,按模态分lm/vlm/vam三个子包。encoders/+projectors/负责把外部模态信号接入 LLM 主干。trainers/按模态组织训练脚本;dataset/按数据格式组织数据集。
2. 模型能力矩阵
| 子包 | 模态 | 主干 | 额外组件 |
|---|---|---|---|
models/lm |
文本 | LM(LMForCausalLM) |
— |
models/vlm |
文本 + 图像 | VLM(继承 LMForCausalLM) |
SiglipVisionEncoder + MMVisionProjector |
models/vam |
文本 + 图像 + 语音 | VAM(继承 LMForCausalLM) |
上述 + SenseVoice + MMAudioProjector + TalkerModule |
继承关系:VLM 和 VAM 都继承自 LMForCausalLM,因此**共享 LM 主干 + lm_head + generate()**,只在 forward 里额外拼接视觉/音频特征。
3. 一次前向的数据流(以 LM 为例)
input_ids
└─ embed_tokens ──► dropout
│
├─ (RoPE 频率 precompute 一次,缓存为 buffer freqs_cos/freqs_sin)
│
└─ N × Block:
residual = x
x = x + Attention(RMSNorm(x), rope, mask) # 带 QK-Norm + GQA
x = x + MLP(RMSNorm(x)) # SwiGLU 或 MoE
│
└─ RMSNorm(x)
└─ lm_head ──► logits
损失 = CrossEntropy(logits[:, :-1], labels[:, 1:], ignore_index=-100) + aux_loss(仅 MoE)。
4. 训练入口
python -m trainers.lm.full_sft --config configs/lm/lm_full_sft.yaml
python -m trainers.vlm.full_sft --config configs/vlm/vlm_sft.yaml
python -m trainers.vam.full_sft --config configs/vam/vam.yaml
配置读取:utils.training.apply_config(parser, default_config) 把 YAML 的
model/train/paths 三段扁平化后作为 argparse 默认值;CLI 显式参数覆盖 YAML。
5. 关键设计取舍(面试可聊)
- Pre-Norm + 残差:
Block用 RMSNorm 包裹子层,残差直接相加(标准 LLaMA 风格)。 - QK-Norm:attention 里对 q/k 每个 head 做
RMSNorm(head_dim),稳定训练(Qwen 风格)。 - GQA:
num_key_value_heads可小于num_attention_heads,k/v 通过repeat_kv复制。 - 权重绑定:
tie_word_embeddings=True时lm_head.weight与embed_tokens.weight共享。 - MoE 可插拔:
Block根据config.use_moe在FeedForward/MOEFeedForward间切换;aux_loss在MLP.forward内累加,主模型forward汇总。 - 配置驱动:所有超参集中在
LMConfig(及其子类),trainer 用**vars(args)构造, 所以 YAML 能完整控制模型结构。