大模型预训练、SFT、RLHF 训练过程中,性能达标不等于训练有效,精度才是模型最终价值的核心衡量指标。昇腾 NPU 迁移训练经常出现 loss 抖动、NaN/INF 溢出、收敛轨迹与标杆不一致、下游评测指标下降等精度问题。昇腾 DaVinci 硬件、CANN 工具链提供完整精度评估体系,包含单 step 数值对齐、loss 收敛观测、中间张量 Dump 比对、下游数据集评测、溢出检测全套能力。本文从硬件精度特性、评估原理、代码示例、编译运行、关键调优手段、指标对比、常见问题、总结八大维度系统讲解昇腾大模型训练精度评估实践,保障昇腾环境下大模型训练精度无损。

一、昇腾大模型精度硬件基础

昇腾 AI 处理器 DaVinci 架构 AI Core 支持 FP32、FP16、BF16 多精度混合计算,矩阵单元 Cube、向量单元 Vector 具备不同的数值计算特性,大模型训练精度相关硬件特性:

  1. 多浮点格式支持:FP16、BF16 混合精度训练;BF16 拥有更大指数域,可缓解梯度下溢,适合大模型训练;FP16 需要 Loss‑Scaler 防止梯度下溢。

  2. 算子精度模式:CANN 提供 origin、force_fp16、allow_fp32_to_fp16 等算子精度模式,会直接影响矩阵乘、Softmax、RMSNorm 等 Transformer 核心算子输出数值。

  3. 混合并行计算:张量并行、序列并行、数据并行场景下 HCCL 集合通信存在浮点归约误差,多卡场景误差会累积放大。

  4. 硬件计算固有微小误差:硬件浮点运算存在 ULP 微小误差,正常可接受;误差持续累积则会引发训练失效。

大模型精度评估分为两层:

  1. 数值层评估:单 step 前向 / 反向张量、logits、loss、梯度,和 CPU/GPU 标杆做比对;

  2. 业务层评估:loss 收敛曲线、perplexity 困惑度、MMLU/C‑Eval 等下游评测集指标。

二、核心评估原理

2.1 精度问题分类

  1. 数值异常类:出现NaN/INF,loss 直接爆炸,训练中断;

  2. 轨迹偏差类:无 NaN,但 loss 下降曲线与标杆不一致,前期偏差小,后期误差累积越来越大;

  3. 最终效果类:loss 看起来正常,但下游评测指标显著低于标杆,属于隐性精度问题。

2.2 核心评估指标

指标

说明

合格参考标准

余弦相似度

张量向量相似度,越接近 1 越好

>0.999

KL 散度

概率分布差异,越小越好

BF16<0.005,FP16<0.0001

最大绝对误差

张量元素最大差值

根据模型业务容忍度判定

Perplexity(PPL)

验证集困惑度,越小代表模型拟合越好

与标杆差值≤5%

MMLU/C‑Eval

下游问答评测准确率

与标杆差值≤1‑2 个百分点

2.3 完整评估链路

固定随机种子→单step对齐验证(Dump中间张量)→多step loss收敛观测→验证集PPL评估→下游数据集评测;出现偏差时定位可疑算子→修改配置重新验证。

关键前提:固定随机种子,数据集 shuffle、权重初始化、dropout 随机行为必须完全固定,否则无法做数值比对。

2.4 评估工具栈

  1. msprobe:Dump 训练中间张量,跨平台精度比对;

  2. msit llm compare:大模型专用精度比对工具,解析 Transformer 层输出、logits;

  3. MindStudio 精度分析器:可视化误差热力图,溢出检测;

  4. 开源评测框架:lm‑evaluation‑harness,完成 MMLU/C‑Eval 等业务指标评测。

三、昇腾大模型精度评估代码实现(PyTorch‑NPU)

示例包含:随机种子固定、单 step dump 配置、验证集 PPL 计算、下游评测调用,适配大模型 SFT 训练场景。

import os
import torch
import torch_npu
import random
import numpy as np
from torch.utils.data import DataLoader
from transformers import AutoModelForCausalLM, AutoTokenizer
import lm_eval

def seed_all(seed=42):
    """固定全部随机种子,保证精度比对可复现"""
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch_npu.npu.manual_seed_all(seed)
    os.environ['CUBLAS_WORKSPACE_CONFIG'] = ":4096:8"
    torch.use_deterministic_algorithms(True)

def set_dump_env():
    """配置msprobe dump环境,仅采集step0,用于单step精度对齐"""
    os.environ["MSPROBE_CONFIG"] = '''{
        "task":"statistics",
        "dump_path":"./npu_dump_data",
        "step":[0],
        "rank":[0],
        "level":"L1"
    }'''

def calc_ppl(model, tokenizer, val_dataloader, device):
    """计算验证集Perplexity困惑度,业务精度核心指标"""
    model.eval()
    total_loss = 0.0
    total_tokens = 0
    with torch.no_grad():
        for batch in val_dataloader:
            input_ids = batch["input_ids"].to(device)
            attention_mask = batch["attention_mask"].to(device)
            out = model(input_ids=input_ids, attention_mask=attention_mask, labels=input_ids)
            loss = out.loss
            num_tokens = int(attention_mask.sum().item())
            total_loss += loss.item() * num_tokens
            total_tokens += num_tokens
    avg_nll = total_loss / total_tokens
    ppl = float(torch.exp(torch.tensor(avg_nll)))
    return ppl

def eval_downstream(model, tokenizer):
    """调用lm‑evaluation‑harness执行下游MMLU评测"""
    results = lm_eval.simple_evaluate(
        model="hf",
        model_args={"pretrained":model, "tokenizer":tokenizer},
        tasks=["mmlu"],
        batch_size=2
    )
    return results["results"]["mmlu"]["acc,none"]

def main():
    seed_all(seed=42)
    set_dump_env()
    device = torch.device("npu:0")
    torch_npu.npu.set_device(device)

    # 加载大模型与tokenizer
    model_path = "./llama‑7b‑sft"
    model = AutoModelForCausalLM.from_pretrained(
        model_path, torch_dtype=torch.bfloat16
    ).npu()
    tokenizer = AutoTokenizer.from_pretrained(model_path)

    # 模拟验证集dataloader
    val_dataset = []
    val_dataloader = DataLoader(val_dataset, batch_size=2)

    # 1.单step训练,dump中间张量
    model.train()
    dummy_input = tokenizer("hello world", return_tensors="pt").to(device)
    out = model(**dummy_input, labels=dummy_input["input_ids"])
    loss = out.loss
    loss.backward()
    print(f"step‑0 loss value: {loss.item()}")

    # 2.计算验证集PPL
    ppl = calc_ppl(model, tokenizer, val_dataloader, device)
    print(f"validation perplexity: {ppl:.4f}")

    # 3.下游MMLU评测
    mmlu_acc = eval_downstream(model, tokenizer)
    print(f"MMLU accuracy: {mmlu_acc:.4f}")

if __name__ == "__main__":
    main()

四、编译与运行

4.1 环境依赖

# 依赖包
pip install torch‑npu transformers lm‑evaluation‑harness
# CANN版本要求 ≥8.0.RC1

4.2 执行训练 & dump 采集

# 执行精度评估脚本,产出dump数据 ./npu_dump_data
python llm_accuracy_eval.py

4.3 msprobe 执行跨平台精度比对

标杆(GPU/CPU 环境)运行同一套代码产出golden_dump_data;昇腾 NPU 产出npu_dump_data,执行比对:

cat > compare.json <<EOF
{
  "npu_path": "./npu_dump_data/dump.json",
  "bench_path": "./golden_dump_data/dump.json",
  "is_print_compare_log":true
}
EOF

msprobe -f pytorch compare -i compare.json -o cmp_result

4.4 大模型 logits 专用比对 msit llm compare

msit llm compare \
‑gp ./golden_dump/tensors/0_1234 \
‑mp ./npu_dump/tensors/0_1234 \
‑o llm_cmp_out

4.5 MindStudio 图形化评估

  1. 导入 dump 数据目录;

  2. 打开 Accuracy Analyzer 精度分析器;

  3. 查看余弦相似度、KL 散度热力图,定位误差最大算子层;

  4. 开启溢出检测,扫描 NaN/INF 发生的算子位置。

五、关键调优手段

5.1 随机种子与确定性计算

  • 必须开启seed_all全套种子固定;

  • 开启torch.use_deterministic_algorithms(True),部分算子开启确定性模式;

  • 多卡分布式场景,dataloader 的 shuffle 种子也要固定,否则输入样本不一致无法比对。

5.2 混合精度参数调优

  • FP16 训练:开启动态 GradScaler,防止梯度下溢产生 NaN;

  • BF16 训练:一般不需要 loss‑scaler,优先推荐大模型预训练 / SFT 使用 BF16;

  • 配置算子精度模式,RMSNorm、Softmax 关键层必要时切换 origin 原始精度模式,降低计算误差。

5.3 Dump 采集策略

  • 优先采集step0,越早发现偏差越容易定位根因;

  • 大模型不要 dump 全部 step,dump 会大量占用磁盘 IO;

  • 先用statistics统计模式(只存均值最大最小)排查,确认异常后再开启完整 tensor dump。

5.4 多卡并行精度控制

  • HCCL 集合通信开启高精度归约;

  • 序列并行、张量并行场景,对齐标杆的并行切分逻辑;

  • 观察多卡各 rank loss 是否一致,单 rank 异常说明该卡通信或者计算存在问题。

5.5 分层评估策略

  1. 第一层:单 step 数值对齐(logits、loss、梯度);

  2. 第二层:多 step loss 收敛曲线、验证集 PPL;

  3. 第三层:MMLU/C‑Eval 等真实业务评测;

不要跳过前两层直接看下游指标,隐性精度问题很难定位。

5.6 NaN/INF 溢出排查

  • 开启昇腾溢出检测环境变量:export MS_ASCEND_CHECK_OVERFLOW_MODE=INFNAN_MODE;

  • 出现 NaN 优先排查:学习率过大、梯度裁剪未生效、FP16 下溢、长序列 softmax 数值越界。

六、精度指标对比

测试条件:Llama‑7B SFT 训练,BF16,昇腾 910B,对比 GPU 标杆结果

运行环境

step0 loss

验证集 PPL

MMLU 准确率

说明

GPU 标杆

2.314

7.82

43.2%

基准参考

昇腾(未调参,存在算子精度模式不匹配)

2.472

9.15

38.7%

数值偏差累积,业务指标下降

昇腾(种子固定 + origin 算子精度 + 溢出防护)

2.318

7.89

42.8%

、常见问题与优化建议

  1. dump 比对差异很大,但 loss 看起来正常

    1. 原因:单算子微小误差,经过多层网络互相抵消;但训练步数加深误差会累积爆发。

    2. 方案:检查算子精度模式,重点关注 RMSNorm、Softmax、GEMM;优先保证 step0 前向 logits 余弦相似度 > 0.999。

  2. 训练出现 NaN / INF,loss 直接变成 nan

    1. 原因:FP16 梯度下溢、学习率过大、长序列 attention 数值溢出、梯度裁剪顺序错误。

    2. 方案:切换 BF16;开启溢出检测定位产生 NaN 算子;调小学习率;检查 GradScaler 与梯度裁剪顺序。

  3. 单 step 对齐正常,训练几百 step 之后 loss 偏离标杆

    1. 原因:多卡 HCCL 归约累积误差、dropout 随机未完全固定、优化器状态更新差异。

    2. 方案:确认全部随机种子;HCCL 开启高精度归约;观测优化器 moment 张量 dump 比对。

  4. loss 与 PPL 看起来合格,但下游 MMLU 指标偏低

    1. 原因:训推不一致,训练与推理 tokenizer、special token、RoPE 实现逻辑不一致,属于隐性精度。

    2. 方案:统一训练推理预处理模板;核对 bos/eos/pad token id,对齐开源标杆实现。

  5. 多卡不同 rank loss 不一致

    1. 原因:dataloader 数据分发不一致、HCCL 通信异常、并行切分配置错误。

    2. 方案:固定 dataloader 种子;检查 HCCL 日志,确认集合通信执行正常。

八、总结

昇腾大模型训练精度评估是一套分层验证体系,不能仅依靠 loss 打印判断训练是否合格。从单 step 张量数值比对、loss 收敛、困惑度 PPL、下游数据集评测逐层递进,借助 msprobe、msit llm compare、MindStudio 精度分析工具,定位算子、混合精度、随机种子、多卡通信带来的各类精度风险。

实际开发建议:迁移大模型训练任务,第一步完成单 step 对齐验证;再做多轮训练观测 loss 与 PPL;最后执行 MMLU/C‑Eval 等真实业务评测。区分硬件固有微小浮点误差和异常累积偏差,保障昇腾 NPU 上大模型预训练、SFT、RLHF 训练效果无损。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐