Installing TensorFlow 2.4 and JupyterLab on Mac with M1 (outdated)

This post is now outdated since Apple released TensorFlow 2.5 optimized for Macs, which is twice as fast as TensorFlow 2.4 was on my M1. See how to install it at

A few weeks ago (see Getting started with ML: Colab or self-hosted Jupyter?), I said I would eventually install JupyterLab locally on my Mac with M1.


The date is May 22, 2021. After 3 months of trial and error, I finally managed to run TensorFlow and Jupyter Lab on M1. It turns out it's about 6 times faster than Colab.


The quickest way to do it is to follow this guide with one change (see below):

Installing Tensorflow on M1 Macs
Once I started my journey into data science, I immediately regretted the decision my younger self made on purchasing my Macbook Pro. I went for storage over memory or processing speed and it showed…

Instead of using the provided yml, you should use this yml:

name: apple_tensorflow
  - conda-forge
  - nodefaults
  - grpcio
  - h5py
  - ipython
  - numpy=1.19.5
  - pip=20.2.4
  - python=3.8
  - scipy
  - termcolor
  - typeguard
  - wheel
  - absl-py
  - astunparse
  - python-flatbuffers
  - gast
  - google-pasta
  - keras-preprocessing
  - opt_einsum
  - protobuf
  - tensorboard
  - tensorflow-estimator
  - termcolor
  - typing_extensions
  - wrapt
  - jupyterlab
  - pandas
  - seaborn
  - scikit-learn
  - matplotlib
  - notebook

The only difference is, it forces numpy to use 1.19.5 instead of 1.20.*. 1.20.* is known to not play well with TensorFlow. If you're interested, you can read my notes of how I ended up with this solution.

Installing pip

First I had to install pip. I followed However, running python returned this error:

ERROR: This script does not work on Python 2.7 The minimum supported Python version is 3.6. Please use instead.

Instead I had to run python3

% python3
Defaulting to user installation because normal site-packages is not writeable
Collecting pip
  Downloading pip-21.0.1-py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 1.4 MB/s 
Installing collected packages: pip
  WARNING: The scripts pip, pip3 and pip3.8 are installed in '/Users/[username]/Library/Python/3.8/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-21.0.1
WARNING: You are using pip version 19.2.3; however, version 21.0.1 is available.
You should consider upgrading via the '/Applications/ -m pip install --upgrade pip' command.

This is strange, why does it say that it installed pip 21, then tells me I am using pip 19?

Anyway, to finish I add Python's bin folder to the path with vim .zshrc. When I reopen the terminal and run pip, it works as expected.

Installing pipenv

Over at, I follow their install command:

% pip install --user pipenv

Then try it by running pipenv, and it works.

Installing packages

JupyterLab installs fine.

% pipenv install jupyterlab
Creating a virtualenv for this project...
Pipfile: /Users/[username]/git/jupyter/Pipfile
Using /usr/bin/python3 (3.8.2) to create virtualenv...
⠦ Creating virtual environment...created virtual environment in 410ms
  creator CPython3macOsFramework(dest=/Users/[username]/.local/share/virtualenvs/jupyter-l45QZaht, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/[username]/Library/Application Support/virtualenv)
    added seed packages: pip==21.0.1, setuptools==52.0.0, wheel==0.36.2
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

✔ Successfully created virtual environment! 
Virtualenv location: /Users/[username]/.local/share/virtualenvs/jupyter-l45QZaht
Creating a Pipfile for this project...
Installing jupyterlab...
Adding jupyterlab to Pipfile's [packages]...
✔ Installation Succeeded 
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success! 
Updated Pipfile.lock (73f34e)!
Installing dependencies from Pipfile.lock (73f34e)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

But it failed for TensorFlow.

% pipenv install tensorflow
Installing tensorflow...
Adding tensorflow to Pipfile's [packages]...
✔ Installation Succeeded 
Pipfile.lock (73f34e) out of date, updating to (afb705)...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✘ Locking Failed! 
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 741, in _main
[ResolutionFailure]:       resolve_packages(pre, clear, verbose, system, write, requirements_dir, packages, dev)
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 702, in resolve_packages
[ResolutionFailure]:       results, resolver = resolve(
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 684, in resolve
[ResolutionFailure]:       return resolve_deps(
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 1395, in resolve_deps
[ResolutionFailure]:       results, hashes, markers_lookup, resolver, skipped = actually_resolve_deps(
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 1108, in actually_resolve_deps
[ResolutionFailure]:       resolver.resolve()
[ResolutionFailure]:   File "/Users/[username]/Library/Python/3.8/lib/python/site-packages/pipenv/", line 833, in resolve
[ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: Could not find a version that matches tensorflow (from -r /var/folders/ym/2b7pw1yn0v71ybqwb07t4vw00000gn/T/pipenv_jovmhf7requirements/pipenv-f853nmkj-constraints.txt (line 2))
No versions found
Was reachable?

The URL is indeed reachable. I get the same error when I run the recommended pipenv lock --clear. When I run pipenv graph, however, I do see TensorFlow installed:

  - absl-py [required: ~=0.10, installed: 0.11.0]
    - six [required: Any, installed: 1.15.0]
  - astunparse [required: ~=1.6.3, installed: 1.6.3]
    - six [required: >=1.6.1,<2.0, installed: 1.15.0]
    - wheel [required: >=0.23.0,<1.0, installed: 0.36.2]
  - flatbuffers [required: ~=1.12.0, installed: 1.12]
  - gast [required: ==0.3.3, installed: 0.3.3]
  - google-pasta [required: ~=0.2, installed: 0.2.0]
    - six [required: Any, installed: 1.15.0]
  - grpcio [required: ~=1.32.0, installed: 1.32.0]
    - six [required: >=1.5.2, installed: 1.15.0]
  - h5py [required: ~=2.10.0, installed: 2.10.0]
    - numpy [required: >=1.7, installed: 1.19.5]
    - six [required: Any, installed: 1.15.0]
  - keras-preprocessing [required: ~=1.1.2, installed: 1.1.2]
    - numpy [required: >=1.9.1, installed: 1.19.5]
    - six [required: >=1.9.0, installed: 1.15.0]
  - numpy [required: ~=1.19.2, installed: 1.19.5]

Running JupyterLab

Following, I run:

pipenv shell
jupyter lab

Training a model

Looks like in Colab, keras is not automatically available as in Colab. On, seeing from the screenshot, I should be importing it from tensorflow instead:

from tensorflow import keras

But every time I run this import, the Kernel crashes.

So it might be that TensorFlow did in fact not install correctly.

Using TensorFlow's M1 build

I am using a new Mac Mini with M1 processors. On this post, it seems that TensorFlow requires specific Python versions and hardware.

Could not find a version that satisfies the requirement tensorflow
I installed the latest version of Python (3.6.4 64-bit) and the latest version of PyCharm (2017.3.3 64-bit). Then I installed some modules in PyCharm (Numpy, Pandas, etc), but when I tried installing

So let's check the requirements on the official site. I remembered the announcement that TensorFlow supported M1 processors. Here's the blog post:

It turns out the instructions to install this special build is at a separate repository, and is being brought into the main repository. So until then, we have to use the separate repository and instructions at

The installation guide is really nice. You can run their script, and it will create a venv environment with TensorFlow installed. After installing, I switch to the environment, install Jupyter Lab, run it and try importing tf again:

. "/Users/[username]/tensorflow_macos_venv/bin/activate"
pip install jupyterlab
jupyter lab

But I still get the same crash.

It also didn't output a precise error message, and when running, Jupyter doesn't tell whether there is a log file.

Googling the error some more, some recent posts recommend to upgrade Numpy:

The second link also recommends to try in a separate python script first, as does, but for other reasons.

First I upgraded numpy just to see if it would work with dumb luck. pip list reveals I had version 1.18.5. Running pip install -U numpy upgraded it to version 1.20.1.

I ran JupyterLab and it failed again to load tf again.

Finally I tried with the python interpreter:

% python
Python 3.8.2 (default, Dec 21 2020, 15:06:04) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from tensorflow import keras
zsh: illegal hardware instruction  python

Now we're getting somewhere! Googling the error, I end up on They say you should set up the environment to use the arm64 build of Python. Another person says you should disable Rosetta to run in the Terminal, which is roughly the same thing.

Trying to run the interpreter with arch, I get:

% arch -arm64 python
Python 3.8.2 (default, Dec 21 2020, 15:06:03) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from tensorflow import keras
Traceback (most recent call last):
  File "/Users/[username]/tensorflow_macos_venv/lib/python3.8/site-packages/tensorflow/python/", line 64, in <module>
    from tensorflow.python._pywrap_tensorflow_internal import *
ImportError: dlopen(/Users/[username]/tensorflow_macos_venv/lib/python3.8/site-packages/tensorflow/python/, 6): no suitable image found.  Did find:
	/Users/[username]/tensorflow_macos_venv/lib/python3.8/site-packages/tensorflow/python/ mach-o, but wrong architecture
	/Users/[username]/tensorflow_macos_venv/lib/python3.8/site-packages/tensorflow/python/ mach-o, but wrong architecture

I don't know what this means. Could it be that I should have run the install script without Rosetta enabled in the first place? The original install command was:

/bin/bash -c "$(curl -fsSL"

So this time I tried:

arch -arm64 /bin/bash -c "$(curl -fsSL"

It ran fine when activating with . "/Users/[username]/tensorflow_macos_venv/bin/activate", but when testing in the interpreter, I got the same error as above.

I tried using arch to run the activate script, but I get strange arch-related errors about commands not being in the PATH.

Since I really don't know what I am doing with this arch command, I decided to disable running Terminal with Rosetta and try again. Still no luck:

% python
Python 3.8.2 (default, Dec 21 2020, 15:06:04) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow
zsh: illegal hardware instruction  python

Let's see what the TF for M1 repo says:

Let's see what my platform is:

% uname -m

Weird. I thought I had disabled Rosetta?... I close all my windows and try again.

% uname
% uname -m
% file $(which python)
/usr/bin/python: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/python (for architecture x86_64):	Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture arm64e):	Mach-O 64-bit executable arm64e

Alright, let's download the internet and reinstall for the nth time:

And it worked!!

~ % python
Python 3.8.2 (default, Dec 21 2020, 15:06:03) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow

Phew, the key information was using uname -m to make sure you're running Terminal in arm64 mode. I wish this information was shown prominently in the installation notes. I might contribute a PR later.

Back to JupyterLab

I am now able to import tensorflow.keras, set up my model and image generators. When trying to train the model, I get this error:

~/tensorflow_macos_venv/lib/python3.8/site-packages/keras_preprocessing/image/ in load_img(path, grayscale, color_mode, target_size, interpolation)
    109         color_mode = 'grayscale'
    110     if pil_image is None:
--> 111         raise ImportError('Could not import PIL.Image. '
    112                           'The use of `load_img` requires PIL.')
    113     with open(path, 'rb') as f:

ImportError: Could not import PIL.Image. The use of `load_img` requires PIL.

Apparently I should install a package called pillow: But running pip install Pillow throws an error about missing jpeg dependency:

__main__.RequiredDependencyException: jpeg

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/private/var/folders/ym/2b7pw1yn0v71ybqwb07t4vw00000gn/T/pip-install-wnvucnmh/pillow_17e014a21d31478bb1bd2fbf32cd1d2a/", line 922, in <module>
    raise RequiredDependencyException(msg)

The headers or library files could not be found for jpeg,
a required dependency when compiling Pillow from source.

Please see the install instructions at:

On Mac OS, you can install it with Homebrew:

But now that Rosetta is disabled, Homebrew won't work:

% brew install jpeg
Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)!
Please create a new installation in /opt/homebrew using one of the
"Alternative Installs" from:
You can migrate your previously installed formula list with:
  brew bundle dump

The fix is to run the command using arch, according to

% arch -x86_64 brew install jpeg
==> Downloading
==> Downloading from
######################################################################## 100.0%
==> Pouring jpeg-9d.big_sur.bottle.tar.gz
/usr/local/Homebrew/Library/Homebrew/download_strategy.rb:94: warning: conflicting chdir during another chdir block
🍺  /usr/local/Cellar/jpeg/9d: 21 files, 953.8KB
==> `brew cleanup` has not been run in 30 days, running now...
Removing: /Users/[username]/Library/Caches/Homebrew/Cask/ (2.6MB)
Pruned 1 symbolic links and 5 directories from /usr/local

Back to installing Pillow:

Collecting pillow
  Using cached Pillow-8.1.0.tar.gz (44.9 MB)
Building wheels for collected packages: pillow
  Building wheel for pillow ( ... done
  Created wheel for pillow: filename=Pillow-8.1.0-cp38-cp38-macosx_10_14_arm64.whl size=707578 sha256=4c08daab32255655bb04495b979369cdccc6b8eb38095494c019c3b86bf42f85
  Stored in directory: /Users/[username]/Library/Caches/pip/wheels/4e/db/04/9dcbaf9865568850d9bbdeb9b6b697e70f804d18e7e8aac050
Successfully built pillow
Installing collected packages: pillow
Successfully installed pillow-8.1.0

For Pillow to be available in the JupyterLab environment, I had to restart the kernel.

Running again, I get a new error:

~/tensorflow_macos_venv/lib/python3.8/site-packages/PIL/ in raise_oserror(error)
     65     if not message:
     66         message = f"decoder error {error}"
---> 67     raise OSError(message + " when reading image file")

OSError: broken data stream when reading image file

To make sure my image files were not corrupted, I unzipped my dataset file again. It failed again. So some of my images are truncated. According to this issue on the Pillow repository, I can make Pillow ignore truncation errors with a flag:

from PIL import ImageFile

Let's run again. Another error pops up:

~/tensorflow_macos_venv/lib/python3.8/site-packages/keras_preprocessing/image/ in apply_affine_transform(x, theta, tx, ty, shear, zx, zy, row_axis, col_axis, channel_axis, fill_mode, cval, order)
    279     """
    280     if scipy is None:
--> 281         raise ImportError('Image transformations require SciPy. '
    282                           'Install SciPy.')
    283     transform_matrix = None

ImportError: Image transformations require SciPy. Install SciPy.

But the Tensorflow for M1 at states that NumPy is not available for M1:

SciPy and dependent packages and Server/Client TensorBoard packages

Let's try anyway:

% pip install scipy
Collecting scipy
  Using cached scipy-1.6.1.tar.gz (27.3 MB)
  Installing build dependencies ... error
  ERROR: Command errored out with exit status 1:
   command: /Users/[username]/tensorflow_macos_venv/bin/python3 /Users/anhtuan/tensorflow_macos_venv/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /private/var/folders/ym/2b7pw1yn0v71ybqwb07t4vw00000gn/T/pip-build-env-j_l1er80/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i -- wheel 'setuptools<=51.0.0' 'Cython>=0.29.18' 'pybind11>=2.4.3' 'numpy==1.19.2; python_version=='"'"'3.6'"'"' and platform_machine=='"'"'aarch64'"'"'' 'numpy==1.19.2; python_version=='"'"'3.7'"'"' and platform_machine=='"'"'aarch64'"'"'' 'numpy==1.16.5; python_version=='"'"'3.6'"'"' and platform_machine!='"'"'aarch64'"'"' and platform_python_implementation != '"'"'PyPy'"'"'' 'numpy==1.16.5; python_version=='"'"'3.7'"'"' and platform_machine!='"'"'aarch64'"'"' and platform_python_implementation != '"'"'PyPy'"'"'' 'numpy==1.17.3; python_version=='"'"'3.8'"'"' and platform_machine!='"'"'aarch64'"'"' and platform_python_implementation != '"'"'PyPy'"'"'' 'numpy==1.19.3; python_version=='"'"'3.9'"'"' and platform_python_implementation != '"'"'PyPy'"'"'' 'numpy==1.19.0; python_version=='"'"'3.6'"'"' and platform_python_implementation=='"'"'PyPy'"'"'' 'numpy==1.20.0; python_version=='"'"'3.7'"'"' and platform_python_implementation=='"'"'PyPy'"'"'' 'numpy; python_version>='"'"'3.10'"'"'' 'numpy; python_version>='"'"'3.8'"'"' and platform_python_implementation=='"'"'PyPy'"'"''
       cwd: None
  Complete output (4841 lines):
  Ignoring numpy: markers 'python_version == "3.6" and platform_machine == "aarch64"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.7" and platform_machine == "aarch64"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.6" and platform_machine != "aarch64" and platform_python_implementation != "PyPy"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.7" and platform_machine != "aarch64" and platform_python_implementation != "PyPy"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.9" and platform_python_implementation != "PyPy"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.6" and platform_python_implementation == "PyPy"' don't match your environment
  Ignoring numpy: markers 'python_version == "3.7" and platform_python_implementation == "PyPy"' don't match your environment
  Ignoring numpy: markers 'python_version >= "3.10"' don't match your environment
  Ignoring numpy: markers 'python_version >= "3.8" and platform_python_implementation == "PyPy"' don't match your environment

I'll skip the rest of the 4000 lines of logs. Basically it doesn't work. After some more digging, I found the open issue on scipy:

Numpy is fine though:

So until scipy is properly fixed to run on M1, I am stuck to using Colab. It only took me ten hours to find out!


Some people report having better luck with Conda, including installing scipy:

But to try it properly, I'd have to learn conda. I'll try later.


According to this post, it seems pretty straightforward with Miniforge3 as well. Let's try it.

Installing Tensorflow on M1 Macs
Once I started my journey into data science, I immediately regretted the decision my younger self made on purchasing my Macbook Pro. I went for storage over memory or processing speed and it showed…

A few gotchas. Right after installing Miniforge, it put me into the "base" environment. So when I tried to create a new environment as instructed, it would just spit some weird error. I had to deactivate, then create the environment as instructed, using their yml file.

After installing the environment, then the custom build of TensorFlow for M1, I tried training a sequential model. The code looks like this:

from tensorflow.keras.datasets import imdb
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=maxwords)
from tensorflow.keras.preprocessing.sequence import pad_sequences
x_train = pad_sequences(x_train, maxlen=maxlen)
x_test = pad_sequences(x_test, maxlen=maxlen)

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Embedding
model = Sequential()
model.add(Embedding(maxwords, 32))
model.add(Dense(1, activation="sigmoid"))
model.compile(loss="binary_crossentropy", metrics=["accuracy"]), y_train, batch_size=128, epochs=10, validation_split=.2)

However, it throw this error when instantiating LSTM:

NotImplementedError: Cannot convert a symbolic Tensor (strided_slice:0) to a numpy array.

The solution, according to this post, is to either use Python 3.8, or downgrade numpy.

I ran python --version and checked that I am using 3.8.1, and I used pip list to figure out my version of numpy. It's 1.20.3. I tried installing an earlier version with pip install numpy==1.19.5. Among the many errors, I got things like:

  clang: error: the clang compiler does not support 'faltivec', please use -maltivec and include altivec.h explicitly
  Running from numpy source directory.

[home]/miniforge3/envs/tensorflow/lib/python3.8/distutils/ UserWarning: Unknown distribution option: 'define_macros'

I have no idea what these mean. One person on StackOverflow seems to have managed to install it. See the post. They mention building from source and disabling some option. But I'm surprised that Miniforge was able to install it without any strange config. So instead, I specified the version 1.19.5 into the yml file I used to create an environment earlier.

... And it worked! Finally!

On the M1, one epoch takes 8s

Let's run it on Colab, and compare performance.

On Colab, for the same model, one epoch takes 53s

8s vs 53s. So it's about 6 times faster. Maybe performance increase will differ with the type of model. I'll perform more tests later.