浅谈混合精度训练imagenet 零、序 本文没有任何的原理和解读,只有一些实验的结论,对于想使用混合精度训练的同学可以直接参考结论白嫖,或者直接拿github上的代码(文末放送)。 二、混合精度训练 混合精度训练,以pytorch 1.6版本为基础的话,大致是有3种方案,依次介绍如下: 模型和输入输出直接half,如果有BN,那么BN计算需要转为FP32精度,我上面的问题就是基于此来训练的 四、不同混合精度训练方法对比 实验均在ResNet50和imagenet下面进行的,LR随着BS变换和线性增长,公式如下 实验结果 模型FP16+BNFP32实验记录 模型数据集batchsize(所有卡的总数 Apex混合精度实验记录 模型MODE数据集batchsize(所有卡的总数)优化器LearningRatetop1@accResNet50O1(FP16训练,部分op,layer用FP32计算)ImageNet1k4096SGD O1的精度。
GitHub 仓库地址:https://github.com/yanqiangmiffy/amp-pytorch Pytorch自动混合精度训练模板 使用 pytorch 的自动混合精度教程 {‘建筑物’ -> 0, ‘森林’ -> 1, ‘冰川’ -> 2, ‘山’ -> 3, ‘海’ -> 4, ‘街道’ -> 5 } 数据集解压直接放在data目录下 data: seg_pred Adam + Cosine Learning rate scheduling with warmup 运行命令 python main.py --checkpoint_name baseline 3 混合精度训练 未使用混合精度训练: for batch_idx, (inputs, labels) in enumerate(data_loader): self.optimizer.zero_grad() self.model(inputs) loss = self.criterion(outputs, labels) loss.backward() self.optimizer.step() 使用混合精度训练
1. 1 首先实例化 torch.cuda.amp.autocast(enable=True) 作为上下文管理器或者装饰器,从而使脚本使用混合精度运行。 torch.nn.CrossEntropyLoss().cuda() # 定义优化器 opt = torch.optim.SGD(net.parameters(), lr=0.001) # 是否使用混合精度训练 set_to_none=True here can modestly improve performance end_timer_and_print("Mixed precision:") 02 混合精度测试 从实验2.1和2.2中,可以发现在batch size=40的情况下,不使用混合精度时,GPU内存占用为7011MB,运行时间为47.55 s。 而使用混合精度时,GPU内存占用为4997MB,运行时间为27.006 s。在当前运行配置中,内存占用节省了约28.73%,运行时间节省了约43.21%。
Tensor Core + Mixed Precision 例如: Transformer Linear 层 Attention Projection MLP CNN 卷积 大量采用 FP16/BF16 混合精度计算 T4 矩阵规模 512~4096 4. Tensor Core不是简单降低精度 很多人认为: FP16 = 精度差 实际上: Tensor Core 混合精度: 输入: FP16 计算: FP32 accumulate 输出: FP32 实验结论 本次 Tesla T4 实验得到: Tensor Core 显著提高 GEMM 性能 矩阵越大,Tensor Core优势越明显 混合精度是AI推理的重要优化 CUDA Kernel 可以让我们理解 对于深度学习推理和训练,合理使用 FP16/BF16 混合精度,是获得高吞吐的重要手段。
AI编辑:我是小将 混合精度训练(mixed precision training)可以让模型训练在尽量不降低性能的情形下提升训练速度,而且也可以降低显卡使用内存。 目前主流的深度学习框架都开始支持混合精度训练。对于PyTorch,混合精度训练还主要是采用NVIDIA开源的apex库。 但是,PyTorch将迎来重大更新,那就是提供内部支持的混合精度训练,而且是自动混合精度训练: ? torch.cuda.amp.GradScaler : 对梯度进行scale来加快模型收敛,因为float16梯度容易出现underflow(梯度过小) 两者结合在一起,可以实现自动混合精度训练: # scaler.update() 当然,混合精度训练肯定要支持分布式训练,由于autocast是thread local的,所以要注意以下不同的情形: 如果使用torch.nn.DataParallel
本小节主要介绍kNN算法的分类精度以及在sklearn中的实现。 分类精度 ? 因为计算分类精度的功能非常常用,因此我们将其加入playML包下,在playML包下新建一个名为"metrics"(度量)的Python文件,里面的内容如下: ? 在jupyter中调用即可: ? 在jupyter中直接计算分类精度: ? sklearn中的分类精度 ? ? 这里简单总结一下求解分类精度: ?
HAWQ:基于 Hessian 的混合精度神经网络量化 本文为 UC Berkeley 大学发表在 ICCV 2019上的混合精度量化论文。 但是,将模型统一量化为超低精度会导致精度显着下降。一种新颖的解决方案是使用混合精度量化,因为与其他层相比,网络的某些部分可能允许较低的精度。但是,没有系统的方法来确定不同层的精度。 对于深度网络,蛮力方法不可行,因为混合精度的搜索空间在层数上是指数级的。另一个挑战是在将模型量化到目标精度时用于确定逐块微调顺序复杂度是阶乘级别的。 解决此问题的一种可能方法是使用混合精度量化,其中较高的精度用于网络的某些“敏感”层,而较低的精度用于“非敏感”层。但是,为每一层找到正确精度的搜索空间在层数上是指数级的。 Inception-V3 on ImageNet 消融实验 海森混合精度量化的有效性 ? 海森混合精度量化消融实验 Block-Wise微调的有效性 ? Block-Wise微调消融实验 ? ?
PyTorch分布式训练工作原理:分布式数据并行与混合精度训练导入与数据加载import torchimport torchvisionimport torchvision.transforms as is_main_process(): torch.save(*args, **kwargs)def is_main_process(): return get_rank() == 0混合精度训练混合精度结合了 GPU19.1DistributedDataParallel 2 GPU9.8DistributedDataParallel 4 GPU6.1DistributedDataParallel 4 GPU + 混合精度6.5在理想的并行世界中,N个worker应该提供N倍的加速。 实际中,使用4个GPU的DistributedDataParallel模式可以获得2倍的加速。混合精度训练通常能提供显著的加速,但在A100 GPU和其他基于Ampere的GPU架构上增益有限。
除此之外,nn.DataParallel 需要所有的GPU都在一个节点(一台机器)上,且并不支持 Apex 的 混合精度训练. 3. 另外,本文还演示了如何使用Apex进行简单的混合精度分布式训练。 使用Apex进行混合混合精度训练 混合精度训练,即组合浮点数 (FP32)和半精度浮点数 (FP16)进行训练,允许我们使用更大的batchsize,并利用NVIDIA张量核进行更快的计算。 opt_level 从 O0 (全部使用浮点数)一直到 O3 (全部使用半精度浮点数)。而 O1 和 O2 属于不同的混合精度程度,具体可以参阅APEX的官方文档。注意之前数字前面的是大写字母O。 Line37-38:混合精度训练需要缩放损失函数以阻止梯度出现下溢。不过Apex会自动进行这些工作。 这个脚本和之前的分布式训练脚本的运行方式相同。
这个小节主要是介绍混合线性模型的理论知识,包括固定因子的显著性检验(Wald),随机因子的检验(LRT),固定因子的效应值(BLUE),随机因子的效应值(BLUP)。 1. 题目:混合线性模型理论1 ? 在这里插入图片描述 2. 大纲 混合线性方程组中矩阵的书写形式,固定因子如何构建矩阵,随机因子如何构建矩阵,固定因子和随机因子的显著性检验。 ? 3. 4. 混合线性模型 混合线性模型的矩阵写法: ? 模型解释: ? 矩阵形式推导: ? 5. 单因素随机区组:混合线性模型 固定因子:单因素 随机因子:区组 ? 写出似然函数: ? 相关系列: 混合线性模型学习笔记1 混合线性模型学习笔记2 混合线性模型学习笔记3
混合精度在计算方法中结合了不同的数值精度。 使用精度低于FP32的系统可以减少内存使用,允许部署更大的网络。 数据传输需要更少的时间,而且计算性能会提高,尤其是在NVIDIA gpu上,它的Tensor Core支持这种精度。 DNNs的混合精度训练实现了两个主要目标: -减少需要的内存,使训练更大的模型或训练更大的小批量 -通过低精度算法降低所需资源,缩短训练/推理时间。 ? 本视频演示了如何在TensorFlow里训练ResNet-50与混合精度。 在这个视频中有五件重要的事情: 混合精度训练可以提高计算性能,并在保持训练精度的同时减少内存带宽。 NVIDIA官网关于混合精度的文档: ?
混合精度训练:只看训练过程就够了 一句话说清楚混合精度训练 在训练时,用半精度(FP16)算得快,用单精度(FP32)存得稳,两者结合就是混合精度训练。 一、训练时发生了什么变化? FP32 FP32 FP32 FP32 (稳但慢) (稳但慢) (稳但慢) (稳但慢) (稳但慢) 混合精度训练(FP16+FP32): criterion(output, target) loss.backward() # 反向 optimizer.step() # 更新 # 启用混合精度后 (只改4处!) 可以大一点 批量大小 原来的 2倍左右 省下来的内存可以放更多数据 热身(Warmup) 必须用 前几个epoch慢慢提高学习率 示例: # 原来:batch_size=32, lr=0.001 # 混合精度后
特别是其自动混合精度(Auto-Mixed Precision, AMP)功能,能够在保持模型精度的前提下显著提升计算性能。 自动混合精度技术原理与实现 自动混合精度是一种先进的数值计算优化技术,通过在训练和推理过程中动态选择合适的数据精度来提升计算效率。 自动混合精度系统会自动分析计算图中的每个算子,智能地将数据类型转换为最适合的低精度格式,从而实现计算性能的整体优化。 训练循环的核心在于正确实现自动混合精度的前向传播和反向传播过程。 实验结果表明,通过Intel Extension for PyTorch实现的自动混合精度优化能够在保持模型精度的前提下显著提升训练和推理性能。
混合精度在计算方法中结合了不同的数值精度。NVIDIA Volta架构和Turing架构的GPU引入了TensorCore,它在单精度数学管道上提供了显著的吞吐量加速。 通过将梯度张量和激活张量上的存储需求和内存流量减半,可以以较低的精度对深度学习网络进行训练,以实现高吞吐量。以下Nvidia工具可以让您分析您的模型是否最大限度地利用TensorCore。
二、混合精度优化策略 (一)FP8混合精度训练框架 混合精度优化是DeepSeek在训练过程中采用的另一种重要策略。 通过灵活使用不同精度的数据格式,混合精度优化能够在保持模型性能的同时,显著提升计算效率和资源利用率。 DeepSeek采用了FP8混合精度训练框架。 为了平衡计算效率和模型性能,DeepSeek在混合精度优化中采用了关键操作保留高精度的策略。 这样可以确保注意力权重的计算结果具有较高的精度,从而提高模型的输出质量。 (三)精细量化策略 在混合精度优化中,量化是另一个关键环节。 此外,混合精度优化通过使用低精度数据格式,进一步提高了计算效率。这种优化使得DeepSeek能够在有限的硬件资源下,实现更高的模型容量。
降低计算精度是比较直接的方法。2017 年以来,fp16 混合精度技术 [2] 获得了广泛应用。在对模型效果无损的前提下,将模型训练和推理的速度提升了 50% 以上。 而为了维持模型效果,更低精度的方法(例如 int8)通常需要使用如下传统方案: 首先使用 fp16 混合精度将模型训练至收敛; 然后在模型计算密集型算子的权重、输入和输出位置处,插入伪量化结点,进行量化感知训练 由于目前流行的深度学习框架不支持 int8 精度,所以量化感知训练需要插入 fp16 的伪量化结点来模拟 int8 量化,导致量化感知训练反而比 fp16 混合精度训练慢 2-3 倍。 LightSeq 快准狠地实现了 int8 精度的量化训练和推理: 快:A100 多卡训练最高加速 5.2 倍,T4 单卡推理最高加速 8.9 倍。 准:训练和推理效果基本无损。 这是因为在 T4 显卡上,int8 GEMM 的加速会随着 shape 的增大而有明显增加。因此在 T4 显卡上进行量化推理时,输入数据量越大,加速效果越好。
降低计算精度是比较直接的方法。2017 年以来,fp16 混合精度技术 [2] 获得了广泛应用。在对模型效果无损的前提下,将模型训练和推理的速度提升了 50% 以上。 而为了维持模型效果,更低精度的方法(例如 int8)通常需要使用如下传统方案: 首先使用 fp16 混合精度将模型训练至收敛; 然后在模型计算密集型算子的权重、输入和输出位置处,插入伪量化结点,进行量化感知训练 由于目前流行的深度学习框架不支持 int8 精度,所以量化感知训练需要插入 fp16 的伪量化结点来模拟 int8 量化,导致量化感知训练反而比 fp16 混合精度训练慢 2-3 倍。 LightSeq 快准狠地实现了 int8 精度的量化训练和推理: 快:A100 多卡训练最高加速 5.2 倍,T4 单卡推理最高加速 8.9 倍。 准:训练和推理效果基本无损。 这是因为在 T4 显卡上,int8 GEMM 的加速会随着 shape 的增大而有明显增加。因此在 T4 显卡上进行量化推理时,输入数据量越大,加速效果越好。
计算机表示浮点数有多种精度,其中Float16和Float32最为常见,即 fp32: Sign(1bit) + Range(8 bits) + Precision(23 bits) fp16: Sign 于是就有人提出了采用fp16来进行训练,具体而言在计算激活值和梯度的时候以fp16精度存储,执行优化算法的时候还原为fp32(缺失位补0),这样最终的效果是模型在GPU上以fp16和fp32两种方式加载 ,这被称为混合精度训练(mixed precision training),这种方式占用了更少的显存(全精度需要保存2份原始模型,混合精度保存1份原始模型,1份半精度模型,是原始模型的1.5倍),也加速了训练过程 ,即精度损失换时间。 ,仅需在TrainingArguments种设置fp16标志位为True: training_args = TrainingArguments(per_device_train_batch_size=4,
因此,通过提供比基于ViT的模型更快的速度和比基于CNN的模型更高的精度,基于ViG的模型可能是一种可能的解决方案。 此外,MobileViG-B比DeiT-S快6倍,能够在Top-1的精度上击败DeiT-S和Swin Tiny。 如表4所示,在相似的模型大小下,MobileViG在目标检测和/或实例分割方面的参数或改进的平均精度(AP)方面优于ResNet、PoolFormer、EfficientFormer和PVT。 在MobileViG中获得的结果表明,混合CNN-GNN架构是CNN、ViT和混合CNN-ViT设计的可行替代方案。 混合CNN-GNN架构可以提供基于CNN的模型的速度以及ViT模型的准确性,使其成为高精度移动端架构设计的理想候选者。
常用的浮点数有双精度和单精度。除此之外,还有一种叫半精度的东东。 双精度64位,单精度32位,半精度自然是16位了。 半精度是英伟达在2002年搞出来的,双精度和单精度是为了计算,而半精度更多是为了降低数据传输和存储成本。 很多场景对于精度要求也没那么高,例如分布式深度学习里面,如果用半精度的话,比起单精度来可以节省一半传输成本。考虑到深度学习的模型可能会有几亿个参数,使用半精度传输还是非常有价值的。 比较下几种浮点数的layout: 双精度浮点数: ? 单精度浮点数: ? 半精度浮点数: ? 它们都分成3部分,符号位,指数和尾数。 不同精度只不过是指数位和尾数位的长度不一样。