Czy też tak macie? Diabeł siedzący na ramieniu szepcze wam do ucha „no weź zaktualizuj, przecież to zajmie chwilkę”. Tak właśnie zaczyna się historia instalacji biblioteki Tensorflow od Google pozwalająca na uczenie sieci neuronowych tzw. deep learning. Wszystko miało pójść gładko, jednak jej konfiguracja na ubuntu 16.04 jeszcze może przysporzyć wiele kłopotów.
Aktualizacja ubuntu 16.04, co mnie podkusiło
Wpis ten z jednej zawiera instrukcję instalacji wspomnianej biblioteki, a z drugiej przedstawia historię moich zmagań, walki i poświęcenia, opisuje chwile zwątpienia, załamania oraz ostatecznego triumfu. Drogi czytelniku jeżeli zależy tobie tylko na instrukcji instalacji Tensorflow 0.9 na ubuntu 16.04 to zapraszam do tego gist’a, natomiast jeżeli jesteś zainteresowany historią to proszę czytaj dalej.
- Zaktualizowana procedura instalacji TensorFlow r0.12 i CUDA 8.0
- Kolejna aktualizacja TensorFlow 1.0 z virtualenv i python 3.5, cuDNN 5.1 i CUDA 8
Cała przygoda z instalacją Tensorflow rozpoczęła się od aktualizacji ubuntu, jak mawiają lepsze jest wrogiem dobrego, lecz nie bacząc na mądrości ludowe postanowiłem dokonać aktualizacji systemu operacyjnego mojego serwera obliczeniowego na uczelni. Swoją drogą, maszyna całkiem wydajna 64GB RAM oraz 3 karty graficzne Geforce 780 TI, całość służyła mi głównie do prowadzenia badań polegających optymalizacji algorytmów pod GPU.
Wróćmy do sedna sprawy serwer pracował pod ubuntu 14.04, lecz podkusiło mnie aby dokonać jego aktualizacji do 16.04. Tak naprawdę to podkusiła mnie zmiana wersji Pythona, który w 16.04 domyślnie jest w wersji 3.5. Czytałem tyle achów i ochów o nowszym, szybszym, stabilniejszym, elegantszym Pythonie 3.5, że postanowiłem zaktualizować całą maszynę (sic!) zamiast zaktualizować tylko Pythona. A co tam? Przecież to tylko chwila, nie?
Lecz, nie śmiejcie się jeszcze, nie jestem w cale taki głupi, z moich przygód z informatyką wiem, że zawsze coś może pójść nie tak, więc szybki research w sieci czy nie ma problemów z aktualizacją, bibliotekami itp. utwierdził mnie tyko w przekonaniu, że wszystko pójdzie szybko i gładko. Już czujecie co się święci?
Więc zachęcony pozytywnymi komentarzami, bo przecież taka aktualizacji to spowoduje, że wszystko nagle zacznie działać lepiej, szybciej, z 3 kart zrobi się 6, podwoi się ram na maszynie oraz na dodatek będę szybciej biegał, rozpocząłem proces aktualizacji. Uważnie i krok po kroku wykonywałem polecenia z tutoriala
Trzy magiczne komendy
$ sudo apt-get update $ sudo apt-get upgrade $ sudo do-release-upgrade -d
i po sprawie. Serwer zrestartowałem, następnie szybkie
$ lsb_release -a
i ku mojej radości ujrzałem
Distributor ID: Ubuntu Description: Ubuntu 16.04.1 LTS Release: 16.04 Codename: xenial
Aktualizacja sterownika karty graficznej NVidia na ubuntu 16.04
Czyli aktualizacja się powiodła, lecz zanim odtrąbiłem kolejny sukces w mojej karierze (już wpisywałem to do swojego CV) postanowiłem sprawdzić czy wszystko działa. Na pierwszy rzut poszły karty graficzne i jakież było moje zdziwienie gdy:
$ nvidia-smi modprobe: FATAL: Module nvidia not found in directory /lib/modules/4.4.0-31-generic NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
Można się było tego spodziewać, nowsze jądro, więc i inne sterowniki do karty są potrzebne. Żaden problem, wyrzuciłem stare sterowniki
$ sudo apt-get purge nvidia
i zainstalowałem nowe
#Add the ppa repo $ sudo add-apt-repository ppa:graphics-drivers/ppa $ sudo apt-get update #Install the recommended driver (currently nvidia-367) $ sudo ubuntu-drivers autoinstall $ sudo reboot
dzięki czemu moje karty zostały rozpoznane, niestety najnowszy sterownik NVidia 367.35 nie ma ma wsparcia dla wszystkich czujników dla moich kart, więc nie pokazuje wykorzystania pamięci oraz procesorów na karcie. Nic to, ważne, że karty są.
$ nvidia-smi Wed Jul 20 22:54:15 2016 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 367.35 Driver Version: 367.35 | |-------------------------------+----------------------+----------------------+ | 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 | 0000:03:00.0 N/A | N/A | | 27% 48C P0 N/A / N/A | 0MiB / 3018MiB | N/A Default | +-------------------------------+----------------------+----------------------+ | 1 GeForce GTX 780 Ti Off | 0000:04:00.0 N/A | N/A | | 22% 44C P0 N/A / N/A | 0MiB / 3020MiB | N/A Default | +-------------------------------+----------------------+----------------------+ | 2 GeForce GTX 780 Ti Off | 0000:08:00.0 N/A | N/A | | 0% 32C P0 N/A / N/A | 0MiB / 3020MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | | 1 Not Supported | | 2 Not Supported | +-----------------------------------------------------------------------------+
Instalacja CUDA 7.5, cuDNN oraz Tensorflow
Idziemy więc dalej, skoro nie dział sterownik to trzeba zaktualizować CUDA toolkit, pomógł mi w tym post na formu NVidia tensorflow-cannot-find-cudnn-ubuntu-16-04-cuda7-5
$ sudo apt-get install nvidia-cuda-toolkit $ sudo apt-get install libcupti-dev zlib1g-dev
chyba karta się odwróciła, bo to czego najbardziej się obawiałem poszło szybko i sprawnie. Co prawda biblioteki cuda zostały zainstalowane w folderze /usr/lib/nvidia-cuda-toolkit a Tensorflow domyślnie oczekuje, że będą w /usr/local/cuda/, lecz tym problemem zajmiemy się za chwilę, sprawdzam co zostało zainstalowane
$ dpkg --get-selections | grep nvidia nvidia-367 install nvidia-cuda-dev install nvidia-cuda-doc install nvidia-cuda-gdb install nvidia-cuda-toolkit install nvidia-opencl-dev:amd64 install nvidia-opencl-icd-367 install nvidia-prime install nvidia-profiler install nvidia-settings install
Aby uszczęśliwić Tensorflow i ułatwić sobie pracę, utworzyłem symlinki w folderze /usr/local/cuda
# Put symlinks in /usr/local/cuda $ sudo mkdir /usr/local/cuda $ cd /usr/local/cuda $ sudo ln -s /usr/lib/x86_64-linux-gnu/ lib64 $ sudo ln -s /usr/include/ include $ sudo ln -s /usr/bin/ bin $ sudo ln -s /usr/lib/x86_64-linux-gnu/ nvvm $ sudo mkdir -p extras/CUPTI $ cd extras/CUPTI $ sudo ln -s /usr/lib/x86_64-linux-gnu/ lib64 $ sudo ln -s /usr/include/ include
Należy także upewnić się czy zmienna $PATH zawiera ścieżkę do folderu /usr/local/cuda
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/cuda/bin:/usr/local/cuda/bin
U mnie był problem, że ścieżki do cuda pojawiały się na początku, co powodowało później pewne zamieszanie z pythonem, więc wyedytowałem plik ~/.bashrc, w którym ścieżkę do $CUDA_HOME dałem na koniec
export CUDA_HOME=/usr/local/cuda export CUDA_ROOT=${CUDA_HOME} export LD_LIBRARY_PATH=${CUDA_HOME}/lib64 PATH=${PATH}:${CUDA_HOME}/bin export PATH ....
Poza tym musiałem usunąć pozostałości po poprzednich wersjach CUDA
$ sudo rm -r /etc/profile.d/cuda_var.sh
Diabeł tkwi w wersjach cuDNN
Tensorflow wymaga biblioteki cuDNN (https://developer.nvidia.com/cudnn), aby ją ściągnąć należy się zarejestrować i zalogować do NVidia developer, następnie wypełnić szybką ankietę i otrzymamy dostęp do kolejnych wersji, w chwili pisania posta dostępne są
Poziom frustracji wzrasta z każdą komendą
Od tego momentu, zaczęły padać same fucki, ku..y, ja jeb.e i wiele innych pięknie brzmiących słów zaczerpniętych z gwary podsklepowej. Wszystko za sprawą mojej ślepej chęci optymalizowania wszystkiego i próbowania nowych rzeczy. Zgadnijcie, którą wersję wybrałem cuDNN? No, nie zgadliście to nie jest v5.1 RC, aż taki głupi nie jestem, padło na v5 for CUDA 7.5. A dlaczego? Bo naczytałem się, że o parę procent poprawili wydajność w stosunku do starej, stabilnej, sprawdzonej, przetestowanej przez miliony instalacji wersji v4.
No i zaczęła się moja droga krzyżowa. Żadna z udostępnionych przez Google gotowych zbudowanych paczek nie wspiera cuDNN v5, zostaje tylko własna kompilacja. Więc jako stary wyga, któremu żadne gcc nie jest straszne, robię git clone tensorflow, mam kod. Doczytuję w dokumentacji, że do zbudowania potrzebne jest narzędzie bazel (#wtf), nigdy z niego nie korzystałem, lecz piszą, że jest super wydajne, więc płynę dalej. Instaluję bazel, szukam procedury instalacji i bazel wspiera tylko ubuntu 14.04 i 15.10. Dobra szukam w sieci jak to ustrojstwo zainstalować, mam, na blogu jakiegoś chińczyka napisane jest, że wystarczy ściągnąć paczkę deb i będzie działać. A więc ściągam instaluje i boom, okazuje się że potrzebuje openjdk. Zaszedłem już daleko, szybkie apt-get install openjdk załatwi sprawę.
Niestety nie załatwiło.
Domyślne openjdk-9-jdk nie chce się zainstalować, ok 1h węszenia w sieci pozwala mi stwierdzić, że nikomu się nie instaluje. Uff, jest to jakieś pocieszenie. Znalazłem sposób, aby w końcu zainstalować i na usta znowu pocisnęły się niecenzuralne słowa. Żona kazała mi z tym laptopem z domu się wynosić, jak mam zamiar tak dalej się zachowywać, a koty to się już same wyniosły.
Ożeż, Bazel nie współpracuje z openjdk-9-jdk, trzeba zainstalować openjdk-8-jdk. Zainstalowałem, wykonuje kolejne komendy z dokumentacji od Google
bazel build -c opt --config=cuda //tensorflow/cc:tutorials_example_trainer
Po ok 10 minutach, błędy kompilacji. A czegóż się spodziewałeś? Kolejne 2h walki z problemem, edycja kodu itp. I nagle olśnienie. Po co mi cuDNN v5, wrzuć wersję v4. Po zmarnowanych ok 4h, wykorzystanie cuDNN v4 pozwoliło mi na zainstalowanie Tensorflow z gotowej paczki przygotowanej przez Google.
Przestroga dla reszty – Nie idźcie tą drogą, kompilacja tensorflow to zuo.
Światełko w tunelu cuDNN v4
Instalacja cuDNN jest bardzo prosta, ściągamy ze strony NVidi odpowiednią paczkę, rozpakowujemy i kopiujemy pliki do odpowiednich folderów. Pomocny może okazać się post how-can-i-install-cudnn-on-ubuntu-16-04
$ tar xzvf cudnn-7.0-linux-x64-v4.0-prod.tg $ cd cuda $ sudo cp include/cudnn.h /usr/include $ sudo cp lib64/libcudnn* /usr/lib/x86_64-linux-gnu/ $ sudo chmod a+r /usr/lib/x86_64-linux-gnu/libcudnn*
Następnie zgodnie z dokumentacją od Google (https://www.tensorflow.org/versions/r0.9/get_started/os_setup.html#virtualenv-installation), stworzyłem przy pomocy virtualenv lokalne środowisko z pythonem 3.5 i w nim zainstalowałem Tensorflow 0.9 z wsparciem dla GPU.
$ virtualenv -p python3 tfenv $ source tfenv/bin/activate # Ubuntu/Linux 64-bit, GPU enabled, Python 3.5 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. (tfenv)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl (tfenv)$ pip3 install --upgrade $TF_BINARY_URL
Na koniec przetestowałem czy wszystko gra. Stworzyłem skrypt testowy test_tf.py
import tensorflow as tf tf_session = tf.Session() x = tf.constant(1) y = tf.constant(1) print(tf_session.run(x + y))
i uruchmiłem go
$ python test_tf.py
W terminalu ujrzałem:
(tfenv)$ python test_tensorflow.py I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so locally I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:924] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: name: GeForce GTX 780 Ti major: 3 minor: 5 memoryClockRate (GHz) 1.0845 pciBusID 0000:08:00.0 Total memory: 2.95GiB Free memory: 2.88GiB W tensorflow/stream_executor/cuda/cuda_driver.cc:572] creating context when one is currently active; existing: 0x260d110 I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:924] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 1 with properties: name: GeForce GTX 780 Ti major: 3 minor: 5 memoryClockRate (GHz) 1.0845 pciBusID 0000:04:00.0 Total memory: 2.95GiB Free memory: 2.88GiB W tensorflow/stream_executor/cuda/cuda_driver.cc:572] creating context when one is currently active; existing: 0x2a39af0 I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:924] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 2 with properties: name: GeForce GTX 780 Ti major: 3 minor: 5 memoryClockRate (GHz) 1.0845 pciBusID 0000:03:00.0 Total memory: 2.95GiB Free memory: 2.88GiB I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 1 2 I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y Y Y I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 1: Y Y Y I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 2: Y Y Y I tensorflow/core/common_runtime/gpu/gpu_device.cc:806] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 780 Ti, pci bus id: 0000:08:00.0) I tensorflow/core/common_runtime/gpu/gpu_device.cc:806] Creating TensorFlow device (/gpu:1) -> (device: 1, name: GeForce GTX 780 Ti, pci bus id: 0000:04:00.0) I tensorflow/core/common_runtime/gpu/gpu_device.cc:806] Creating TensorFlow device (/gpu:2) -> (device: 2, name: GeForce GTX 780 Ti, pci bus id: 0000:03:00.0) 2
Najważniejsze, że Tensor rozpoznał i wczytał biblioteki od CUDA, rozpoznał moje trzy karty oraz na końcu dał poprawy wynik „2”. Mogłem ogłosić pełne zwycięstwo.
Wnioski na przyszłość
Czego mnie nauczyło to doświadczenie, podejrzewam, że niczego. Przecież już wielokrotnie przerabiałem podobny scenariusz, diabeł siedzący na ramieniu co rusz mi podpowiada „now weź, zaktualizuj, pójdzie szybko, to tylko jedno polecenie”. I wklepujesz to jedno polecenie, chwilę się zastanawiasz, ba nawet zadajesz sam sobie pytanie, a co jeżeli coś pójdzie nie tak, lecz po chwili i tak naciskasz enter. I gdzieś jakby w dole słyszysz rubaszny śmiech. Niby jestem mądrzejszy, bardziej doświadczony, przecież sprawdzam w sieci czy dana aktualizacja może zaszkodzić, lecz na palcach jednej ręki mogę policzyć te bezproblemowe sytuacje.
Artykuł ciekawy i przydatny. Trochę odbiegając od tematu, mam pytanie czy warto instalować TFlearn (czyli nakładkę na TensorFlow ułatwiającą korzustanie z TF w Pythonie) ??????
Na chwilę obecną moja odpowiedź brzmi nie wiem, TFLearn mam na liście TODO.
Z tego co wiem to dużo czerpie z filozofi Scikit-learn, z którą akurat pracuje mi się dobrze, spójne api, zachowywana kompatybilność wstecz i bardzo stabilna. Jednak jest stosunkowo zamknięta pod względem funkcjonalnym tzn. ma gotowe komponenty do wykorzystania, ale czasami potrzeba czegoś niestandardowego szczególnie w badaniach i trzeba wgryzać się w szczegóły.
Podsumowując, mogą wyrazić jedynie moje przypuszczenia, że z TFlearn jest podobnie, więc jeżeli potrzebujesz gotowych komponentów do wykorzystania to będzie idealna.
Wiele dobrego słyszałem o bibliotece Keras i u mnie na liście do przetestowania jest wyżej, śledzę jej autora na Twiterze i dosyć często jest aktualizowana o nowe metody, architektury itp.
zastanawialem sie do czego to mozna by uzyc i stwierdzam, ze znalazlem jedno zastosowanie (po za traceniem czasu i pradu).
Rozwiazanie captcha Aero2. na githubie sa dane.
Zastanawialem sie nad prostym kolko i krzyzyk i okazuje sie, ze to albo dosc potezne narzedzie (glebokosc ruchow, trzeba by zdrowo opisac plansze) albo gdy wrzucimy po prostu 9 pol (+1 kto teraz gra) i poprosimy o 9 pol wyniku to …. nic nie dostaniemy. Glebokie uczenie jest za slabe nawet na tak marna gre. Chyba, ze jak mowie dodamy odrebne uczenie dla kazdych tripletow pol ale wtedy to niewiele tego uczenia zostaje 😉
zagranie w cos rownie prostego wlasciwie wymagalo by rownie wielkich nakladow na przygotowania.