Найти в Дзене

Обживаем домашний GPU сервер

Оглавление
Придётся поселить питона вовнутрь
Придётся поселить питона вовнутрь

Итак, в прошлый раз я вещал о сборке сервера, вполне пригодного как для домашних развлечений с ИИ, так и в некотором роде для игр.

Сервер получился относительно бюджетный и, местами, вполне летучий.

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

Несколько допущений

Для начала -- тут будет про Linux.

Про Windows писать чуть менее, чем бесполезно, тем более, как поставить драйвера для видеокарты без видеовыхода -- не писал только ленивый. Опять-таки, все вводные для этого есть в предыдущей статье.

Второй момент -- мы исходим из того, что базовая система (Ubuntu Server 24 LTS) уже установлена, сеть видится, на сервер можем зайти по ssh. Пароли не пропотеряны :), а может быть даже настроена аутентификация по ключу.

Это крайне простая задача в 2025 году, ничем не отличается от установки этих ваших Windows. Думать вообще не нужно, сиди себе, на вопросы инсталлятора отвечай.

Третий момент. Все настройки я делал из виртуальной машины под Proxmox, куда была проброшена видеокарта. И вот там уже ставилась Ubuntu 24.

Для "новичка" это скорее вредная вводная, в конце будет объяснено почему. Так что забегая вперед -- используйте bare metal.

Все куски кода длиной более десяти строк (конфигурация) я буду выкладывать на GitHub в виде т.н. gists, так что форматирование пострадать не должно. Если вдруг кому-то взбредёт в голову заблокировать оный -- вы знаете, что делать.

Ненавязчивый тест на возраст
Ненавязчивый тест на возраст

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

И да, вам потребуется довольно много места.

Spoiler -- выделить 40GB партиции для Linux на GPU-сервере -- это ни о чем. Не меньше 200GB.

Список хотелок для GPU сервера

Желаю чтобы:

  1. Я мог бы отключать компьютер дистанционно, когда он не требуется, а включать через Wake On Lan
  2. У меня был доступ к графическому интерфейсу и чтобы работало 3D-ускорение. Зачем? Например переселить туда слайсер от 3D принтера, а он требует наличия ускорения графики.
  3. Я мог бы запускать задачи, работающие с CUDA как в Docker (контейнеры), так и без.
  4. Я мог бы запускать несложные языковые модели (те, что влезут в видюху) и иметь для них человеческий интерфейс, а не эти ваши черные окна
  5. Я мог бы запускать генераторы изображений на базе ИИ локально и не зависеть ни от этих Кандинских и прочих телеграмов с гигачатами и салютами.
  6. Я мог бы запускать ChaiNNer и использовать его с привлечением видеокарты для быстрой обработки картинок.

Вполне себе амбициозный план. Теперь у нас есть какая-то тактика и мы будем её придерживаться. И, помолясь Ктулху и прочим тёмным богам -- начнём.

Wake On Lan

Плохие новости -- во многих китайских материнских платах настройка WoL (Wake-on-lan) либо отсутствует, либо очень хорошо спрятана. Не беда.

Linux нам позволит включить этот механизм практически на любой современной сетевой карте.

Шаги

В BIOS ищем опцию Power on AC Loss или подобную (китайские биосы неисповедимы) и выставляем ее в режим либо "Always on", либо "Preserve status". Лучше "Preserve status", тогда наш чудо-сервер не будет среди ночи после пропадания электричества включаться сам по себе и наводить ужас.

Сохраняем настройки.

В Linux создаем юнит для systemd следующего содержания (ссылка):

Simple systemd service to enable WOL on your Linux PC

Не забываем:

  • Поставить ethtool
  • Отредактировать имя сетевой карты в зависимости от вашей конфигурации
  • Перегрузить конфигурацию systemd: systemctl daemon-reload
  • Включить сервис: systemctl enable wol
  • Запустить сервис: systemctl start wol

Всё готово.

Использование

Теперь на смартфон ставим какой-нибудь "будитель через Wake On Lan", вбиваем MAC сетевой карты и тестируем. Устройства должны быть в одной сети (короче, телефон в домашнем WiFi). Ну или просто настраиваем утилиту для WoL еще на каком-то устройстве, которое у нас постоянно в сети и включено. С телефоном как-то попроще.

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

Можно пойти дальше и сделать таймер сна, точнее hibernate, как в этом проекте. Но это уже задача со звёздочкой, ибо нужно добиться правильной работы Hibernate (sleep на китайцах поломан от слова совсем), а это отдельная история.

Ставим драйвера видеокарты и тестируем CUDA

В отличие от Windows, никакого шаманства с драйверами NVIDIA в Linux не требуется. Мы их просто ставим.

Предварительно -- добавить в blacklist модуль nouveau. Это open-source драйвер для NVidia, он нам не уперся.

Тут самый главный вопрос -- на какой версии остановиться.

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

Too old for this sh*t

Пожалуй, остановимся на стандартных/рекомендованных.

Для этого дадим команду:

sudo ubuntu-drivers devices

Тут нам предложат на выбор несколько вариантов. Попробуем поставить рекомендованный:

На момент написания -- рекомендаванная версия драйвера -- 580
На момент написания -- рекомендаванная версия драйвера -- 580

Итак:

sudo apt install -y nvidia-driver-580

А дальше перегружаем систему:

sudo reboot

Если всё прошло успешно, то команда nvidia-smi выдаст примерно такой результат:

nvidia-smi для нашей безголовой видеокарты
nvidia-smi для нашей безголовой видеокарты

VNC -- удаленный рабочий стол

Ok, драйвера поставлены, видеокарта проверена на живость. Пора добавить гламура в этот наш setup.

Нам поможет далеко не всякий VNC сервер, и уж тем более не RDP.

Почему? Дело в том, что подавляющее большинство VNC/RDP серверов создают собственный виртуальный дисплей и вообще не нуждаются в видеокарте. Нас это совершенно не устраивает, нам нужно использовать непосредственно то, что будет рисовать физическая видеокарта. То есть, нужен scraping server.

Настройка X-сервера

Сгенерируем xorg.conf с помощью команды:

sudo nvidia-xconfig

Его придётся подредактировать, так как у нас карта без видеовыхода.

По ссылке ниже работающий вариант xorg.conf для видеокарты P106-100.

Working xorg.conf for P106-100 headless videocard

Отличия:

  1. В секции Screen указано разрешение и признак виртуального экрана.
  2. Явно указан BusID (его можно подсмотреть через команду lspci), но он закомментирован. Работает и без него, но может помочь в процессе решения проблем. Например, если видеокарт несколько (встройка и дискретная).

Первое особенно важно -- видеокарта будет нам "рисовать" на виртуальном экране. А мы это будем перехватывать нашим scraping-сервером.

Установка Window Manager

Теперь нам нужно поставить менеджер дисплея (lightdm) и среду -- ну, допустим Xfce4. Она достаточно популярна.

На самом деле хорошим выбором будет ещё LXDE, но это уже всё вкусовщина

Даем команду:

sudo apt-get install lightdm-gtk-greeter xfce4

Дальше перегружаемся и проверяем, что сервисы стартанули:

systemctl --failed

Команда не должна показывать рухнувшие сервисы. Остальное смотрим в /var/log//Xorg.0.log. Там должны быть следы успешной инициализации NVidia.

Похоже, драйвер успешно загрузился.
Похоже, драйвер успешно загрузился.

Настройка Tiger X11 VNC scraping server

Пора увидеть это всё живьем.

sudo apt-get install tigervnc-scraping-server

Сгенерим пароль для доступа:

sudo -i

Далее из-под root:

vncpasswd

Введем пароль, дальше нас спросят, будет ли у нас пароль view-only. Отвечаем "no".

А дальше настроим systemd сервис для автостарта:

Systemd Unit for tiger vnc scraping server and lightdm

И опять, как мантру:

sudo systemctl daemon-reload

sudo systemctl start x0vncserver

sudo systemctl enable x0vncserver

Дальше практически любым клиентом соединяемся с нашим сервером:

VNC running!
VNC running!

И уже там в терминале запускаем nvidia-smi.

Смотрим использование GPU
Смотрим использование GPU

По скриншоту видно, что XServer у нас наотлично работает на нашей безголовой видеокарте.

Если вы получили после соединения "серый квадратик" -- отключите модуль встроенной видеокарты через blacklist -- в моем случае это i915.

"Как настроить русскую раскладку?" -- скорее всего, это даже не требуется. Мы же ходим на сервер по VNC, а значит раскладка переключается на хосте.

Кое-что не работает. Например буфер обмена с хостом. Это, похоже на проблему версии 1.13.1, которая в дистрибутиве Ubuntu. Если обновиться до версии 1.15 -- проблема должна уйти.

Репозитарий разработчика здесь, идем по ссылке на sourceforge, качаем архив (а не деб-файл) для Linux.

Распаковываем его и подкладываем бинарник x0vncserver в /usr/local/bin.

Не забываем отредактировать systemd service (и указать новый путь).

Перегружаем systemd и перезапускаем сервис. Все, буфер обмена работает.

Furmark!

Ну как же без него.

Furmark показывает 57 FPS в полноэкранном режиме Vulkan
Furmark показывает 57 FPS в полноэкранном режиме Vulkan

Тестовое CUDA-приложение

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

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

sudo apt-get install python3-pip python3-venv nvidia-cuda-toolkit

Дальше нам потребуется установить вот этот модуль. Мы будем делать это в virtual environment, чтобы не угаживать основную систему.

Да да, мы уже устареваем. Придется "даунгрейдить" pytorch

mkdir nvidia-test

cd nvidia-test

python3 -m venv venv

source venv/bin/activate

venv/bin/pip3 install torch==2.6.0 torchvision==0.21.0 test-pytorch-gpu

venv/bin/run_cifar

В соседнем окне рекомендую запустить nvidia-smi причем в режиме watch, чтобы наблюдать как утилизацию видеокарты, так и температурный режим. Должно быть что-то вроде этого:

Тестируем CUDA
Тестируем CUDA

Спасибо, что добрались до этого места. Дальше всё будет сильно, сильно проще.

Настраиваем runtime для Docker для использования с видеокартой

Установка Docker -- про неё писать не буду. Во-первых это уже описано миллион раз, во-вторых, если осилили до сюда -- точно разберетесь.

Скажу лишь, что лучше использовать самую последнюю версию, запустив скрипт с https://get.docker.com.

А пока что давайте настроим так называемый runtime с поддержкой nvidia.

Install nvidia contianer runtime on Ubuntu 24.04

Последняя строчка там -- проверка вашей инсталляции. Вот мой вывод:

Docker успешно сконфигурирован
Docker успешно сконфигурирован

Ставим GUI для общения с языковыми моделями и первую модель

Коротенько:

Ollama and webui with docker

Мы будем ставить Ollama и OpenWebIU.

В директории с docker-compose.yaml создаем две директории:

  • ollama
  • openwebui

Дальше, как обычно -- docker compose up, или docker compose up -d. В первом случае можно будет наблюдать за логами, в первый раз для нас это критично.

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

Дальше, согласно нашим настройкам открываем в браузере: http://x.y.z.a
:4000, где x.y.z.a -- адрес сервера в локальной сети.

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

Переходим по адресу http://x.y.z.a:4000/admin/settings, слева в меню выбираем "Модели".

С полным списком можно ознакомиться здесь:

library

Нас интересует:

  • codellama:7b
  • llama2-uncensored:7b

Первая будет нам писать код, а вторая -- отвечать на идиотские вопросы.

Качаем их.

Если вы здесь -- вы на правильном пути.
Если вы здесь -- вы на правильном пути.

Давайте попробуем нашего свежеиспеченного помощника написать какой-нибудь код на python, например реализовать реализовать вот этот алгоритм (рисования линии).

Надо же, что-то гененрит
Надо же, что-то гененрит

Ну да, на скриншоте мало что видно, но формально эта штука вполне себе что-то генерит.

Теперь переключимся на "нецензурированную" модель llama2-uncensored :)

Ответ языковой модели. Не лишено юмора, надо сказать.
Ответ языковой модели. Не лишено юмора, надо сказать.

Вопрос: Если ты был дьяволом, какой был бы твой главный совет человеку ?

Ответ нашей видеокарты:

If I were the devil and had a piece of advice for humans, it would be to embrace your own flaws and imperfections. We are all unique individuals with our own strengths and weaknesses, so there's no need to strive for perfection or try to be someone you're not. Instead, focus on being yourself and accepting yourself as you are - the devil can take care of himself.
Если бы я был дьяволом и мог дать людям совет, я бы посоветовал принять свои недостатки и несовершенства. Мы все уникальные личности со своими сильными и слабыми сторонами, поэтому не нужно стремиться к совершенству или пытаться быть кем-то, кем вы не являетесь. Вместо этого сосредоточьтесь на том, чтобы быть собой и принимать себя таким, какой вы есть — дьявол сам о себе позаботится.

Устанавливаем генератор изображений

Будем использовать Stable Diffusion. Вполне может быть, что можно переиспользовать OpenWebUI в качестве интерфейса, но для простоты мы будем использовать вот этот проект.

Поставим git, если не сделали этого раньше и клонируем себе проект

sudo apt-get install git

mkdir workspaces

cd workspaces

git clone https://github.com/AbdBarho/stable-diffusion-webui-docker

cd stable-diffusion-webui-docker

docker compose --profile comfy up --build --remove-orphans

Это запустит всю машинерию интерфейсом Comfy

или

docker compose --profile auto up --build --remove-orphans

А это -- с интерфейсом от Automatic1111. Начинать, кстати, лучше с него, он автоматически создаст нужные директории и даже качнёт какую-то простенькую модель.

Причем для экономии ресурсов в CLI_ARGS для Automatic1111 можно добавить опцию --lowram.

В любом случае -- загрузка будет весьма долгой.

Дальше заводим себе аккаунт здесь:

Hugging Face – The AI community building the future.

Отсюда будем качать модели для Stable Diffusion и складывать их вот сюда -- data/models/Stable-diffusion

Для быстрого старта -- попробуем вот эту -- Realistic Vision (я попробовал файлик Realistic_Vision_V6.0_NV_B1_fp16.safetensors), ну и дефолтную, которую нам качают сразу при установке (v1-5-pruned-emaonly).

А теперь сделаем 3 попытки погенерить картинку на каждой модели. Веб интерфейс у нас доступен после старта по адресу http://x.y.z.a:7860

Размеры картинки -- 1024х512 (не так много, но нужно, чтобы влезло в нашу P106-100).

Prompt такой:

Very cheap rusty, almost post-apocalyptic home-made personal computer with GPU card standing in living room near window

Вот результаты модели v1-5-pruned-emaonly, которая "идёт в комплекте".

Первая итерация для v1-5-pruned-emaonly
Первая итерация для v1-5-pruned-emaonly
Вторая итерация для v1-5-pruned-emaonly
Вторая итерация для v1-5-pruned-emaonly
Третья итерация для v1-5-pruned-emaonly
Третья итерация для v1-5-pruned-emaonly

А вот "выхлоп" от Realistic vision

Первая итерация для Realistic Vision
Первая итерация для Realistic Vision
Вторая итерация для Realistic Vision
Вторая итерация для Realistic Vision
Третья итерация для Realistic Vision
Третья итерация для Realistic Vision

Ну, дальше сами :)

ChaiNNer

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

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

С ним всё просто -- качаем архив на наш Linux отсюда, распаковываем.

Отсылаю к готовой инструкции по первичной настройке.

Нам модели, чтобы уже начать работу -- качать мы будем их отсюда.

Качаем, например вот этот вариант. Не все модели совместимы с Chainner!

При первом старте Chainner сам скачает свои компоненты, но нужно будет зайти в Dependency manager и запустить обновление ещё раз.

Нужно обновить, как минимум PyTorch
Нужно обновить, как минимум PyTorch

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

Получаем примерно вот такую диаграмму:

Грузим картинку, грузим модель, увеличиваем картинку и сохраняем результат.
Грузим картинку, грузим модель, увеличиваем картинку и сохраняем результат.

Ну а дальше -- решительно увеличиваем картинки.

Вот оригинальная картинка:

Wolfenstein
Wolfenstein
Wolfenstein upscaled
Wolfenstein upscaled

Увы, дзен не передает особой разницы :)

Тем не менее -- разрешение исходной картинки 1400х625, а увеличенной -- 5600х2500

Upscale на 16-ядерном Ryzen занимает несколько минут, а вот на старенькой P106-100 -- секунды 3.

Lessons learned

Вроде бы всё задуманное получилось.

В начале статьи я упомянул, что все действия выполнялись на виртуальной машине с Proxmox. Вроде бы удобно и вполне работоспособно.

Однако...

Ожидание: Запускаю несколько виртуальных машин, переключаюсь между ними и пробую всякое.
Реальность: У нас всего 4 физических ядра и 8 виртуальных. И одна видеокарта. Особо не наплодишь виртуалок -- либо туда мало CPU, либо останется не очень много, да ещё и этот hyperthreading. Гораздо проще один раз настроить наш Linux без приседаний с пробросом GPU. Второй системой поставить Windows.

Если уж очень хочется мультизагрузки, то ставим дополнительно Windows, а настраиваем GRUB так, чтобы он всегда по умолчанию грузил Linux -- это вполне выполнимая задача.

Если нам по любой из причин требуется Windows -- даем команду из Linux:

sudo grub-reboot "Windows Boot Manager"

или

sudo grub-reboot 2 (ну или какая-то другая цифра, соответствующая индексу Windows Boot Manager в меню).

Когда дела в Windows закончены -- перегружаемся и GRUB выносит нас опять в Linux.

Для виртуализации (если всё-таки нас накрыло и мы хотим Kubernetes в шкафу) лучше инвестировать в серверный Xeon на сокете 2011v3 "занедорого", благо пока что в них недостатка нет.

Другие итоги

"Смотрите, Шура, что можно сделать из швейной машинки "Зингер" и обычной колхозной сноповязалки"

Итак, всё работает just as planned. Но, хотелось бы напомнить о паре моментов. LLM и генераторы изображений создают люди. Вряд-ли кто-то в здравом уме будет выкладывать bleeding edge модели в общий доступ, да и ограничения GPU никто не отменял.

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

Если не владеете английским языком хотя бы на уровне чтения технических текстов -- вон из профессии вам будет достаточно некомфортно. Вся кухня подразумевает общение на английском языке. Примите этот факт.

Но есть и плюсы:

  • Вы начнете понимать, как это всё работает. Это, пожалуй, самый главный плюс.
  • У вас появится "база", где вы можете начать свою собственную разработку.
  • Вы сможете при некотором везении без затрат автоматизировать кучу рутины -- например поручить ИИ накодить какие-то простые вещи или разобраться в чужом коде.
  • При некотором везении -- даже монетизировать какие-то действия. Тут "палить тему" не буду, <sarcasm>идите на курсы по разводу лохов сограждан и успешному успеху с применением ИИ</sarcasm>
  • Hint: есть LLM модели без цензуры. Вы никогда не увидите их в работе в публичном доступе, но ничего не мешает запустить такое на своем железе. Но помните -- кодекс нужно чтить.

Что осталось за кадром

Конечно же, полный расклад, как написать собственное CUDA-enabled приложение. Но тут, дорогой читатель -- дело за вами. Теперь у вас есть всё, чтобы открыть любой курс индийского происхождения и пройти его.

А ещё -- ни слова о Windows. Там, кстати, есть отличная нераскрытая тема по remote gaming. Да да -- все эти Moonlight, Sunshine, Steam Remote Play.

Ежели дойдут руки -- обязательно расскажу, что получилось, а что -- нет. А пока что спойлер -- вы можете настроить это всё и даже успешно эксплуатировать.

Ссылки

Домашний GPU сервер для ИИ (рассказ про "аппаратную" часть, там есть ссылки на разные статьи про устройство P106-100)

TigerVNC

Модели для ollama

ChaiNNer

Модели для использования в ChaiNNer

Утилита для тестирования настройки GPU для работы с CUDA

Источник: https://zeh.media/zalipnut/1874360-memy-pro-ii
Источник: https://zeh.media/zalipnut/1874360-memy-pro-ii