tutorial,

AI - Apple Silicon Mac M1/M2 原生支持 TensorFlow 2.10 GPU 加速(tensorflow-metal PluggableDevice)

Read in English

前言

几天前,见到 https://github.com/apple/tensorflow_macos 已经 Archived,并在 README 中看到了 TensorFlow v2.5 原生支持了 M1。

You can now leverage Apple’s tensorflow-metal PluggableDevice in TensorFlow v2.5 for accelerated training on Mac GPUs directly with Metal. Learn more here.

本文作为Apple Silicon Mac M1/M2 机器学习环境 (TensorFlow, JupyterLab, VSCode)的更新篇,为大家详细介绍如何安装最新支持 GPU 加速版本的 TensorFlow。

系统要求

  • macOS 12.0+

当前不支持

  • 多 GPU 支持
  • 英特尔 GPU 的加速
  • V1 TensorFlow 网络

Xcode

从 App Store 安装 Xcode。

Command Line Tools

Apple Developer 下载安装 Xcode Command Line Tools 或者执行以下命令。

1
catchzeng@m1 ~ % xcode-select --install

Homebrew

1
catchzeng@m1 ~ % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Miniforge

Anaconda 无法在 Apple Silicon 上运行, Miniforge 是用来替代它的。

https://github.com/conda-forge/miniforge 下载 Miniforge3-MacOSX-arm64

如果你使用的是 bash,执行以下命令,安装 Miniforge

1
catchzeng@m1 ~ % bash Miniforge3-MacOSX-arm64.sh

如果你使用的是 zsh,执行以下命令,安装 Miniforge

1
catchzeng@m1 ~ % zsh Miniforge3-MacOSX-arm64.sh

重启终端并检查 Python 安装情况。

1
2
3
4
(base) catchzeng@m1 ~ % which python
/Users/catchzeng/miniforge3/bin/python
(base) catchzeng@m1 ~ % which pip
/Users/catchzeng/miniforge3/bin/pip

创建虚拟环境

创建一个 conda 创建虚拟环境,这里使用 python 3.9.5 (TensorFlow 需要)。

1
2
3
(base) catchzeng@m1 ~ % conda create -n tensorflow python=3.9.5
(base) catchzeng@m1 ~ % conda activate tensorflow
(tensorflow) catchzeng@m1 ~ %

安装 Tensorflow dependencies

首次安装

1
(tensorflow) catchzeng@m1 ~ % conda install -c apple tensorflow-deps

注:tensorflow-deps 的版本是基于 TensorFlow 的,因此可以根据自己的需求指定版本安装:

v2.8

1
(tensorflow) catchzeng@m1 ~ % conda install -c apple tensorflow-deps==2.8.0

v2.10

1
(tensorflow) catchzeng@m1 ~ % conda install -c apple tensorflow-deps==2.10.0

升级安装

如果之前已经安装了 v2.8,想要更新 v2.10 的,可以执行以下命令安装。

1
2
3
4
5
6
7
# 卸载已安装的 tensorflow-macos 和 tensorflow-metal
(tensorflow) catchzeng@m1 ~ % python -m pip uninstall tensorflow-macos
(tensorflow) catchzeng@m1 ~ % python -m pip uninstall tensorflow-metal
# 升级 tensorflow-deps
(tensorflow) catchzeng@m1 ~ % conda install -c apple tensorflow-deps --force-reinstall
# 后者指向特定的 conda 环境
(tensorflow) catchzeng@m1 ~ % conda install -c apple tensorflow-deps --force-reinstall -n tensorflow

安装 Tensorflow

1
(tensorflow) catchzeng@m1 ~ % python -m pip install tensorflow-macos

安装 metal plugin

1
(tensorflow) catchzeng@m1 ~ % python -m pip install tensorflow-metal

安装必须的包

1
2
(tensorflow) catchzeng@m1 ~ % brew install libjpeg
(tensorflow) catchzeng@m1 ~ % conda install -y matplotlib jupyterlab

注意: libjpeg 是 matplotlib 需要依赖的库。

测试

TensorFlow

1
2
3
4
5
6
7
8
9
10
11
(tensorflow) catchzeng@m1 ~ % python
Python 3.9.5 | packaged by conda-forge | (default, Jun 19 2021, 00:24:55)
[Clang 11.1.0 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
Init Plugin
Init Graph Optimizer
Init Kernel
>>> print(tf.__version__)
2.10.0
>>>

JupyterLab

1
(tensorflow) catchzeng@m1 ~ % jupyter lab

1
2
3
4
5
6
7
8
9
10
11
12
from tensorflow.keras import layers
from tensorflow.keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=64)
test_loss, test_acc = model.evaluate(test_images, test_labels)
test_acc

打开活动监视器,可以看到 Python 正在使用 GPU 资源。

VSCode

安装 Python 支持

选择虚拟环境并信任 notebook

运行 notebook

延伸阅读

参考


CatchZeng
Written by CatchZeng Follow
AI (Machine Learning) and DevOps enthusiast.