M1 맥북 tensorflow 설치

이민기·2022년 5월 26일
1
post-thumbnail

M1 맥북 Tensorflow

1) Miniforge 설치

M1용 Miniforge Shell Script 다운로드
https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh

아래의 명령을 따라 Miniforge 실행
chmod +x ~/Downloads/Miniforge3-MacOSX-arm64.sh
sh ~/Downloads/Miniforge3-MacOSX-arm64.sh
source ~/miniforge3/bin/activate

2) Conda 환경 실행

conda create --name tf25 python=3.8
conda activate tf25

3) M1 실리콘용 Tensorflow 설치

2.5.0 설치가 중요하다. 현재 Tensorflow 기본버전은 2.6.0인데 Bigsur에서는 에러를 낸다. 2.6.0을 설치하려면 RC2인 몬테레이를 설치한 후에 이용 가능하다고 되어 있는데, 해보지는 않아서 장담할 수 없다.
conda install -c apple tensorflow-deps==2.5.0
pip install tensorflow-macos==2.5.0
pip install tensorflow-metal==0.1.2

4) 패키지 설치하기

필요한 패키지를 Conda로 설치해준다.
conda install -c conda-forge -y pandas jupyter

5) MNIST 실행해보기

우선 Tensorflow Dataset을 설치하고, 노트북을 실행한다.
pip install tensorflow_datasets
jupyter notebook

아래의 코드로 M1의 GPU 정상동작을 확인한다. 1개 있다고 나오면 정상동작이다.
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))

MNIST 학습 코드를 실행해본다.
%%time
import tensorflow.compat.v2 as tf
import tensorflow_datasets as tfds

tf.enable_v2_behavior()

from tensorflow.python.framework.ops import disable_eager_execution
disable_eager_execution()

(ds_train, ds_test), ds_info = tfds.load(
'mnist',
split=['train', 'test'],
shuffle_files=True,
as_supervised=True,
with_info=True,
)

def normalize_img(image, label):
"""Normalizes images: uint8 -> float32."""
return tf.cast(image, tf.float32) / 255., label

batch_size = 128

ds_train = ds_train.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_train = ds_train.cache()
ds_train = ds_train.shuffle(ds_info.splits['train'].num_examples)
ds_train = ds_train.batch(batch_size)
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE)

ds_test = ds_test.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_test = ds_test.batch(batch_size)
ds_test = ds_test.cache()
ds_test = ds_test.prefetch(tf.data.experimental.AUTOTUNE)

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, kernel_size=(3, 3),
activation='relu'),
tf.keras.layers.Conv2D(64, kernel_size=(3, 3),
activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),

tf.keras.layers.Dropout(0.25),

tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),

tf.keras.layers.Dropout(0.5),

tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.001),
metrics=['accuracy'],
)

model.fit(
ds_train,
epochs=12,
validation_data=ds_test,
)

몇개의 Warning이 나오지만 아래 내용이 나오는 것으로 보아 GPU를 활용하는 것처럼 보인다.
I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:112]
Plugin optimizer for device_type GPU is enabled.

최종적으로 아래의 결과를 얻었다.
Epoch 12/12
469/469 [==============================] - 10s 20ms/step - batch: 234.0000 -
size: 1.0000 - loss: 0.0028 - accuracy: 0.9991 - val_loss: 0.0428 - val_accuracy: 0.9900
CPU times: user 1min 13s, sys: 55.6 s, total: 2min 9s
Wall time: 2min 9s

7) Google Colab과의 비교

작년말 M1의 학습능력에 실망하고, Google Colab을 다시 이용했기 때문에 비교해보기로. 

우선 GPU를 이용하지 않았을 때
Epoch 12/12
469/469 [==============================] - 120s 243ms/step - batch: 234.0000

  • size: 1.0000 - loss: 0.0023 - accuracy: 0.9991 - val_loss: 0.0407 - val_accuracy: 0.9912
    CPU times: user 43min 15s, sys: 1min 29s, total: 44min 45s
    Wall time: 25min 34s

GPU를 이용했을 때 (K80밖에 안 잡히네 ㅠ)
Epoch 12/12
469/469 [==============================] - 17s 16ms/step - batch: 234.0000 -
size: 1.0000 - loss: 0.0028 - accuracy: 0.9991 - val_loss: 0.0494 - val_accuracy: 0.9882
CPU times: user 3min 27s, sys: 1min 18s, total: 4min 45s
Wall time: 3min 53s

GPU를 이용하지 않은 경우 대비해서는 12배 이상 M1이 빠르고 GPU(K80) 이용 대비해서도 2배정도는 빠르다. 단, Colab은 매 Epoch 마다 데이터를 가져오는 데 지연이 있는 듯 해서, 매 Epoch간 비교를 하면 M1 GPU로 학습할 때 K80보다 약 70% 정도 더 빠른 수준인 듯 하다. 

M1 수준이 이 정도니 M1 Pro나 M1 Max를 보유한 사용자는 간단한 학습용으로 별도의 GPU를 구매하지 않아도 될 듯. 비교 기사를 보니 2080 정도의 성능을 낸다고.. (하지만, 난 M1으로 충분해 ㅠ)

profile
지나가는사람

0개의 댓글