Иногда возникают проблемы с развертыванием среды разработки в облаке, ведь бесплатных сервисов с большими облачными вычислительными мощностями почти нет. Тот же 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.
- Для создания виртуального окружения введите консоли следующий код.
python3 -m venv myenv |
Myenv – название нашего вирт. окружения. Естественно, его можно изменить. При помощи этой команды создается особая директория, в которой и будут храниться нужные нам библиотеки.
- Активация виртуального окружения. Окружения можно активировать и деактивировать в зависимости от проекта.
myenv\Scripts\activate |
- Дальше при помощи pip, о котором мы расписали выше, следует установить все зависимости, если нужно, с их версиями по спецификации. Например:
(myenv) user@host:~$ pip install tensorflow-gpu==2.10.0 |
- Так устанавливаем все нужные библиотеки наших версий. Не забудьте создать файл с требованиями, в котором будут перечислены все зависимости, чтобы все библиотеки с виртуальной среды на другом ПК было бы легко установить…
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 по максимуму, а также легко разворачивать виртуальное окружение в любой среде выполнения.