M1MAX MacBook Proで深層学習

Apple Siliconが搭載されたMacBook Proが発売されました。深層学習的にどれくらいのパフォーマンスがあるのか調べてみました。

実行環境

  • Applie Siliconに最適化されたTensorFlow 2.6.0
  • CPU / GPUとして M1 MAX 32コアGPU,64GBユニファイドメモリが搭載された, 16インチMacBook Pro (2021モデル)
  • OSは,macOS Monterey(12.0.1)

開発環境整備

環境整備は,既にたくさん情報が出ているので簡単に実行環境が整備できますが,一応,手順を書いておきます。ただ,tensorflow addonsのインストールは,現在(11/21)では conda install (pip install) できないので(そのうちできるようになると信じたい),ソースコードからのビルドが必要です。その手順もメモしておきます。

参考にしたWebページは→【M1 Pro/Max対応】M1 Mac環境構築ベストプラクティス

(1) Xcodeのインストール→App Storeからインストール

(2) Command Line Toolsのインストール

$ xcode-select --install

(3) Homebrewのインストール→これもHomebrewの公式ホームページの指示に従い,普通にインストールします。

(4) Python環境のインストール
まだM1に対応したライブラリが整理されていないこともあり,Miniforgeを使ってPythonの開発環境を整えます。TensorFlowを使う場合は,現時点ではこれが一番楽なようです。上で紹介した「M1 Mac環境構築ベストプラクティス」の指示に従い,MiniforgeのGitHubページから,Apple Silicon用の Miniforge3-MacOSX-arm64.sh をダウンロードします。ダウンロードが終わったら,ターミナルから,このシェルスクリプトを実行すると,Apple Silicon(M1チップ)用のPythonの開発環境がインストールされます。インストール中にY/Nが聞かれますが,全てYで大丈夫だと思います。

(5) (4)のインストールが終わったら,一旦,ターミナルを閉じて,またターミナルを開きます。そうすると,自動的にPythonのベーシック環境がアクティベート(有効化)された状態になります。コンソールのプロンプトの先頭に(base)がついていたらOKです。

(base) labnomackbookpro:~ username $ 

そうしたら,次に,Pythonの仮想環境を作ります。仮想環境上で環境構築するとパッケージの依存関係などが壊れても簡単にやり直せます。

conda create --name tensorflow26 python=3.9

tensorflow26のところは自由に名前をつけて良いです。また,参考Webページだと,Python3.8でないといけないと書いてありますが,TensorFlow2.6 はPython 3.9に正式に対応していますので,Python3.9で全く問題ありません。

(6) 仮想環境の有効化
次のコマンドで作成した仮想環境を有効化します。

$ conda activate tensorflow26

(7) パッケージ(ライブラリ)のインストール
ここからは,仮想環境 tensorflow26 が有効化されているという前提での説明です。
numpyやopencvはconda installコマンドでインストールできます。

$ conda install numpy opencv matplotlib

なお,condaに対応していないパッケージもありますが,そのときは,pip installを使います。注意点としては,同じパッケージを conda と pip でインストールしないことです。そうなったら仮想環境の作り直しになってしまいます。そうなってもすぐに復元できるように,参考Webにあるように,environment.yaml でパッケージリストを作っておくと良いと思います。

(8) TensorFlowのインストール
次の手順でインストールします(事前にnumpy, opencv, matplotlibのインストールをしておいた方が良いみたいです)

$ conda install -c apple tensorflow-deps
...
$ python -m pip install tensorflow-macos
...
$ python -m pip install tensorflow-metal

11/21時点では,ver.2.6.0がインストールされます(なお,最新バージョンは,2.7.0です)。以上で,M1チップのGPUを活用するTensorFlowのインストールは終わりです・・・が,TensorFlowの拡張ライブラリである TensorFlow Addons を使うためには,これをインストールしなければなりません。しかし,conda install でも pip install でもうまくインストールできませんでした。なので,ソースコードをビルドして,インストールする必要があります。

(9) M1対応のTensorFlow addons のビルドとインストール
ビルドするためには,bazelのインストールが必要です。

$ conda install bazel

また,Pythonのパッケージであるwheel と setuptools を最新にしておかないと,ビルドが通らないことがあるので,これらのパッケージを upgrade しておいた方が良いです。
Githubからソースコードをダウンロードしてビルドします。手順はこのGitHubの公式ページにも書いてあります。

$ git clone https://github.com/tensorflow/addons.git
$ cd addons
$ python ./configure.py
$ bazel build build_pip_pkg
$ bazel-bin/build_pip_pkg artifacts

ビルドが成功すれば,artifactsディレクトリに,tensorflow_addons-0.16.0.dev0-cp39-cp39-macosx_11_0_arm64.whl ができているはずです。macosx_12じゃないかと思うんですが,まぁ,いいか (^^;
これを pip install すれば,インストールできるはずです。

$ python -m pip install artifacts/tensorflow_addons-0.16.0.dev0-cp39-cp39-macosx_11_0_arm64.whl

(10) 動作確認
CIFAR10タスクのデータを,VGG16(パラメータ数は1,485万くらい)を使って訓練するコードを用意しました。 device:GPU:0 のGPUの部分をCPUにすると,GPUが使われないようになります。以下のコードでは,GPUありなしの訓練で,約10倍の速度差がありました。これとは別のコードで,tensorflow-addonsのAPIも動作することを確認しました。
なお,参考までに,他のGPUと比較してみますと,M1のGPUは,RTX A6000と比較して4倍,RTX 3070と比較しても2倍程度遅いですが,Google Colaboratoryの無料インスタンスで使えるK80と比較すると約2倍速いようでした。モデル訓練中もMacBookのファンが全然回らずに,訓練中も他の仕事(パワーポイントを作ったり)がストレスなくできます。また,給電なしでも5〜6時間はバッテリーだけで深層学習できちゃいそうです。すごいですね,M1 MacBook Pro。
PyTorchもconda install でインストールできますが,まだM1 GPUには対応していないようです。

import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.metrics import SparseCategoricalAccuracy
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import VGG16 # Pre-trained VGG16 model

CIFAR10 = tf.keras.datasets.cifar10 # Use CIFAR10 dataset
(x_train, y_train), (x_valid, y_valid) = CIFAR10.load_data()
y_train = np.squeeze(y_train) # reduce demension
y_valid = np.squeeze(y_valid)

# data conversion 
def convert_data(x, y):
    x = tf.cast(x, tf.float32) # float32
    x /= 255. # pixcel normalization 
    return x, tf.cast(y, tf.int32)

train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)) 
valid_ds = tf.data.Dataset.from_tensor_slices((x_valid, y_valid)) 
AUTOTUNE = tf.data.experimental.AUTOTUNE 
train_ds = train_ds.shuffle(len(x_train)) 
train_ds = train_ds.repeat(1) 
train_ds = train_ds.batch(50) 
train_ds = train_ds.map(lambda x, y: tf.py_function(convert_data, [x, y], Tout=[tf.float32, tf.int32])) 
train_ds = train_ds.prefetch(buffer_size=AUTOTUNE) 
valid_ds = valid_ds.batch(50)
valid_ds = valid_ds.map(lambda x, y: tf.py_function(convert_data, [x, y], Tout=[tf.float32, tf.int32]))

# Pre-Trained VGG16
vgg16 = VGG16(include_top=False, weights='imagenet', input_shape=(32, 32, 3), pooling='avg')
h = Dropout(0.3)(vgg16.output)
h = Dense(256, activation='relu', name='dense01')(h) 
output = Dense(10, activation='softmax', name='output1')(h) 
vgg16.trainable = True 
model = Model(inputs=vgg16.input, outputs=output) 
model.summary()

model.compile(optimizer=Adam(0.0001), loss='sparse_categorical_crossentropy', metrics=SparseCategoricalAccuracy())   
with tf.device('/device:GPU:0'):
    model.fit(train_ds, epochs=10, validation_data=valid_ds, use_multiprocessing=True)

M1MAX MacBook Proで深層学習」への11件のフィードバック

  1. takeda 返信

    bazel-bin/build_pip_pkg artifacts
    の部分で
    cp: dist/*.whl: No such file or directory
    とエラーが出てしまいます。おそらくは
    addons/build_deps/build_pip_pkg.sh
    を実行した際に97行目の
    cp dist/*.whl “${DEST}”
    で発生しているのですがシェルに詳しくないもので原因がわかりません。
    解決策など分かりますでしょうか。

    • Hiromitsu Nishizaki 投稿者返信

      ありがとうございます。
      おそらく,bazel-bin/build_pip_pkg artifacts でビルドに失敗しているみたいです。
      私の場合は,Pythonのパッケージの wheel と setuptools を最新版にアップデートすると,ビルドに成功しましたので,もし,最新版でなければアップデートされると良いと思います。

  2. TAKEDA 返信

    ありがとうございます。解決しました。
    一方tensorflowをインポートし、
    tf.config.experimental.list_physical_devices(‘GPU’)
    でGPU のコア数を確認したところ1つしか認識されていないようでした。
    上記の手順を踏めば自動的にGPUを認識するものだと思っていましたが、違うのでしょうか。
    (10)のコードを動かした際にはGPUは全て認識されていましたか。

    • Hiromitsu Nishizaki 投稿者返信

      GPUのコア数の表示ではなくて,使えるデバイスの確認だと思います。
      tf.config.experimental.list_physical_devices(‘GPU’)
      を実行すると
      [PhysicalDevice(name=’/physical_device:GPU:0′, device_type=’GPU’)]
      という表示がでます。GPUのデバイスIDが0になっているのが分かります。この表示がでていれば,モデル訓練時にGPUが利用されると思います。

  3. TAKEDA 返信

    返信ありがとうございます。
    そうだったのですか。確かに
    [PhysicalDevice(name=’/physical_device:GPU:0′, device_type=’GPU’)]
    という表示が出ました。ただ、訓練する際に
    Plugin optimizer for device_type GPU is enabled.
    というwarningが出てしまいます。また訓練速度も遅く、手元にあるmacbook air 2017 の4倍ほどかかっています。度々の質問で申し訳ありませんが、解決方法など分かりませんでしょうか。

    • Hiromitsu Nishizaki 投稿者返信

      そうなんですね。
      model.fitを実行するときに,

      with tf.device('/device:CPU:0'):
        model.fit(.....)

      のように設定すると,CPUだけを使って動きますので,CPUだけでも macbook air 2017よりも遅いと,GPUではなく,別の要因かもしれません。
      また,tensorflow以外のpythonのプログラムも遅いのかどうかも確認されると良いかもしれません。

      あまり解決策になっておらず,申し訳ないです。

  4. TAKEDA 返信

    返信ありがとうございます。
    どうやらGPUではなくtensorflow自体に原因があるようでしたので、そちらの方を探ってみようと思います。
    度々の回答ありがとうございました。

  5. 匿名 返信

    64GBもメモリあったら大きなモデルも学習出来るんですかね。

  6. Syungyo 返信

    TensorFlow Addonsを導入するためにwheelを最新版にアップデートしたいのですが、
    conda update wheel
    としても最新版の0.37.1になりません。
    原因としては、
    conda install -c apple tensorflow-deps
    で依存ライブラリをインストールすることで、wheelのバージョンが0.35.1に固定されてしまうからだと考えています。
    初歩的な質問で恐縮ですが、wheelを最新版にアップデートする方法を教えて頂ければ幸いです。

    • Hiromitsu Nishizaki 投稿者返信

      wheelのインストールログを見ると,
      python -m pip install wheel --upgrade
      で最新版のwheelにアップデートしたみたいです。
      参考になれば幸いです。

      • Syungyo 返信

        早速のご返信ありがとうございます。

        無事wheelをアップデートでき、addonsも導入できました。
        ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です