Apex Patch以代码patch的形式发布,用户通过对原始Apex进行patch,可以在华为昇腾AI处理器上,使用Apex的自动混合精度训练功能进行模型训练,提升AI模型的训练效率,同时保持模型的精度和稳定性。此外,Apex-patch额外提供了如梯度融合、融合优化器等,以提升部分场景下模型在昇腾NPU上的训练效率,供用户选择使用。
在安装Apex Patch之前,请参考Apex-patch配套软件,安装最新昇腾软件栈。
推荐使用docker,在容器内编译:参考链接
建议用户以非root用户做环境的安装。若使用容器环境编译,建议使用普通用户,本仓库提供的Dockerfile仅供参考。请用户关注容器挂载目录安全性,避免系统路径,推荐只挂载业务路径,避免不必要的安全问题。
git clone -b master https://gitee.com/ascend/apex.git
cd apex/
1、请确保torch已安装,setuptools版本小于等于65.7.0。推荐使用65.7.0,若安装其它版本请用户自行确保对应版本无重大漏洞。
2、执行(支持python3.7-3.10,确保python3.x命令存在)
bash scripts/build.sh --python=3.7
过程中会自动拉取apex官方源码,请保证网络畅通,生成的二进制包在apex/dist目录下。
进入apex/dist目录,执行以下命令:
cd apex/dist/
pip3 uninstall apex
pip3 install --upgrade apex-0.1+ascend-{version}.whl # version为python版本和cpu架构
如需要保存安装日志,可在pip3 install命令后面加上参数 --log <PATH>
,并对您指定的目录<PATH>
做好权限管控。
Pytorch框架训练环境的卸载可以参考昇腾官方文档。
Apex及Apex-patch的卸载只需执行命令:
pip3 uninstall apex
如需要保存卸载日志,可在pip3 install命令后面加上参数 --log <PATH>
,并对您指定的目录<PATH>
做好权限管控。
导入apex包,使用apex.amp.initialize方法包装模型和优化器并指定opt_level为'O1',并使用apex.amp.scale_loss方法包装损失值和优化器对损失进行动态缩放,实现混合精度训练:
import torch
+ import apex # 导入apex包
epoch = 10 # 训练轮次
loss_function = torch.nn.MSELoss() # 损失函数
input_data = [torch.rand(16, device='npu') for i in range(10)] # 构造简易模型输入
dataset = [(data, 0.5 * torch.sum(data).unsqueeze(0)) for data in input_data] # 构造简易数据集
model = torch.nn.Linear(in_features=16, out_features=1, device='npu') # 构造简易模型
optimizer = torch.optim.SGD(params=model.parameters(), lr=1e-3) # 创建优化器
+ # 使用apex.amp.initialize方法包装模型和优化器进行混合精度训练,opt_level取'O0'时,表示使用FP32训练,opt_level取'O1'或'O2'时,表示使用混合精度训练
+ model, optimizer = apex.amp.initialize(models=model, optimizers=optimizer, opt_level='O1')
for i in range(epoch):
for x, target in dataset:
optimizer.zero_grad()
output = model(x)
loss = loss_function(output, target)
- loss.backward()
+ # 使用apex.amp.scale_loss方法包装损失值和优化器进行动态损失缩放
+ with apex.amp.scale_loss(loss, optimizer) as scaled_loss:
+ scaled_loss.backward()
optimizer.step()
详细使用方式请请参考Apex官方文档。
导入apex包,使用apex.amp.initialize方法包装模型和优化器并将参数combine_grad设置为True,示例如下:
import torch
+ import apex # 导入apex包
epoch = 10 # 训练轮次
loss_function = torch.nn.MSELoss() # 损失函数
input_data = [torch.rand(16, device='npu') for i in range(10)] # 构造简易模型输入
dataset = [(data, 0.5 * torch.sum(data).unsqueeze(0)) for data in input_data] # 构造简易数据集
model = torch.nn.Linear(in_features=16, out_features=1, device='npu') # 构造简易模型
optimizer = torch.optim.SGD(params=model.parameters(), lr=1e-3) # 创建优化器
+ # 使用apex.amp.initialize方法包装模型和优化器进行混合精度训练,opt_level='O1'表示使用混合精度训练,combine_grad=True表示开启融合梯度
+ model, optimizer = apex.amp.initialize(models=model, optimizers=optimizer, opt_level='O1', combine_grad=True)
for i in range(epoch):
for x, target in dataset:
optimizer.zero_grad()
output = model(x)
loss = loss_function(output, target)
- loss.backward()
+ # 使用apex.amp.scale_loss方法包装损失值和优化器进行动态损失缩放
+ with apex.amp.scale_loss(loss, optimizer) as scaled_loss:
+ scaled_loss.backward()
optimizer.step()
导入apex包,使用apex.amp.initialize方法包装模型和优化器并将参数combine_grad设置为True,并将torch原生优化器torch.optim.xxx替换为apex.optimizers.xxx, 其中xxx为融合优化器名称,示例如下所示,apex-patch支持的优化器见特性介绍。
import torch
+ import apex # 导入apex包
epoch = 10 # 训练轮次
loss_function = torch.nn.MSELoss() # 损失函数
input_data = [torch.rand(16, device='npu') for i in range(10)] # 构造简易模型输入
dataset = [(data, 0.5 * torch.sum(data).unsqueeze(0)) for data in input_data] # 构造简易数据集
model = torch.nn.Linear(in_features=16, out_features=1, device='npu') # 构造简易模型
- optimizer = torch.optim.SGD(params=model.parameters(), lr=1e-3) # 创建优化器
+ # 使用apex.optimizers.NpuFusedSGD替换torch.optim.SGD
+ optimizer = apex.optimizers.NpuFusedSGD(model.parameters(), lr=1e-3)
+ # 使用apex.amp.initialize方法包装模型和优化器进行混合精度训练,opt_level='O1'表示使用混合精度训练,combine_grad=True表示开启融合梯度
+ model, optimizer = apex.amp.initialize(models=model, optimizers=optimizer, opt_level='O1', combine_grad=True)
for i in range(epoch):
for x, target in dataset:
optimizer.zero_grad()
output = model(x)
loss = loss_function(output, target)
- loss.backward()
+ # 使用apex.amp.scale_loss方法包装损失值和优化器进行动态损失缩放
+ with apex.amp.scale_loss(loss, optimizer) as scaled_loss:
+ scaled_loss.backward()
optimizer.step()
Apex-patch已适配特性如下:
原生API及参数说明请参考Apex官方文档, Apex-patch新增特性说明如下:
apex.amp.initialize(models, optimizers=None, enabled=True, opt_level="O1", cast_model_type=None, patch_torch_functions=None, keep_batchnorm_fp32=None, master_weights=None, loss_scale=None, cast_model_outputs=None, num_losses=1, verbosity=1, dynamic_init_scale=2.**16, scale_growth_factor=2., scale_backoff_factor=0.5, scale_window=2000, min_loss_scale=None, max_loss_scale=2.**24, combine_grad=None, combine_ddp=None, ddp_replica_count=4, user_cast_preferred=None, check_combined_tensors=None)
根据选择的opt_level等配置初始化模型、优化器,也可开启融合梯度优化、融合数据并行优化等。amp.initialize 应在构建完模型和优化器后调用,但应在通过任何 DistributedDataParallel 装饰器装饰模型之前调用。目前,amp.initialize 只应调用一次,尽管它可以处理任意数量的模型和优化器。
启用融合功能(combine_grad/combine_ddp)后,在创建融合张量时会申请融合后张量大小的内存,device内存不足时不建议使用。融合张量内存与原张量共享内存,若更改其一的内存地址,将破坏共享内存机制,可以引起精度异常等问题,使用时须用户自行保证共享内存不被破坏。
model, optim = apex.amp.initialize(model, optim, opt_level="O3", keep_batchnorm_fp32=True, ddp_replica_count=8)
apex.amp.scale_loss(loss, optimizers, loss_id=0, model=None, delay_unscale=False, delay_overflow_check=False)
使用混合精度时对loss进行scale,避免在低精度模式下梯度溢出。
API及参数说明请参考Apex官方文档,Apex-patch中修改了接口内部实现,以保证在NPU上功能正常,在开启融合功能时使用融合张量进行scale/unscale以提升训练效率。
融合优化器算法实现上等价于torch中的优化器实现,在梯度更新阶段利用Tensor融合技术,使用融合的梯度和参数进行更新,以提升部分场景下昇腾训练服务器上模型训练的效率。
启用融合优化器(如apex.optimizers.NpuFusedSGD)后,在创建融合张量时会申请融合后张量大小的内存,device内存不足时不建议使用。融合张量内存与原张量共享内存,若更改其一的内存地址,将破坏共享内存机制,可以引起精度异常等问题,使用时须用户自行保证共享内存不被破坏。
将torch.optim.XXX替换为apex.optimizers.NpuFusedXXX,如:
opt = apex.optimizers.NpuFusedSGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=0.1)
class apex.optimizers.NpuFusedSGD(params, lr=required, momentum=MOMENTUM_MIN, dampening=DAMPENING_DEFAULT, weight_decay=WEIGHT_DECAY_MIN, nesterov=False)
参数说明:
class NpuFusedAdam(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, amsgrad=False)
参数说明:
class NpuFusedAdamW(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=1e-2, amsgrad=False)
参数说明:
class NpuFusedAdamP(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, delta=0.1, wd_ratio=0.1, nesterov=False)
参数说明:
class NpuFusedBertAdam(params, lr=required, warmup=-1, t_total=-1, schedule='warmup_linear', b1=0.9, b2=0.99, e=1e-6, weight_decay=0.01, max_grad_norm=-1)
参数说明:
class NpuFusedAdadelta(params, lr=1.0, rho=0.9, eps=1e-6, weight_decay=0)
参数说明:
class Lamb(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-6, weight_decay=0, adam=False)
参数说明:
class NpuFusedLamb(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-6, weight_decay=0, adam=False, use_global_grad_norm=False)
参数说明:
class NpuFusedRMSprop(params, lr=1e-2, alpha=0.99, eps=1e-8, weight_decay=0, momentum=0, centered=False)
参数说明:
class NpuFusedRMSpropTF(params, lr=1e-2, alpha=0.9, eps=1e-10, weight_decay=0, momentum=0., centered=False, decoupled_decay=False, lr_in_momentum=True)
参数说明:
用户可在运行系统配置时开启ASLR(级别2)以提高系统安全性,保护系统随机化开启。 可参考以下方式进行配置:
echo 2 > /proc/sys/kernel/randomize_va_space
因Apex-patch源码需由用户自行编译,建议用户对编译后生成的SO文件开启strip,又称移除调试符号信息,开启方式可参考以下方式:
strip -s /xxx/python3/lib/site-packages/change_data_ptr.{version}.so # 根据apex实际安装目录替换目录前缀
基于安全性考虑,建议您在执行任何命令时,不建议使用root等管理员类型账户执行,遵循权限最小化原则。
建议用户在主机(包括宿主机)及容器中设置运行系统umask值为0027及以上,保障新增文件夹默认最高权限为750,新增文件默认最高权限为640。
建议用户对个人数据、商业资产、源文件、训练过程中保存的各类文件等敏感内容做好权限管控。涉及场景如apex安装目录权限管控、多用户使用共享数据集权限管控等场景,管控权限可参考表1进行设置。
表1 文件(夹)各场景权限管控推荐最大值
类型 | linux权限参考最大值 |
---|---|
用户主目录 | 750(rwxr-x---) |
程序文件(含脚本文件、库文件等) | 550(r-xr-x---) |
程序文件目录 | 550(r-xr-x---) |
配置文件 | 640(rw-r-----) |
配置文件目录 | 750(rwxr-x---) |
日志文件(记录完毕或者已经归档) | 440(r--r-----) |
日志文件(正在记录) | 640(rw-r-----) |
日志文件目录 | 750(rwxr-x---) |
Debug文件 | 640(rw-r-----) |
Debug文件目录 | 750(rwxr-x---) |
临时文件目录 | 750(rwxr-x---) |
维护升级文件目录 | 770(rwxrwx---) |
业务数据文件 | 640(rw-r-----) |
业务数据文件目录 | 750(rwxr-x---) |
密钥组件、私钥、证书、密文文件目录 | 700(rwx—----) |
密钥组件、私钥、证书、加密密文 | 600(rw-------) |
加解密接口、加解密脚本 | 500(r-x------) |
Apex-patch通过源码发布,需要用户自行编译,在编译时会下载依赖第三方库并执行构建shell脚本,在编译过程中会产生临时程序文件和编译目录。用户可根据需要自行对源代码目录内的文件进行权限管控避免安全风险。管控权限可参考表1进行设置。
建议根据运行环境资源状况编写训练脚本,如模型大小、数据集、混合精度模式等选择不当时,可能导致显存超限等情况,进一步引发错误并退出进程。
运行异常时会退出进程并打印报错信息,建议根据报错提示定位具体原因。
Apex-patch为Apex基于昇腾NPU的适配,接口使用继承官方Apex,可参考Apex官方文档。
新增公开接口参考特性介绍,未展示接口为内部接口,不对外暴露,可能会修改或删除,不建议用户直接使用。
├── Apex
├──patch
├──npu.patch # Apex-patch对于原生Apex的patch文件,用于原生Apex中混合精度等功能基于昇腾AI处理器的适配
├──scripts
├──docker/ # 使用Docker构建安装包的脚本与说明文件
├──build.sh # 构建安装包脚本
├──gen.sh # 使用Apex-patch对官方Apex打patch的脚本
├──make_patch.sh # 生成patch文件脚本
├──src
├──apex
├──contrib/ # 提供Tensor融合的Python API,供融合优化器使用
├──optimizers/ # 融合优化器的实现,部分场景下发挥昇腾的算力
├──csrc/combine_tensors/ # 提供Tensor融合的C++接口
├──tests # 测试用例
├──LICENSE
CANN版本 | PyTorch版本 | Ascend Extension for PyTorch版本 | Python版本 | Apex 版本或代码分支 |
---|---|---|---|---|
8.0.RC3 | 2.1.0 | v2.1.0-6.0.rc3 | Python3.8x,Python3.9x,Python3.10x,Python3.11x | master |
8.0.RC3 | 2.3.1 | v2.3.1-6.0.rc3 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC3 | 2.4.0 | v2.4.0-6.0.rc3 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC2 | 1.11.0 | v1.11.0-6.0.rc2 | Python3.7x(Python3.7.5及以上),Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC2 | 2.1.0 | v2.1.0-6.0.rc2 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC2 | 2.2.0 | v2.2.0-6.0.rc2 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC2 | 2.3.1 | v2.3.1-6.0.rc2 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC1 | 1.11.0 | v1.11.0-6.0.rc1 | Python3.7x(Python3.7.5及以上),Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC1 | 2.1.0 | v2.1.0-6.0.rc1 | Python3.8x,Python3.9x,Python3.10x | master |
8.0.RC1 | 2.2.0 | v2.2.0-6.0.rc1 | Python3.8x,Python3.9x,Python3.10x | master |
7.0.0 | 1.11.0 | v1.11.0-5.0.0 | Python3.7x(Python3.7.5及以上),Python3.8x,Python3.9x,Python3.10x | master |
7.0.0 | 2.0.1 | v2.0.1-5.0.0 | Python3.8x,Python3.9x,Python3.10x | master |
7.0.0 | 2.1.0 | v2.1.0-5.0.0 | Python3.8x,Python3.9x,Python3.10x | master |
昇腾训练设备包含以下型号,都可作为PyTorch模型的训练环境,并使能Apex-patch相关功能
产品系列 | 产品型号 |
---|---|
Atlas 训练系列产品 | Atlas 800 训练服务器(型号:9000) |
Atlas 800 训练服务器(型号:9010) | |
Atlas 900 PoD(型号:9000) | |
Atlas 300T 训练卡(型号:9000) | |
Atlas 300T Pro 训练卡(型号:9000) | |
Atlas A2 训练系列产品 | Atlas 800T A2 训练服务器 |
Atlas 900 A2 PoD 集群基础单元 | |
Atlas 200T A2 Box16 异构子框 | |
Atlas 300T A2 训练卡 |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。