GenStudio 于 2025 年 5 月 推出 GenStudio 高级版/企业版升级服务,大幅提升 API 调用频率GenStudio 于 2025 年 5 月 推出 GenStudio 高级版/企业版升级服务,大幅提升 API 调用频率 ,依然保留免费基础服务了解计费
Skip to content

使用 Loss 对齐工具

我们在 Megatron-Infinigence 训练镜像中预置了 Loss 对齐工具。

该工具位于以下路径:

shell
/root/megatron-infinigence/tools/loss_align/

工具简介

该工具用于分析和排查两次训练过程中 Loss 曲线不一致的原因。该工具的工作原理为:在训练框架中设置预埋点,并通过训练框架相关选项控制模块开关和埋点粒度等级,在训练过程中对数据进行保存,然后执行对比工具加载数据,并按训练流程顺序给出关键节点的输出对比。

optimization 训练 Loss 曲线仍然是下降趋势,但相比于 baseline,呈现出差异逐渐增大的趋势

参数配置

Loss 对齐工具提供了丰富的参数配置选项,分为训练框架相关选项和对比工具相关选项两大类。

训练框架相关选项

shell
--loss-aglin                        # 开启 Loss 对齐模式
--loss-align-level 0|1|2            # 埋点粒度等级(0-粗粒度(默认)、1-中等粒度、2-细粒度)
--loss-align-save-path <path>       # 现场保存路径(没有该目录会新建,已有该目录会覆盖)
--loss-align-check                  # 是否对埋点数据严格检查(一般用于验证埋点正确性,可不加)
--no-save-model-metadata            # 不保存模型结构信息(默认保存)
--no-save-model-params              # 不保存模型权重(默认保存)
--no-save-train-hyperparams         # 不保存训练超参(默认保存)
--no-save-sample-data               # 不保存采样数据(默认保存)
--no-save-forward-output            # 不保存前向传播输出(默认保存)
--no-save-loss-output               # 不保存损失函数输出(默认保存)
--no-save-backward-output           # 不保存反向传播输出(默认保存)
--no-save-optimizer-output          # 不保存优化器输出(默认保存)

对比工具相关选项

shell
--loss-aglin-load-path1             # 需要进行 Loss 对比的现场目录一(必填项)
--loss-aglin-load-path2             # 需要进行 Loss 对比的现场目录二(必填项)
--verbose                           # 是否需要打印 tensor 列表的详细对比
--no-check-model-metadata           # 不检查模型结构信息(默认检查)
--no-check-model-params             # 不检查模型权重(默认检查)
--no-check-train-hyperparams        # 不检查训练超参(默认检查)
--no-check-sample-data              # 不检查采样数据(默认检查)
--no-check-forward-output           # 不检查前向传播输出(默认检查)
--no-check-loss-output              # 不检查损失函数输出(默认检查)
--no-check-backward-output          # 不检查反向传播输出(默认检查)
--no-check-optimizer-output         # 不检查优化器输出(默认检查)

警告

此工具需要在训练过程中保存大量数据到磁盘,不是在正常训练中使用的,使用该工具时,需要把相关数据维度降低才可用(比如 layer 层数降至 1-2 层等)。

示例一 对比多卡 Dense 模型

Step 1 执行 baseline 训练

bash
cd /root/megatron-infinigence
bash tools/loss_align/examples/llama2.sh

/root/megatron-infinigence 会生成 baseline 目录,为该次训练的所保存的要对齐的数据。

Step 2 执行 optimize 训练

以下步骤模拟一个优化改动的场景,修改其中的 LR 超参,并保存到另外一个目录:

bash
vim tools/loss_align/examples/llama2.sh

需要进行以下两处修改:

  1. 修改 --lr0.00016
  2. 修改 --loss-align-save-path/root/megatron-infinigence/optimize
bash
bash tools/loss_align/examples/llama2.sh

/root/megatron-infinigence 会生成 optimize 目录。

Step 3 执行对比查看差异

bash
cd /root/megatron-infinigence
python tools/loss_align/compare_loss.py --load-path1 baseline --load-path2 optimize
root@is-dbjkqk3jbo3pyeqg-devmachine-0:~/megatron-infinigence# python tools/loss_align/compare_loss.py --load-path1 baseline --load-path2 optimize
loss_align_load_path1: baseline
loss_align_load_path2: optimize
loss_align_level: 0
train_iters: 1
decoder_layers: 2
world_size: 8

model_metadata (r0): YES
model_metadata (r1): YES
model_metadata (r2): YES
model_metadata (r3): YES
model_metadata (r4): YES
model_metadata (r5): YES
model_metadata (r6): YES
model_metadata (r7): YES
model_init_params (r0): YES, 0
model_init_params (r1): YES, 0
model_init_params (r2): YES, 0
model_init_params (r3): YES, 0
model_init_params (r4): YES, 0
model_init_params (r5): YES, 0
model_init_params (r6): YES, 0
model_init_params (r7): YES, 0
>>> iteration-0
train_hyperparams (r0): NO
{'lr': ([0.00015, 0.00015], [0.00016, 0.00016])}

由于超参 LR 属于两次训练 Loss 一致的先决条件,若其不一致,最终 Loss 必然导致不一致,因此直接退出,显示两次训练脚本中不同的 LR 值(有多个值是因为在优化器中会根据参数类型分为多个组)。

示例二 对比多卡 MoE 模型

Step 1 执行 baseline 训练

bash
cd /root/megatron-infinigence

vim tools/loss_align/examples/mixtral.sh

修改 --loss-align-level2(细粒度埋点)

bash
bash tools/loss_align/examples/mixtral.sh

/root/megatron-infinigence 生成 baseline 目录,为该次训练的所保存的要对齐的数据。

Step 2 执行 optimize 训练

以下步骤模拟一个优化改动的场景,修改 MoE router 中的 softmax 作用位置,并保存到另外一个目录:

bash
vim tools/loss_align/examples/mixtral.sh

需要进行以下两处修改:

  1. 添加一个选项 --moe-router-pre-softmax
  2. 修改 --loss-align-save-path/root/megatron-infinigence/optimize
bash
bash tools/loss_align/examples/mixtral.sh

/root/megatron-infinigence 会生成 optimize 目录。

Step 3 执行对比查看差异

bash
python tools/loss_align/compare_loss.py --load-path1 baseline --load-path2 optimize
root@is-dbjkqk3jbo3pyeqg-devmachine-0:~/megatron-infinigence# python tools/loss_align/compare_loss.py --load-path1 baseline --load-path2 optimize
loss_align_load_path1: baseline
loss_align_load_path2: optimize
loss_align_level: 0
train_iters: 1
decoder_layers: 2
world_size: 8

model_metadata (r0): YES
model_metadata (r1): YES
model_metadata (r2): YES
model_metadata (r3): YES
model_metadata (r4): YES
model_metadata (r5): YES
model_metadata (r6): YES
model_metadata (r7): YES
model_init_params (r0): YES, 0
model_init_params (r1): YES, 0
model_init_params (r2): YES, 0
model_init_params (r3): YES, 0
model_init_params (r4): YES, 0
model_init_params (r5): YES, 0
model_init_params (r6): YES, 0
model_init_params (r7): YES, 0
>>> iteration-0
train_hyperparams (r0): YES
train_hyperparams (r1): YES
train_hyperparams (r2): YES
train_hyperparams (r3): YES
train_hyperparams (r4): YES
train_hyperparams (r5): YES
train_hyperparams (r6): YES
train_hyperparams (r7): YES
sample_data r0: YES, 0
sample_data r1: YES, 0
sample_data r2: YES, 0
sample_data r3: YES, 0
sample_data r4: YES, 0
sample_data r5: YES, 0
sample_data r6: YES, 0
sample_data r7: YES, 0
forward_output (r0): NO, 1e-1
forward_output (r1): NO, 1e-1
forward_output (r2): NO, 1e-1
forward_output (r3): NO, 1e-1
forward_output (r4): NO, 1e0
forward_output (r5): NO, 1e0
forward_output (r6): NO, 1e0
forward_output (r7): NO, 1e0
loss_output (r4): NO, 1e-2
loss_output (r5): NO, 1e-2
loss_output (r6): NO, 1e-2
loss_output (r7): NO, 1e-2
optimizer_output (updated_params): NO, 1e-4
optimizer_output (norms): NO, 1e-1

结果显示,前向输出存在不一致,rank0-rank3 均为 1e-1 级误差,rank4-rank7 均为 1e0 级误差。

Step 4 详细对比分析

为进一步分析问题,可添加 --verbose 参数查看所有模块的详细输出对比,以确定具体的问题模块:

bash
python tools/loss_align/compare_loss.py --load-path1 baseline --load-path2 optimize --verbose
forward_output (r0): NO, 1e0
+--------------------------------------------------+-------+------------------+---------------+----------+----------+
| key                                              | level | shape            | dtype         | same_hash| diff_order|
+--------------------------------------------------+-------+------------------+---------------+----------+----------+
| [GAS-0] embed_out                                | 1     | (512, 1, 1024)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] input_norm_out                     | 1     | (512, 1, 1024)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_qkv_out                       | 2     | (1024, 1, 8, 64) | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_qkv_k_out                     | 2     | (1024, 1, 8, 64) | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_qkv_v_out                     | 2     | (1024, 1, 8, 64) | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_rope_q_out                    | 2     | (1024, 1, 8, 64) | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_rope_k_out                    | 2     | (1024, 1, 8, 64) | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_core_out                      | 2     | (1024, 1, 512)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_proj_out                      | 2     | (512, 1, 1024)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] attn_out                           | 0     | (512, 1, 1024)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] premlo_norm_out                    | 1     | (512, 1, 1024)   | torch.bfloat16| True     | 0        |
| [GAS-0] [L-0] MoE_router_probs_out               | 1     | (1024, 2)        | torch.bfloat16| False    | 1e-1     |
| [GAS-0] [L-0] MoE_router_indices_out             | 1     | (1024, 2)        | torch.int64   | False    | 1e0      |

结果显示,在 MoE router 的两个输出中首次出现不一致,误差等级分别为 1e-1 和 1e0,表明 router 模块存在差异(图中 GAS-x 为梯度累积次数,L-x 为层数),与之前设置的 --moe-router-pre-softmax 参数相关。