paint-brush
ハグフェイスを超えてビジョントランスフォーマー (ViT) をスケーリング@maziyar
4,569 測定値
4,569 測定値

ハグフェイスを超えてビジョントランスフォーマー (ViT) をスケーリング

Maziyar Panahi2022/08/25
Read on Terminal Reader
Read this story w/o Javascript

長すぎる; 読むには

この記事の目的は、Hugging Face から Vision Transformer (ViT) モデルをスケールアウトし、それらを実稼働環境にデプロイして高速で高性能な推論を行う方法を示すことです。最後に、Databricks、Nvidia、Spark NLP を使用して、Hugging Face の ViT モデルを 25 倍 (2300%) スケーリングします。

People Mentioned

Mention Thumbnail

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - ハグフェイスを超えてビジョントランスフォーマー (ViT) をスケーリング
Maziyar Panahi HackerNoon profile picture

Hugging Face で最先端のViTモデルをスピードアップ 🤗 Databricks、Nvidia、Spark NLP で最大 2300% (25 倍高速) 🚀

私はSpark NLPオープンソース プロジェクトの貢献者の 1 人であり、つい最近、このライブラリがエンド ツー エンドのVision Transformers (ViT)モデルのサポートを開始しました。私は毎日の仕事で Spark NLP やその他の ML/DL オープンソース ライブラリを使用しており、最先端の画像分類タスク用に ViT パイプラインを展開し、Hugging FaceSpark NLPの詳細な比較を提供することにしました。

この記事の目的は、Hugging Face から Vision Transformer (ViT) モデルをスケールアウトし、高速で高性能な推論のために実稼働環境にデプロイする方法を示すことです。最後に、Databricks、Nvidia、Spark NLP を使用して、Hugging Face の ViT モデルを25 倍 (2300%)スケーリングします。

この記事では、次のことを行います。

  • Vision Transformer (ViT) の簡単な紹介
  • CPU および GPU 上の Dell サーバー内のベンチマーク Hugging Face
  • CPU および GPU 上の Dell サーバー内の Spark NLP のベンチマーク
  • CPU および GPU 上の Databricks 単一ノード内のベンチマーク Hugging Face
  • CPU および GPU 上の Databricks 単一ノード内の Spark NLP のベンチマーク
  • CPU と GPU を使用して 10 倍のノードにスケーリングされた Databricks 内の Benchmark Spark NLP
  • すべてをまとめてください!
  • 完全な透明性の精神で、ログ、スクリーンショット、さらには数値を含む Excel シートを含むすべてのノートブックがGitHub で提供されています。

    ビジョン トランスフォーマー (ViT) モデルの紹介

    さかのぼること 2017 年、Google AI の研究者グループは、すべての自然言語処理 (NLP) 標準を変更する変換モデル アーキテクチャを紹介する論文を発表しました。この論文では、言語アプリケーションの新しいより効率的なモデルとして、自己注意と呼ばれる新しいメカニズムについて説明しています。たとえば、変圧器ベースのモデルで最も人気のある 2 つのファミリは、GPT と BERT です。

    ちょっとしたトランスフォーマーの歴史https://huggingface.co/course/chapter1/4

    トランスフォーマーの仕組みに関する素晴らしい章があります。興味がある場合は読むことを強くお勧めします。

    これらの新しい Transformer ベースのモデルは NLP タスクに革命をもたらしているように見えますが、コンピューター ビジョン (CV) での使用はかなり制限されたままです。コンピューター ビジョンの分野は、畳み込みニューラル ネットワーク (CNN) の使用によって支配されており、CNN に基づく一般的なアーキテクチャ (ResNet など) があります。これは、今回 Google Brain の別の研究者チームが 2021 年 6 月に画像は 16x16 の言葉に値する: 大規模な画像認識のための変換器」というタイトルの論文で「Vision Transformer」 (ViT) を紹介するまで当てはまりました

    このホワイト ペーパーは、先ほど説明した BERT や GPT などの変換器ベースのモデルで使用されているのと同じ自己注意メカニズムを使用することによる、画像認識に関するブレークスルーを表しています。 BERT のような Transformed ベースの言語モデルでは、入力は文 (単語のリストなど) です。ただし、ViT モデルでは、最初に画像をサブ画像パッチのグリッドに分割し、次に各パッチを線形プロジェクトに埋め込んでから、埋め込まれた各パッチをトークンにします。結果は、BERT と同様にモデルに渡す一連の埋め込みパッチです。

    Google Research の 2021 年のオリジナル論文で紹介された ViT モデル構造の概要

    Vision Transformer は、より高い精度に重点を置いていますが、計算時間は短縮されています。この論文で公開されているベンチマークを見ると、精度の状態はほぼ同じであるにもかかわらず、 Noisy Studentデータセット (Google が 2020 年 6 月に公開) に対するトレーニング時間が 80% 短縮されていることがわかります。今日の ViT パフォーマンスの詳細については、 Papers With Codeのページにアクセスしてください。

    一般的な画像分類ベンチマークの最新技術との比較。 ( https://arxiv.org/pdf/2010.11929.pdf )

    また、ViT アーキテクチャを介してモデルをトレーニングしたら、NLP で行うのと同じように、トランスフォーマーを事前トレーニングして微調整できることにも言及することが重要です。 (それは実際にはかなりクールです!)

    ViT モデルを CNN と比較すると、計算コストがはるかに低く、精度が高いことがわかります。画像の分類、オブジェクトの検出、画像のセグメンテーションなど、Computer Vision のさまざまなダウンストリーム タスクに ViT モデルを使用できます。これはヘルスケアのドメイン固有でもあり、 大腿骨骨折肺気腫乳がんCOVID-19アルツハイマー病のViT モデルを事前トレーニング/微調整できます¹。

    ViT モデルがどのように機能するかを深く掘り下げたい場合に備えて、この記事の最後に参考文献を残しておきます。

    [1]: ディープ ダイブ: ハグ フェイス オプティマム グラフコアのビジョン トランスフォーマーhttps://huggingface.co/blog/vision-transformers

    一部の ViT モデルの動作

    ビジョン トランスフォーマー (ViT) モデル ( vit-base-patch16–224 ) は、解像度 224x224 で ImageNet-21k (1400 万の画像、21,843 クラス) で事前トレーニングされ、ImageNet 2012 (100 万の画像、1,000 クラス) で微調整されています。解像度 224x224:

    https://huggingface.co/google/vit-base-patch16-224

    食品分類に使用される微調整された ViT モデル:

    https://huggingface.co/nateraw/foodhttps://huggingface.co/julien-c/hotdog-not-hotdog

    ただし、予測に関しては、DL/ML モデルには制限と制限があります。 100% の精度を持つモデルは存在しないため、ヘルスケアなどの重要な目的でモデルを使用する場合は注意してください。

    画像は以下から取得: https://www.akc.org/expert-advice/lifestyle/do-you-live-in-dog-state-or-cat-state/ — ViT モデル: https://huggingface.co /julien-c/hotdog-not-hotdog


    Hugging Face のこれらのモデルを使用したり、新しい ViT モデルを微調整して実際の生産での推論に使用したりできますか? AWS EMR、Azure Insight、GCP Dataproc、Databricks などの分散計算用のマネージド サービスを使用して、それらをどのようにスケーリングできますか?

    うまくいけば、これらのいくつかは、この記事の終わりまでに答えられるでしょう.

    ベンチマークを始めましょう!

    ベンチマークに関する詳細:

    1- データセット: ImageNet mini:サンプル(>3K) —フル(>34K)

    Kaggle から ImageNet 1000 (ミニ) データセットをダウンロードしました: https://www.kaggle.com/datasets/ifigotin/imagenetmini-1000

    34K を超える画像を含むトレイン ディレクトリを選択し、それをimagenet-miniと呼びました。これは、時間がかかるベンチマークを実行するのに十分な画像が必要だったからです。さらに、全データセットの 10% 未満をランダムに選択し、それをimagenet-mini-sampleと呼びました。これには、小規模なベンチマーク用の3544 枚の画像があり、バッチ サイズなどの適切なパラメーターを微調整することもできます。

    2- モデル: Google の「 vit-base-patch16–224

    Hugging Face でホストされている Google のこのモデルを使用します: https://huggingface.co/google/vit-base-patch16-224

    3- ライブラリ: Transformers 🤗 & Spark NLP 🚀

    ベアメタルサーバーでのHugging Faceのベンチマーク

    Dell PowerEdge C4130 の ViT モデル

    ベアメタル サーバーとは何ですか?ベアメタル サーバーは、1 人のユーザーのみが使用する単なる物理コンピューターです。このマシンにはハイパーバイザーはインストールされておらず、仮想化も行われておらず、すべてがメインの OS (Linux — Ubuntu) で直接実行されています。このマシンの CPU、GPU、およびメモリの詳細な仕様は、ノートブックの中にあります。

    私の最初のテストと、DL エンジン間の推論速度を比較した Hugging Face エンジニアリング チームによって書かれたほぼすべてのブログ投稿で明らかになったように、Hugging Face ライブラリ (Transformer) での推論の最高のパフォーマンスは、TensorFlow で PyTorch を使用することによって達成されます。これが、TensorFlow が Hugging Face の二流市民であることが原因かどうかはわかりません。これは、サポートされている機能、サポートされているモデルが少ない、例が少ない、チュートリアルが古い、および TensorFlow をもっと求めているユーザーから回答された過去 2 年間の年次調査のためです。または PyTorch は、CPU と GPU の両方で推論のレイテンシが低いだけです。
    TensorFlow は依然として最も使用されているディープ ラーニング フレームワークです

    理由はどうあれ、Hugging Face ライブラリの PyTorch を選択して、画像分類ベンチマークで最高の結果を得ることができました。これは、Hugging Face で ViT モデル (もちろん PyTorch) を使用するための単純なコード スニペットです。

     from transformers import ViTFeatureExtractor, ViTForImageClassification from PIL import Image import requests url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
    image = Image.open(requests.get(url, stream= True ).raw) feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) inputs = feature_extractor(images=image, return_tensors= "pt" ) outputs = model(**inputs) logits = outputs.logits # model predicts one of the 1000 ImageNet classes
    predicted_class_idx = logits.argmax(- 1 ).item() print("Predicted class:", model.config.id2label [predicted_class_idx] )

    これは、画像を入力として予測するのは簡単に見えるかもしれませんが、大量の画像、特に GPU では適していません。画像を連続して予測することを避け、GPU などの高速化されたハードウェアを利用するには、Hugging Face でパイプライン経由で可能な画像のバッチをモデルに供給するのが最善です。言うまでもなく、Hugging Face のパイプラインを拡張するか、独自に行うことで、バッチ処理手法を実装できます。

    画像分類の単純なパイプラインは次のようになります。

     from transformers import ViTFeatureExtractor, ViTForImageClassification from transformers import pipeline feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device=- 1 )

    ドキュメントに従って、機能エクストラクタとモデル (もちろん PyTorch チェックポイント) 用にgoogle/vit-base-patch16–224をダウンロード/ロードして、画像分類をタスクとしてパイプラインで使用しました。このパイプラインには、ベンチマークにとって重要な 3 つの要素があります。

    > device : -1 (デフォルト) の場合、CPU のみを使用しますが、正の整数の場合、関連付けられた CUDA デバイス ID でモデルを実行します (GPU を非表示にして、PyTorch に強制的に CPU を使用させるのではなく、CPU を使用させるのが最善です)ここではこの数に依存します)。

    > batch_size:パイプラインがDataLoaderを使用する場合 (Pytorch モデルの GPU でデータセットを渡す場合)、推論に使用するバッチのサイズは必ずしも有益ではありません。

    > GPU 上の Hugging Face パイプラインでバッチ処理を最大限に活用するには、DataLoader または PyTorch Dataset のいずれかを使用する必要があります。

    ベンチマークを進める前に、Hugging Face Pipelines の推論用バッチ処理に関して、常に機能するとは限らないことを知っておく必要があります。 Hugging Face のドキュメントに記載されているように、 batch_sizeを設定しても、パイプラインのパフォーマンスがまったく向上しない場合があります。パイプラインが遅くなる可能性があります。

    https://huggingface.co/docs/transformers/main_classes/pipelines#pipeline-batching

    公平を期すために、私のベンチマークでは、1 から始まる一連のバッチ サイズを使用して、その中から最良の結果を見つけられるようにしました。これは、CPU で Hugging Face パイプラインのベンチマークを行った方法です。

     from transformers import pipeline pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device=- 1 ) for batch_size in [ 1 , 8 , 32 , 64 , 128 ]:    print ( "-" * 30 )    print ( f"Streaming batch_size= {batch_size} " )    for out in tqdm(pipe(dataset, batch_size=batch_size), total= len (dataset)):        pass

    サンプル (3K) ImageNet データセットに対する、CPU 上の Hugging Face 画像分類パイプラインの最初のベンチマークの結果を見てみましょう。

    CPU 上のハグ顔画像分類パイプライン — 3544 画像を予測

    ご覧のとおり、サンプル データセットから約3544 枚の画像の処理を完了するのに約 3 分 ( 188 秒)かかりました。パイプライン/データセット/ハードウェアに最適なバッチ サイズ (8) がわかったので、このバッチ サイズでより大きなデータセット ( 34K images ) に対して同じパイプラインを使用できます。

    CPU 上のハグ顔画像分類パイプライン - 34745 枚の画像を予測

    今回は、CPU 上の34745 枚の画像のクラスの予測を完了するのに約 31 分 ( 1,879 秒) かかりました。

    ほとんどのディープ ラーニング モデル、特にこれらの新しいトランスフォーマー ベースのモデルを改善するには、GPU などの高速化されたハードウェアを使用する必要があります。まったく同じデータセットでまったく同じパイプラインをベンチマークする方法を見てみましょうが、今回はGPUデバイスで行います。前述のように、デバイスを 0 (最初の GPU) などの CUDAデバイスID に変更する必要があります。

     from transformers import ViTFeatureExtractor, ViTForImageClassification from transformers import pipeline import torch device = "cuda:0" if torch.cuda.is_available() else "cpu"
    print (device) feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) model = model.to(device) pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device= 0 ) for batch_size in [ 1 , 8 , 32 , 64 , 128 , 256 , 512 , 1024 ]:    print ( "-" * 30 )    print ( f"Streaming batch_size= {batch_size} " )    for out in tqdm(pipe(dataset, batch_size=batch_size), total= len (dataset)):        pass
    

    device=0 の設定に加えて、.to(device) を介して GPU デバイスで PyTorch モデルを実行する推奨方法にも従いました。高速ハードウェア (GPU) を使用しているため、テストの最大バッチ サイズを 1024 に増やして、最良の結果を見つけました。

    サンプルの ImageNet データセット (3K) に対する GPU デバイスでのハグ顔画像分類パイプラインを見てみましょう。

    GPU でのハグ顔画像分類パイプライン — 3544 枚の画像を予測

    ご覧のとおり、 GPU デバイスで imagenet-mini-sample データセットから約3544 枚の画像の処理を完了するのに約50 秒かかりました。バッチ処理は特に CPU からの結果と比較して速度を改善しましたが、改善はバッチ サイズ 32 付近で止まりました。結果はバッチ サイズ 32 以降は同じですが、より大きなベンチマークを利用するためにバッチ サイズ256を選択しました。 GPUメモリも十分。

    GPU でのハグ顔画像分類パイプライン - 34745 枚の画像を予測

    今回のベンチマークでは、 GPUデバイス上の34745 枚の画像のクラスの予測を完了するのに約 8:17 分 ( 497 秒) かかりました。 CPU と GPU デバイスでのベンチマークの結果を比較すると、ここの GPU が勝者であることがわかります。

    Hugging Face (PyTorch) は、CPU と比較して GPU で最大 3.9 倍高速です

    Hugging Face Pipelines を使用して ViT PyTorch チェックポイントをロードし、データをトーチ データセットにロードし、CPU と GPU の両方でモデルにすぐに使用できるバッチ処理を使用しました。 CPU で同じパイプラインを実行する場合と比較して、 GPUは最大3.9 倍高速です。

    CPU の代わりにGPU デバイスを使用して画像分類を実行するように ViT パイプラインを改善しましたが、複数のマシンにスケールアウトする前に、単一のマシンでCPUGPUの両方でパイプラインをさらに改善できますか? Spark NLP ライブラリを見てみましょう。

    Spark NLP: 最先端の自然言語処理

    Spark NLP は、オープンソースの最先端の自然言語処理ライブラリです ( https://github.com/JohnSnowLabs/spark-nlp )

    Spark NLP は、Apache Spark 上に構築された最先端の自然言語処理ライブラリです。分散環境で簡単に拡張できる機械学習パイプラインに、シンプルでパフォーマンスが高く正確な NLP アノテーションを提供します。 Spark NLP には、 200 以上の言語による 7000 以上の事前トレーニング済みパイプラインモデルが付属しています。また、トークン化、単語のセグメンテーション、品詞のタグ付け、単語と文の埋め込み、名前付きエンティティの認識、依存関係の解析、スペル チェック、テキストの分類、感情分析、トークンの分類、機械翻訳 (+180 言語)、要約と質問応答、テキスト生成、画像分類 (ViT)、その他多数のNLP タスク

    Spark NLP は、 BERTCamemBERTALBERTELECTRAXLNetDistilBERTRoBERTaDeBERTaXLM-RoBERTaLongformerELMOUniversal Sentenceなどの最先端のトランスフォーマーを提供する、本番環境で唯一のオープンソース NLP ライブラリです。 Encoder 、Google T5MarianMTGPT2 、および Vision Transformer ( ViT ) は、 PythonおよびRだけでなく、Apache Spark をネイティブに拡張することにより、大規模な JVM エコシステム ( JavaScala 、およびKotlin ) にも適用されます。

    ベアメタル サーバーでの Spark NLP のベンチマーク

    Dell PowerEdge C4130 上の ViT モデル

    Spark NLP には、最近の4.1.0リリースで追加された Hugging Face と同じ画像分類用の ViT 機能があります。この機能はViTForImageClassificationと呼ばれ、240を超える事前トレーニング済みのモデルが用意されており Spark NLP でこの機能を使用する簡単なコードは次のようになります。

     from sparknlp.annotator import * from sparknlp.base import * from pyspark.ml import Pipeline imageAssembler = ImageAssembler() \ .setInputCol( "image" ) \ .setOutputCol( "image_assembler" ) imageClassifier = ViTForImageClassification \ .pretrained( "image_classifier_vit_base_patch16_224" ) \ .setInputCols( "image_assembler" ) \ .setOutputCol( "class" ) \ .setBatchSize( 8 ) pipeline = Pipeline(stages=[ imageAssembler, imageClassifier ])

    Spark NLP と Hugging Face を比較して、画像分類予測用の事前トレーニング済み ViT モデルのダウンロードと読み込みについて、画像の読み込みと Hugging Face ライブラリ外での argmax などの事後計算の使用を除けば、どちらも非常に単純です。また、両方を保存して、後でパイプラインとして機能させ、これらの行を 1 行のコードに減らすこともできます。

    Spark NLP (左) と Hugging Face (右) での画像分類のための ViT モデルの読み込みと使用

    Apache Spark にはLazy Evaluationと呼ばれる概念があるため、 ACTIONが呼び出されるまでプロセスの実行は開始されません。 Apache Spark のアクションは、.count()、.show()、または .write() などの多くの RDD ベースの操作であり、ここでは説明しません。この記事ではそれらについて知る必要はありません。私は通常、ターゲット列の count() またはディスク上の結果の write() のいずれかを選択して、DataFrame 内のすべての行の実行をトリガーします。また、Hugging Face ベンチマークと同様に、選択したバッチ サイズをループして、最良の結果を見逃さずにすべての可能な結果を得られるようにします。

    これで、Spark NLP で ViT モデルをロードする方法がわかりました。また、アクションをトリガーして、DataFrame のすべての行の計算をベンチマークに強制する方法もわかりました。あとは、 oneAPI Deep Neuralから oneDNN を学習するだけです。ネットワーク ライブラリ (oneDNN) 。 Spark NLP の DL エンジンは TensorFlow であるため、oneDNN を有効にして CPU の速度を向上させることもできます (他のすべてと同様に、これをテストして、速度が向上し、逆ではないことを確認する必要があります)。 oneDNN が有効になっていない通常の CPU に加えて、このフラグも使用します。

    Hugging Face のすべての ViT モデルが Spark NLP でも利用可能であり、パイプラインでそれらを使用する方法がわかったので、ベアメタルの Dell サーバーで以前のベンチマークを繰り返して、CPU と GPU を比較します。サンプル (3K) ImageNet データセットに対する、Spark NLP の画像分類パイプラインの CPU での結果を見てみましょう。

    oneDNN を使用しない CPU での Spark NLP 画像分類パイプライン — 3544 枚の画像を予測

    サンプル データセットから約3544 枚の画像の処理を完了するのに、約 2.1 分 ( 130 秒)かかりました。より小さなデータセットでさまざまなバッチ サイズを試すことは、タスク、データセット、およびマシンに適したバッチ サイズを選択するのに役立ちます。ここで、バッチ サイズ 16が、パイプラインが最良の結果を提供するための最適なサイズであることは明らかです。

    また、 oneDNNを有効にして、この特定の状況で、oneDNN を使用しない CPU と比較してベンチマークが改善されるかどうかを確認したいと思います。 TF_ENABLE_ONEDNN_OPTS の環境変数を1に設定することで、Spark NLP でoneDNNを有効にできます。このフラグを有効にして、CPU で前のベンチマークを再実行し、最適なバッチ サイズを見つけるとどうなるか見てみましょう。

    oneDNN を使用した CPU 上の Spark NLP 画像分類パイプライン — 3544 枚の画像を予測

    この特定の状況で TensorFlow に対して oneDNN を有効にすると、明らかに結果が少なくとも 14% 向上しました。何も変更する必要はなく、export TF_ENABLE_ONEDNN_OPTS=1 と言うだけなので、違いを確認するために、より大きなデータセットのベンチマークにも使用します。これは約数秒速いですが、より大きなデータセットの 14% で結果の数分を削減できます。

    oneDNN を使用しない CPU のバッチ サイズ 16 と、oneDNN を有効にした CPU のバッチ サイズ 2 が最良の結果であることがわかったので、より大きなデータセット ( 34K images ) に対して同じパイプラインを使用し続けることができます。

    oneDNN を使用しない CPU での Spark NLP 画像分類パイプライン — 34745 枚の画像を予測

    今回のベンチマークでは、oneDNN が有効になっていないCPUデバイスで34745 枚の画像のクラスの予測を完了するのに約 24 分 ( 1423 秒) かかりました。次に、TensorFlow に対して oneDNN を有効にし、バッチ サイズ 2 を使用するとどうなるかを見てみましょう (最良の結果)。

    oneDNN を使用した CPU での Spark NLP 画像分類パイプライン — 34745 枚の画像を予測

    今回は約21分( 1278秒)かかりました。サンプル ベンチマークから予想されるように、oneDNN を有効にしない場合と比較して、結果が約11% 改善されていることがわかります。

    GPU デバイスでまったく同じパイプラインをベンチマークする方法を見てみましょう。 Spark NLP で GPU を使用する必要があるのは、Spark NLP セッションを開始するときに gpu=True で開始することだけです。

    火花 = sparknlp.start(gpu=True)
    # ここでもメモリを設定できます
    spark = sparknlp.start(gpu=True, memory="16g")

    それでおしまい!パイプラインに GPU で実行できるものがあれば、明示的に何もする必要なく自動的に実行されます。

    サンプルの ImageNet データセット (3K) に対する GPU デバイス上の Spark NLP 画像分類パイプラインを見てみましょう。

    GPU での Spark NLP 画像分類パイプライン — 3544 枚の画像を予測

    小さなデータセットで適切なバッチ サイズを見つけるという私の十字軍が正しいかどうかを知りたいという好奇心から、大きなデータセットで GPU を使用して同じパイプラインを実行し、バッチ サイズ 32 が最良の結果をもたらすかどうかを確認しました。

    GPU での Spark NLP 画像分類パイプライン — 34745 枚の画像を予測

    ありがたいことに、バッチ サイズ 32 で最適な時間が得られます。つまり、約 4 分半 ( 277 秒) かかりました。

    oneDNN を使用した CPUの結果の方が高速だったので、その結果を選び、それらをGPUの結果と比較します。

    Spark NLP (TensorFlow) は GPU と CPU で最大 4.6 倍高速 (oneDNN)

    これは素晴らしい! GPU 上の Spark NLP は、oneDNN が有効になっている場合でも、CPU よりも最大4.6 倍高速であることがわかります。

    これらの結果が Hugging Face ベンチマークとどのように比較されるかを見てみましょう。

    Spark NLP は、CPU 上の Hugging Face よりも、3K 画像を含むサンプル データセットの画像クラスを予測する際に 65% 高速であり、34K 画像を含むより大きなデータセットでは 47% 高速です。また、Spark NLP は、34K 画像を含む単一の GPU 推論のより大きなデータセットで Hugging Face よりも 79% 高速であり、より小さなデータセットでは最大 35% 高速です。


    Spark NLP は、CPU または GPU のいずれかを使用して単一のマシンで Hugging Face よりも高速でした — Vision Transformer (ViT) を使用した画像分類

    Databricks での Spark NLP と Hugging Face

    Databricks とは何ですか?すべてのデータ、分析、AI を 1 つのプラットフォームに

    Databricks は、大量のデータを処理および変換するために多くの企業で広く使用されている一連のデータ エンジニアリングおよびデータ サイエンス ツールを備えたクラウドベースのプラットフォームです。ユーザーは、大量のデータの処理と変換から、多くの ML/DL パイプラインを実行してデータを探索するまで、さまざまな目的で Databricks を使用します。

    免責事項:これは Databricks の私の解釈であり、他にも多くの機能が付属しており、それらを確認する必要があります: https://www.databricks.com/product/data-lakehouse

    Databricks は、AWS、Azure、および GCP クラウドをサポートしています: https://www.databricks.com/product/data-lakehouse

    AWS 上の CPU を使用した Databricks 単一ノードで顔を抱きしめる

    Databricks は、1 台のマシンのみで Apache Spark を使用するか、非 Spark アプリケーション、特に ML および DL ベースの Python ライブラリを使用する場合に適したクラスターを作成する場合に、 「単一ノード」クラスター タイプを提供します。 Databricks 11.1 ML ランタイムを選択すると、Hugging Face が既にインストールされています。ベンチマークを開始する前の単一ノード Databricks (CPU のみ) のクラスター構成は次のようになります。

    Databricks 単一ノード クラスター — CPU ランタイム

    AWSm5n.8xlargeインスタンスを使用するこのクラスターの概要は、1 つのドライバー (1 つのノードのみ)、 128 GBのメモリ、 32 コアの CPU があり、1 時間あたり5.71 DBUのコストがかかるということです。 AWS の「DBU」については、 https ://www.databricks.com/product/aws-pricing でお読みいただけます。

    Databricks 単一クラスター — AWS インスタンス プロファイル

    単一ノードの Databricks (CPU のみ) で、前のセクション (ベアメタル Dell サーバー) のベンチマークを複製してみましょう。 Hugging Face と ImageNet のサンプルサイズのデータセットから始めて、以前のベンチマークでたまたま実証済みのプラクティスであったため、より大きなデータセットに使用できる適切なバッチ サイズを見つけます。

    Databricks シングルノード CPU での Hugging Face 画像分類パイプライン — 3544 枚の画像を予測

    CPUのみを使用する単一ノードの Databricks で、サンプル データセットから約3544 枚の画像の処理を完了するのに、約 2 分半 ( 149 秒) かかりました。 CPU のみを使用するこのマシンでの最適なバッチ サイズは8であるため、これを使用してより大きなデータセットでベンチマークを実行します。

    Databricks シングルノード CPU での Hugging Face 画像分類パイプライン - 34745 枚の画像を予測

    34K を超える画像を含む大規模なデータセットでは、これらの画像のクラスの予測を完了するのに約 20 分半 ( 1233 秒) かかりました。次のベンチマークでは、単一ノードの Databricks クラスターが必要ですが、今回は GPU ベースのランタイムが必要で、GPU ベースの AWS インスタンスを選択する必要があります。

    AWS で GPU を使用した Databricks 単一ノードで顔を抱きしめる

    新しいクラスターを作成してみましょう。今回は GPU を備えたランタイムを選択します。この場合は 11.1 ML (Apache Spark 3.3.0、GPU、Scala 2.12 を含む) と呼ばれ、必要なすべての CUDA および NVIDIA ソフトウェアがインストールされています。次に必要なことは、GPU を備えた AWS インスタンスも選択することです。私は、1 つの GPU を備え、他のクラスターと同様の数のコア/メモリを備えたg4dn.8xlargeを選択しました。この GPU インスタンスには、 Tesla T416 GB メモリ ( 15 GB 使用可能な GPU メモリ)。

    Databricks 単一ノード クラスター — GPU ランタイム

    これは、前のクラスターと同様に、単一ノード クラスターの概要です。コア数とメモリ量は同じですが、Tesla T4 GPU が付属しています。

    Databricks 単一ノード クラスター — AWS インスタンス プロファイル

    GPU を備えた単一ノード クラスターができたので、ベンチマークを続行して、Hugging Face が Databricks のこのマシンでどのように機能するかを確認できます。より小さいデータセットでベンチマークを実行して、どのバッチ サイズが GPU ベースのマシンにより適しているかを確認します。

    Databricks 単一ノード CPU 上のハグ顔画像分類パイプライン - 3544 画像を予測

    GPU デバイスを使用した単一ノードの Databricks クラスターで、サンプル データセットから約3544 枚の画像の処理を完了するのに、約 1 分 ( 64 秒) かかりました。バッチ サイズ 1 の結果を見ると、バッチ処理によって速度が改善されましたが、バッチ サイズ 8 の後、結果はほとんど同じままでした。バッチ サイズ 8 の後も結果は同じですが、より多くの GPU メモリを利用するために、より大きなベンチマークではバッチ サイズ256を選択しました。 (正直なところ、8 と 256 はどちらもほとんど同じパフォーマンスでした)

    より大きなデータセットでベンチマークを実行し、バッチ サイズ 256 で何が起こるか見てみましょう。

    Databricks シングルノード CPU でのハグ顔画像分類パイプライン - 34745 枚の画像を予測

    大規模なデータセットでは、34K を超える画像のクラスの予測を完了するのに約 11 分 ( 659 秒) かかりました。 CPU を搭載した単一ノードと 1 つの GPU を搭載した単一ノードでのベンチマークの結果を比較すると、ここの GPU ノードが勝者であることがわかります。

    Hugging Face (PyTorch) は GPU と CPU で最大 2.3 倍高速

    GPUは、Hugging Face on Databricks Single Node の CPU で同じパイプラインを実行する場合と比較して、最大2.3 倍高速です

    今度は、同じクラスターで同じデータセットに対して Spark NLP を使用して同じベンチマークを実行し、Hugging Face と比較します。

    単一ノード Databricks での Spark NLP のベンチマーク

    まず、Single Node Databricks CPU に Spark NLP をインストールしましょう。

    クラスター内の [ Libraries ] タブで、次の手順に従う必要があります。
    — 新規インストール -> PyPI -> spark-nlp==4.1.0 -> インストール
    — 新規インストール -> Maven -> 座標 -> com.johnsnowlabs.nlp:spark-nlp_2.12:4.1.0 -> インストール
    — oneDNN を有効にするために、` TF_ENABLE_ONEDNN_OPTS=1`を `Cluster->Advacend Options->Spark->Environment variables` に追加します

    Python、Scala、および Java の CPU 上の Databricks に Spark NLP をインストールする方法

    AWS 上の CPU を使用した Databricks 単一ノードでの Spark NLP

    Databricks の単一ノード クラスターに Spark NLP がインストールされたので、CPU と GPU の両方でサンプルと完全なデータセットのベンチマークを繰り返すことができます。まず、サンプル データセットに対する CPU のベンチマークから始めましょう。

    Databricks シングルノード CPU (oneDNN) での Spark NLP 画像分類パイプライン — 3544 枚の画像を予測

    Hugging Face に使用した CPU を備えた同じ単一ノードの Databricks クラスターで、 3544 枚の画像の処理とそれらのクラスの予測を完了するのに約 2 分 ( 111 秒) かかりました。 16 のバッチ サイズが最良の結果であることがわかるので、これを次の大きなデータセットのベンチマークで使用します。

    Databricks シングルノード CPU (oneDNN) での Spark NLP 画像分類パイプライン — 34742 画像を予測

    34K を超える画像を含む大規模なデータセットでは、これらの画像のクラスの予測を完了するのに約 18 分 ( 1072 秒) かかりました。次に、GPU を使用したクラスターで同じベンチマークを繰り返します。

    AWS で GPU を使用する Databricks 単一ノード

    まず、Single Node Databricks GPUに Spark NLP をインストールします (唯一の違いは、Maven の「 spark-nlp-gpu」を使用することです)。

    Databricks クラスターSpark NLPをインストールする
    — クラスタ内の [ Libraries ] タブで、次の手順に従う必要があります。
    — 新規インストール -> PyPI -> spark-nlp==4.1.0 -> インストール
    — 新規インストール -> Maven -> 座標 -> com.johnsnowlabs.nlp:spark-nlp-gpu_2.12:4.1.0 -> インストール

    Python、Scala、および Java の GPU 上の Databricks に Spark NLP をインストールする方法

    より小さいデータセットでベンチマークを実行して、どのバッチ サイズが GPU ベースのマシンにより適しているかを確認します。

    Databricks 単一ノード GPU での Spark NLP 画像分類パイプライン — 3544 枚の画像を予測

    GPU デバイスを使用した単一ノードの Databricks で、サンプル データセットから約3544 枚の画像の処理を完了するのに 1 分もかかりませんでした ( 47 秒)。この特定のユース ケースでは、バッチ サイズ 8が最高のパフォーマンスを発揮したことがわかるので、より大きなデータセットでベンチマークを実行します。

    Databricks 単一ノード GPU での Spark NLP 画像分類パイプライン — 34742 画像を予測

    大規模なデータセットでは、 34K を超える画像のクラスの予測を完了するのに約 7 分半 ( 435 秒) かかりました。 CPU を搭載した単一ノードと 1 つの GPU を搭載した単一ノードでのベンチマークの結果を比較すると、ここの GPU ノードが勝者であることがわかります。

    Spark NLP は、GPU と Databricks 単一ノードの CPU で最大 2.5 倍高速です

    これは素晴らしい! GPU 上の Spark NLP は、oneDNN が有効になっている場合でも、CPU よりも最大2.5 倍高速であることがわかります (oneDNN は、CPU での結果を 10% から 20% 改善します)。

    これらの結果が、同じ Databricks 単一ノード クラスターの Hugging Face ベンチマークとどのように比較されるかを見てみましょう。


    Spark NLPは、 CPU上の Hugging Face よりも、3K 画像を含むサンプル データセットの画像クラスを予測する際に最大15%高速であり、34K 画像を含むより大きなデータセットでは最大34%高速です。また、 Spark NLPは、単一のGPUで 34K 画像を含む大規模なデータセットで Hugging Face よりも51% 高速であり、3K 画像を含む小規模なデータセットで最大36%高速です。


    Spark NLPは、 CPUGPUの両方で、Databricks の単一ノードでの Hugging Faceよりも高速です

    単一のマシンを超えたスケーリング

    これまでのところ、 GPU上の Hugging Faceは、ベアメタル サーバーと Databricks シングル ノード上のCPU上の Hugging Faceよりも高速であることを確認しました。これは、これらの新しいトランスフォーマー ベースのモデルで GPU と CPU を比較すると予想されることです。

    また、 Spark NLPは、ベアメタル サーバーと Databricks シングル ノード クラスターの両方で、まったく同じパイプライン (ViT モデル) の Hugging Faceよりも優れており、CPU と GPU デバイスの両方でパフォーマンスが優れていることも確認しています。一方、これは私が期待したものではありませんでした。この記事を準備していたとき、Spark NLP での TensorFlow の推論は、PyTorch を使用した Hugging Face での推論よりもわずかに遅いか、少なくとも互角であると予想していました。私はこのセクションを目指し、単一のマシンを超えてパイプラインをスケーリングしました。しかし、Spark NLP は、 CPUGPUの両方で、小規模なデータセットと大規模なデータセットの両方で、単一のマシンでも Hugging Face よりも高速であるようです。

    質問: ViT パイプラインをさらに高速化するにはどうすればよいですか?さらに大きなデータセットがあり、それらを 1 台のマシンに収めることができない場合や、結果を返すのに時間がかかりすぎる場合はどうすればよいでしょうか?

    回答:スケールアウト!これは、同じマシンのサイズを変更する代わりに、クラスターにマシンを追加することを意味します。これらすべてのジョブ/タスク/DAG のスケジューリング/失敗したタスクの管理などを管理するために何かが必要です。それらにはオーバーヘッドがありますが、何かをより高速にしたり、(単一のマシンを超えて) 可能にしたりする必要がある場合は、ある種の分散システムを使用する必要があります。

    スケールアップ =より多くの負荷を処理できるように、マシンを大きくまたは高速にします。

    スケールアウト =並列にマシンを追加して負荷を分散します。

    Hugging Face のスケールアウト:

    Hugging Face の公式 Web サイトのページを見ると、スケーリングの推論はマルチ GPU を使用することによってのみ可能であることがわかります。スケール アウトとは何かを説明していますが、これはまだ 1 台のマシンにとどまっています。

    https://huggingface.co/docs/transformers/performance

    また、Hugging Face での推論のためのマルチ GPUソリューションは現時点では存在しないことは言うまでもありません。

    https://huggingface.co/docs/transformers/perf_infer_gpu_many

    そのため、Hugging Face パイプラインをスケールアウトするためのネイティブまたは公式の方法はないようです。ジョブ キュー、メッセージング プロトコル、RESTful API バックエンド、および各要求を異なるマシンに分散するために必要なその他のコンポーネントなどのマイクロサービスで構成されるアーキテクチャを実装できますが、これは実際のシステムをスケールアウトするのではなく、個々のユーザーによる要求をスケーリングします。自体。

    さらに、このようなシステムのレイテンシーは、Apache Spark などのネイティブ分散システムとは比較になりません (gRPC はこのレイテンシーを下げる可能性がありますが、それでも競争力はありません)。単一障害点の問題は言うまでもなく、失敗したジョブ/タスク/入力の管理、および Apache Spark からすぐに使用できる何百もの他の機能を自分で実装/維持する必要があります。

    Hugging Face の Web サイトには、REST エンドポイントをスケーリングしてより多くのユーザーにサービスを提供することでまったく同じアーキテクチャを描写したブログ投稿があります。 、それらはすべて、推論 REST エンドポイントにヒットするユーザー/リクエストの数をスケーリングしています。さらに、Databricks でこの方法でHugging Face をスケーリングすることはできません。

    たとえば、fastAPI 内の推論は、ローカルの推論よりも 10 倍遅くなります: https://towardsdatascience.com/hugging-face-transformer-inference-under-1-millisecond-latency-e1be0057a51c

    Hugging Face がスケールアウトするためのネイティブ ソリューションを提供したら、もう一度ベンチマークを実行します。それまでは、ラウンド ロビン アルゴリズムで REST エンドポイントに到達するために 1 台のマシンからデータセットをループ処理する必要がある場合のスケールアウトはありません。 (行/シーケンス/画像をバッチ処理して一度に GPU に供給した部分についてもう一度考えてみてください。そうすれば、それが得られます)

    Spark NLP のスケールアウト:

    Spark NLP は Spark ML の拡張機能であるため、Databricks、AWS EMR、Azure Insight、GCP Dataproc、Cloudera、SageMaker、Kubernetes など (およびこれらに限定されない) Apache Spark がサポートするすべてのプラットフォームでネイティブかつシームレスにスケーリングします。

    コードの変更は必要ありません。 Spark NLP は、コードを変更することなく、1 台のマシンから無数のマシンにスケーリングできます。

    また、Spark NLP からモデルをエクスポートして、まったく別のライブラリで使用し、推論を高速化またはスケーリングする必要もありません。

    Spark NLP エコシステム: 最適化、テスト、およびサポートされている統合

    AWS 上の CPU を使用した Databricks マルチノード

    クラスターを作成しましょう。今回はクラスター モード内の標準を選択します。これは、クラスター内に複数のノードを持つことができることを意味します。これは、Apache Spark 用語では、1 つのドライバーと N 個のワーカー (エグゼキューター) を意味します。

    また、[ライブラリ] タブを使用して、この新しいクラスターに Spark NLP をインストールする必要があります。 CPU を使用した単一ノード Databricks の前のセクションで説明した手順に従うことができます。ご覧のとおり、Hugging Face と Spark NLP の両方のベンチマークに使用したのと同じ CPU ベースの AWS インスタンスを選択したので、ノードを追加したときにどのようにスケールアウトするかを確認できます。

    これは、クラスター構成がどのように見えるかです。

    CPU のみの Databricks マルチノード (標準) クラスター

    以前のベンチマークで使用したものと同じ Spark NLP パイプラインを再利用し(コードを変更する必要はありません) 、34K 画像を含むより大きなデータセットのみを使用します。さぁ、始めよう!

    2x ノードの CPU で Spark NLP をスケーリングする

    2x ノードの Databricks — CPU のみ

    ノードをもう 1 つ追加して、処理を行うマシンの合計を 2 台にしましょう。単一マシンのセットアップ (Colab、Kaggle、Databricks の単一ノード、またはローカルの Jupyter ノートブック) からマルチノード クラスターのセットアップ (Databricks、EMR、GCP、Azure、Cloudera) に移行するときに、Spark NLP の美しさを忘れないでください。 、YARN、Kubernetes など)、ゼロコード変更が必要です!そして、私はゼロを意味します!それを念頭に置いて、34K 画像を含むより大きなデータセットで、この新しいクラスター内で同じベンチマークを実行します。

    CPU を備えた 2 つのノードでの Spark NLP 画像分類パイプライン (oneDNN) — 34742 画像を予測

    34K 画像のクラスの予測が完了するまでに約9 分( 550 秒) かかりました。 Spark NLP を使用した2x ノードでのこの結果と、Databricks の単一ノードでの Hugging Face の結果を比較してみましょう (特に Databricks では、Hugging Face は複数のマシンでスケールアウトできなかったため、参照として単一ノードでの Hugging Face の結果を繰り返します)。 :

    Spark NLPは、 2x ノードの Hugging Face よりも124% 高速です

    以前は、Spark NLP は、CPU のみを使用して、単一ノードの Databricks クラスターで Hugging Face を15%上回っていました。

    今回は、1 つのノードではなく 2 つのノードのみを使用することで、Spark NLP は Hugging Face よりも 124% 速く 34K を超える画像のプロセスを完了しました。4 つのノードを備えた CPU で Spark NLP をスケーリングします。

    前のようにクラスターのサイズを 2 倍にして、 2x ノードから4x ノードにしましょう。これは、クラスターが 4x ノードでどのように見えるかです:

    4x ノードの Databricks — CPU のみ

    34K の画像を含む大規模なデータセットで、この新しいクラスターで同じベンチマークを実行します。

    CPU (oneDNN) を備えた 4 つのノードでの Spark NLP 画像分類パイプライン — 34742 画像を予測

    34K 画像のクラスの予測が完了するまでに約5 分( 289 秒) かかりました。 Spark NLP を使用した4x ノードでのこの結果と、Databricks の CPU での Hugging Face を比較してみましょう。

    Spark NLPは、 4x ノードの Hugging Face よりも327% 高速です

    ご覧のとおり、Spark NLP は、Databricks で4x ノードのみを使用しながら、CPU で Hugging Face よりも327% 高速です。

    8x ノードの CPU で Spark NLP をスケーリングする

    ここで、4 倍のノードを追加して前のクラスターを 2 倍にし、合計8 倍のノードにします。ちなみに、このクラスターのサイズ変更は非常に簡単です。クラスター構成でワーカーの数を増やすだけです。

    Databricks で Spark クラスターのサイズを変更する

    8x ノードの Databricks — CPU のみ

    今回は8x ノードで同じベンチマークを実行してみましょう。

    CPU を備えた8x ノード上の Spark NLP 画像分類パイプライン (oneDNN) — 34742 画像を予測

    34K 画像のクラスの予測を完了するのに 2 分半 ( 161 秒) 以上かかりました。 Spark NLP を使用した8x ノードでのこの結果と、Databricks の CPU での Hugging Face を比較してみましょう。

    Spark NLPは、 8x ノードの Hugging Face よりも666% 高速です

    ご覧のとおり、Spark NLP は、Databricks で8x ノードのみを使用しながら、CPU で Hugging Face よりも666% 高速です。

    ここで 6 の数は無視しましょう。 (気分が良くなった場合は665.8%でした)

    10x ノードの CPU で Spark NLP をスケーリングする

    Spark NLP を使用して Databricks の CPU で ViT モデルの予測をスケールアウトするために、クラスターのサイズをもう一度変更し、ノードを 10 倍に増やします。

    10x ノードの Databricks — CPU のみ

    今度は10x ノードで同じベンチマークを実行してみましょう。

    CPU を備えた10x ノード上の Spark NLP 画像分類パイプライン (oneDNN) — 34742 画像を予測

    34K 画像のクラスの予測を完了するのに2 分未満 ( 112 秒) かかりました。 10x ノードでのこの結果を、Databricks の CPU での Spark NLP と Hugging Face の以前のすべての結果と比較してみましょう。

    Spark NLPは、 10x ノードの Hugging Face よりも1000% 高速です

    これは、Databricks でSpark NLPを使用して、Hugging Face からの Vision Transformer モデルを10x ノードスケールアウトする方法です!私たちのパイプラインは、CPU 上の Hugging Face よりも1000% 高速になりました。

    Spark NLP を使用するだけで、1 つのノードでスタックしている Hugging Face よりもViTパイプラインを1000% 高速化することができましたが、使用したのはCPUのみでした。 GPU クラスターでパイプラインをスケールアウトして、同じ改善が得られるかどうか見てみましょう。

    AWS で GPU を使用した Databricks マルチノード

    GPU ベースのマルチノード Databricks クラスターを持つことは、単一ノード クラスターを持つこととほとんど同じです。唯一の違いは、標準を選択し、単一ノードの GPU のベンチマークで選択した同じ AWS インスタンス仕様で同じ ML/GPU ランタイムを維持することです。

    また、[ライブラリ] タブを使用して、この新しいクラスターに Spark NLP をインストールする必要があります。前と同じように、GPU を使用した単一ノード Databricks で説明した手順に従うことができます。

    GPU を使用した Databricks マルチノード (標準) クラスター

    2x ノードの GPU で Spark NLP をスケーリングする

    マルチノードの Databricks GPU クラスターは、単一ノードの Databricks クラスターで Spark NLP と Hugging Face を比較するために、以前にベンチマークを実行するために使用したg4dn.8xlargeの同じ AWS GPU インスタンスを使用します。

    今回はノードが 2 つある場合の概要を以下に示します。

    2x ノードの Databricks — ノードあたり 1 つの GPU

    2 つのノードを持つこの GPU クラスターで同じパイプラインを実行します。

    GPU を使用した 2 つのノードでの Spark NLP 画像分類パイプライン — 34742 枚の画像を予測

    34K 画像のクラス予測を完了するのに 4 分 ( 231 秒) かかりました。 Spark NLP を使用した2x ノードでのこの結果と、Databricks の GPU での Hugging Face を比較してみましょう。

    Spark NLPは、 2x ノードの Hugging Face よりも185% 高速です

    2x ノードの Spark NLP はほぼ3 倍高速( 185% ) GPU を使用している場合、1 つの単一ノードでの Hugging Face よりも優れています。

    4x ノードの GPU で Spark NLP をスケーリングする

    GPU クラスターのサイズを 2x ノードから4x ノードに変更しましょう。これは、GPU を使用した4x Nodesでの今回の外観の概要です。

    4x ノードの Databricks — ノードあたり 1 つの GPU

    4x ノードで同じベンチマークを実行して、何が起こるか見てみましょう。

    GPU を使用した4x ノードでの Spark NLP 画像分類パイプライン — 34742 画像を予測

    今回は、データセット内のすべての34K 画像の分類を完了するのに約 2 分 ( 118 秒) かかりました。単一ノードでの Hugging Face とマルチノード クラスターでの Spark NLP の観点から、これが何を意味するかをよりよく理解するために、これを視覚化してみましょう。

    Spark NLPは、 4x ノードの Hugging Face よりも458% 高速です

    これは、Hugging Face と比較して458% のパフォーマンス向上です。 4x ノードで Spark NLP を使用して、パイプラインを5.6 倍高速化しました。

    8x ノードの GPU で Spark NLP をスケーリングする

    次に、クラスターのサイズを変更して、Databricks に 8 つのノードが含まれるようにします。概要は次のとおりです。

    8x ノードの Databricks — ノードあたり 1 つの GPU

    各 AWS インスタンス ( g4dn.8xlarge ) には 1 つのNVIDIA T4 GPU 16 GB (15 GB の使用可能メモリ) があります。ベンチマークを再実行して、分散システムでのスケールアウトにはオーバーヘッドがあり、マシンを追加し続けることはできないため、改善点を見つけられるかどうかを確認してみましょう。

    GPU を使用した8x ノードでの Spark NLP 画像分類パイプライン — 34742 画像を予測

    Databricks クラスターで8x ノードを使用して34K 画像の分類を完了するのに、ほぼ 1 分 ( 61 秒) かかりました。それでもパフォーマンスを向上させることができたようです。この結果を、単一ノードの Hugging Face とマルチノード クラスターの Spark NLP の前の結果の次に並べてみましょう。

    Spark NLPは、 8x ノードの Hugging Face よりも980% 高速です

    8x ノードを使用した Spark NLP は、GPU 上の Hugging Face よりもほぼ11 倍 (980%) 高速です。

    10x ノードの GPU で Spark NLP をスケーリングする

    CPU のマルチノード ベンチマークと同様に、GPU クラスターのサイズをもう一度変更して10x ノードにし、最終的なノード数を一致させたいと思います。このクラスターの最終的な要約は次のとおりです。

    10x ノードの Databricks — ノードあたり 1 つの GPU

    この特定の GPU クラスターで最後のベンチマークを実行してみましょう (コードの変更はありません)。

    GPU を使用した10x ノードでの Spark NLP 画像分類パイプライン — 34742 画像を予測

    34743 を超える画像のクラスの予測を完了するのに 1 分もかかりませんでした ( 51 秒)。それらをすべて並べて、Databricks の Spark NLP パイプラインの Hugging Face からの Vision Transformer モデルのスケールアウトがどのように進んだかを見てみましょう。

    Spark NLPは、 10x ノードの Hugging Face よりも1200% 高速です

    これで完了です。

    Databricks でSpark NLPを使用して、Hugging Face のVision Transformerモデルを10x ノードスケールアウトすることができました。私たちのパイプラインは、GPU の Hugging Face と比較して1200% のパフォーマンス向上13 倍高速になりました。

    最初に CPU と GPU 間の改善を比較し、次に GPU で Spark NLP を使用して Hugging Face CPU から Databricks の 10x ノードに移行することで、パイプラインがどれだけ高速になるかを比較して、これらすべてのベンチマークをまとめてみましょう。

    すべてをまとめる:

    Databricks: 単一ノードと複数ノード

    CPU を搭載した 10x ノードでの Spark NLP 🚀 は、Hugging Face 🤗 CPU を搭載した単一ノードでスタックした場合よりも 1000% (11 倍) 高速です


    GPU を使用した 10x ノードでの Spark NLP 🚀 は、Hugging Face 🤗 GPU を使用した単一ノードでスタックした場合よりも 1192% (13 倍) 高速です

    AWS CPU インスタンスと AWS GPU インスタンスの価格差はどうですか? (つまり、お金を払えばもっともらえるということですよね?)

    CPU を搭載したAWS m5d.8xlargeと 1 つの GPU と同様の仕様を搭載したAWS g4dn.8xlarge の比較

    わかりました、価格はほとんど同じようです!それを念頭に置いて、1 台のマシンにスタックされたCPUでのHugging Faceから、 10x GPUを備えた10x NodesでのSpark NLPに移行すると、どのような改善が得られるでしょうか?

    GPU 上のSpark NLPは、CPU 上の Hugging Face よりも25 倍 (2366%) 高速です

    GPU を使用した 10x ノードでの Spark NLP 🚀 は、CPU を使用した単一ノードでの Hugging Face 🤗 よりも 2366% (25 倍) 高速です

    最後の言葉

    • 完全な透明性の精神で、ログ、スクリーンショット、さらには数値を含む Excel シートを含むすべてのノートブックがGitHub で提供されています。
    • Spark NLP のスケーリングでは、コードを変更する必要はありません。単一ノード Databricks から 10 ノードまでのベンチマークを実行することは、同じノートブックで同じコード ブロックを再実行することを意味しました
    • これら 2 つのライブラリには、さまざまなユース ケースのさまざまな環境で速度と効率を最適化するための多くのベスト プラクティスが付属していることに注意してください。たとえば、パーティションと、それらと並列処理および Apache Spark のディストリビューションとの関係については説明しませんでした。クラスターを微調整するための多くの Spark 構成があり、特に CPU と GPU 間のタスク数のバランスを取ります。問題は、ベンチマークに使用したのとまったく同じ環境内でそれらのいずれかを高速化できるかということです。答えは100%です!大多数のユーザーにとってシンプルであることを優先して、デフォルト値とすぐに使える機能を備えた両方のライブラリのすべてを維持しようとしました。
    • Hugging Face やその他の DL ベースの Python ライブラリを Spark UDF にラップしてスケーリングすることができます。これは、私が自分でこれを行ったので、ある程度機能します(ネイティブソリューションがない場合)。このようなトランスフォーマー ベースのモデルを UDF でラップする場合の過剰なメモリ使用量、シリアライゼーションの問題、レイテンシの増加、およびその他の問題の詳細については説明しません。 Apache Spark を使用している場合は、必要な機能を Apache Spark でネイティブに拡張するライブラリを使用してください。
    • この記事全体を通して、PyTorch の Hugging Face と TensorFlow の Spark NLP について言及するのに苦労しました。 PyTorch と TensorFlow の間で Hugging Face によって行われたすべてのベンチマークで、PyTorch が推論の勝者であったという事実を考えると、これは大きな違いです。 Hugging Face では、PyTorch のレイテンシがはるかに低く、Transformers の TensorFlow よりもはるかに高速であるように見えます。 Spark NLP がまったく同じ TensorFlow を使用し、Hugging Face の PyTorch と比較してすべてのベンチマークで優れているという事実は大きな問題です。 Hugging Face の TensorFlow が無視されているか、PyTorch は TensorFlow と比較して推論が高速です。いずれにせよ、Spark NLP が TensorFlow に加えて TorchScript と ONNX ランタイムのサポートを開始したときに何が起こるかを見るのが待ちきれません。
    • ML および ML GPU Databricks ランタイムには、Hugging Face がインストールされています。これは非常に優れています。ただし、Hugging Face が Databricks で使いやすいというわけではありません。 Hugging Face による Transformer ライブラリは、DBFS (Databricks のネイティブ分散ファイル システム) または Amazon S3 をサポートしていません。ノートブックにあるように、データセットの圧縮バージョンをダウンロードして展開し、それらを使用する必要がありました。これは、Databricks のユーザーや、運用環境の他のプラットフォームの実際のやり方ではありません。データは分散ファイル システム内に保持され、セキュリティ対策が実装されており、それらのほとんどは十分に大きいため、パーソナル コンピューターではダウンロードできません。 DBFS に既にあるデータセットをダウンロードして圧縮し、S3 にアップロードして公開し、ノートブックに再度ダウンロードする必要がありました。 Hugging Face が DBFS/S3 をサポートしていれば、かなり面倒なプロセスを回避できたはずです。

    参考文献

    ViT

    抱きしめる顔

    データブリック

    スパークNLP