Questo articolo costituisce il primo di una serie di articoli sul tema del moderno machine learning tramite il deep learning applicato alla ricerca di trading sistematico. In particolare descriviamo come installare un moderno ambiente di ricerca di deep learning su una macchina Linux tramite la libreria TensorFlow, che costituirà la base di tutte le successive ricerche di deep learning su DataTrading.
Ambiente di ricerca avanzata sul trading quantitativo con il machine learning richiede un framework solido per astrarre le specifiche del modello di machine learning dall’implementazione del modello. A tale scopo possiamo usare la libreria TensorFlow, sviluppata e rilasciata da Google. Le prime versione della libreria TensorFlow fornivano tale astrazione, evitando la necessità di scrivere modelli di deep learning ottimizzati in C, C++ o FORTRAN di basso livello e il modello di programmazione GPU CUDA fornito da Nvidia.
Da allora la situazione è ulteriormente migliorata. Keras, una popolare libreria per la specifica di modelli di deep learning è stata ora incorporata direttamente in TensorFlow tramite l’API tf.keras
di deep learning di alto livello. In questo modo è ancora più semplice specificare modelli di deep learning all’interno di TensorFlow.
Esistono molti modi per installare TensorFlow, a seconda del sistema operativo e dell’hardware disponibili. È possibile eseguire il codice TensorFlow tramite immagini pre-costruite per macchine virtuali su istanze cloud basate su GPU.
Tuttavia, per alcuni casi d’uso è probabilmente vantaggioso addestrare ed eseguire modelli di deep learning su una workstation personalizzata in locale. Questo articolo descrive come installare TensorFlow su una workstation di questo tipo in cui il sistema operativo sottostante è Ubuntu 18.04.
Installazione di TensorFlow
Nelle sezioni seguenti descriviamo i prerequisiti Python necessari, come installare TensorFlow per l’uso solo della CPU e come installare tutti i prerequisiti CUDA richiesti per l’uso della GPU con TensorFlow.
Prerequisiti dell’ambiente Python
E’ necessario disporre di un funzionale ambiente virtuale Python3 dove eseguire TensorFlow. Per semplificare l’installazione di un ambiente di ricerca Python, consigliamo di scaricare l’ultima distribuzione Anaconda, Individual. Alla data di scrittura di questo articolo l’ultima versione include Python 3.7.
Lo script di installazione di Linux Python 3.7 può essere trovato qui. Possiamo fare riferimento alle istruzioni di installazione di Anaconda per dettagli aggiornati su come installare Anaconda su un sistema Linux.
Una volta che Anaconda è stato installato, dobbiamo creare un ambiente virtuale separato per isolare l’installazione di TensorFlow. Ai fini di questo tutorial l’ambiente virtuale è stato denominato tf
. E’ sufficiente digitare quanto segue in un terminale:
conda create -n tf
conda activate tf
In questo modo creiamo un nuovo ambiente virtuale Conda chiamato tf
e lo attiviamo.
Installazione di TensorFlow per l’utilizzo della CPU
Se non è disponibile una GPU compatibile con Nvidia CUDA, è possibile installare TensorFlow per essere usato solo con una CPU. L’allenamento sarà significativamente più lento su una CPU rispetto a una GPU. Nonostante ciò un’installazione sulla CPU può rivelarsi utile per i modelli più piccoli e per scopi di studio da auto-didatta
Per installare TensorFlow è sufficiente digitare quanto segue in un terminale con un ambiente Conda attivato:
pip install tensorflow
Con questo comando installiamo TensorFlow e le dipendenze necessarie. Al termine, possiamo passare al seguente paragrafo Convalida dell’installazione di TensorFlow.
Installazione di TensorFlow per l’utilizzo della GPU
L’installazione di TensorFlow su una GPU Nvidia ha la reputazione di essere difficile. Spesso richiede abilità da riga di comando abbastanza esperte per diagnosticare potenziali problemi che possono sorgere.
In DataTrader abbiamo precedentemente eseguito questa procedura su GPU Nvidia che vanno da un paio di vecchie varianti GeForce GTX 780 Ti fino a un’istanza GeForce GTX 1080 Ti più recente.
Lungo la strada abbiamo riscontrato alcune delle difficoltà comuni, in particolare relative all’avvio sicuro UEFI (vedi sotto) e all’installazione del driver Nvidia. Per fortuna ora la procedura è più semplice di quanto non fosse in passato.
L’ultima gamma di GPU Nvidia di fascia consumer alla data di scrittura di questo articolo sono le serie 20xx RTX , che ora sono consigliate poiché funzionano bene con i moderni modelli di deep learning e sono ragionevolmente economiche.
Panoramica
Per installare TensorFlow 2.2 con funzionalità CUDA, eseguiamo prima una serie di controlli per garantire la compatibilità sia con l’hardware che con il software sulla specifica workstation.
Una volta completati questi controlli, seguiamo le istruzioni ufficiali di installazione di TensorFlow con la GPU installando CUDA, cuDNN, TensorRT e un appropriato driver Nvidia.
Una volta che tutti i pacchetti sono stati installati con successo, testiamo che TensorFlow funzioni con le GPU importando la libreria ed eseguendo un calcolo tensoriale di base.
Avvio UEFI sicuro
Un problema che si verifica spesso quando si tenta di installare i driver Nvidia su Linux riguarda un’impostazione della scheda madre nota come Secure UEFI Boot. Affinché l’installazione del driver abbia successo, è necessario disabilitare questa impostazione sulla maggior parte delle schede madri.
La procedura per eseguire questa operazione è altamente specifica per ogni particolare scheda madre. Pertanto non possiamo fornire istruzioni dettagliate che si applicano a una gamma di configurazioni di sistema.
In termini generali è necessario accedere al BIOS all’avvio della macchina. Di solito possiamo accedervi premendo il tasto Canc o F10. Una volta nel BIOS dobbiamo passare alla sezione che determina le impostazioni di avvio. Per disabilitare Secure UEFI Boot a volte dobbiamo eseguire il backup e la rimozione di determinate chiavi mentre in altri casi dobbiamo semplicemente modificare un parametro booleano.
Se questa funzione non è disabilitata, con ogni probabilità si verificheranno problemi in seguito all’installazione del driver Nvidia. Possono verificarsi problemi quando si tenta di accedere a Ubuntu dopo l’avvio. Il problema è particolarmente difficile da risolvere in quanto spesso comporta l’impossibilità di caricare la GUI di Ubuntu!
Verifiche di installazione pre-CUDA
Prima di considerare l’installazione di CUDA, vale la pena eseguire i seguenti controlli prima dell’installazione di CUDA per evitare problemi successivi:
- Verificare che il sistema disponga di una GPU compatibile con CUDA
- Verificare che la versione di Ubuntu sia supportata
- Verificare che GNU Compiler Collection (gcc) sia installato
- Verificare che siano disponibili i pacchetti di sviluppo appropriati e le intestazioni del kernel
- Verificare la presenza di driver Nvidia attualmente installati che potrebbero entrare in conflitto con CUDA
Verificare che la GPU sia compatibile con CUDA
Il comando lspci
stampa informazioni dettagliate sui bus PCI e sui dispositivi all’interno della workstation. Possiamo usarlo per determinare il tipo di scheda Nvidia disponibile. Digitiamo quanto segue in un terminale:
lspci | grep -i nvidia
Dovremmo ottenere un output simile al seguente:
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)
Vediamo che nella workstation sono installate due schede GeForce GTX 780 Ti. Nvidia fornisce un elenco di GPU compatibili con CUDA qui . Controlla la tua scheda rispetto a questo elenco per assicurarti che fornisca la capacità CUDA necessaria.
Verificare che la versione di Ubuntu sia supportata
Il comando unix name uname
restituisce il nome, la versione e ulteriori dettagli sulla macchina e sul sistema operativo. Digitiamo quanto segue in un terminale per determinare l’architettura dell’hardware della macchina:
uname -m
Dovremmo ottenere il seguente output:
x86_64
Ciò mostra che è disponibile una CPU compatibile con x86 a 64 bit.
Per determinare la versione di Ubuntu installata, digitiamo quanto segue:
cat /etc/lsb-release
Otteniamo un output simile al seguente, supponendo che sia installato Ubuntu 18.04 LTS :
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
Ciò conferma la compatibilità dell’hardware della macchina e del sistema operativo.
Verificare che gcc sia installato
Per installare CUDA è necessario avere installato un compilatore C++. A tale scopo Ubuntu fornisce la GNU Compiler Collection (gcc). Se non è stato installato in precedenza, di solito è necessario eseguire il seguente comando di installazione:
sudo apt-get install build-essential
Possiamo verificare la versione di gcc con il seguente comando:
gcc --version
L’output è simile al seguente:
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 questo caso la versione di gcc è 7.5.0, che è sufficiente ai fini dell’installazione di CUDA.
Controlla i pacchetti di sviluppo e le intestazioni appropriati
Per determinare quale kernel Linux è disponibile, digitiamo quanto segue in un terminale:
uname -r
L’output è simile al seguente:
5.3.0-62-generic
Dopo aver determinato il nome del kernel, dobbiamo installare gli specifici headers del kernel e i pacchetti di sviluppo tramite il comando seguente. Assicuriamoci di sostituire la versione del kernel con l’output di cui sopra:
sudo apt-get install linux-headers-5.3.0-62-generic
L’output (estratto) è simile al seguente:
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.
Quanto sopra conferma che gli headers erano già installate sulla workstation.
Controlliamo gli attuali driver Nvidia
Se il driver Nvidia è già installato, è possibile determinare la versione digitando quanto segue nel terminale:
nvidia-smi
L’output è simile al seguente:
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 questo caso il driver Nvidia installato è alla versione 440.100.
Siamo ora pronti per procedere con l’installazione di CUDA, cuDNN e TensorRT.
Installazione di CUDA Framework
I seguenti passaggi sono tratti dalla documentazione di installazione della GPU TensorFlow e sono stati testati su una workstation locale.
Immettiamo i seguenti comandi nel terminale per installare CUDA 10.1 (non 10.2) sul sistema:
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
Con i comandi precedenti scarichiamo il repository CUDA per Ubuntu 18.04 come pacchetto Debian. Otteniamo quindi le chiavi. Usiamo il comando dpkg
per installare il pacchetto CUDA di Debian. Aggiorniamo quindi i repository apt e scarichiamo ed installiamo gli altri repository (nvidia-machine-learning-repo-***
). Infine aggiorniamo ancora una volta i repository apt.
A questo punto possiamo installare il driver Nvidia alla versione 450:
sudo apt-get install --no-install-recommends nvidia-driver-450
Una volta completato, dobbiamo riavviare il sistema per assicurarci che il driver Nvidia sia stato caricato correttamente. Dopo il riavvio possiamo usare nvidia-smi
per garantire che le GPU siano ancora visibili dal sistema:
nvidia-smi
L’output è simile al seguente:
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 |
+-----------------------------------------------------------------------------+
A questo punto dobbiamo scaricare le librerie di runtime CUDA 10.1 e cuDNN 7.6. La dimensione totale del file dei pacchetti è di circa 5 GB. A seconda della connessione questo richiederà probabilmente del tempo sia per il download che per l’installazione. Digitiamo quanto segue per installare i pacchetti:
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
Facoltativamente) possiamo installare TensorRT, progettato per “migliorare la latenza e il throughput per l’inferenza su alcuni modelli”, come menzionato nella documentazione della GPU TensorFlow. Per eseguire questa operazione, digitiamo quanto segue in un terminale:
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
Ora abbiamo installato tutte le librerie e i pacchetti necessari.
Allo stesso modo precedente, possiamo ora installare TensorFlow per la CPU. Assicuriamoci che l’ambiente virtuale Conda sia attivato e digitiamo quanto segue per installare TensorFlow:
pip install tensorflow
Il passaggio finale consiste nel verificare che l’installazione sia andata a buon fine e che TensorFlow venga eseguito sulla GPU.
Convalida dell’installazione di TensorFlow
Per convalidare l’installazione di TensorFlow su una GPU, apriamo una console Python interattiva digitando quanto segue nel terminale:
python
Eseguiamo i seguenti comandi nella shell Python per importare TensorFlow e verificare che sia compilato su CUDA:
import tensorflow as tf
tf.test.is_built_with_cuda()
In caso di successo, l’output dovrebbe semplicemente indicare 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
Se stiamo utilizzando la versione CPU di TensorFlow, questo comando restituisce False
.
Per determinare quali GPU sono state rilevate da TensorFlow, possiamo eseguire il seguente comando in una console Python dopo aver importato TensorFlow:
tf.config.list_physical_devices('GPU')
L’output (estratto) è simile al seguente:
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]
In questo caso sono state rilevate entrambe le due GPU 780 Ti, citate in precedenza nell’articolo.
Come verifica finale (sia per versione CPU che GPU) possiamo effettuare un calcolo base di TensorFlow direttamente dalla riga di comando. Questo significa che quanto segue non viene eseguito all’interno di una console Python. Invece il comando viene eseguito in un normale terminale Ubuntu:
python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))"
L’output (estratto) è simile al seguente:
..
..
..
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)
L’ultima riga contiene il risultato del calcolo reduce_sum
. Poicheé una distribuzione normale casuale viene campionata all’interno di questo calcolo, è possibile che il tensore risultante abbia un valore diverso rispetto a quello precedente.
Questo verifica che TensorFlow sia stato installato correttamente sulla GPU.
Prossimi passi
La prossima serie di articoli descrive una panoramica della logica e del funzionamento di TensorFlow. Dopo il nostro tour di TensorFlow iniziamo a creare alcune architetture di machine learning per risolvere alcuni semplici problemi di classificazione. Infine iniziamo a descrivere le architetture di reti neurali profonde e come implementarle con TensorFlow.