最近、深層学習の分野で著名な研究者であり、Lightning AI の主任人工知能教育者でもある Sebastian Raschka 氏が、CVPR 2023 で「コード変更を最小限に抑えた PyTorch モデル トレーニングのスケーリング」という基調講演を行いました。
研究結果をより多くの人々と共有するために、Sebastian Raschka はスピーチを記事にまとめました。この記事では、最小限のコード変更で PyTorch モデルのトレーニングをスケーリングする方法について説明し、低レベルのマシンの最適化ではなく、混合精度メソッドとマルチ GPU トレーニング モードを活用することに焦点を当てていることを示しています。
この記事では、Visual Transformer (ViT) を基本モデルとして使用します。ViT モデルは、基本的なデータ セットでゼロから開始します。約 60 分間のトレーニング後、62% のパフォーマンスを達成します。テストセットの精度。
GitHub アドレス: https://github.com/rasbt/cvpr2023
以下は記事の原文です:
次のセクションでは、Sebastian が調査します。広範なコードのリファクタリングによってトレーニング時間と精度を向上させる方法。
モデルとデータセットの詳細はここでは主な焦点ではないことに注意してください (読者が自分のマシンで再現できるように、できるだけシンプルにすることを目的としているだけです) 、あまりにも多くの依存関係をダウンロードしてインストールする必要はありません)。ここで共有されているすべての例は GitHub にあり、読者は完全なコードを探索して再利用できます。
スクリプト 00_pytorch-vit-random-init.py の出力。
現在、テキストや画像の深層学習モデルをゼロからトレーニングするのは非効率であることがよくあります。通常、事前トレーニングされたモデルを利用し、モデルを微調整して、時間とコンピューティング リソースを節約しながら、より良いモデリング結果を取得します。
上で使用したのと同じ ViT アーキテクチャを考慮し、別のデータセット (ImageNet) で事前トレーニングして微調整すると、より短い時間でより良い結果を達成できます。 : 20 分以内 (3 トレーニング エポック) 95% のテスト精度。
00_pytorch-vit-random-init.py と 01_pytorch-vit.py の比較。
微調整により、最初からトレーニングする場合と比べて、モデルのパフォーマンスが大幅に向上することがわかります。以下の棒グラフはこれをまとめたものです。
00_pytorch-vit-random-init.py と 01_pytorch-vit.py の比較ヒストグラム。
もちろん、モデルのパフォーマンスはデータセットやタスクによって異なる場合があります。ただし、多くのテキストや画像のタスクでは、共通の公開データセットで事前トレーニングされたモデルから始める価値があります。
次のセクションでは、予測精度を犠牲にすることなくトレーニング時間を短縮するためのさまざまなテクニックを検討します。
最小限のコード変更で PyTorch でのトレーニングを効率的に拡張する 1 つの方法は、オープンソース ファブリック ライブラリを使用することです。これは、PyTorch の軽量ラッパー ライブラリ/インターフェイスと考えることができます。 pip経由でインストールします。
pip install lightning
以下で説明するすべてのテクニックは、純粋な PyTorch で実装することもできます。 Fabric は、このプロセスをより便利にすることを目的としています。
「コードを高速化するための高度なテクニック」を検討する前に、まず Fabric を PyTorch コードに統合するために必要な小さな変更を紹介します。これらの変更を加えると、コードを 1 行変更するだけで、高度な PyTorch 機能を簡単に使用できるようになります。
PyTorch コードと Fabric を使用するように変更されたコードの違いは微妙であり、次のコードに示すように、いくつかの小さな変更のみが必要です。
通常の PyTorch コード (左) と Fabric を使用した PyTorch コード
总结一下上图,就可以得到普通的 PyTorch 代码转换为 PyTorch+Fabric 的三个步骤:
这些微小的改动提供了一种利用 PyTorch 高级特性的途径,而无需对现有代码进行进一步重构。
深入探讨下面的「高级特性」之前,要确保模型的训练运行时间、预测性能与之前相同。
01_pytorch-vit.py 和 03_fabric-vit.py 的比较结果。
正如前面柱状图中所看到的,训练运行时间、准确率与之前完全相同,正如预期的那样。其中,任何波动都可以归因于随机性。
在前面的部分中,我们使用 Fabric 修改了 PyTorch 代码。为什么要费这么大的劲呢?接下来将尝试高级技术,比如混合精度和分布式训练,只需更改一行代码,把下面的代码
fabric = Fabric(accelerator="cuda")
改为
fabric = Fabric(accelerator="cuda", precisinotallow="bf16-mixed")
04_fabric-vit-mixed-precision.py 脚本的比较结果。脚本地址:https://github.com/rasbt/cvpr2023/blob/main/04_fabric-vit-mixed-precision.py
通过混合精度训练,我们将训练时间从 18 分钟左右缩短到 6 分钟,同时保持相同的预测性能。这种训练时间的缩短只需在实例化 Fabric 对象时添加参数「precisinotallow="bf16-mixed"」即可实现。
混合精度训练实质上使用了 16 位和 32 位精度,以确保不会损失准确性。16 位表示中的计算梯度比 32 位格式快得多,并且还节省了大量内存。这种策略在内存或计算受限的情况下非常有益。
之所以称为「混合」而不是「低」精度训练,是因为不是将所有参数和操作转换为 16 位浮点数。相反,在训练过程中 32 位和 16 位操作之间切换,因此称为「混合」精度。
如下图所示,混合精度训练涉及步骤如下:
这种方法在保持神经网络准确性和稳定性的同时,实现了高效的训练。
更详细的步骤如下:
步骤 4 中的乘积用于更新原始的 FP32 神经网络权重。学习率有助于控制优化过程的收敛性,对于实现良好的性能非常重要。
前面谈到了「float 16-bit」精度训练。需要注意的是,在之前的代码中,指定了 precisinotallow="bf16-mixed",而不是 precisinotallow="16-mixed"。这两个都是有效的选项。
在这里,"bf16-mixed" 中的「bf16」表示 Brain Floating Point(bfloat16)。谷歌开发了这种格式,用于机器学习和深度学习应用,尤其是在张量处理单元(TPU)中。Bfloat16 相比传统的 float16 格式扩展了动态范围,但牺牲了一定的精度。
扩展的动态范围使得 bfloat16 能够表示非常大和非常小的数字,使其更适用于深度学习应用中可能遇到的数值范围。然而,较低的精度可能会影响某些计算的准确性,或在某些情况下导致舍入误差。但在大多数深度学习应用中,这种降低的精度对建模性能的影响很小。
虽然 bfloat16 最初是为 TPU 开发的,但从 NVIDIA Ampere 架构的 A100 Tensor Core GPU 开始,已经有几种 NVIDIA GPU 开始支持 bfloat16。
我们可以使用下面的代码检查 GPU 是否支持 bfloat16:
>>> torch.cuda.is_bf16_supported()True
如果你的 GPU 不支持 bfloat16,可以将 precisinotallow="bf16-mixed" 更改为 precisinotallow="16-mixed"。
接下来要尝试修改多 GPU 训练。如果我们有多个 GPU 可供使用,这会带来好处,因为它可以让我们的模型训练速度更快。
这里介绍一种更先进的技术 — 完全分片数据并行(Fully Sharded Data Parallelism (FSDP)),它同时利用了数据并行性和张量并行性。
在 Fabric 中,我们可以通过下面的方式利用 FSDP 添加设备数量和多 GPU 训练策略:
fabric = Fabric(accelerator="cuda", precisinotallow="bf16-mixed",devices=4, strategy="FSDP"# new!)
06_fabric-vit-mixed-fsdp.py 脚本的输出。
现在使用 4 个 GPU,我们的代码运行时间大约为 2 分钟,是之前仅使用混合精度训练时的近 3 倍。
在数据并行中,小批量数据被分割,并且每个 GPU 上都有模型的副本。这个过程通过多个 GPU 的并行工作来加速模型的训练速度。
如下简要概述了数据并行的工作原理:
每个 GPU 都在并行地处理不同的数据子集,通过梯度的平均化和参数的更新,整个模型的训练过程得以加速。
这种方法的主要优势是速度。由于每个 GPU 同时处理不同的小批量数据,模型可以在更短的时间内处理更多的数据。这可以显著减少训练模型所需的时间,特别是在处理大型数据集时。
然而,数据并行也有一些限制。最重要的是,每个 GPU 必须具有完整的模型和参数副本。这限制了可以训练的模型大小,因为模型必须适应单个 GPU 的内存。这对于现代的 ViTs 或 LLMs 来说这是不可行的。
与数据并行不同,张量并行将模型本身划分到多个 GPU 上。并且在数据并行中,每个 GPU 都需要适 应整个模型,这在训练较大的模型时可能成为一个限制。而张量并行允许训练那些对单个 GPU 而言可能过大的模型,通过将模型分解并分布到多个设备上进行训练。
テンソル並列処理はどのように機能しますか?行列の乗算について考えると、分散計算を行うには行方向と列方向の 2 つの方法があります。簡単にするために、列ごとの分布計算を考えてみましょう。たとえば、次の図に示すように、大規模な行列乗算演算を複数の独立した計算に分解し、それぞれを異なる GPU で実行できます。次に、結果を取得するために結果が連結されるため、計算負荷が効果的に分散されます。
以上がコードを 1 行変更するだけで、PyTorch のトレーニングが 3 倍高速になります。これらの「先進技術」が鍵となりますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。