logits采集比对
简介
当选取了合适的BadCase后,则需要采集其推理过程的中间数据,用于定位引入精度问题的具体token。
在定位精度问题时,通常采用“自下而上”的分层比对方法,从模型每个token最后一层输出的logits开始比对,找到首个与标杆数据比对精度不达标的输出token。
例如,模型A在外部设备上使用PyTorch框架进行推理,在昇腾设备上使用MindIE的加速库(ATB)框架进行推理,首先要分别采集模型A在外部设备和昇腾设备上推理的logits结果,然后比对两份logits结果,找到引入精度问题的具体token。
logits采集
- 使用msit llm dump工具采集标杆模型logits。通过在Pytorch执行脚本中加入dump的逻辑代码实现标杆模型logits的采集,参数解释请参见PyTorch 场景的精度数据采集。
- 在模型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(): # 推理流程代码
其中,启动确定性计算是为了保证结果的可重现性,规避随机带来的误差。
- 脚本执行完成后,标杆模型的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
- (可选)建议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所示,表明已正确开启确定性计算。
- 在模型A推理脚本中增加dump相关的配置代码,示例如下:
- 使用msit llm dump采集ATB模型logits。msit支持通过命令方式对ATB模型的数据进行dump,参数解释参考请参见加速库模型数据 dump。
- 执行以下命令,获取模型网络结构信息,首次dump时需获取模型网络结构信息。
msit llm dump --exec "bash run.sh" --type layer -seed 2345
- 执行完成后,默认落盘在当前执行文件夹下,落盘数据目录结构如下。
{ATB_DUMP_DIR1}/ # 数据保存路径 ├── msit_dump_{TIMESTAMP}/ # 数据落盘时间戳目录 └── layer/ # 网络结构子目录 ├── {PID}/ # 进程号 ├── {LayerName}.json
打开模型A的PID文件夹,文件内容如图2所示。
如果使用MindIE 1.0.RC1及之后版本,ATB模型由Prefill模型和Decoder模型组成,因此ATB的logits需要分别采集Prefill的logits和Decoder的logits。例如,模型A总共有68层,其中Prefill模型输出的最后一层为LmHead_33,Decoder模型输出的最后一层为LmHead_67,因此需要采集33和67层的logits。
- 二次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
- 采集完成后,落盘数据格式如下。
{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目录
- 执行以下命令,获取模型网络结构信息,首次dump时需获取模型网络结构信息。
logits比对
- 通过msit llm compare工具比对标杆模型logits与ATB模型的logits。
- 比对完成后,会生成比对结果msit_cmp_report_{TIMESTAMP}.csv文件,文件保存在比对结果保存路径下,指标结果请参见精度比对结果参数说明。
由于不同业务场景对精度的要求并不一致,通常情况下,重点指标可以参考如下要求:
- KL散度:bfloat16<0.005,float16<0.0001
- 余弦相似度: >0.999
- 分析比对结果。根据精度标准,可能出现两种情况:
- 所有logits都满足当前场景的精度要求,则表明是“后处理”的输出异常,此时可以对temperature、topK、topP等“后处理”参数进行复检,或者对“后处理”的代码实现进行调试,从而定位具体原因。
- logits中存在不满足精度标准的结果,从比较结果中找到首个精度不达标的token,进行整网精度比对。
模型A的精度比对结果示例如图3所示,发现第三个Token的logits存在精度劣化问题,cosine_similarity=0.975758,KL散度=19.457,那么将对token 3进行整网精度比对,进一步定位问题。
父主题: 采用msit工具定位