CPU上でBERT推論をスケーリングアップする(パート1)

'CPU上でBERT推論をスケーリングアップする(パート1)' can be condensed to 'CPU上でBERT推論をスケーリングアップする(パート1)'

.centered { display: block; margin: 0 auto; } figure { text-align: center; display: table; max-width: 85%; /* デモです; 必要に応じていくつかの量 (px や %) を設定してください */ margin: 10px auto; /* 中央に配置する場合は不要です */ }

1. コンテキストと動機

2019年10月、私の同僚であるLysandre Debutが包括的な(当時の)推論パフォーマンスベンチマークブログを公開しました(1)。

その後、 🤗 transformers(2)は非常に多くの新しいアーキテクチャを迎え、🤗 hub(3)には2021年第1四半期時点で9,000以上の新しいモデルが追加されました。

NLPの風景はますますプロダクションで使用されるBERTのようなモデルを傾向としており、これらのアーキテクチャを効率的に展開して実行することは依然として課題です。これが私たちが最近導入した 🤗 Inference API の理由です:このAPIを使用すると、高度な技術的側面に掘り下げる代わりに、ユーザーと顧客のための価値を構築に集中できます。

このブログ投稿は、BERTモデルの推論におけるCPUのハードウェアおよびソフトウェアの最適化のほとんどをカバーするシリーズの第1部です。

この最初のブログ投稿では、ハードウェアの部分をカバーします:

  • ベースラインの設定 – ボックス外の結果
  • 現代のCPUを活用する際の実用的な技術的考慮事項
  • コア数のスケーリング – コア数を増やすことで実際にパフォーマンスが向上するのか?
  • バッチサイズのスケーリング – 複数の並列かつ独立したモデルインスタンスでスループットを増やす

私たちは、最も有名なTransformerモデルアーキテクチャであるBERT(Delvin & al. 2018)(4)に焦点を当てることにしました。このブログ投稿では、記事を簡潔にするためにBERTのようなモデルに焦点を当てますが、説明されている技術はHugging Faceのモデルハブのどのアーキテクチャにも適用できます。Transformerアーキテクチャの詳細な説明は行いませんが、それについて学ぶには、Jay Alammar氏のIllustrated Transformerブログポストをお勧めします(5)。

今日の目標は、PyTorchとTensorFlowでの推論にBERTのようなモデルを使用したオープンソースの視点でどこにいるのか、また推論の高速化にどのように活用できるかを示すことです。

2. ベンチマーク方法論

Hugging FaceのモデルハブからBERTのようなモデルを活用する際には、より速くするために調整できる多くのノブがあります。また、「より速い」という意味を定量化するために、広く採用されているメトリクスに頼ることにします:

  • レイテンシ:モデルの単一の実行(つまり、フォワードコール)にかかる時間
  • スループット:一定時間内に実行される回数

これらの2つのメトリクスは、このブログ投稿の中で利点とトレードオフを理解するのに役立ちます。

ベンチマーク方法論は、トランスフォーマーとtransformersが提供する最新の機能を統合し、コミュニティがベンチマークを実行し共有するためのより簡単な方法を提供するように、ゼロから再実装されました。このフレームワーク全体は、Facebook AI & ResearchのHydra設定ライブラリに基づいており、ベンチマークの実行中に関与するすべての項目を簡単に報告および追跡できるため、全体の再現性が向上しています。プロジェクトの全体の構造はこちらで確認できます。

2021年版では、以前のブログ(1)と同様にPyTorchとTensorflowを介して推論のワークロードを実行する機能と、それらのトレースされた相当物であるTorchScript(6)、Google Accelerated Linear Algebra(XLA)(7)も維持しました。さらに、トランスフォーマーベースのモデルに特化した多くの最適化を提供するONNX Runtime(8)のサポートも含めることにしました。これにより、パフォーマンスについて話す際に強力な候補となります。

最後に、この新しい統一されたベンチマーキング環境は、float16int8int4 のより少ない精度の数値表現を使用して量子化モデル(Zafrir & al.)(9)を含む、異なるシナリオでの推論を簡単に実行できるようにします。この方法は、「量子化」として知られ、すべての主要なハードウェアプロバイダーで増加している採用を見ています。近い将来、Hugging Faceで積極的に取り組んでいる追加の方法であるDistillation、Pruning、Sparsificatonを統合する予定です。

3. ベースライン

以下のすべての結果は、Amazon Web Services(AWS)のc5.metalインスタンスで実行されました。このインスタンスの選択は、以下のようなDeep Learningワークロードの高速化に役立つすべての便利なCPU機能を提供します。

  • AVX512命令セット(各種フレームワークでデフォルトで利用されない場合があります)
  • Intel Deep Learning Boost(ベクトルニューラルネットワーク命令とも呼ばれる)は、量子化ネットワーク(int8データ型を使用する)の実行に特化したCPU命令を提供します

メタルインスタンスの使用は、クラウドプロバイダを使用する際に発生する可能性のある仮想化の問題を回避するためです。これにより、ハードウェアに完全な制御権が与えられます。特に、後述するNUMA(Non-Unified Memory Architecture)コントローラをターゲットにする際に重要です。

使用したオペレーティングシステムはUbuntu 20.04(LTS)で、すべての実験はHugging Face transformersバージョン4.5.0、PyTorch 1.8.1、Google TensorFlow 2.4.0を使用して行われました。

4. デフォルトの結果

図1. PyTorch(1.8.1)対Google TensorFlow(2.4.1)のデフォルトの結果
図2. PyTorch(1.8.1)対Google TensorFlow(2.4.1)のデフォルトの結果 - (大きなバッチサイズ)

まっすぐな話、デフォルトの設定では、PyTorchはここでテストされたすべての構成に対してTensorFlowよりも優れた推論結果を示しています。デフォルトの結果は、PyTorchとTensorFlowの両方にとって「最適な」セットアップを反映していない可能性があるため、これは誤解を招くことがあります。

2つのフレームワークの間のこのような違いを説明する可能性の1つは、オペレータ内の並列セクションを実行するための基礎となるテクノロジーです。PyTorchでは、効率的な線形代数計算のためにOpenMP(10)とIntel MKL(現在はoneDNN)(11)を内部的に使用していますが、TensorFlowはEigenと独自のスレッディング実装に依存しています。

5. モダンCPUでの全体的なスループットを向上させるためのBERT推論のスケーリング

5.1. 導入

BERT推論などのタスクのレイテンシとスループットを向上させるためには、さまざまな方法があります。オペレーティングシステムの機能を有効にする、よりパフォーマンスの高い依存ライブラリとの交換、フレームワークのプロパティを注意深くチューニングする、そして最後に、CPUのすべてのコアを利用する並列化ロジックを使用するなど、さまざまなレベルでの改善とチューニングが行えます。

このブログ投稿の残りの部分では、後者であるマルチプルインファレンスストリームに焦点を当てます。

アイデアはシンプルです。同じモデルの複数のインスタンスを割り当て、各インスタンスの実行を専用の、重複しないCPUコアのサブセットに割り当てることで、真に並列なインスタンスを作成します。

5.2. モダンCPUのコアとスレッド

CPUコアの使用を最適化するためのCPU推論の最善の方法に向かう途中で、過去20年間少なくとも目にしたことがあるかもしれないのが、モダンCPUの仕様には「コア」と「ハードウェアスレッド」または「物理的」および「論理的」な数値が報告されていることです。これらの概念は、インテルのプラットフォームでは同時マルチスレッディング(SMT)またはハイパースレッディングと呼ばれるメカニズムを指します。

これを説明するために、2つのタスクABが並列に実行されると想像してください。各タスクは独自のソフトウェアスレッド上で実行されます。ある時点で、これらの2つのタスクはメインメモリ、SSD、HDD、またはネットワークからリソースを取得する必要がある場合があります。スレッドが異なる物理コアにスケジュールされ、ハイパースレッディングがない場合、これらの期間中、タスクを実行しているコアはリソースの到着を待ってアイドル状態になり、実際には何も行わず、完全に利用されません。

今では、SMT によって、タスクAとBの2つのソフトウェアスレッドを同じ物理コア上でスケジュールすることができます。そのため、実行はその物理コア上で交互に行われます。

タスクAとタスクBは物理コア上で同時に実行され、片方のタスクが停止しているときでも、もう一方のタスクは引き続きコア上で実行を続けることができます。これにより、そのコアの利用率を向上させることができます。

図3. Intel Hyper Threadingテクノロジー(SMT)のイラスト

上記の図3は単一のコアのセットアップを想定して単純化しています。マルチコアCPU上でSMTがどのように機能するかの詳細については、次の2つの記事を参照してください。これらの記事は非常に深い技術的な説明を提供しています。

  • Intel® Hyper-Threadingテクノロジー – 技術ユーザーガイド(12)
  • ハイパースレッディングテクノロジー入門(13)

モデル推論のワークロードに戻ります… 考えてみると、完全に最適化されたセットアップの完璧な世界では、計算に大部分の時間がかかります。この文脈では、論理コアを使用してもパフォーマンスの利点は得られません。なぜなら、両方の論理コア(ハードウェアスレッド)が同じコアの実行リソースを競合するからです。その結果、タスクは一般的な行列の乗算( gemms(14))の大部分を占めるため、CPUによって制約され、SMTからの利益はありません。

5.3. マルチソケットサーバーとCPUアフィニティの活用

現在のサーバーは多くのコアを持ち、そのうちのいくつかはマルチソケットセットアップ(つまり、マザーボード上の複数のCPU)をサポートしています。Linuxでは、lscpuコマンドを使用してシステム上のCPUの仕様とトポロジーを報告します。

ubuntu@some-ec2-machine:~$ lscpu
アーキテクチャ:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
バイトオーダー:                      リトルエンディアン
アドレスサイズ:                   46ビット物理、48ビット仮想
CPU(s):                          96
オンラインCPU(s)リスト:             0-95
スレッド数:              2
コア数:              24
ソケット数:                       2
NUMAノード数:                    2
ベンダーID:                       GenuineIntel
CPUファミリー:                      6
モデル:                           85
モデル名:                      Intel(R) Xeon(R) Platinum 8275CL CPU @ 3.00GHz
ステッピング:                        7
CPU MHz:                         1200.577
CPU最大MHz:                     3900.0000
CPU最小MHz:                     1200.0000
BogoMIPS:                        6000.00
仮想化:                  VT-x
L1dキャッシュ:                       1.5 MiB
L1iキャッシュ:                       1.5 MiB
L2キャッシュ:                        48 MiB
L3キャッシュ:                        71.5 MiB
NUMAノード0のCPU(s):               0-23,48-71
NUMAノード1のCPU(s):               24-47,72-95

この場合、2つのソケットがあり、各ソケットには24個の物理コア2つのスレッドがあります(SMT)。もう1つの興味深い特性は、NUMAノード(0、1)というコアとメモリがシステム上にマッピングされている方法を表します。

ノンユニフォームメモリアクセス(NUMA)は、ユニフォームメモリアクセス(UMA)の反対であり、UMAでは全体のメモリプールがソケット間とメインメモリの間の単一の統一バスを介してすべてのコアからアクセス可能です。一方、NUMAではメモリプールを分割し、各CPUソケットがメモリのサブセットをアドレス指定する責任を持ち、バス上の混雑を減らします。

図5. UMAとNUMAアーキテクチャの違いのイラスト(出典:(15))

このような強力なマシンの潜在能力を十分に活用するためには、モデルのインスタンスがすべての物理的なコアに正しくディスパッチされ、メモリの割り当ても「NUMA対応」となるようにする必要があります。

Linuxでは、NUMAのプロセス設定はnumactlを介して調整することができます。これにより、プロセスを一連のCPUコアにバインドするインターフェース(スレッドアフィニティと呼ばれる)が提供されます。また、メモリの割り当てポリシーも調整できます。これにより、プロセスに割り当てられたメモリがコアのメモリプールにできるだけ近い位置にあることが保証されます(明示的なメモリ割り当て指示と呼ばれます)。

注意:ここではコアとメモリのアフィニティの両方を設定することが重要です。ソケット0での計算とソケット1へのメモリの割り当てでは、システムはメモリの交換のためにソケット共有バスを介して移動する必要があり、望ましくないオーバーヘッドが発生します。

5.4. スレッドアフィニティとメモリ割り当てポリシーの調整

モデルのインスタンスのリソース割り当てを制御するために必要なすべてのツマミが揃ったので、それらを効果的に展開してレイテンシとスループットに与える影響を確認していきましょう。各コマンドとパラメータの影響を把握するために、段階的に進めていきます。

まず、チューニングなしで推論モデルを起動し、計算がどのようにCPUコアにディスパッチされるかを観察します(左)。

python3 src/main.py model=bert-base-cased backend.name=pytorch batch_size=1 sequence_length=128

次に、numactlを使用してコアとメモリのアフィニティを指定します。すべての物理的なコアと1つのスレッド(スレッド0)のみを使用します(右):

numactl -C 0-47 -m 0,1 python3 src/main.py model=bert-base-cased backend.name=pytorch batch_size=1 sequence_length=128
Figure 6. Linux htop command side-by-side results without & with Thread Affinity set

ご覧の通り、特定の調整なしでは、PyTorchとTensorFlowは単一のソケット上で作業をディスパッチし、そのソケット内のすべての論理コア(24コアの両方のスレッド)を使用します。また、前述のように、この場合ではSMT機能を利用したくありませんので、プロセスのスレッドアフィニティをハードウェアスレッド1つだけを対象に設定します。

注意:これはこの実行に特有のものであり、個々のセットアップによって異なる場合があります。したがって、各具体的なユースケースに対してスレッドアフィニティの設定を確認することをお勧めします。

ここでnumactlで行ったことを強調しておきましょう:

  • -C 0-47numactlにスレッドアフィニティ(0から47のコア)を指定します。
  • -m 0,1numactlにメモリを両方のCPUソケットに割り当てるよう指定します。

プロセスをコア[0…47]にバインドしている理由について疑問がある場合は、lscpuの出力を確認してください。そこにはNUMA node0NUMA node1というセクションがあり、その形式はNUMA node<X> <logical ids>です。

この場合、各ソケットは1つのNUMAノードであり、NUMAノードは2つあります。各ソケットまたはNUMAノードには24個の物理コアとコアごとに2つのハードウェアスレッドがあります。つまり、48個の論理コアです。NUMAノード0では、ソケット0の24個の物理コア上のハードウェアスレッド0は0から23であり、ハードウェアスレッド1は24から47です。同様に、NUMAノード1では、ソケット1の24個の物理コア上のハードウェアスレッド0は48から71であり、ハードウェアスレッド1は72から95です。

前述のように、物理コアごとに1つのスレッドを対象としているため、各コアでスレッド0のみを選択し、論理プロセッサ0から47を選択します。両方のソケットを使用しているため、メモリの割り当ても対応させる必要があります(0,1)。

両方のソケットを使用することは、特に問題のサイズが小さい場合には常に最良の結果をもたらすとは限りませんので、ご注意ください。両方のソケットを使用して計算リソースを活用する利点は、ソケット間の通信オーバーヘッドによって減少したり、完全に打ち消される可能性があります。

6. コア数のスケーリング – より多くのコアを使用することは実際にパフォーマンスを向上させるのか?

モデルの推論パフォーマンスを向上させる可能な方法を考えるとき、最初の合理的な解決策は同じ量の作業を行うためにより多くのリソースを投入することです。このブログシリーズの残りの部分では、このセットアップをコア数のスケーリングと呼び、タスクを達成するためにシステム上で使用されるコア数のみが異なることを意味します。これはHPCの世界ではよくストロングスケーリングとも呼ばれます。

この段階では、すべてのコアをタスクに投入して最小のレイテンシを実現するために、コアのサブセットのみを割り当てる意味がわからないかもしれません。

確かに、問題のサイズによっては、タスクにさらにリソースを投入することでより良い結果が得られるかもしれません。また、小さな問題の場合、より多くのCPUコアを使用しても最終的なレイテンシが改善されない可能性もあります。

これを説明するために、以下の図6は異なる問題のサイズ(batch_size = 1, sequence length = {32, 128, 512})を取り、PyTorchとTensorFlowの両方で計算を実行するために使用するCPUコア数に対するレイテンシを報告しています。

計算に関与するリソースの数を制限するためには、intra操作(計算を行う演算子内での操作、または「カーネル」とも呼ばれる)に関与するCPUコアを制限する必要があります。

これは、次のAPIを使用して行われます:

  • PyTorch:torch.set_num_threads(x)
  • TensorFlow:tf.config.threading.set_intra_op_parallelism_threads(x)
Figure 7. Latency measurements

問題のサイズによっては、計算に関与するスレッドの数がレイテンシの測定にプラスの影響を与えることがわかります。

小規模の問題やVoAGIサイズの問題では、1つのソケットのみを使用することが最も優れたパフォーマンスを提供します。大規模な問題では、クロスソケット通信のオーバーヘッドは計算コストでカバーされるため、両方のソケットで利用可能なすべてのコアを使用することで利益を得ることができます。

7. マルチストリーム推論 – 複数のインスタンスを並列に使用する

まだ読んでいるのであれば、CPU上で並列推論ワークロードを設定するのに適しているはずです。さて、私たちが持っている強力なハードウェアが提供するいくつかの可能性と、前述のノブを調整してできるだけ直線的に推論をスケーリングする方法についてハイライトしていきます。

次のセクションでは、もう1つの可能なスケーリングソリューションであるバッチサイズのスケーリングについて探っていきますが、それに入る前に、Linuxツールを活用してスレッドアフィニティを割り当て、効果的なモデルインスタンスの並列性を実現する方法について見ていきましょう。

コア数のスケーリングのセットアップではタスクにより多くのコアを投入するのではなく、今度はより多くのモデルインスタンスを使用します。各インスタンスは、CPUコアのサブセット上で真に並列に動作し、他のインスタンスとはリソースを共有しません。

7.1. 複数の独立したインスタンスを割り当てる方法

まずは簡単に始めましょう。ソケットごとに24個のコアが割り当てられた2つのインスタンスを生成したい場合:

numactl -C 0-23 -m 0 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=24
numactl -C 24-47 -m 1 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=24

ここからは、各インスタンスが他とはリソースを共有せず、すべてがハードウェアの観点から最大の効率で動作しています。レイテンシの測定は、単一のインスタンスが達成するものと同じですが、スループットは実際には2倍高くなり、2つのインスタンスが真に並列に動作しています。

インスタンスの数をさらに増やし、各インスタンスに割り当てるコア数を減らすことができます。4つの独立したインスタンスを実行し、それぞれが効果的に12個のCPUコアにバインドされます。

numactl -C 0-11 -m 0 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=12
numactl -C 12-23 -m 0 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=12
numactl -C 24-35 -m 1 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=12
numactl -C 36-47 -m 1 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=12

結果は同じであり、4つのインスタンスは実際には真に並列に実行されています。レイテンシは前の例よりもわずかに高くなります(コアの数が2倍少ないため)、しかしスループットは再び2倍高くなります。

7.2. スマートディスパッチング – 異なる問題サイズに対して異なるモデルインスタンスを割り当てる

このセットアップが提供するもう一つの可能性は、さまざまな問題サイズに対して慎重に調整された複数のインスタンスを持つことです。スマートディスパッチングのアプローチを使用することで、リクエストのワークロードに応じて最適なレイテンシを提供するため、着信リクエストを適切な構成にリダイレクトすることができます。

# 小規模な問題(シーケンス長が32以下)は8つのコアのみを使用します(ソケット0のコアのうち8/24個使用)
numactl -C 0-7 -m 0 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=32 backend.name=pytorch backend.num_threads=8

# VoAGIサイズの問題(32>シーケンス>=384)は残りの16個のコアを使用します(ソケット0のコアのうち(8+16)/24個使用)
numactl -C 8-23 -m 0 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=128 backend.name=pytorch backend.num_threads=16

# 大規模な問題(シーケンス>=384)はCPU全体を使用します(ソケット1のコアのうち24/24個使用)
numactl -C 24-37 -m 1 python3 src/main.py model=bert-base-cased batch_size=1 sequence_length=384 backend.name=pytorch backend.num_threads=24

8. バッチサイズスケーリング – 複数の並列かつ独立したモデルインスタンスを使用してスループットとレイテンシを向上させる

推論のスケーリングアップにおけるもう一つ非常に興味深い方向性は、実際のワークロードが減少すると同時に、プールにさらにいくつかのモデルインスタンスを配置することです。

この方法は、問題のサイズ(バッチサイズ)と計算に関与するリソース(コア)の両方を変更します。

例えば、C個のCPUコアを持つサーバーがあり、B個のサンプルとS個のトークンを含むワークロードを実行したいとします。このワークロードは、形状が[B, S]のテンソルとして表すことができます。ここで、Bはバッチのサイズであり、SはB個のサンプル内の最大シーケンス長です。

すべてのインスタンス(N)に対して、それぞれがC / N個のコアで実行され、タスクのサブセット[B / N, S]を受け取ります。

各インスタンスはグローバルバッチを受け取るのではなく、その代わりにそれぞれのサブセット[B / N, S]を受け取ります。これが「バッチサイズスケーリング」という名前の由来です。このようなスケーリング方法の利点を強調するために、以下のチャートにはモデルインスタンスのスケーリング時のレイテンシとスループットへの効果が報告されています。

結果を見る際には、レイテンシとスループットの側面に焦点を当てましょう:

一方で、インスタンスプール全体で最大のレイテンシを取ることで、バッチ内のすべてのサンプルを処理するのにかかる時間を反映しています。言い換えれば、インスタンスは真に並列的に動作するため、すべてのインスタンスがバッチのチャンクを取得するのにかかる時間は、プール内の個々のインスタンスが自分のチャンクを終了するのにかかる最も長い時間によって決まります。

下の図7に示されているように、インスタンス数を増やすと実際の遅延の利益は問題のサイズに非常に依存します。すべての場合において、遅延を最小化するための最適なリソース配分(バッチサイズとインスタンス数)を見つけることができますが、計算に関与するコア数に特定のパターンはありません。

また、結果は別のシステム(つまり、オペレーティングシステム、カーネルバージョン、フレームワークバージョンなど)では全く異なる場合があることに注意することも重要です。

図8は、インスタンス数が最小の場合に最小の遅延を目指すための最適な多重インスタンスの設定をまとめています。たとえば、{batch = 8、sequence length = 128}を使用して4つのインスタンス(それぞれ{batch = 2}および12コア)を使用すると、最も遅延の小さい測定結果が得られます。

図9は、さまざまな問題サイズに対してPyTorchとTensorFlowの両方で遅延を最小化するセットアップを報告しています。

ネタバレ:このチャートに大きな影響を与える多くの他の最適化については、後続のブログ投稿で詳しく説明します。

図8. 合計バッチサイズが8の場合のインスタンス数に対する最大遅延の変化
図9. 合計バッチサイズが8の場合の遅延を最小化する最適なインスタンス数

一方、スループットは並列に実行されるすべてのモデルインスタンスの合計として観察されます。これにより、より多くのインスタンスを追加し、それぞれがより少ないリソースと比例したワークロードを持つ場合のシステムのスケーラビリティを視覚化することができます。ここでは、ほぼ線形のスケーラビリティが示され、最適なハードウェア使用が実現されます。

図10. 合計バッチサイズが8の場合のインスタンス数に対する合計スループット

9. 結論

このブログ投稿では、PyTorchとTensorFlowのデフォルトのBERT推論パフォーマンスについて、簡単なPyPiのインストールおよび追加の調整なしで期待できるパフォーマンスについて説明しました。ここで提供される結果はデフォルトのフレームワークのセットアップを反映しているため、絶対的な最高のパフォーマンスを提供するわけではありません。このブログ投稿では、ハードウェアと効率性に焦点を当てるため、最適化は含まれていません。最適化については2部で詳しく説明します! 🚀

次に、スレッドのアフィニティの設定と、ターゲットの問題のサイズとタスクを達成するために必要なコア数のトレードオフの影響と重要性について説明しました。また、最適化デプロイメント時に使用するどの基準(遅延 vs スループット)を定義することも重要です。その結果として得られる設定はまったく異なる場合があります。

より一般的な観点では、小さな問題サイズ(短いシーケンスや小さなバッチ)では、最適な遅延を実現するためにははるかに少ないコアが必要である可能性があります。大きな問題(非常に長いシーケンスや大きなバッチ)と比較すると。

これらすべての側面を考慮することは、最終的なデプロイメントプラットフォームを考える際に興味深いです。なぜなら、インフラストラクチャの費用を大幅に削減することができるからです。たとえば、48コアのマシンは4.848ドル/時間の料金がかかりますが、8コアしかないより小さなインスタンスでは、費用を0.808ドル/時間に引き下げることができ、6倍のコスト削減を実現します。

最後に、このブログ投稿で議論されたノブの多くは、Intelによって作成されたオリジナルのスクリプトから着想を得たランチャースクリプトを介して自動的に調整することができます。ランチャースクリプトは、正しいスレッドのアフィニティでPythonプロセスを自動的に起動し、多くのパフォーマンスのヒントとともにインスタンス間でリソースを分割することができます。これらのヒントの多くについては、2部で詳しく説明します 🧐。

次回のブログ投稿では、さらにモデルの遅延をさらに低減するためのより高度な設定と調整技術について説明します。例えば:

  • ランチャースクリプトの解説
  • メモリ割り当てライブラリの調整
  • LinuxのTransparent Huge Pagesメカニズムの使用
  • ベンダー固有のMath/Parallelライブラリの使用

お楽しみに!🤗

謝辞

  • Omry Yadan(Facebook FAIR)- OmegaConf&Hydraの作者であり、Hydraの正しい設定に関するすべてのヒントを提供してくれました。
  • インテルおよびインテルラボのNLP同僚 – トランスフォーマーおよびNLP分野全般における最適化および研究に取り組んでいる継続的な努力に感謝します。
  • Hugging Faceの同僚 – レビュープロセスでのすべてのコメントと改善に感謝します。

参考文献

  1. Transformersのベンチマーク:PyTorchとTensorFlow
  2. HuggingFaceのTransformers:最先端の自然言語処理
  3. HuggingFaceのモデルハブ
  4. 言語理解のためのディープバイダイレクショナルトランスフォーマーの事前学習(Devlin&al. 2018)
  5. Jay Alammarのイラスト付きトランスフォーマーブログ記事
  6. PyTorch – TorchScript
  7. Google Accelerated Linear Algebra(XLA)
  8. ONNX Runtime – 機械学習の推論とトレーニングの最適化と加速
  9. Q8BERT – 量子化された8ビットBERT(Zafrir&al. 2019)
  10. OpenMP
  11. Intel oneDNN
  12. Intel® Hyper-Threading Technology – Technical User Guide
  13. Hyper-Threading Technologyへの導入
  14. BLAS(Basic Linear Algebra Subprogram)- Wikipedia
  15. NUMAに最適化されたアプリケーション

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

人工知能

「シフトのCEOであるクリス・ナーゲル – インタビューシリーズ」

クリスはSiftの最高経営責任者です彼は、Ping Identityを含むベンチャー支援および公開SaaS企業のシニアリーダーシップポジシ...

AIテクノロジー

アンソニー・グーネティレケ氏は、Amdocsのグループ社長であり、テクノロジー部門および戦略部門の責任者です- インタビューシリーズ

アンソニー・グーネティレーケは、Amdocsでグループ社長、テクノロジーと戦略担当です彼と企業戦略チームは、会社の戦略を策...

人工知能

「コマンドバーの創設者兼CEO、ジェームズ・エバンスによるインタビューシリーズ」

ジェームズ・エバンズは、CommandBarの創設者兼CEOであり、製品、マーケティング、顧客チームを支援するために設計されたAIパ...

機械学習

もし芸術が私たちの人間性を表現する方法であるなら、人工知能はどこに適合するのでしょうか?

MITのポストドクターであるジヴ・エプスタイン氏(SM '19、PhD '23)は、芸術やその他のメディアを作成するために生成的AIを...

機械学習

「Prolificの機械学習エンジニア兼AIコンサルタント、ノラ・ペトロヴァ – インタビューシリーズ」

『Nora Petrovaは、Prolificの機械学習エンジニア兼AIコンサルタントですProlificは2014年に設立され、既にGoogle、スタンフ...

人工知能

ピーター・マッキー、Sonarの開発者担当責任者-インタビューシリーズ

ピーター・マッキーはSonarのDeveloper Relationsの責任者です Sonarは、悪いコードの1兆ドルの課題を解決するプラットフォー...