127 подписчиков

Как подготовить Linux к запуску и обучению нейросетей? (+ Docker)

Приветствую всех ценителей мира нейросетей!

Сегодня мы окунемся в увлекательный и занимательный процесс подготовки серверов под управлением операционных систем на базе ядра Linux для работы с нейросетями. В частности мы сосредоточимся на настройке машинок бегающих под управлением Debian и Ubuntu с установленными графическими ускорителями от Nvidia.

К данному мему я бы ещё добавил что работать всё это будет на Linux ;) https://twitter.com/nearcyan/status/1769967455818957074
К данному мему я бы ещё добавил что работать всё это будет на Linux ;) https://twitter.com/nearcyan/status/1769967455818957074

Изложенная тема рассчитана на людей которые уверенно работают с Linux, но при этом не встречались с задачами по запуску нейросетевого добра на данном классе ОС, поэтому многие мелкие подробности касательно работы с Linux я пропущу.

Публикацию составлял таким образом, чтобы она могла быть использована как шпаргалка по установке и настройке всего необходимого, начиная с драйверов Nvidia и CUDA, заканчивая Docker и вспомогательными инструментами.

Кстати, как закончите с настройкой сервера рекомендую попробовать запустить модель ruGPT-3.5 от Сбера, у меня как-раз публикация "ИИ в каждый дом! Инструкция по запуску ruGPT-3.5 13B" на эту тему написана ;)

Итак, начнем-с...

Подготовительный этап

Прежде чем мы продолжим предполагается, что все команды вы будете выполнять из под пользователя root, для того чтобы на него переключиться на Debian просто пишем команду:

su

А на Ubuntu такую:

sudo su

Далее, я буду считать, что у вас имеется некая "чистая" операционная система на которой ещё муха не сидела, поэтому первым делом обновим список пакетов и накатим свежие заплатки безопасности.

apt update
apt dist-upgrade

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

Итак, общий вид команды загрузки данного пакета следующий:

wget https://developer.download.nvidia.com/compute/cuda/repos/$distro/$arch/cuda-keyring_1.0-1_all.deb

Тут вместо $distro/$arch потребуется указать версию своей операционной системы и её архитектуру, вот список операционок которые я обычно настраиваю:

  • debian10/x86_64
  • debian11/x86_64
  • debian12/x86_64
  • ubuntu2004/x86_64
  • ubuntu2204/x86_64

А тут можно посмотреть полный список всех возможных вариантов.

Так будет выглядеть команда скачивания пакета если у вас например Debian 12:

wget https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-keyring_1.0-1_all.deb

А вот так если Ubuntu 22.04 LTS:

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb

Ну и так далее, по аналогии.

Теперь установим скачанный пакет:

dpkg -i cuda-keyring_1.0-1_all.deb

Данная команда выполнит установку пакета, закинет сертификат шифрования cuda-archive-keyring.gpg в папку /usr/share/keyrings/, а в папку /etc/apt/sources.list.d/ положит файл вида cuda-$distro-$arch.list, давайте убедимся в этом:

ls -la /etc/apt/sources.list.d/ | grep cuda

Если в ответе будет что-то типа:

-rw-r--r-- 1 root  root   137 мар 23 10:40 cuda-debian12-x86_64.list

То значит всё настроено правильно.

Обновим список пакетов:

apt update

И поставим драйверы Nvidia:

apt install nvidia-driver cuda

Эта команда установит самую свежую версию CUDA и самую свежую версию драйвера Nvidia, но если требуется установить какую-то конкретную версию CUDA то пишем команду вида:

apt install nvidia-driver cuda-11-8

11-8 это тоже самое что 11.8, то есть такая команда установит драйверы для работы с CUDA 11.8 ну и так далее, по аналогии.

После завершения установки драйвера Nvidia желательно перезагрузиться, однако, если будете доустанавливать CUDA то перезагружаться будет не нужно. По завершению перезагрузки выполним команду:

nvidia-smi

Если она покажет что-то типа этого, то всё сделано правильно:

Пример выдачи команды nvidia-smi
Пример выдачи команды nvidia-smi

Мы можем спокойно поставить сразу несколько версий CUDA, например у меня в системе на момент написания статьи установлены 11.7, 11.8, 12.2 и 12.4, каждая версия ставится в отдельную папку в /usr/local/.

ls -la /usr/local/ | grep cuda
Список всех версий CUDA в системе
Список всех версий CUDA в системе

Вы наверно обратили внимание на то, что /usr/local/cuda - это символическая ссылка, которая ведёт на /etc/alternatives/cuda (а та в свою очередь ведёт на /usr/local/cuda-12.4), если кратко то это так называемые альтернативы. Данный механизм позволяет иметь в системе несколько версий библиотек или приложений и позволяет средствами системы между ними переключаться.

update-alternatives --config cuda
Выбор из списка альтернатив
Выбор из списка альтернатив

В данной ситуации мы можем написать любое число от 0 до 4 и переключить всю систему глобально на нужную версию драйвера CUDA, в настоящий момент видно, что CUDA 12.4 была выбрана в автоматическом режиме.

Пишем нужное число и жмём клавишу [Enter].

Убедимся что нужная версия CUDA выбрана в системе, выполним команду:

nvcc --version
Вывод информации об утилите nvcc
Вывод информации об утилите nvcc

Если после release указана выбранная версия, то всё ок и можем двигаться дальше.

Про то как установить CUDA на другие операционные системы тут.

Установка Docker и всего необходимого

Следующий традиционный компонент серверов на которых я запускаю нейросети это Docker, ну уж очень удобный инструмент, без него как без командной строки, жить можно, но очень неудобно.

Кстати, ранее я писал очень подробную инструкцию про Docker и про хитрости его использования, рекомендую ознакомиться если не читали.

Традиционно на новых серверах установка Docker у меня начинается с удаления барахлишка, которое иногда устанавливают систему неопытные админы, поэтому для начала выполняем команду:

apt remove docker.io docker-doc docker-compose podman-docker containerd runc

Иногда на хитрые сборки Ubuntu ставят ещё пакет docker-compose-v2, его тоже нужно будет удалить если он установлен.

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

apt-get update
apt-get install ca-certificates curl apt-transport-https

Теперь создадим специальную папку и положим в неё ключик которым подписаны пакеты:

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

Если у вас Ubuntu, то можно заменить linux/debian/gpg на linux/ubuntu/gpg, но особого смысла в этом нет, так как файл что там, что сям один и тот же.

Теперь добавим в список сорслист информацию о репозитории Docker:

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/$(. /etc/os-release && echo "$ID") \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

Обновим список пакетов и установим Docker Engine, а также некоторые полезные плагины:

apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Если всё прошло хорошо, то выполнение команды ниже не покажет ошибок:

docker run hello-world
Вывод контейнера hello-world
Вывод контейнера hello-world

Про установку Docker Engine на другие ОС можно почитать тут.

Установка Nvidia Docker Runtime

С докером закончили, теперь надо сделать так, чтобы он мог работать с графическим ускорителем от Nvidia

Сначала скачаем ключ репозитория:

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

Теперь скачаем сорслист, на лету подправим его и положим куда нужно:

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

Теперь обновим список пакетов и установим утилиту nvidia-ctk:

apt update
apt install -y nvidia-container-toolkit

Про то как установить Nvidia Docker Runtime на других ОС тут.

Для того чтобы сконфигурировать Docker таким образом, чтобы он увидел ускорители Nvidia потребуется выполнить следующую команду:

nvidia-ctk runtime configure --runtime=docker
Подготовка Docker для работы с Nvidia
Подготовка Docker для работы с Nvidia

Утилита отрапортует, что она что-то там добавила в конфигурацию /etc/docker/daemon.json, давайте взглянем что именно было добавлено:

Содержимое /etc/docker/daemon.json
Содержимое /etc/docker/daemon.json

Как видно утилита добавила в блок runtimes секцию nvidia и указала название бинарника, который позволяет докеру работать с карточками.

Теперь рестартанём Docker Engine:

systemctl restart docker

И проверим подхватил ли Docker указанный рантайм:

docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
Если вы видите что-то типа этого то Docker увидел вашу карточку
Если вы видите что-то типа этого то Docker увидел вашу карточку

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

Что дальше? И некоторые тонкости...

Теперь давайте разбираться с тем как пользоваться всем этим добром, для начала настоятельно рекомендую установить пакеты с python3 и python3-venv, в дальнейшем они вам пригодятся.

Python3

Первый пакет - это собственно сам интерпретатор Python 3й версии, в Ubuntu 22.04 это будет Python 3.10. а в Debian 12, если ничего не путаю, должен быть Python 3.11.

А второй - это специальный модуль Python, который позволяет создавать изолированные виртуальные окружения и в них уже работать.

В качестве альтернативы venv (virtual environment) существуют ещё: Conda (которая из России не работает без VPN) от IBM, pyenv представляющий из себя нечто среднее между venv и Conda, а также некоторые другие, чуть менее популярные решения.

С большой вероятностью вы будет использовать Python 3.11 или выше, но почти наверняка в системе этот пакет не будет установлен, поэтому поставим его и venv заодно:

apt update
apt install python3.11 python3.11-venv

Следом нам понадобится пакет pipx, он позволяет устанавливать и запускать различные приложения написанные на языке Python в специальной изолированной средее, в частности нас интересует утилита nvitop.

Pipx + Nvitop

Обновим списки и поставим pipx:

apt update
apt install pipx

Далее, чтобы запустить приложение nvitop пишем:

pipx run nvitop

Ждём некоторое время, после чего будет запущено приложение внешне и по функционалу напоминающее htop, но со статистической информацией о видеокартах.

Вывод утилиты nvitop
Вывод утилиты nvitop

Чтобы выйти из программы жмём клавишу [Q], можно перемещаться по процессам стрелочками и завершить процесс нажав клавишу [K], а затем [Enter] на нужном.

Но если вам не хочется устанавливать лишний софт на свой сервер, то могу порекомендовать решение на базе связки из nvidia-smi и watch, просто пишем в консоли:

watch nvidia-smi
Приветствую всех ценителей мира нейросетей!-11

Чтобы выйти жмём комбинацию клавиш [Ctrl] + [C].

Проброс видеокарт в контейнер через Docker

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

Для начала попробуем выполнить эту процедуру используя стандартную утилиту docker:

docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

Ранее мы уже выполняли эту команду, давайте рассмотрим подробнее её параметры:

  • --runtime=nvidia - говорит нам о том, что мы просим Docker-сервер использовать рантайм с названием nvidia, так как оно было указано в момент настройки /etc/docker/daemon.json:
  • --gpus all - этот параметр говорит о том к каким видеокартам будет доступ из контейнера, если написать all то контейнер будет иметь доступ ко всем видеокартам установленным в системе, но можно ограничить этот список, через запятую перечислив номера видеокарт, например --gpus 0,1,2 в таком виде в контейнер будут прокинуты первая, вторая и третья видеокарты (считаем от нуля), подробнее тут.

Проброс видеокарт через Docker Compose

Теперь рассмотрим ситуацию при которой запуск нейросетевых контейнеров осуществляется при помощи docker compose, предположим у нас есть контейнер с приложением ollama, попробуем запустить его без поддержки видеокарт:

Пример запуска OLLAMA без поддержки видеокарты
Пример запуска OLLAMA без поддержки видеокарты

Тут исходник:

А вот так необходимо сделать чтобы пробросить видеокарты:

Добавим секцию deploy в конфигурацию сервиса ollama
Добавим секцию deploy в конфигурацию сервиса ollama

Кот тут.

Как видно мы добавили секцию deploy, а в ней прописали resources и перечислил список устройств для рантайма nvidia которые мы хотим передать. Вместо count: all мы можем через запятую указать список карточек, в общем всё как в случае с утилитой Docker.

Завершение

Таким образом, мы прошли через весь процесс подготовки серверов под управлением Linux для работы с нейросетями, начиная от установки драйверов Nvidia и CUDA, заканчивая настройкой Docker и интеграцией с графическими ускорителями.

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

Если вам понравилась эта публикация, не забудьте поставить лайк и подписаться на мой Telegram-канал, где я делюсь своими мыслями, новостями и экспериментами. К тому же, если вы хотите поддержать мои усилия то можете сделать пожертвование на CloudTips. Ваша поддержка поможет мне продолжать свою работу и делиться новыми открытиями с вами.

Спасибо за ваше внимание и до новых встреч!