Pythonスキルの習得

【PyTorch】M2Max GPUによる、ディープラーニング性能検証 – RTX3090、Intel製CPUとの比較 –

【PyTorch】M2Max GPUによる、ディープラーニング性能検証 - RTX3090、Intel製CPUとの比較 -

こんにちは、Zero-Cheeseです。

本記事では、「M2Max GPU」による、ディープラーニング性能の、検証結果をご紹介します。

  • 「M2Max GPU、ディープラーニング用途に使えそう?」
  • 「ぶっちゃけ、Nvidia製グラボに対してどう?」

と思われている方の、参考になれば幸いです。

本検証には、PyTorchを使用しています。

比較したPCの概要は、以下の通りです。(詳細は、本編で)

  • M2 Max搭載Macbook Pro(メモリ64GB版)
  • RTX3090 + Corei9 9900K(メモリ32GB)← 自作PC
  • GTX1080Ti + Corei7(メモリ32GB) ← 自作PC
  • GTX1080 + Corei7(メモリ32GB)← 自作PC

検証した、ディープラーニングのモデルは、以下の通りです。

(よく使われている「CNN、拡散モデル、Transformer」モデルから、1つずつ選んでみました。)

  • CNN → ResNet50 学習時間
  • 拡散モデル → Stable Diffusionで、1枚の絵を作り出す時間
  • Transformerモデル → T5を使った文章要約 学習時間

関連記事の紹介です。

本記事を読んで、ディープラーニング用の自作PCを組みたいと思った方は、下記リンクまでどうぞ。

GPU、電源などの選定方法、注意点をまとめて、ご紹介しています。

ディープラーニング 自作PC に必要なスペックと注意点、おすすめパーツのご紹介
ディープラーニング 自作PC に必要なスペックと注意点、おすすめパーツのご紹介ディープラーニング用の自作PCとして、必要なスペック、注意点、オススメのパーツを紹介した記事です。...

検証したPC 詳細スペック

検証したPCの、主要スペックをご紹介します。

※ ②〜⑤は、デスクトップ型の「自作PC」です。

メモリは、32GBで揃えるつもりでした。

しかし、MacはCPU・GPUとも、同じメモリ領域を使用(ユニファイドメモリアーキテクチャー)するため、その影響を加味して、64GB版を使用しています。

用いたGPUのFLOPS(1秒間に何回、浮動小数点の計算ができるか)は、以下の通りです。(FP32の結果になります。)

※ 横軸の単位:TFLOPS(1TFLOPS =「1秒間に1兆回」計算できる能力)

(2023年現在、ノートPC搭載のGPUが、2017年時点のフラッグシップ「GTX 1080Ti」の性能を超えてきたのは、正直「スゴい!!」)

ディープラーニング 検証結果

評価した項目は以下の通りです。

  • 速度(学習速度 or 推論速度)

※ 「3回」繰返した平均値にて評価

検証に使用した、ディープラーニングの詳細情報は、次の章で紹介しています。

CNN(ResNet50) 検証結果

データセット「Cifar10」

  • batch_size:32
  • 10 Epochs

の条件で、学習に要した時間を評価しています。

「GPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

  • M2MaxのGPUは、Nvidia製GPUに比べ、2倍以上の時間を要している。
  • WIndowsとUbuntu、差がすごい・・

「GPU vs CPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

※ 「Corei9 9900K」は、Windows環境にて検証
  • M2MaxのGPUは、CPU処理に比べ、圧倒的に速い
  • M2Max(GPU)は、Intel製CPU処理に比べても、速い

拡散モデル(Stable Diffusion) 検証結果

  • 画像サイズ:512 × 512 px
  • プロンプト:Future Technology

の条件で、画像一枚を作るのに、要した時間を評価しています。

「GPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

  • M2MaxのGPUは、Nvidia製GPUに比べ、時間を要している。
  • RTX3090(Ubuntu環境)、むちゃくちゃ、速い!!

「GPU vs CPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

※ 「Corei9 9900K」は、Windows環境にて検証
  • M2Max(GPU)は、CPUに比べ、恐ろしく速い!!

Tramsformerモデル(T5) 検証結果

  • 学習データ数:約4700データ
  • batch_size:2
  • 10 Epochs

の条件で、学習に要した時間を評価しています。

データセットに関しては、後の章を、ご確認下さい。

「GPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

  • M2Max(GPU)で、Transformerの処理は、大幅に時間がかかる。

「GPU vs CPU」 検証結果

下記グラフの横軸:時間(sec) (つまり、値が小さいほど、性能が高い)

※ 「Corei9 9900K」は、Windows環境にて検証
  • CPUに比べて処理速度は速いが、CNNや拡散モデルに比べて、CPU → GPU の性能差が縮まっている。

(補足)検証に使った、ディープラーニングの詳細情報

評価に使用した、ディープラーニングの、詳細情報をご紹介します。

ご興味のない方は、Skipして頂いて、大丈夫です。

画像分類系(ResNet50)の学習 詳細情報

使用したモデルは、ResNet50になります。

学習データに関しては、「Cifar10」を使いました。

Cifar10をご存じない方は、@ITさんのサイトで、分かりやすく解説されています。

32×32 pxの画像が学習用として5万枚用意されており、「蛙、飛行機など」10種類に分類された、データセットです。

評価に使用したPythonのコードは、以下の通りです。

import time

import torch
import torchvision
from torchvision import transforms
import torchvision.models as models

num_epochs = 10         # 学習を何回、繰り返すか (エポックと呼ばれる。)
num_batch = 100         # 1度に、何枚の画像を取出すか
learning_rate = 0.001   # 学習率
image_size = 32 * 32      # 画像の画素数(幅x高さ)

# モデルの準備
model_resnet50 = models.resnet50(pretrained=False)
model_resnet50.fc = torch.nn.Linear(model_resnet50.fc.in_features, 10)

# CIFAR10の準備
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.491, 0.482, 0.446), (0.247, 0.243, 0.261))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
train_dataloader = torch.utils.data.DataLoader(trainset, batch_size=16, shuffle=True)
# 精度を検証しないため、下記は不要
# testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
# test_dataloader = torch.utils.data.DataLoader(testset, batch_size=16, shuffle=False)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

# 学習
# GPUが使える場合は、GPU使用モードにする。
device = torch.device('cuda') if torch.cuda.is_available() else \
            torch.device('mps') if torch.backends.mps.is_available() else torch.device('cpu')
print(f'Device: {device}')
# ニューラルネットワークの生成して、GPUにデータを送る
model = model_resnet50.to(device)
# モデルを訓練モードにする
model.train()

# 損失関数の設定(説明省略)
criterion = torch.nn.CrossEntropyLoss()
# 最適化手法の設定(説明省略)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

start_time = time.time()
# 設定したエポック数分、学習する。
for epoch in range(num_epochs):
    loss_sum = 0

    for inputs, labels in train_dataloader:

        # GPUが使えるならGPUにデータを送る
        inputs = inputs.to(device)
        labels = labels.to(device)

        # optimizerを初期化
        optimizer.zero_grad()

        # ニューラルネットワークの処理を実施
        outputs = model(inputs)

        # 損失(出力とラベルとの誤差)の計算
        loss = criterion(outputs, labels)
        loss_sum += loss

        # 学習
        loss.backward()
        optimizer.step()

    # 学習状況の表示
    print(f"Epoch: {epoch+1}/{num_epochs}, Loss: {loss_sum / len(train_dataloader)}")
# 総学習時間
print(f'Elapsed_Time: {time.time() - start_time} sec')

画像生成系(Stable Diffusion)の生成 詳細情報

下記記事にて、紹介したコードを使用しています。

【Python】自分のPCで、画像生成AI「Stable Diffusion v1.4」を実行するまで(GPU版) - インストール方法の紹介 -
【Python】自分のPCで、画像生成AI「Stable Diffusion」を実行する方法(GPU版) - 概要、NSFW無効化も紹介 -画像生成AI「Stable Diffusion」のインストール方法を紹介した記事です。Stable Diffusionの概要、実行するまでの手順、セーフティーフィルター(NSFW)の無効化 まで、紹介しています。...

使用したプロンプト:Future Technology

評価に使用したPythonコードは、以下の通りです。(CUDAの場合)

import torch
from torch import autocast
from diffusers import StableDiffusionPipeline

hugging_token = '<取得したトークン>'

ldm = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4",
                                              use_auth_token=hugging_token
                                              ).to("cuda")

prompt = '<生成したい画像を表現した、文字列>'

# 1000枚画像を作りたい場合
num_images = 1000
for j in range(num_images):
    with autocast("cuda"):
        image = ldm(prompt).images[0] # 500×500px画像が生成

    # save images (本コードでは、直下に画像が生成されていきます。)
    image.save(f"./image_{i}.png")

文章要約(T5)の学習 詳細情報

使用したモデルは、T5(t5-small)になります。

データセットに関しては、Kaggleで使われた、インドのニュース記事を集めたものになります。

約4500件、ニュース記事と、その要約文が、データセットとなっています。

Datasetの詳細を知りたい方は、こちら(Kaggleサイト)まで

ソースコードを全部紹介しようと思いましたが、大部分がデータセットの整形部分になってしまうので、モデルを読み込んだ部分のみ、紹介しています。

batch_size = 2で学習し、最適化アルゴリズムには、Adamを使用しています。

from transformers import T5ForConditionalGeneration

model = T5ForConditionalGeneration.from_pretrained("t5-small")

まとめと所感

まとめ:

「CNN、拡散モデル、Transformer」を使って、性能を検証しました。

  • Nvidia製GPU > M2 Max(GPU)>> M2 Max(CPU)
  • ただし、Transformer系は、Nvidia製GPU >> M2 Max(GPU)

という事が判明しました。

以下、所感です。

性能面では、Nvidia製GPUが圧勝でした

FLOPSだけを見ると、M2Max(GPU)はGTX1080Tiに対し同等以上でしたが、敗北という形になりました。

特にTransformerは、顕著な差が見られました。

最近のディープラーニングは、ChatGPTなど「Transformer」が主流という事もあり、この性能差は、無視できない方もいるかと思います。

なぜ、ここまで差が生じたのかを考えると、

  • RTX3090は、Transformer用の「専用処理回路」があるため、ムッチャ速い
  • M2Maxによるmps(GPU)処理は、2023年3月時点では、対応していない機能(float16等)がある

と推測をしています。

また本記事の趣旨から外れますが、WindowsとUbuntuで、2倍以上の差が出たのは興味深いと思いました。

今度、WindowsとUbuntuに絞って、検証をしてみようと思っています。

その際は記事にします。Twitter等でお知らせするので、お付合い頂けますと幸いです(笑)

雑談

以下、ただの雑談になります。(お時間がある方は、お付き合い頂けますと、幸いです。)

最近、2018年製 Macbook Proから、M2Max搭載のMacbook Proに買い替えました。

買い換える前、

  • Unityはまともに動かない
  • 3Dソフトは、固まる
  • ついでに、AfterEffectsまで固まる
  • あげくの果てに、Photoshopを起動するだけで、恐ろしく時間がかかる

という状態で、「もう限界!!」でした。

こんな状態だったので、M2Max搭載のMacbookProが販売されるのを、ずーーーと待ち続けてました。

(半年以上、待ってましたw 心が折れそうになって、M1Max買おうと思った事も・・笑)

そういう状況だったので、2023年の1月にサプライズで「販売するよ!」ってアナウンスがあってすぐ、M2Maxを購入してしまいました。

(本当は、初期ロットは避けるべきかもしれませんが・・ でも今の所、すごく快調です。 ハズレPCは引かなかったみたいで、ホッとしています。)

ちなみに、AfterEffects、Blender、VRoidStudio,Unity等、重いソフトでも、快調に動作しています。

Blenderで、相当重い3Dアニメーションが、ノートPCでヌルヌルで動いているのは、正直「スゲー」と思いました。

だから、ディープラーニングもいけると思ったのですが、このような結果になってしまいました(笑)

でも私の使い方として、M2Max搭載PCでは、ディープラーニングのプログラムを作り事がメインなので、十分です。

(プログラムを作った後、動作確認に使う程度です。後は専用サーバーにお任せです。)

完全にお話は変わりますが、

今度、VRoidStudioで作った「キャラ」を、Unity上で強化学習させて、遊んでみようと思います。(鬼ごっことか、作っています。)

VRoidで作ったキャラを、Unityで動かすところまで実装しました。(キーボード操作等により、走ったりする機能は、既に実装済み) こんな感じ↓

もし、そこそこのレベルになったら、記事にしてみます。

ご興味がありましたら、ぜひ読んで下さい。

本記事も、最後までお付き合い頂き、ありがとうございました。

それではまた、お会いしましょう!