Как развернуть виртуальную среду модели машинного обучения на любой машине?

6e17a47a5c5443b30e9a80327492e176.jpg

Иногда возникают проблемы с развертыванием среды разработки в облаке, ведь бесплатных сервисов с большими облачными вычислительными мощностями почти нет. Тот же Google Collab имеет свои лимиты по использованию GPU, после израсходования всей памяти необходимо ждать сутки. А цена платной версии порой не совсем оправдана… Если у вас есть своя неплохая видеокарта, всегда можно отказаться от облачной разработки и перейти к домашнему варианту.  

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

Итак, как же контейнизировать собственную виртуальную среду и развернуть ее с использованием своего GPU?  

Вам потребуется:

  1. Предустановленная библиотека cuDNN под TensorFlow. Она нужна, чтобы получить доступ к ядрам своей карточки. Кстати, Pytorch не требует никаких библиотек и использовать GPU там можно спокойно. 

  2. Упаковать ваши наработки Jupyter в .py файлы. 

  3. Создать виртуальное окружение, указав предварительно все используемые библиотеки в requirements.txt. для быстрого развертывания. 

  4. Создать Docker-образа, по желанию, и развернуть окружение где вашей душе угодно с задействованием CUDA.

Среда разработки с библиотекой cuDNN и подключением CUDA

Для работы со своим GPU проще всего воспользоваться CUDA Toolkit, иначе CUDA — интерфейсом для параллельного вычисления однотипных вычислений. У Nvidia есть своя библиотека для эффективного использования ядер — cuDNN. А еще мы напоминаем, что библиотека закачивается вместе с некоторыми фреймворками. 

Как развернуть среду разработки с cuDNN?

Для начала следует обновить драйвера карточки. Сделать это можно на сайте Geforce Experience. И скачать сам Toolkit тут: Toolkit и библиотека CuDNN. 

Установка последнего —  простое копирование файлов из папки без привычной установки, поэтому проверить работы библиотеки можно следующим образом, например, в Visual Studio:

import tensorflow as tf
from tensorflow.python.client import device_lib

print(tf.test.is_built_with_cuda()) #проверка работы CUDA

print(tf.sysconfig.get_build_info(), "\n") #static numbers
sys_details = tf.sysconfig.get_build_info()
print('Prescribed CUDA version:', sys_details["cuda_version"]) #версия CUDA 
print('Prescribed cuDNN version:', sys_details["cudnn_version"], "\n") #версия CUDNN

print(tf.reduce_sum(tf.random.normal([1000, 1000]))) #проверка тензоров
print(tf.config.list_physical_devices('GPU'), "\n") #проверка доступных видеокарт/GPU

print(device_lib.list_local_devices())

Необходимо установить сам фреймворк для ML. Для примера мы возьмем TensorFlow. Напоминаем, что далеко не все версии TensorFlow работают с видеокартами или попросту GPU, так что будьте внимательными. Максимальная поддерживаемая версия TF ля работы видеокарт на Windows с версией самого Python от 3.7 до 3.10 — 2.10.0 

Установить все можно через pip.Обычно Pip можно закачать прямо в установщике Python для Windows. 

Устанавливаем дополнительные библиотеки: Pandas, Matplotlib и Numpy.

pip install tensorflow-gpu==2.10.0 
pip install numpy pandas matplotlib 

Дальше приводим простой пример развертывания модели машинного обучения с использованием GPU. В нашем случае на основе данных MNIST. 

import keras
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Dropout
from keras.datasets import mnist
import sys

# import tensorflow as tf
# config = tf.compat.v1.ConfigProto(gpu_options = 
#                          tf.compat.v1.GPUOptions(per_process_gpu_memory_fraction=0.8)
# # device_count = {'GPU': 1}
# )
# config.gpu_options.allow_growth = True
# session = tf.compat.v1.Session(config=config)
# tf.compat.v1.keras.backend.set_session(session)


def one_hot(data, num_categories):
    oh = np.zeros((len(data),num_categories))
    for i,entry in enumerate(data):
        oh[i, entry] = 1
    return oh


# импортируем данные
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Делаем препроцессинг данных
x_train = x_train.reshape( (60000,28,28,1) ) / 256
x_test = x_test.reshape( (10000,28,28,1) ) / 256
y_train = one_hot(y_train, 10)
y_test = one_hot(y_test, 10)

# Строим саму модель
model = Sequential()
input_shape=(28,28,1)
model.add(Conv2D(filters=32,
                 kernel_size=(3,3),
                 activation='relu',
                 input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2,2),
                       strides=(2,2)))
model.add(Conv2D(filters=32,
                 kernel_size=(3,3),
                 activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2),
                       strides=(2,2)))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(units=256,
                activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(units=10,
                activation='softmax'))

# load model weight

# Компилируем
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
model.summary()

# Обучаем модель
num_epochs = 1
if num_epochs != 0:

    model.fit(x_train, y_train,
              batch_size=4,
              epochs=num_epochs)

# Делаем оценку
score = model.evaluate(x_test, y_test)
print('\nScore: ', score)

Готово. Напоминаем, если у вас стоит целая рендер-ферма под рукой — меняем единицу на нужное число в строке: "# device_count = {'GPU': 1}”.

В строке выше можно определить коэффициент используемой видеопамяти.  

Пусть наша модель предварительно в файле .py будет называться model — так мы ее и будем называть в дальнейшем. 

Поздравляем, вы установили глобальную библиотеку для работы с графическими ядрами. Чтобы перезапустить приложение на стороннем ПК, нам следует создать Docker-файл.  Но перед этим нужно создать виртуальное окружение, которое мы и положим в наш «контейнер». 

Создание виртуального окружения в Python

Виртуальное окружение — одна из прекраснейших особенностей этого языка программирования. Вот «наимпортировали» вы килотонны библиотек в своей проект, а как запустить его с другого ПК? Вот здесь виртуальное окружение позволяет создать локальные зависимости для отдельных проектов, не засоряя среду, и решить проблему несовместимости между операционками (окружение можно запустить с любой ОС, будь то Linux или Windows). 

Если еще проще, виртуальное окружение — набор инструментов, который будет прилагаться к вашей программе. Его можно активировать/деактивировать для интерпретатора. 

Но это не все. Библиотеки ведь бывают совершенно разных версий… Та же TensorFlow может быть несовместима для работы с видеокартами. Виртуальное окружение позволяет интерпретатору задействовать библиотеки нужных версий. Если поставить библиотеки глобально, то тогда новые версии будут заменять старые, и предыдущие проекты могут не работать. 

Нужные нам библиотеки расписаны выше. 

Создать виртуальное окружение просто. Мы будем расписывать создание для Windows. 

1. Для создания виртуального окружения введите консоли следующий код. 

python3 -m venv myenv

Myenv — название нашего вирт. окружения. Естественно, его можно изменить. При помощи этой команды создается особая директория, в которой и будут храниться нужные нам библиотеки. 

2. Активация виртуального окружения. Окружения можно активировать и деактивировать в зависимости от проекта. 

myenv\Scripts\activate

3. Дальше при помощи pip, о котором расписали выше, следует установить все зависимости, если нужно, с их версиями по спецификации. Например:

(myenv) user@host:~$ pip install tensorflow-gpu==2.10.0

4. Так устанавливаем все нужные библиотеки наших версий. Не забудьте создать файл с требованиями, в котором будут перечислены все зависимости, чтобы все библиотеки с виртуальной среды на другом ПК было бы легко установить.

pip freeze > requirements.txt

Создание requirements необязательно, но это хороший тон в комьюнити кодеров. Зайдите в любой репозиторий GitHub и увидите, что в каждом проекте такой текстовик вшит. 

Файл с зависимостями позволяет не перекидывать директорию, допустим, вашему другу, а попросту скинуть ему готовые .py скрипты и сам файл с требованиями, чтобы он смог переустановить все нужные библиотеки/фреймворки в своей виртуальной среде. 

В нашем случае весь список нужных библиотек для нашей модели можно подсмотреть в самом коде скрипта, который мы привели в первой главе. И не забудьте, что все ваши функции из Jupyter необходимо перевести в файлы питона .py и переместить в созданную директорию. 

Для Linux cхема установки выглядит схожим образом, но с использованием слегка видоизмененных команд. 

Docker и контейнеризация 

ec69e25adcb21faff88ba74234961719.png

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

Иначе докер — некое подобие виртуальной машины. 

Если у вас еще нет Docker, начните с установки его на вашу операционную систему. Вы можете загрузить и установить Docker Desktop с официального веб-сайта Docker. Дальше необходимо проверить версию своего CUDA при помощи команды nvcc - version (в командной строке).

И оценить свою версию cuDNN. Это важно, иначе при написании кода можно ошибиться с версией и Docker не будет использовать видеокарту. Все же хостом контейнера выступает ваш ПК.  Дальше необходимо выбрать версию Docker-образа в соответствии с вашими cuDNN и CUDA версиями: nvidia/cuda:10.1-cudnn7-runtime 

Сам Dockerfile — набор последовательных инструкций для сборки контейнера.  Докер-файл выполняет все инструкции последовательно. 

В нашем случае нам необходимо завернуть в контейнер наше виртуальное окружение с установкой всех зависимостей (библиотек, прописанных в requirements.txt) и cкриптов в редакторе .py для работы с самой моделью машинного обучения. 

В нашем случае нужно создать инструкции для запуска скрипта Model.py и установить все зависимости. 

FROM — указывает базовый образ, на основе которого будет создаваться ваш образ Docker. Вы можете выбрать предварительно созданный образ из Docker Hub или создать свой собственный.

Далее, предположим, у нас нет в контейнере предустановленного python. Соответственно нам нужно его зашить в контейнер. Делается это при помощи команды RUN.

RUN apt-get update && \
apt-get install -y python3

Дальше необходимо добавить все папки и файлы (приложения) в контейнер.

В нашем случае скрипт и список зависимостей при помощи команды COPY

COPY model.py / home/ Model.py

COPY requirements.txt / home / requirements.txt

Далее необходимо установить зависимости (в нашем случае библиотеки).

Можно сделать это вручную с перечислением всех библиотек при помощи команды RUN через pip.

RUN pip install package1 package2 package3

Или же воспользоваться нашим созданным файлом requirements.txt.

RUN pip install -r requirements.txt

Таким образом, мы загрузили наш скрипт на Питоне с готовой моделью и все зависимости с файла requirements.txt 

Так как в нашем докер-файле используется всего один скрипт на питоне, то нам достаточно вписать:

ENTRYPOINT ["/usr/bin/python3", "./model.py"]

Также может быть использована команда CMD. Неудивительно, что наша команда называется ENTRYPOINT (входная точка), отсюда начнет выполняться приложение нашего контейнера.

Далее для построения образа необходимо прописать следующую строчку и построить сам Docker. 

docker build -t model

После model через пробел нужно указать место, куда Docker положит контейнер. 

Запускать контейнер необходимо с использованием GPU ресурсов, это прописывается в команде:

docker run --gpus=all -it model

Где model — имя контейнера или его id. А указание --gpus=all — для обозначения, что при запуске будут задействоваться GPU-ресурсы. 

Docker и перекидывание виртуального окружения со скриптами и requirements.txt?

Предустановленный cuDNN и правильный выбор версии TensorFlow позволяет нам попросту запустить вашу модель машинного обучения на ПК с использованием GPU,  , но при этом перекидывание подобной виртуальной среды на другой ПК — несколько муторная задача. С другой стороны, первой части инструкции достаточно, чтобы использовать ускорители своего проекта локально из дома, если вы не хотите переносить скрипты на другую машину. 

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

© Habrahabr.ru