昇腾社区首页
中文
注册

logits采集比对

简介

当选取了合适的BadCase后,则需要采集其推理过程的中间数据,用于定位引入精度问题的具体token。

在定位精度问题时,通常采用“自下而上”的分层比对方法,从模型每个token最后一层输出的logits开始比对,找到首个与标杆数据比对精度不达标的输出token。

例如,模型A在外部设备上使用PyTorch框架进行推理,在昇腾设备上使用MindIE的加速库(ATB)框架进行推理,首先要分别采集模型A在外部设备和昇腾设备上推理的logits结果,然后比对两份logits结果,找到引入精度问题的具体token。

logits采集

  1. 使用msit llm dump工具采集标杆模型logits。通过在PyTorch执行脚本中加入dump的逻辑代码实现标杆模型logits的采集,参数解释请参见PyTorch场景的精度数据采集
    1. 在模型A推理脚本中增加dump相关的配置代码,示例如下:
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      import torch
      from msit_llm import DumpConfig, register_hook
      from transformers import AutoTokenizer, AutoModelForCausalLM
      
      # 在推理模型完成初始化之前,固定随机种子,启动确定性计算
      from msit_llm import seed_all
      seed_all(seed=2345)
      
      # 配置dump参数,其中:
      # dump_last_logits=True 表示只采集模型最后一个layer的输出,即输出Token的logits,
      # token_range=list(range(1000)) 表示前1000个Token的logits,不足1000则采集模型输出的所有输出Token的logits
      # dump_path="/data/atb_dump_path",为dump数据保存路径,请根据实际情况替换
      
      dump_config = DumpConfig(dump_last_logits=True, token_range=list(range(1000)), dump_path="/data/atb_dump_path")
      
      # 推理模型初始化 
      model_weight_path="/data/model_path"  # model_weight_path为模型A权重路径,请根据实际情况替换
      tokenizer = AutoTokenizer.from_pretrained(model_weight_path)
      model = AutoModelForCausalLM.from_pretrained(model_weight_path).cuda()
      register_hook(model, dump_config)  # model是要dump中间tensor的模型实例,在模型初始化后添加代码
      
      with torch.no_grad():
          # 推理流程代码
      

      其中,启动确定性计算是为了保证结果的可重现性,规避随机带来的误差。

    2. 脚本执行完成后,标杆模型的logits将保存到dump_path指定目录下,数据目录结构如下所示。
      {GOLDEN_DUMP_DIR}/                         # 数据保存路径
      ├── msit_dump_{TIMESTAMP}/                 # 数据落盘时间戳目录
          └── torch_tensors/                     # tensor子目录
              ├── cuda{device_id}_{PID}/         # 设备ID_进程号子目录
                  ├── model_tree.json            # 模型拓扑结构文件
                  ├── {TID}                      # Token ID
                      ├── {LayerName}            # 网络层名称
                          ├── output.pth         # 输出Tensor
    3. (可选)建议dump两次logits数据,并执行以下命令,比对两次dump相同Token的logits(此处比对token 0,即文件夹0下的output.pth数据)。
      msit llm compare -gp {DUMP_DIR1}/0/{logits_Layer_Name}/output.pth -mp  {DUMP_DIR2}/0/{logits_Layer_Name}/output.pth

      两次dump对应相同Token的logits所有精度指标如图1所示,表明已正确开启确定性计算。

      图1 精度指标
  2. 使用msit llm dump采集ATB模型logits。msit支持通过命令方式对ATB模型的数据进行dump,参数解释参考请参见加速库模型数据 dump
    1. 执行以下命令,获取模型网络结构信息,首次dump时需获取模型网络结构信息。
      msit llm dump --exec "bash run.sh" --type layer -seed 2345
    2. 执行完成后,默认落盘在当前执行文件夹下,落盘数据目录结构如下。
      {ATB_DUMP_DIR1}/                           # 数据保存路径
      ├── msit_dump_{TIMESTAMP}/                 # 数据落盘时间戳目录
          └── layer/                             # 网络结构子目录
              ├── {PID}/                         # 进程号
                  ├── {LayerName}.json

      打开模型A的PID文件夹,文件内容如图2所示。

      图2 PID文件夹文件列表

      如果使用MindIE 1.0.RC1及之后版本,ATB模型由Prefill模型和Decoder模型组成,因此ATB的logits需要分别采集Prefill的logits和Decoder的logits。例如,模型A总共有68层,其中Prefill模型输出的最后一层为LmHead_33,Decoder模型输出的最后一层为LmHead_67,因此需要采集33和67层的logits。

    3. 二次dump时,采集模型A最后一层输出,指定-ids 33,67。
      msit llm dump --exec "bash run.sh" --type model tensor -ids 33,67 -er 0,1000 -child False -stp 1 -seed 2345
    4. 采集完成后,落盘数据格式如下。
      {ATB_DUMP_DIR2}/                               # 数据保存路径
      ├── msit_dump_{TIMESTAMP}/                     # 数据落盘时间戳目录
          └── layer/                                 # 网络结构子目录
          └── model/                                 # 模型信息目录
              ├── {PID}                              # 进程号子目录
                  ├── {model_name}_Prefill.json      # 模型Prefill层信息
                  ├── {model_name}_Decoder.json      # 模型Decoder层信息
          └── tensors/                               # tensor子目录
              ├── {device_id}_{PID}/                 # 设备ID_进程号子目录
                  ├── {TID}                          # Token ID
                      ├── {LayerName}                # 网络层名称
                          ├── after                  # 网络层输出tensor目录
                              ├── outtensor0.bin     # 输出tensor
                          ├── before                 # 网络层输入tensor目录

logits比对

  1. 通过msit llm compare工具比对标杆模型logits与ATB模型的logits。

    在采集完标杆模型和ATB模型的logits数据后,即可通过msit llm compare工具实现logits的自动比对,参数解释请参见大模型精度比对

    比对命令示例如下,其中COMPARE_PATH是比对结果保存路径。

    msit llm compare -gp {GOLDEN_DUMP_DIR}/msit_dump_{TIMESTAMP}/torch_tensors/cuda{device_id}_{PID}/ -mp {ATB_DUMP_DIR}/msit_dump_{TIMESTAMP}/tensors/{device_id}_{PID}  -o {COMPARE_PATH}
  2. 比对完成后,会生成比对结果msit_cmp_report_{TIMESTAMP}.csv文件,文件保存在比对结果保存路径下,指标结果请参见精度比对结果参数说明

    由于不同业务场景对精度的要求并不一致,通常情况下,重点指标可以参考如下要求:

    • KL散度:bfloat16<0.005,float16<0.0001
    • 余弦相似度: >0.999
  3. 分析比对结果。
    根据精度标准,可能出现两种情况:
    1. 所有logits都满足当前场景的精度要求,则表明是“后处理”的输出异常,此时可以对temperature、topK、topP等“后处理”参数进行复检,或者对“后处理”的代码实现进行调试,从而定位具体原因。
    2. logits中存在不满足精度标准的结果,从比较结果中找到首个精度不达标的token,进行整网精度比对。

    模型A的精度比对结果示例如图3所示,发现第三个Token的logits存在精度劣化问题,cosine_similarity=0.975758,KL散度=19.457,那么将对token 3进行整网精度比对,进一步定位问题。

    图3 模型A精度比对结果