Как развернуть виртуальную среду модели машинного обучения на любой машине?
Иногда возникают проблемы с развертыванием среды разработки в облаке, ведь бесплатных сервисов с большими облачными вычислительными мощностями почти нет. Тот же Google Collab имеет свои лимиты по использованию GPU, после израсходования всей памяти необходимо ждать сутки. А цена платной версии порой не совсем оправдана… Если у вас есть своя неплохая видеокарта, всегда можно отказаться от облачной разработки и перейти к домашнему варианту.
Напоминаем, что GPU выполняет вычислительную работу быстрее из-за возможности параллельного выполнения процессов. Если вы хотите использовать много видеокарт — следует подключить ее к одной системе, сформировав своеобразную ферму.
Итак, как же контейнизировать собственную виртуальную среду и развернуть ее с использованием своего GPU?
Вам потребуется:
Предустановленная библиотека cuDNN под TensorFlow. Она нужна, чтобы получить доступ к ядрам своей карточки. Кстати, Pytorch не требует никаких библиотек и использовать GPU там можно спокойно.
Упаковать ваши наработки Jupyter в .py файлы.
Создать виртуальное окружение, указав предварительно все используемые библиотеки в requirements.txt. для быстрого развертывания.
Создать 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 и контейнеризация
Контейнер позволяет развернуть ваше виртуальное окружение с готовыми скриптами на любой машине… Называют его еще 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 по максимуму, а также легко разворачивать виртуальное окружение в любой среде выполнения.