Machine learning with Intel / AMD GPU’s on Mac OS

I have found machine learning with GPU acceleration on Mac OS to be much more difficult to setup than on Windows, or Linux. This seems to be in no small part because of Apple. Apple has removed all support for NVIDIA GPU’s from the OSX platform. So no CUDA. In addition they don’t support the open source standard for machine learning on linux Rocm.

So what options do we have? Well we have to piece together a set of interlocking software to make things work.

PlaidML. PlaidML is a machine learning backend or compiler. It supports Apples Metal api. This will be our base. PlaidML ships with a implementation of Keras. So if all you are looking for is Keras support you can stop after installing PlaidML.

nGraph. However what if you want to use Tensorflow or PyTorch? nGraph has our back. nGraph is yet another machine learning compiler. NGraph supports using PlaidML as it’s backend. This effectively can translate between Tensorflow and PlaidML. Then PlaidML will use Apples Metal API. So using nGraph+PlaidML we can achieve something like this.

Tensorflow -> nGraph -> PlaidML -> Metal -> GPU

NGraph+PlaidML work to abstract away the hardware from our machine learning software.

As you can see nGraph + PlaidML overcomes our limitation of No CUDA or RocM. This setup will compile everything down to Apples Metal API.

Installing PlaidML

Please note these instructions assume you already have homebrew installed and Python3

Create a Python Virtualenv so we can keep our ML Python install contained from the system.

Note that if you ever close the terminal or restart the machine you will need to source the Virtualenv again.

python3 -m venv ml-venv
source ml-venv/bin/activate

Now install PlaidML

pip3 install -U plaidml-keras

Configure PlaidML

Now we need to tell PlaidML what graphics card we will be using. Run setup. If you have a eGPU plug it in first so it can be detected.

You will be asked if you want to use experimental devices. Such as OpenCL or llvm. Choose no to use Apple’s Metal API.
If you have more then one Graphics card you will be asked what one to use. If you ever need to change the card in use just run setup again. As you can see Intel GPU’s work as well. Very cool if you need to do some work on the go.
Finally you will be asked to save the settings. Choose y for yes.

Test PlaidML

At this point you have a working Keras install that can use GPU acceleration. Let’s test it out.

pip3 install plaidml-keras plaidbench
plaidbench keras mobilenet
If everything is working correctly you should see an output like above. We can also see our GPU is being used for processing.

Using PladML’s built in Keras

If you want to use the built in Keras that comes with PlaidML then add the following code to your Jupyter Notebook or Python file.

import os
os.environ["KERAS_BACKEND"] = "plaidml.keras.backend"

Installing Tensorflow and nGraph

Let’s continued setting up nGraph + PlaidML and Tensorflow. First let’s install Tensorflow.

pip3 install -U tensorflow==1.14.0
pip3 install -U ngraph-tensorflow-bridge

As of the writing of this article Tensorflow 1.14.0 is the newest supported version by nGraph. Check the nGraph website for updates.

Optional dependencies

Let’s also install some other common libraries used in ML so we won’t have to deal with finding them later. This is not required for this tutorial but will save headaches later.

pip3 install opencv-contrib-python
pip3 install numpy
pip3 install scipy
pip3 install pillow 
pip3 install scikit-learn scikit-image
pip3 install imutils h5py requests progressbar2
pip3 install matplotlib

Let’s also install Jupyter Notebook as we will probably need it later.

pip3 install jupyterlab

Working with Tensorflow.

Working with Tensorflow should be basically the same as normal. However you will have to make the following code changes to activate GPU acceleration.

At the top of your NoteBook or python file before importing Tensorflow.

import ngraph_bridge

Then find import tensorflow as tf and add this code after it.

config = tf.ConfigProto()
config_ngraph_enabled = ngraph_bridge.update_config(config)
sess = tf.Session(config=config_ngraph_enabled)