Всем привет! Есть у меня на антросолях сервер с видеокартой Nvidia на котором я частенько провожу всякие эксперименты связанные с нейросетями, там обучение, запуск и так далее, ну и короче надоело мне заходить на этот сервер и работать из консоли, да через screen скриптики гонять, захотелось какой-нибудь удобный UI доступный через Web.
Скажу честно, мне нравится Гоголь Colab, но сами понимаете, работать с компанией Гугл в наши дни дело такое, могут забанить в любой момент, поэтому хотелось что-то подобное, но чтобы моё, домашнее, self-hosted'ное.
Благо существует такой замечательный проект, как Jupyter Notebook и JupyterLab для запуска этих самых нотебуков. Поэтому в данной публикации речь пойдёт про запуск платформы JupyterLab, но в режиме системного сервиса доступного с любого компьютера в сети, а не просто сайтиком на локалхосте, как обычно это делается.
Поэтому давайте рассмотрим эту тему чуточку подробнее.
Настройка операционной системы
В качестве ОС на графическом сервере использую систему Debian GNU/Linux 11 (Bullseye), из коробки в репозитории доступен Python 3.9, не супер свежий, но для многих моих проектов этого более чем достаточно, при желании можно всегда докинуть testing репозитории или подключить сторонний реп с кастомными сборками питончика, но пока что мне это не требуется.
На сервере установлена видеокарта Nvidia RTX 3050 (о её характеристиках почитать можно тут), следовательно нужны ещё и драйверы Nvidia, использовать будем те, что идут в штатной поставке вместе с CUDA, ставить их разумеется будем из официального репозитория для машинных лёрнингистов.
Для начала установим один хитрый пакет:
sudo apt install software-properties-common
Далее активируме contrib и non-free ветки репозиториев:
sudo add-apt-repository contrib
sudo add-apt-repository non-free
Далее скачаем файл с ключиками репозитория Nvidia:
wget https://developer.download.nvidia.com/compute/cuda/repos/debian11/x86_64/cuda-keyring_1.0-1_all.deb
Установим:
sudo dpkg -i cuda-keyring_1.0-1_all.deb
Активируем репозиторий с CUDA:
echo "deb [signed-by=/usr/share/keyrings/cuda-archive-keyring.gpg] https://developer.download.nvidia.com/compute/cuda/repos/debian11/x86_64/ /" | sudo tee /etc/apt/sources.list.d/cuda-debian11-x86_64.list
Обновляем список пакетов, в выводе должен появиться свежедобавленный реп от Nvidia.
sudo apt update
Установим пакеты:
sudo apt install nvidia-driver cuda-toolkit-12-1
На момент написания статьи CUDA 12.1 была самой новейшей версией, поэтому используется именно она, но в репозитории есть и другие версии, начиная с 11.5 закачивая 12.1.
Если нужны более ранние версии CUDA, то нужно использовать debian10 вместо debian11 в скриптах выше.
Кстати, если вам нужны вообще все библиотеки CUDA какие только есть, то следует использовать метапакет cuda-* (где вместо астериска нужно подставить необходимую версию), но этот вариант тянет за собой графический интерфейс, чего мне очень не хотелось, поэтому я ограничился только лишь cuda-toolkit версией.
Настройка JupyterLab
Существует несколько вариантов установки JupyterLab (далее JL) в системе, в частности через conda, mamba, pip, pipenv или docker. Но с докером я провозился уже так много, что хочется попробовать что-то новенькое, но если вам интересно почитать про развёртывание JL в Docker, то не стесняйтесь, пишите об этом, публикация не заставит себя долго ждать.
И так, мне захотелось развернуть всё при помощи pipenv, установим данную утилиту при помощи pip:
pip install pipenv
Установим окружение и всё необходимое для дальнейшей работы:
pipenv install jupyterlab
Далее пользоваться данным окружением можно следующим образом:
- Чтобы запустить шел pipenv вручную: pipenv shell
- Чтобы запустить JL после входа в шел: jupyter lab
- Чтобы запустить JL не заходя в шел: pipenv run jupyter lab
А вот если надо будет запустить JL в режиме сервиса, доступного не только через localhost, то нужно выполнить следующую команду:
pipenv run jupyter lab --ip='0.0.0.0' --port=8888 --no-browser
Обатите внимание, что указан порт 8888, его можно поменять на любой другой, но мне удобнее чтобы был именно этот.
Проверим, что всё работает корректно выполнив последнюю команду из списка выше:
Вроде всё хорошо, поэтому теперь закроем веб-морду паролем, для этого сгенерируем его следующей командой (не забудьте заменить пароль MY_PASSWORD на свой):
pipenv run python -c "import hashlib, os; salt = os.urandom(6).hex(); hashed_password = hashlib.sha1(('MY_PASSWORD' + salt).encode('utf-8')).hexdigest(); print(f'sha1:{salt}:{hashed_password}')"
Получится что-то типа:
sha1:8a3f05dca5c9:fe910321c1914020631f7e51b6aaf192cc6f801f
Сохраним его, он пригодится позже.
Systemd Unit
Для того чтобы запустить любое приложение в режиме демона можно воспользоваться множеством различных решений, самое совершенное (на мой скромный взгляд) это Systemd, потому что оно уже встроено в систему, для него есть удобный функционал логирования и просмотра журналов, а ещё в случае падения приложения systemd попытается его автоматически перезапустить (подробнее почитать про systemd можно тут).
В директории /etc/systemd/system/ потребуется создать пустой файл, назовём его jupyterlab.service, далее отредактируем его и добавим следующее содержимое:
[Unit]
Description=JupyterLab service
[Service]
Type=simple
PIDFile=/run/jupyterlab.pid
WorkingDirectory=/home/pasha
ExecStart=/home/pasha/.local/bin/pipenv run jupyter lab --notebook-dir=/home/pasha/notebooks --no-browser --NotebookApp.password='sha1:8a3f05dca5c9:fe910321c1914020631f7e51b6aaf192cc6f801f' --ip='0.0.0.0' --port=8888
User=pasha
Group=pasha
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Полный путь: /etc/systemd/system/jupyterlab.service
Вот краткое описание каждой секции и параметра:
- [Unit]: Секция, содержащая метаданные и зависимости.Description: Описание сервиса, в данном случае "JupyterLab service".
- [Service]: Секция, содержащая настройки сервиса и команды для управления им.
- Type: Тип сервиса; "simple" означает, что сервис считается запущенным сразу после запуска основного процесса.
- PIDFile: Путь к файлу, содержащему ID процесса (PID) сервиса.
- ExecStart: Команда для запуска сервиса. Здесь используется pipenv для запуска Jupyter Lab с указанными параметрами, такими как директория ноутбуков, пароль, IP-адрес и порт.
- User: Имя пользователя, от имени которого будет работать сервис.
- Group: Имя группы, к которой относится пользователь, от имени которого будет работать сервис.
- Restart: Политика перезапуска сервиса; "always" означает, что сервис будет перезапускаться всегда, независимо от причины остановки.
- RestartSec: Задержка перед перезапуском сервиса в секундах.
- [Install]: Секция, содержащая настройки для автоматического запуска сервиса при загрузке системы.
- WantedBy: Целевой объект, с которым связан сервис. Значение "multi-user.target" означает, что сервис будет активирован в многопользовательском режиме (когда запущены основные сетевые службы и пользовательские процессы).
Скорее всего User и Group вам нужно будет заменить на своих пользователя и группу соответственно, а также не забудьте поправить путь до pipenv и стартовой директории с нотебуками, скорее всего они у вас будет отличаться, ну и хеш пароля разумеется.
Короче всё готово, теперь заставим systemd увидеть конфигурацию, после чего активируем и запустим сервис.
sudo systemctl daemon-reload
sudo systemctl enable jupyterlab
sudo systemctl start jupyterlab
Проверим статус сервиса командой:
sudo systemctl status jupyterlab
Отлично, сервис запустился и исправно работает, теперь откроем его через браузер. В моём случае у хоста настроено короткое имя gpu01, но я воспользуюсь IP-адресом сервера, у вас он скорее всего будет отличаться.
И так, заходим по порту 8888 на сайт http://192.168.1.20:8888/ и видим форму для ввода пароля.
Авторизуемся и перед нами откроется интерфейс JupyterLab.
Ну вот и всё, делов на пятнадцать минут и у вас готов удобный домашний сервер для экспериментов. Кстати, на всякий случай скажу, что я не рекомендую выставлять JL в интернет без дополнительных уровней безопасности, цель данного проекта не сделать супербезопасный интерфейс, а предоставить пользователям удобный способ работы с питоном и всем, что с этим связано, поэтому и с безопасностью там дела обстоят постольку-поскольку.
Итог
В данной публикации был продемонстрирован способ запуска JupyterLab в режиме веб-сервиса на Linux сервере с видеокартой от Nvidia. Галопом пробежались по основам написания Unit'ов для Systemd и настроили приложение в pipenv.
Надеюсь данная публикация вам понравилась, не забывайте подписываться на мой блог, читать другие мои публикации, писать комментарии и прожимать лайки, а ещё у меня есть Telegram-канал, там вы можете пообщаться с мной и почитать некоторые мои мысли и связанные с ИТ новости.
До встречи в следующей публикации!