Архив за месяц: Декабрь 2018

Пошаговая инструкция по установке tensorflow-gpu и keras на ubuntu

Как известно, нейронные сети весьма требовательны к вычислительным ресурсам и используя лишь мощность одного процессора обучение сети могут затянуться на часы, а то и дни и недели. Но на помощь пришли графические процессоры, в результате вычисления на графических процессорах, в силу иной архитектуры, проходят быстрее. К слову не только нейронные сети научились использовать GPU, некоторые алгоритмы градиентного бустинга весьма успешно используют GPU для ускорения обучения.

В данном посте будет рассказано об общем процесс установки составляющих, а в конце сравним скорость нейронной сети с использованием GPU и без.

Начальные требования:
операционная система: ubuntu 16, 17 или 18
видеокарта nvidia

Установка драйевров
Проверим какие драйверы установятся командой:

ubuntu-drivers devices

Вы должны увидеть примерно нижеследующий вывод:

== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001C81sv00001458sd00003765bc03sc00i00
vendor   : NVIDIA Corporation
model    : GP107 [GeForce GTX 1050]
driver   : nvidia-driver-390 - distro non-free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin

Далее установим драйверы видеокарты:

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt upgrade

sudo ubuntu-drivers autoinstall

sudo reboot

После перезагрузки у вас появится возможность выполнять команду

nvidia-smi

запомните эту команду nvidia-smi — думаю она часто вам будет требоваться, чтобы посмотреть загрузку видеокарт, убить какой-нибудь процесс на видеокарте, да и смотреть текущую температуру для избегания перегрева.

Установка CUDA.
Важно, на данный момент нужна версия 9.0, для совместимости с tensorflow. Скачать можно по ссылке https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1704&target_type=runfilelocal качаем base installer 1.6Gb и запасаемся терпением. Скорости на сайтах nvidia ограничены на отдачу файлов.
Убедитесь, что выбрана конфигурация загрузки как на изображении:
cuda

sudo sh cuda_9.0.176_384.81_linux.run --override --silent --toolkit

Если всё прошло удачно, то появится папка:
ls /usr/local/cuda-9.0/

Добавляем cuda в PATH

export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64\${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

Установка cuDNN
Теперь надо вспомнить навыки регистрации, придётся зарегистрироваться на сайте nvidia для скачивания cudnn (это библиотека оптимизирует расчёт глубоких нейронных сетей)
Ссылка для скачивания https://developer.nvidia.com/compute/machine-learning/cudnn/secure/v7.1.4/prod/9.0_20180516/cudnn-9.0-linux-x64-v7.1

# разархивируем
tar -xzvf cudnn-9.0-linux-x64-v7.1.tgz 

# копируем файлы в директорию с CUDA
sudo cp cuda/include/cudnn.h /usr/local/cuda/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64

# немного меняем права, чтобы файлы библиотеки были доступны всем пользователям
sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*

Теперь добавляем пути в bashrc (в любом редакторе, я предпочитаю mc)

mcedit ~/.bashrc

И в конец файла пишем:

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64\${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

Перезагрузим конфиг bashrc

source ~/.bashrc
sudo ldconfig

И проверим на наличие корректного пути:

echo $CUDA_HOME
# должно вывестить /usr/local/cuda

Установка tensorflow с поддержкой GPU
Подробная инструкция по установке есть на официальном сайте tensorflow.org/install/ но если не лезть в детали, то достаточно запустить 2 команды:

pip3 install tensorflow
pip3 install tensorflow-gpu

pip3 install keras

Теперь можно запускать пример с обучением и предсказанием нейронной сети, например с использованием keras библиотеки.
Отмечу, что по умолчанию keras использует именно GPU, однако считать можно и на CPU. Для сравнения скоростей расчетов можно использовать код отключения GPU — тогда расчёт будет производиться только за счёт процессора. Добавьте этот код перед импортом tensorflow и keras

import os
os.environ["CUDA_VISIBLE_DEVICES"] = ""

Конфигурация компьютера для машинного обучения. Бюджетный и оптимальный подбор.

Искусственный интеллект уже не первый год наступает на пятки естественному и делает это не в последнюю очередь за счёт роста мощности железа. Поэтому для создания современных алгоритмов ML вам скорее всего потребуется производительный компьютер. В данном посте будет предложена 2 сборки:
первая сборка ПК для ML: начинающая, рассмотрим минимальную систему с которой относительно комфортно работать, стоимостью до 30 тысяч рублей.
вторая сбалансированная цена/производительность: подороже, мощнее, позволяющая решать широкий круг задач. стоимостью 60-90 тысяч рублей.
Изначально думал выделить ещё и сборку для энтузиастов, но потом решил что те, кто готов выкладывать большие деньги на ML, те точно знают что они хотят и скорее всего будут собирать под конкретную задачу.

Процессор:
Основные показатели — количество ядер и производительность одного ядра. У Intel более быстрые ядра, зато у AMD за те же деньги вы получите больше ядер. Что важнее и где найти балланс, зависит от задач. Если будете гонять нейронки на видеокартах, то берите интел. Если хотите решать широкий круг задач, то AMD т.к. в конечном итоге при правильном распараллеливании программы расчёты будут идти бысрее. Но учтите, не всё можно распараллелить. По поводу гипертрэйдинга — он немного ускоряет систему, но в реальности не так значительно, поэтому ядра первостепенней.
Бюджетный вариант: 4-6 ядер
Средний вариант: 6-8 или более ядер с хорошим бустингом на одно ядро.

Оперативныя помять:
Бюджетный вариант: 16Gb
Средний: 32Gb двумя планками по 16, чтобы иметь возможность расшириться до 64 в случае необходимости. Больше 64Gb сокеты 1151-v2 и AM4 не поддерживают. Если хотите получить несколько дополнительный процентов производительности от AMD — берите более быструю память и обязательно 2ух канальную.
Много где в AI советуют чтобы количество оперативной памяти было в 2 раза больше чем видео памяти, у меня пока не сложилось конкретной рекомендации на эту тему, но оставлю это здесь.

Видеокарты:
В бюджетной сборке предлагаю обойтись вообще без видекарты (если в процессоре есть встроенная графика) или с самой дешевой, которую найдёте. Так можно сэкономить, приобретя более мощные остальные компоненты и оставляя возможность апргрейда. На ней Вы считать не будете — она только для вывода изображения на монитор и всё! Как же так, возможно кто-то спросит? Ответ простой — GPU в первую очередь нужна для нейронных сетей, но на слабой видеокарте вроде geforce 1050 скорость расчётов будет в большинстве случаев такой же как на мощном CPU. Некоторые алгритмы градиентного бустинга также умеют использовать мощь GPU, но на опыте — в сравнении с 1050 выигрыша никакого нет. А при покупке карты дороже, уже вылезем из бюджета в 30т.р.
В средней сборке видеокарта однозначно нужна и желательно помощнее. Выбор производителя однозначе — это nvidia. Стоит сразу отметить важную деталь — SLI вам никак не понадобится, tensorflow c cuda отлично распараллелены и вы можете использовать разные типы карт nvidia, вовсе не обязательно одинаковые. Однако в нейронных сетях есть такое понятие как батч (batch) и чтобы он был больше — нужно больше памяти на видеокарте. Чем больше batch тем лучше и дабы не быть ограниченным снизу слабой видеокартой по размеру batch — лучше брать видеокарты с одинаковым объёмом памяти.
Времена майнинга прошли и купить карту стало легче, брать ли БУ или нет — каждый пусть решит для себя самостоятельно. Чтобы облегчить выбор, напишу сравнительную производительность разных карт, за базу (1X) пусть выступит 1050. Это позволит вам лучше соотнести мощность с ценой и подобрать оптимум.
1050 1X
1050Ti 1.12X
1060 3Gb 1.95X
1060 6Gb 2.09X
1070 2.91X
1070Ti 3.39X
1080 3.7X
2070 3.9X
1080Ti 4.42X
2080 4.45X
2080Ti 5.79X
Меньше 4 Gb лучше не брать, может оказаться мало даже для простых задач.

Материнская плата:
В выборе материнской плате надо знать следующее — будете ли вы разгонять процессор и сколько видеокарт планируете подключать. Я не являюсь сторонником разгона, но если Вы планируйте выжимать из системы максимум — то обратите внимание на возможность разгона. Более тонкий момент с количеством видекарт, а точнее с количеством PCI-E линий. практически все материнки поддерживают 16 линий для одной видеокарты. Проблемы начинаются при использовании большего количества видеокарт для машинного обучения. Конфигурация 8PCI-E на 8PCI-E для двух видеокарт мне кажется оптимальной для среднего решения. Но если в планах использование только одной видеокарты, то можно и сэкономить не покупая более дорогой сокет.

Жесткий диск:
Бюджетная сборка: берите HDD, скажем на террабайт. Конечно система будет загружаться медленнее чем с ssd. но его можно будет потом докупить. А если сразу выложиться на ssd — то есть опасения что не влезут большие датасеты. Учтите, что на установку всех нужных библиотек и программ вполне может уйти под 100Gb жесткого диска.
В оптимальной сборке предлагается взять SSD + HDD. Некоторые модели SSD-M2 имеют повышенную скорость чтения и записи, по сравнению с обычными SATA3 ssd но с пользовательской стороны значительного ускорения не заметно, однаком любителям топчика — SSD-M2 советую, особенно если оперативной памяти маловато — будет очень быстрый swap.

Охлаждение и корпус:
В бюджетной версии можно обойтись самым простым корпусом, а вот в оптимальном уже стоит задуматься об охлаждении видеокарт/ы и процессора. Если видеокарты всё же две и между ними мало места — то верхняя будет греться ощутимо сильнее. Одно из самый простых и действенных решения — поставить вентилятор аля 140мм сбоку, дующий сразу на видеокарты. Ещё один лайфхак — дабы пыли внутри скапливалось поменьше — рекомендуется вентиляторы на вдув ставить мощнее вентиляторов на выдув.

Блок питания:
Основной параметр — мощность в ватах. Чтобы понять на сколько ватт нужен вам блок, рекомендую в поисковике вбить «power supply calculator» и Вы найдете несколько приятных интерфейсов для расчетов. Для самого бюджетного варианта вполне подойдёт блок на 400-500W, для систем с двумя видеокартами блока на 850W будет достаточно, 850W хватит даже для двух 2080Ti. Для одной 1080Ti или 2080Ti будет достаточно 600W. Для двух средних карт вроде 1070/2070 650/700W тоже будет достаточно. Цены на разные блоки питания скачут существенно, и параметров у них много, но обычно более дорогой блок питания оснащается большим количеством защит и если начинка стоит дорого, лучше взять блок качественнее.

Большинство компонентов можно приобрести на вторичном рынке — это будет заметно дешевле. Конечно, в покупке БУ комплектующих есть некоторый риск, но за те же деньги вы сможете получать результат вычислений быстрее. Меньше всего опасаться можно за процессоры и оперативную память, если они работают — то почти наверняка, при нормальной эксплуатации, они ещё будут работать лет десять.

Два примера Label Encoding или переводим строки в числа в pandas.

При решении задач машинного обучения, часто приходится иметь дело со строковыми параметрами. Чаще всего это категориальные фичи, например названия городов, цвета, должность итд. Некоторые библиотеки могут изначально работать со строковыми параметрами, но для большинства предварительно надо перевести буквы в цифры. Более того, это даже очень рекомендуется т.к. в числовом виде будет использоваться меньше оперативной памяти для хранения обучающей матрицы. Процесс перевода строковых фич (labels) в числовые фичи называется label encoding.

В данном посте будет предложено два практических способа label encoding (не путать с onehot encoding) для дата фреймов pandas. Таким образом у нас есть DataFrame train с категориальными фичами, которые надо преобразовать с помощью метода label encoding.

Способ 1.
Используя библиотеку sklearn.

from sklearn import preprocessing
import pandas as pd

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
cat_cols = ['city', 'color', 'position']

for col in cat_cols:
    lbl = preprocessing.LabelEncoder()
    lbl.fit(list(train[col].values.astype('str')) + list(test[col].values.astype('str')))
    print(lbl.classes_)  # взглянем на категориальные классы
    train[col] = lbl.transform(list(train[col].values.astype('str')))
    test[col] = lbl.transform(list(test[col].values.astype('str')))

Способ 2.
Этот способ основан на методе factorize из библиотеки pandas, поэтому если Вы не используете sklearn — можно «cэкономить» на импортах

import pandas as pd
# Сначала покажем классический пример
labels, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'])
print(labels)  # array([0, 0, 1, 2, 0])
print(uniques)  # ['b', 'a', 'c']

# а теперь пройдемся по всем категориальным колонкам
cat_cols = ['city', 'color', 'position']
for col in cat_cols:
    train[col], _ = pd.factorize(train[col])

Таким образом в обоих способах все строковые значения фич будут заменены на соответсвующие целочисленные значения, что позволит использовать меньше памяти и без дополнительной обработки запускать обучение в разных библиотеках.

Важное замечание, если Вы планируете использовать только линейные модели то onehot encoding сделать всё-таки придется, иначе линейная разделимость будет недостаточной. Для методов же, основанных на деревьях и градиентном спуске label encoding будет достаточно.