行业模型选型

目录

行业模型选型

一、开源模型选型

二、PyTorch模型迁移分析

三、迁移适配

四、精度调试

五、性能调优及算子开发

1. 性能指标

2. 通用优化方法

3. 算子开发


一、开源模型选型

(1) 模型迁移

模型迁移:将原本设计用于GPU其他三方平台的深度学习模型训练代码,经过模型代码修改等适配操作,来适应NPU的架构和编程,让模型能在NPU上进行高性能运行

为什么要做模型迁移 -> 在将模型从其他三方平台迁移到NPU时,由于硬件架构的不同,涉及到一系列底层到上层的适配操作。以GPU为例,模型迁移至NPU需要适配的原因可分为三方面:

硬件特性性能特点差异:由于NPU和GPU的硬件特性和性能特点不同,模型在NPU上可能需要进一步的性能调试和优化,以充分发挥NPU的潜力

②计算架构差异:CUDA(Compute Unified Device Architecture) + CuDNN是NVIDIA GPU的并行计算框架,而CANN(Compute Architecture for Neural Networks)是华为NPU的异构计算架构

③深度学习框架差异为了支持NPU硬件,需要对PyTorch框架进行适配:包括适配张量运算自动微分等功能,以便在NPU上高效执行

(2) 迁移总体思路

通用模型迁移适配方法,可以分为四个阶段:迁移分析迁移适配精度调试性能调优

(3) 需求引入

需求:将开源LLM部署在服务器中,进行微调及推理应用

①框架:PyTorch
②资源:昇腾硬件
③功能:多轮问答
④性能:低延迟(>=50Token/s)

(4) 分析

模型选型:模型智能水平,模型技能情况,模型性能、部署成本与企业数据主权边界,模型领域任务适应性与适配成本

通常来说参数越多的模型,综合能力越强,但在特定任务上,参数较少的模型表现可能超过参数量更大的模型,并非总是要用技能最强的模型,要综合考虑性价比

(5) 性能指标

在计算性能指标中,优先级排序为:吞吐率 > 单步迭代时间 > 线性度 > 内存占用 > 带宽占用 > 训练效率 > 浮点计算次数每秒 > 算力利用率

对于大模型推理,需要额外考虑两点,即大模型首次推理的耗时更长,且推理时延和输入/输出的文字长度相关多Batch推理并行推理场景下,大模型推理的吞吐率有差异

(6) 评测指标

大语言模型与传统自然语言处理算法不同,模型评测需要从多个维度出发

一些常见的评估指标:ROUGE、GLUE基准、TruthfulQA、MMLU、HellaSwag

(7) 模型选择

Decoder-only:适用于文本生成,对话机器人等 -> GPT、LLaMA
Encoder-only:适用于文本表示,文本的分类、实体识别、关键信息抽取等 -> Bert、GLM
Encoder-Decoder:适合做翻译、对话等需要根据给定输入来生成输出的任务 -> T5

选择:Decoder-only架构更适合用于多轮问答任务

(8) Ascend模型库

昇腾AI处理器适配了大量的业界主流开源模型,涵盖计算机视觉、自然语言处理、语音、推荐、多模态、大语言模型等方向

大语言模型(Large Language Model),包括GLM系列、LLaMA系列以及GPT系列等
图文多模态(Multimodal),包括扩散模型相关模型、CLIP、VisualGLM等
计算机视觉(ComputerVision),包括ViT、MAE、SwinTransformer等

(9) 模型使用流程

①环境准备:
准备适用于NPU的环境。包括安装和配置CANNPyTorch,以及确保硬件与软件的兼容性

②PyTorch大模型训练适配:
将原本设计用于GPU的深度学习模型训练代码转移到NPU上
可以将代码迁移到专门为NPU优化的Ascendspeed框架(大模型并行优化加速)中,以获得更好的性能和效率

③精度调试:
模型迁移完成后进行精度测试,确保在NPU上的训练结果与GPU上一致
主要思路:先解决单机训练的精度问题,再解决多机通信造成的精度问题

④性能调优:
在NPU上,可以通过优化算子计算性能、通信性能、内存、调度性能、模型算法等,满足不同场景的需求

二、PyTorch模型迁移分析

(1) 迁移分析

进行模型迁移之前,需要做以下准备与分析工作:
①选取合适的模型,在三方平台(GPU)运行成功,并获取精度/性能基线
②在昇腾设备上搭建环境,并使用迁移分析工具分析模型在腾设备上的支持度

(2) 迁移分析工具

在执行迁移操作前,需借助msFmkTransplt工具,分析基于其他平台(如GPU)的PyTorch训练脚本中算子三方库套件亲和API分析以及动态shape在昇腾AI处理器上的支持情况,分析内容主要包括:

①算子支持情况分析:用户提供待分析的PyTorch训练脚本,可快速获得该训练脚本中不支持torch APIcuda API信息,并输出训练脚本中API精度和性能调优的专家建议

②三方库套件分析:用户提供待分析的三方库套件源码,可快速获得源码中不支持三方库APIcuda信息

③动态shape分析:用户提供待分析的PyTorch训练脚本,可快速获得该训练脚本中包含的动态shape信息

④亲和API分析:用户提供待分析的PyTorch训练脚本,可快速获得该训练脚本中可替换亲和API信息

三、迁移适配

(1) 迁移适配流程

迁移适配流程总体可分为模型脚本迁移模型训练适配两部分:

①模型脚本迁移(改代码):推荐使用自动迁移,通过导入一键迁移库的形式,三方平台上的代码映射为异腾设备代码

②模型训练适配:必须的适配包括环境变量配置,启动脚本配置;对于关键特性适配,用户需要查看特性是否适用于当前训练场景与设备,根据具体情况选择是否适配

(2) 模型脚本迁移

目前支持3种迁移方式:自动迁移(推荐)、工具迁移、手工迁移

自动迁移:在训练脚本中导入脚本转换库,然后拉起脚本执行训练。训练脚本在运行时,会自动将脚本中的CUDA接口替换为昇腾AI处理器支持的NPU接口。整体过程为边训练边转换

工具迁移:使用迁移工具(pytorch_gpu2npuPyTorch GPU2Ascend),自动将训练脚本中的CUDA接口替换为昇腾AI处理器支持的NPU接口,并生成迁移报告(脚本转换日志、不支持算子的列表、脚本修改记录)。训练时,运行转换后的脚本。整体过程为先转换脚本再进行训练

手工迁移:通过分析模型,对比GPU与NPU接口,手动对训练脚本进行修改,以支持在昇腾AI处理器上执行训练。迁移要点如下
①定义NPU为训练设备,将训练脚本中适配GPU的接口切换至适配NPU的接口
②多卡迁移需修改芯片间通信方式为昇腾支持的HCCL

(3) 模型训练适配

在昇腾设备上运行PyTorch模型代码时,需要进行的适配操作

必须的操作包括:
环境变量配置
启动脚本配置
③对于关键特性适配,用户需要查看特性是否适用于当前训练场景与设备,根据具体情况选择是否适配

(4) 模型保存与导出

模型训练完成后,用户可以通过PyTorch提供的接口保存模型文件(pth文件pth.tar文件)用于在线推理;或将模型导出ONNX模型,然后通过ATC工具将其转换为适配腾AI处理器的.om文件用于离线推理

四、精度调试

(1) 精度调试流程

训练本身受数据集、模型结构、并行策略、超参等影响,模型训练过程中可能出现NaN溢出Loss发散等情况,这时需要对模型进行精度调试

在昇腾处理器上训练模型时,一般而言Loss总体呈现下降收敛趋势,即使出现偶尔的尖刺现象也可以通过跳过数据集断点续训等方式规避,最终利用训练后的权重、采用常规数据集评估模型分数符合社区实践评分预期,即可视为完成精度调试

(2) 影响因素 - 数据集

数据是增强大模型能力的决定性因素之一

数据异常触发的训练不稳定:引起训练异常的语料包括字节码、unicode乱码、纯数字文本等。这些语料会无报警地被主流的subword tokenizer分割成token,并转成id序列正常进入训练迭代步骤,但由于这些语料本身没有任何语法语义规律,根据它们来更新参数可能会污染模型。当异常语料数量显著时,甚至会使得模型进入死胡同不能正常收敛

语料混合比例与类型的重要性:不同语言不同语料类型(代码、文本)的混合比例和语料规模对大模型训练精度也有重要影响。需要调节不同来源的语料的混合比例,不能直接使用原始语料合并训练。均衡的语料比例有助于提高模型的泛化能力,特定类型的语料可以提升模型特定的能力

数据规模与模型参数规模的匹配:参数规模也不是越大越好,Hoffmann等人在Chinchilla系列模型中的研究表明,给定算力、语料的token数与模型的参数个数相当时,模型的表现相对更好。不能一味地追求大语料,控制规模、提高质量、训练充分,也很重要

(3) 影响因素 - 超参数配置

超参数对大模型训练收敛有关键性影响:

优化器与学习率:优化器的选择直接影响到模型训练过程中的更新策略,而学习率作为核心超参数之一,若设置不当可能导致训练过程中出现诸如全局梯度范数(GNorm)突变Loss曲线无法收敛上升其至剧烈波动等问题

梯度裁剪阈值:梯度裁剪在后传播过程中能够降低某些张量的梯度值,阻止了梯度爆炸并且使得训练过程更加稳定。裁剪范围值可以通过试验配置,也可以使用文献中的常用值,也可以通过实验观察范围然后选择一个合理值。网络中的所有层通常都使用相同的梯度裁剪配置,一般来说输出层相比隐藏层允许更大范围的梯度

Loss Scale动态调整:在训练期间,Loss Scale作为一个动态调节的超参数,其大小变化同样反映着训练的稳定性状态。若Loss Scale长期低于1,这意味着有一些梯度值大到很容易上溢,同时存在的那些小梯度值会下溢为0,这些情况都使得训练将持续处于不稳定状态

Batch尺寸的影响:Batch尺寸是另一个显著影响训练效果的超参数,它在满足内存需求与提升训练效率间寻求平衡。在大规模模型的分布式训练场景中,用户倾向于选择较大的Batch尺寸以缩短训练时长,然而过大的Batch尺寸也可能导致Loss曲线呈现上升趋势。因此,在调整Batch尺寸时,需综合考虑其对训练效率收敛性的影响,实现最优配置

(4) 影响因素 - 计算精度

浮点数计算:浮点数计算的精度问题根源于计算机中使用特定格式的二进制数表示实数,而二进制只能表示有限数目的离散实数,对于某些十进制小数,只能近似表示。因此选择合适的浮点数精度对于优化模型训练过程至关重要

(5) 影响因素 - 张量分布式并行计算

线性层张量并行

Transformer中会将输入向量通过线性层转成QKV矩阵。线性层是一个h*h权重矩阵,如果h是一万,那么此权重矩阵规模也是亿级。线性层权重矩阵有两种切分方式,行切分列切分

(6) 精度调优方法 - 数据集清洗

在构建高质量机器学习模型的过程中,数据集清洗是一项至关重要的前期任务,旨在提升模型训练效果,防止过拟合生成内容的冗余

非目标语言与低质量样本剔除:剔除非目标任务语言、丟弃低perplexity数据、删去标点/符号过多或过长过短的句子、删除具有某些特定词汇(如html标签、链接、脏话、敏感词)的句子

去重:删除包含大量重复词汇或短语的句子;删除重复率(词/n-grams共现)过高的段落;删除训练集中可能与测试集相关度过高的内容。这样可以提高训练集质量,缓解语言模型生成内容重复的问题,避免测试集泄露带来的过拟合问题

当遇到Loss或者perplexity尖刺,如果确定是数据批次引起的问题,可以跳过尖刺期间看到的一些数据批次,从以前正常的检查点重新开始训练

(7) 精度调优方法 - 超参配置调优

Batch Size配置:在模型训练过程中,Batch Size的设定通常较大,旨在充分利用大规模训练数据,增强模型训练过程的稳定性。例如,设置Batch Size为8196,可使每个批次处理大约1.6M个token输入。GPT-3使用动态调整Batch Size的方式,使其处理的Token数从32K逐渐增大到3.2M

学习率:学习率一般较小,且包含warm up设置,以确保训练平稳。比如在前0.1%~0.5%的训练步骤中,设置一个线性的学习率递增。峰值学习率一般在10^-4以下,比如GPT-3的学习率是6×10^-5。之后,会采用cosine衰减或者线性衰减学习率调度策略,逐渐减小学习率,在收敛前将学习率下降到峰值学习率的10%左右

优化器:优化器一般采用Adam、AdamW以及Adafactor。其中,Adafactor是Adam的一个节约显存的变体。也有使用SGD作为优化器的例子,但并不常见

权重初始化:正确初始化权重可以帮助模型更快低收敛并提高性能。例如,通常使用小的高斯噪声或者使用T-fixup初始化

其他稳定训练技术
①梯度裁剪(Gradient Clipping):作为一种常用的稳定训练手段,通常设定裁剪阈值为1.0,防止梯度过大引发训练不稳定
②Weight Decay(L2正则化):设置合理的权重衰减率,如0.1,有助于防止过拟合,增强模型泛化能力
③特殊层的调整:GLM研究发现,embedding层往往存在较大的梯度异常情况,故需根据实际情况适度调整相关参数

五、性能调优及算子开发

1. 性能指标

(1) 性能调优流程

性能指机器(GPU、NPU或其他平台)在指定模型和输入数据的背景下,完成一次端到端训练所需要花费的时间。考虑到不同模型的训练数据量训练轮次(epoch)差异,此处定义的性能是在完成一个batch训练所需花费的时间

对于一个batch而言,时间主要由以下部分构成:
单batch总时间 = 数据加载时间 + 模型前反向时间 + 优化器时间 + 模型后处理时间 + 通信时间 + 调度时间

2. 通用优化方法

(1) 并行策略通用建议

并行策略的调试与设计需要对具体模型进行详细分析,没有一个通用的万能法则可以适用于所有情况,但可以根据经验总结出一些相对通用的建议:

①在面临显存不足模型过大无法完全加载以及需要进行切分的情况下,优先考虑使用TP(Tensor Parallelism)进行切分,并确保切分的数量小于等于机器内的计算卡数

②如果在TP切分达到最大显存容量仍然不足的情况下,可以考虑在机器之间使用PP(Pipeline Parallelism)进行切分

③在机器资源富裕的情况下,可以开启DP(Data Parallelism)并行,将计算任务分配给多个机器进行并行处理,从而提高处理效率

④即使在模型能够成功运行的情况下,也可以尝试主动地使用降低内存占用的手段,例如ZeRO1和重计算等,然后增大Batch Size

(2) NPU亲和适配优化策略

当前多数模型代码普遍基于GPU实现,NPU和GPU在计算原理底层架构上存在非常大的区别,因此,有些时候我们需要进行模型层面的修改,亲和适配NPU,达到最优的性能。性能优化遵循以下大的逻辑:

消除多余的stream同步:部分开源代码缺少性能考虑,存在很多的stream同步操作,这些同步通常是由h2d(host to device,从CPU侧下发到NPU侧)、d2h(device to host,从NPU侧搬回到CPU侧)操作(如tensor.item、reduce_all、torch.isfinite等)引入的,原则上,我们需要尽可能减少这些异步流同步的操作,让模型通过异步流实现最佳的并行效率

②有时候因为下发或通信等问题,可能导致多卡训练时,卡与卡之间性能不一致,此时由于反向计算后需要对多卡之间的梯度进行同步,产生快卡等慢卡的情况

③部分CPU上运行的优化方法:部分模型仅用单核实现,性能不够理想。此时,可以将计算部分放到NPU上,或者在CPU上,通过多进程的方式进行加速

(3) 融合优化器

大模型训练过程中,优化器会频繁进行h2d(host to device)的操作,以完成对模型参数的更新,造成性能瓶颈。而这些操作的底层逻辑是相同的,只是作用的数据不同,因此,统一在Host侧完成操作再统一下发到Device上,能够显著减少h2d的操作,提高性能

不过,需要注意的是,因为融合后的统一下发会要求更大的内存空间,无法利用Device上的小块内存,因此融合优化器可能会占用更多的内存

昇腾官网中给出的优化器做了昇腾AI处理器亲和性优化,使性能提升

(4) 内存与性能的联系

PyTorch在内存上基于eager模式实现,eager模式的特点是如果没有必要,不会主动释放已经申请的内存,同时,PyTorch默认模式下是整块申请内存,因此,很容易出现碎片化的内存,而当模型当前内存不足够时,会触发内存重整操作,即将碎片化内存(包括之前申请但并未被表示的内存块)整理,得到大块连续内存

如果重整得到的内存能够满足模型训练需要,那么训练就会进行下去,但是这种内存重整操作需要花费大量时间,频繁触发内存重整操作会对模型性能产生很大影响

(5) HCCL

HCCL(Huawei Collective Communication Library,华为集合通信库)是基于昇腾Al处理器的高性能集合通信库,提供单机多卡、多机多卡集合通信原语,在PCIE、HCCS和RoCE高速链路实现集合通信功能,实现分布式训练

3. 算子开发

(1) 算子开发

模型是否可以迁移成功主要取决于模型算子是否支持训练设备,当有不支持算子时,可修改模型脚本用等价支持的算子替换不支持算子,或者新开发算子

①网络训练脚本迁移到昇腾AI处理器时遇到了不支持的算子,如选择LLaMA系列中最新版本的LLaMA3,可能会有算子无法运行
②为优化模型结构而设计的新的PyTorch算子,Ascend暂没有适配
③网络调优时,发现某算子性能较低,影响网络性能,需要重新开发一个高性能算子替换性能较低的算子

(2) 算子开发工具

Ascend C,面向算子开发场景的编程语言,原生支持C和C++标准规范,最大化匹配用户开发习惯;通过多层接口抽象、自动并行计算、孪生调试等关键技术,极大提高算子开发效率,助力AI开发者低成本完成算子开发和模型调优部署

TBE,提供了基于TVM(Tensor Virtual Machine)框架的自定义算子开发能力,通过TBE提供的API可以完成相应神经网络算子的开发

(3) Ascend C

使用Ascend C进行自定义算子开发的突出优势有:

①C/C++原语编程
②编程模型屏蔽硬件差异,编程范式提高开发效率
③多层级API封装,从简单到灵活,兼顾易用与高效
④孪生调试,CPU侧模拟NPU侧的行为,可优先在CPU侧调试

(4) Ascend C编程技术特性

(5) 开发Ascend C算子的基本流程

主要分析算子的数学表达式、输入、输出以及计算逻辑的实现,明确需要调用的Ascend C接口

完成环境准备和初步的算子分析后,即可开始Ascend C核函数的开发

完成了kernel侧(NPU)核函数开发后,即可编写host侧(CPU)的核函数调用程序,实现从host侧的APP程序调用算子,执行计算过程

算子分析 -> 核函数开发 -> CPU运行验证 -> NPU运行验证

(6) Ascend C编写API

Ascend C算子采用标准C++语法和一组类库API进行编程

Ascend C API的计算操作数都是Tensor类型:GlobalTensorLocalTensor

类库API的分类:
①高阶API:提供Matmul、SoftMax等高阶API
②基础API:提供基础功能API。包括向量矩阵计算、数据搬运、内存管理和任务同步

(7) 流水编程范式

Ascend C编程范式是一种流水线式的编程范式,把算子核内的处理程序,分成多个流水任务,通过队列(Queue)完成任务间通信和同步,并通过统一的内存管理模块(Pipe)管理任务间通信内存

(8) Ascend C整体开发流程

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐