Installing TensorFlow 2.2 on Ubuntu 18.04 with an Nvidia GPU

Back in November 2017 we published an article on how to install TensorFlow 1.4 on a system with an Nvidia GPU. Since then much has changed within the deep learning community. TensorFlow itself has matured dramatically. In this article we are going to outline how to install the new version 2.2 of TensorFlow and configure it to work with a modern Nvidia GPU.

Earlier in the year we carried out our 2020 QuantStart Content Survey and Advanced Machine Learning & Deep Learning was voted the most popular topic. This article constitutes the first in a series on the topic of modern machine learning via deep learning as applied to systematic trading research.

In this article we will demonstrate how to install a modern deep learning research environment on a Linux machine via the TensorFlow library, which will form the basis of all subsequent deep learning research on QuantStart.

In the previous article on the same topic we discussed how sophisticated quantitative trading research with machine learning requires a robust framework to abstract away the machine learning model specification from the model implementation.

At the time of the original article the TensorFlow library provided such an abstraction by avoiding the need to write optimised deep learning models in low-level C, C++ or FORTRAN and the CUDA GPU programming model provided by Nvidia.

Since then the situation has improved further. Keras, a popular library for specifying deep learning models has now been directly incorporated into TensorFlow via the tf.keras high level deep learning API. This means it is now even easier to specify deep learning models within TensorFlow.

We have previously mentioned that there are many ways to install TensorFlow, depending on chosen operating system and available hardware. It is possible to execute TensorFlow code via pre-made cloud machine images on GPU-based cloud instances.

However for certain use cases it is arguably beneficial to train and execute deep learning models on a local custom workstation. This article describes how to install TensorFlow on such a workstation where the underlying operating system is Ubuntu 18.04.

For more background on TensorFlow, along with its choice as a deep learning research framework, please see our previous article on the topic.

Installation of TensorFlow

In the following sections we will discuss the necessary Python prerequisites, how to install TensorFlow for CPU-only use and how to install all CUDA prerequisites required for TensorFlow GPU use.

Python Environment Prerequisites

As mentioned in our previous installation article it is necessary to have a functional Python3 virtual environment in which to run TensorFlow.

To simplify the installation of a Python research environment QuantStart recommends downloading the latest Anaconda Individual distribution. As of the writing date of this article the latest version includes Python 3.7.

The Linux Python 3.7 installer script can be found here. Please refer to the Anaconda installation instructions for up to date details on how to install Anaconda on a Linux system.

Once Anaconda has been installed a separate virtual environment needs to be created to isolate the TensorFlow install. For the purposes of this tutorial the virtual environment has been named tf. To do this simply type the following into a terminal:

conda create -n tf
conda activate tf

This will create a new Conda virtual environment called tf and activate it.

Installing TensorFlow for CPU Use

If an Nvidia CUDA-capable GPU is not available then it is possible to install TensorFlow for use solely with a CPU. Training will be significantly slower on a CPU compared to a GPU. Despite this a CPU install may prove useful for smaller models and self-teaching purposes.

To install TensorFlow simply type the following into a Conda activated terminal:

pip install tensorflow

This will install TensorFlow and the necessary dependencies. Once this has finished you can skip ahead to the TensorFlow Installation Validation section below.

Installing TensorFlow for GPU Use

The installation of TensorFlow against an Nvidia GPU has a reputation for being difficult. It often requires reasonably mature command line skills in order to diagnose potential issues that can arise.

At QuantStart we have previously carried out this procedure on Nvidia GPUs ranging from a pair of older GeForce GTX 780 Ti variants through to a newer GeForce GTX 1080 Ti instance.

Along the way we have encountered some of the common difficulties, particularly as related to Secure UEFI Boot (see below) and Nvidia driver installation. Thankfully the procedure is now more straightforward than it has been in the past.

The latest range of consumer grade Nvidia GPUs as of the writing date of this article are the 20xx RTX series, which are now recommended since they work well with modern deep learning models and are reasonably cheap.

Overview

To install TensorFlow 2.2 with CUDA capability we will first carry out a series of checks to ensure compatibility with both the hardware and software on the specific worksation.

Once these checks are complete we will follow the official TensorFlow GPU installation instructions by installing CUDA, cuDNN, TensorRT and an appropriate Nvidia driver.

Once all the packages have been successfully installed we will test that TensorFlow works with the GPUs by importing the library and carrying out a basic tensor computation.

Secure UEFI Boot

An issue that often arises when attempting to install Nvidia drivers on Linux involves a motherboard setting known as Secure UEFI Boot. In order for the driver installation to be successful it is necessary to disable this setting on most motherboards.

The procedure for carrying this out is highly specific to each particular motherboard. Hence it is difficult to provide detailed instructions that apply to a range of system configurations.

In broad terms it will be necessary to enter the BIOS as the machine boots up. This can usually be achieved by pressing the Del or F10 key. Once in the BIOS it is necessary to navigate to the section that determines boot settings. To disable Secure UEFI Boot it sometimes involves backing up and removing certain keys while in other instances it is simply a boolean setting that is easily modified.

If this feature is not disabled then in all likelihood trouble will arise subsequent to the Nvidia driver installation. Issues may occur when attempting to login in to Ubuntu after bootup. The problem is particularly difficult to resolve as it often involves an inability to load the Ubuntu GUI!

Pre-CUDA Installation Checks

Before we consider installing CUDA it is worth carrying out the following pre-CUDA installation checks to avoid any subsequent issues:

  • Check that the system has a GPU that is CUDA capable
  • Check that the Ubuntu version is supported
  • Check that the GNU Compiler Collection (gcc) is installed
  • Check that the appropriate development packages and kernel headers are available
  • Check for any currently installed Nvidia drivers that may conflict with CUDA

Check GPU is CUDA Capable

The lspci command prints detailed information about PCI buses and devices within the workstation. We can use it to determine the type of Nvidia card available. Type the following into a terminal:

lspci | grep -i nvidia

You should see output that resembles the following:

01:00.0 VGA compatible controller: NVIDIA Corporation GK110B [GeForce GTX 780 Ti] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GK110 HDMI Audio (rev a1)
02:00.0 VGA compatible controller: NVIDIA Corporation GK110B [GeForce GTX 780 Ti] (rev a1)
02:00.1 Audio device: NVIDIA Corporation GK110 HDMI Audio (rev a1)

This indicates that two GeForce GTX 780 Ti cards are installed in the workstation. Nvidia provide a list of CUDA capable GPUs here. Check your card against this list to ensure that it provides the necessary CUDA capability.

Check Ubuntu Version is Supported

The unix name uname command outputs the name, version and further details on the current machine and operating system. Type the following into a terminal to determine the architecture of the machine hardware:

uname -m

You should see the following output:

x86_64

This shows that a 64-bit x86 compatible CPU is available.

To determine the version of Ubuntu installed type the following:

cat /etc/lsb-release

You will see output similar to the following assuming Ubuntu 18.04 LTS is installed:

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"

This confirms the compatibility of the machine hardware and the operating system.

Check gcc is Installed

In order to install CUDA it is necessary to have a C++ compiler installed. Ubuntu provides the GNU Compiler Collection (gcc) for this purpose. If it has not been installed previously it is usually necessary to run the following installation command:

sudo apt-get install build-essential

The version of gcc can then be determined with the following command:

gcc --version

The output will be similar to the following:

gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In this case the version of gcc is 7.5.0, which is sufficient for the purposes of CUDA installation.

Check Appropriate Development Packages and Headers

To determine which Linux kernel is available type the following into a terminal:

uname -r

The output will be similar to the following:

5.3.0-62-generic

With the name of the kernel determined the next step is to install the appropriate kernel headers and development packages via the following command. Make sure to replace your kernel version with the output from above:

sudo apt-get install linux-headers-5.3.0-62-generic

The (truncated) output will be similar to the following:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
linux-headers-5.3.0-62-generic is already the newest version (5.3.0-62.56~18.04.1).
linux-headers-5.3.0-62-generic set to manually installed.
The following packages were automatically installed and are no longer required:
  ..
  ..
Use 'sudo apt autoremove' to remove them.
0 to upgrade, 0 to newly install, 0 to remove and 78 not to upgrade.

The above confirms that the headers were already installed on the tested workstation.

Check Current Nvidia Drivers

If you already have an Nvidia driver installed it is possible to determine the version by typing the following into the terminal:

nvidia-smi

The output will be similar to the following:

Wed Jul 15 14:27:36 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.100      Driver Version: 440.100      CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 780 Ti  Off  | 00000000:01:00.0 N/A |                  N/A |
| 37%   55C    P2    N/A /  N/A |   1244MiB /  3018MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 780 Ti  Off  | 00000000:02:00.0 N/A |                  N/A |
| 17%   36C    P8    N/A /  N/A |      1MiB /  3022MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0                    Not Supported                                       |
|    1                    Not Supported                                       |
+-----------------------------------------------------------------------------+

In this instance the Nvidia driver version is 440.100 is already installed.

We are now ready to proceed with the installation of CUDA, cuDNN and TensorRT.

Installation of CUDA Framework

The following steps are taken from the TensorFlow GPU installation documentation and have been tested on a local workstation.

Please enter the following commands into the terminal to install CUDA 10.1 (not 10.2) on the system:

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo dpkg -i cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt-get update

The above commands download the CUDA repository for Ubuntu 18.04 as a Debian package. The keys are then obtained. The dpkg command is then used to install the CUDA Debian package. The apt repositories are then updated and the further repositories (nvidia-machine-learning-repo-***) are downloaded and installed. Finally the apt repositories are updated once again.

At this point it is possible to install the Nvidia driver version 450:

sudo apt-get install --no-install-recommends nvidia-driver-450

Once this completes it will be necessary to reboot the system to ensure that the Nvidia driver can be loaded correctly. After a successful reboot it is possible to utilise nvidia-smi to ensure that the GPUs remain visible:

nvidia-smi

The output will look similar to the following:

Wed Jul 15 14:49:41 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.51.05    Driver Version: 450.51.05    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce GTX 780 Ti  On   | 00000000:01:00.0 N/A |                  N/A |
| 37%   57C    P0    N/A /  N/A |   1057MiB /  3018MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 780 Ti  On   | 00000000:02:00.0 N/A |                  N/A |
| 17%   37C    P8    N/A /  N/A |      3MiB /  3022MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

The next step is to download the CUDA 10.1 and cuDNN 7.6 runtime libraries. The total file size of the packages is approximately 5GB. This will likely take time to both download and install, depending upon your connection. Type the following to install the packages:

sudo apt-get install --no-install-recommends cuda-10-1 libcudnn7=7.6.4.38-1+cuda10.1 libcudnn7-dev=7.6.4.38-1+cuda10.1

The next step is to (optionally) install TensorRT, which is designed to "improve latency and throughput for inference on some models", as mentioned within the TensorFlow GPU documentation. To carry this out type the following into a terminal:

sudo apt-get install -y --no-install-recommends libnvinfer6=6.0.1-1+cuda10.1 libnvinfer-dev=6.0.1-1+cuda10.1 libnvinfer-plugin6=6.0.1-1+cuda10.1

At this stage all of the necessary libraries and packages have been installed.

It is now possible to install TensorFlow in the same manner as for the CPU above. Ensure the Conda virtual environment is activated and type the following to install TensorFlow:

pip install tensorflow

The final step is to verify that the installation has been successful and that TensorFlow runs against the GPU.

TensorFlow Installation Validation

To validate the installation of TensorFlow on a GPU open up an interactive Python console by typing the following into the terminal:

python

Run the following commands in the Python shell to import TensorFlow and check that it is built against CUDA:

import tensorflow as tf
tf.test.is_built_with_cuda()

If successful the output should simply state True:

Python 3.6.9 (default, Apr 18 2020, 01:56:04) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> tf.test.is_built_with_cuda()
True

If you are utilising the CPU version of TensorFlow this will return False.

In order to determine which GPUs have been detected by TensorFlow the following command can be run in a Python console after importing TensorFlow as above:

tf.config.list_physical_devices('GPU')

The (truncated) output will look similar to the following:

[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]

In this instance the two 780 Ti GPUs mentioned earlier in the article have both been detected.

As a final check (for both CPU and GPU versions) it is possible to carry out a basic TensorFlow computation directly from the command line. This means that the following is not executed within a Python console. Instead the command is executed in a normal Ubuntu terminal:

python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))"

This (truncated) output from this command will look similar to the following:

..
..
..
2020-07-15 15:20:15.379624: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-07-15 15:20:15.379944: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-07-15 15:20:15.380279: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-07-15 15:20:15.380570: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1703 MB memory) -> physical GPU (device: 0, name: GeForce GTX 780 Ti, pci bus id: 0000:01:00.0, compute capability: 3.5)
2020-07-15 15:20:15.380931: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-07-15 15:20:15.381252: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:1 with 2652 MB memory) -> physical GPU (device: 1, name: GeForce GTX 780 Ti, pci bus id: 0000:02:00.0, compute capability: 3.5)
tf.Tensor(554.52527, shape=(), dtype=float32)

The last line contains the result of the reduce_sum computation. Note that since a random normal distribution is being sampled within this computation it is possible that the resulting tensor will have a different value compared to the one above.

This now verifies that TensorFlow has been successfully installed against the GPU.

Next Steps

The next series of articles will provide an overview of what TensorFlow is and how it works. Subsequent to our tour of TensorFlow we will begin creating some machine learning architectures to solve some simple classification problems. Eventually we will begin discussion of deep neural network architectures and how to implement them in TensorFlow.

References