Я инженер, и у меня есть эдакий фетиш - все, что важно, должно находиться под моим контролем. Локально, в железе, которое можно измерить осциллографом, нагрузить до упора и при необходимости перепаять. Когда ты привык работать со схемами, сигналами и источниками питания, становится странно отдавать вычисления куда-то наружу и надеяться, что там “все нормально работает”.
Облачные решения на старте выглядят удобно. Быстро запустился, получил результат. Потом начинают всплывать приколы. Сегодня сервис отвечает, завтра отвечает через раз, послезавтра меняется тариф. Нет возможности посмотреть, что происходит с памятью, где узкое место, как ведет себя шина.
Самый наглядный пример - умный дом. Утром нажимаешь “умный” выключатель, а свет не включается сразу, потому что команда уходит в облако и там же обрабатывается. Интернет просел - задержка, иногда вообще нет реакции. Датчик движения срабатывает, но лампа не загорается. Алиса отвечает “отсутствует подключение к интернету». Свет включается через пару секунд, иногда два раза, иногда не выключается. Потом прилетает обновление у производителя, меняется API, и часть сценариев работает нестабильно. Физически все устройства на месте и исправны, но логика находится вне квартиры, поэтому поведение системы определяется не состоянием дома, а состоянием внешнего сервиса.
Та же история с API. В проекте может быть критическая зависимость от внешнего сервиса. Сегодня он отвечает, завтра меняет формат, послезавтра вводит ограничения. Код не менялся, поведение системы меняется. И отладка превращается в попытку понять, что изменилось вне твоего контроля.
У меня в целом, думаю как и у многих, ненависть к подписочным сервисам как к явлению. Платить за токены? Вы чо?)
Локальный вычислительный узел убирает этот класс проблем. Все находится в одной системе, любая зависимость прозрачна, а любая проблема диагностируется на месте. Такой узел с несколькими CPU и GPU я попробую собрать, здесь опишу трудности с которыми столкнулся, как их решил, и какие результаты получил. Зайдет – придумаю с этим что-нибудь еще.
В моей голове вероятные задачи такой системы выглядят так:
Самый очевидный класс задач - обработка данных. Большие массивы логов, симуляции. Можно хранить и анализировать их локально. Построение моделей, фильтрация, поиск аномалий. Все это требует пропускной способности памяти и вычислительных ресурсов.
Компьютерное зрение. Камеры, поток видео, обработка в реальном времени. Детекция объектов, отслеживание, анализ сцен. Здесь важны задержки. Когда обработка идет локально, время отклика определяется только железом, а не сетью.
Обработка видео - апскейл, шумоподавление, перекодирование. Это задачи, которые хорошо ложатся на GPU. Можно обрабатывать большие объемы данных без очередей и ограничений.
Моделирование. Физические процессы, тепловые расчеты, электрические схемы. Многие методы требуют итеративных вычислений. Чем больше ресурсов, тем быстрее сходится модель. Это может быть расчет распределения температуры на плате, симуляция нагрузки на систему питания, анализ сигналов.
Рендеринг и генерация. 3D-графика, генерация изображений, синтез данных. Здесь важна вычислительная плотность. Несколько GPU позволяют параллельно обрабатывать сцены или батчи.
Системы автоматизации. Свои сервисы, нейросети, базы знаний, обработка событий. Можно строить локальные аналоги облачных сервисов. Очереди задач, обработчики, хранение данных, чат-боты, умные ассистенты для дома. Все работает внутри одной инфраструктуры.
Отдельный класс - экспериментальные задачи. Когда нет готового решения и нужно пробовать - менять параметры, запускать расчеты, смотреть результат. Здесь важна возможность быстро перезапускать процессы и не думать о стоимости каждой итерации.
В качестве базы выбрана интересная плата с AliExpress под два процессора и шесть GPU, точная модель Jingsha x99 dual plus. Такие платы выглядят странно, но это лучше чем тонна лапши из райзеров, и все влезет в один ящик вместо целого стеллажа. У платы два сокета 2011-3, 6 слотов PCI-E, 4x16, 2x8. По 4 слота DDR4 памяти на проц.

На процах внимание заострять не буду, БУшные xeon суммарно на 48 ядер. Параллельностью можно объесться, и достаточно. Отдельно про видеокарты, потому что именно они определяют, что система вообще умеет считать и с какой скоростью.
Начиналось все с NVIDIA P104-100. Это майнинговые карты на базе Pascal, по сути переработанные GTX 1070 без видеовыходов. Внутри GPU GP104, порядка 6.5 TFLOPS FP32, 8 ГБ GDDR5. Для задач своего времени это нормальный уровень. Такие карты хорошо подходят для простых вычислений, классических CUDA-задач, некоторых типов обработки данных. Плюс они массовые и дешевые на вторичке. После майнинга их много, и цена часто ниже, чем у “игровых” аналогов.

Но как только начинаются современные задачи, особенно связанные с нейросетями, начинают проявляться ограничения. Архитектура Pascal не содержит специализированных блоков для матричных операций. Все вычисления идут через универсальные CUDA-ядра. Это означает, что операции, которые в новых архитектурах выполняются аппаратно ускоренными блоками, здесь считаются “в лоб”. Разница в скорости накапливается очень быстро.
Отдельный момент - типы данных. В нейросетях активно используются FP16 и INT8. Это уменьшает объем данных и ускоряет вычисления. В Pascal такие режимы либо работают без ускорения, либо сильно ограничены. В результате карта либо считает медленно, либо упирается в память.
Следующий шаг - линейка CMP HX,тоже майнинговые карты, основаны на архитектуре Ampere. Отличаются наличием тензорных ядер. Это специализированные блоки, которые выполняют матричные операции, лежащие в основе нейросетей. Такие операции выполняются значительно быстрее и с меньшим энергопотреблением. Поддерживаются FP16, INT8, смешанная точность. Это позволяет уменьшать объем данных и ускорять вычисления без заметной потери качества.

Кроме этого, улучшена работа с памятью. Увеличены кэши, оптимизирован доступ. Пропускная способность выше, задержки ниже. В задачах, где постоянно происходит обмен данными между ядрами и памятью, это дает заметный эффект.
CMP 90HX (самая жирная карта в этой линейке) имеет чип G102-100, это почти RTX3080, и 10 ГБ видеопамяти (в зависимости от кривизны чипа некоторые банки от максимальной конфигурации на плате отключены, каждый раз разные). Это немного больше, чем 8ГБ у P104, тоже плюс.
Если смотреть на производительность, то разница зависит от задачи.
В классических CUDA-задачах, где нет использования тензорных ядер, прирост есть, но не радикальный. Архитектура новее, частоты выше, память быстрее, но принцип работы тот же.
В задачах нейросетей разница значительно больше. За счет тензорных ядер и поддержки пониженной точности ускорение может быть кратным. Там, где Pascal считает секунды, Ampere укладывается в доли секунды.
В задачах, чувствительных к памяти, тоже есть выигрыш. Более высокая пропускная способность и кэши уменьшают время ожидания данных.
Теперь про стоимость. Это ключевой фактор выбора. CMP 90HX удалось взять примерно по 5 тысяч за штуку. За эти деньги получается GPU уровня Ampere с 10 ГБ памяти. Альтернативы с такими характеристиками в обычных линейках стоят кратно дороже.
В итоге выбор очевиден. P104 - дешево, но ограничено архитектурой и памятью. CMP 90HX - чуть сложнее в настройке, но дает значительно больше вычислительных возможностей за сопоставимые деньги.

Дальше начались практические моменты, опишу ошибки с которыми я столкнулся.
Память. Установлена обычная DDR4, система зависает на POST-коде 79 и дальше не идет. Этот код относится к инициализации хаба и общесистемных интерфейсов. Типичные проблемы с памятью обычно проявляются иначе, чаще это коды вроде 7B или близкие к этапу инициализации DRAM, где BIOS хотя бы явно показывает, что не может поднять модули.
С точки зрения теории, DDR4 память бывает нескольких типов. Основные различия - наличие коррекции ошибок и организация модулей. Есть обычная UDIMM память без ECC, которая используется в десктопах. Есть ECC UDIMM, где добавлены биты коррекции ошибок, но модуль остается небуферизированным. Есть Registered память (RDIMM), где добавлен регистр для стабилизации сигналов и разгрузки контроллера, такие модули применяются в серверах с большим объемом памяти.
ECC работает за счет добавления избыточных битов, которые позволяют обнаруживать и исправлять одиночные ошибки в данных. Это важно при длительной работе под нагрузкой, когда вероятность случайных ошибок растет. Контроллер памяти должен поддерживать ECC, иначе эти биты просто не используются.
В данном случае плата фактически ожидала ECC память. Обычные UDIMM модули определялись некорректно, инициализация не завершалась. При этом код ошибки не указывал напрямую на память, что усложнило диагностику. После установки DDR4 ECC UDIMM система запустилась сразу, без дополнительных настроек.
Серверные платформы часто более чувствительны к типу памяти. Даже если заявлена поддержка обычной DDR4, реальная работа может требовать ECC.
В итоге получился простой вывод: eсли используется серверная плата и серверные процессоры, лучше сразу использовать ECC память. Это экономит время на диагностике и дает более предсказуемую работу системы.
Шум. Учитывая потребление карт в 250 ватт, и двух процов, использовался майнинговый блок питания на 1800 ватт. Разумеется, крутилятор работал на максимальных оборотах. После замены уровень шума снизился. В металлический корпус были установлены тихие 120 вертушки для забора воздуха к плотно стоящим картам. Шум кулеров видеокарты, на счастье, регулировали сами.

Поведение под нагрузкой. Все карты были поочередно проверены отдельно, в одинаковых условиях, в первую очередь на состояние видеопамяти. На первый взгляд каждая из них выглядела рабочей. Они корректно определялись системой, позволяли загрузить модель в видеопамять, не выдавали явных ошибок на этапе инициализации и стресс-теста памяти.
Одна из карт вела себя иначе уже в момент реальной нагрузки. LLM загружалась в видеопамять без проблем, потребление росло, по метрикам карта показывала загрузку до 100 процентов. На этом этапе все выглядело нормально. Дальше выполнение задачи не происходило, генерация не начиналась, вычисления не шли. Hashcat -b ругался, и поведение оставалось таким же.

В этот момент я уже успел сделать неприятный вывод, что проблема системная. Были мысли про шину, про недостаточную ширину PCIe, про то, что сами карты не подходят под мои задачи. Картина выглядела именно так - все вроде работает, но результата нет.
Дополнительно сбивало с толку поведение самой карты. Температура оставалась практически неизменной. В нормальном режиме при полной загрузке GPU чип должен нагреваться, это логично. Здесь этого не происходило. Карта находилась в состоянии, где она по идее занята, но не выполняет реальную работу.
После исключения этой карты из конфигурации поведение системы стало предсказуемым. Загрузка распределилась равномерно, задачи начали выполняться без зависаний.
Вывод: частично неисправный GPU может проходить базовые тесты и корректно определяться системой, но при реальной вычислительной нагрузке переходить в некорректное состояние. Тест памяти нагружает только контроллер памяти и проверяет целостность данных. Основные вычислительные блоки при этом могут не участвовать в полной мере.
PCIe. Через lspci видно, что GPU говорит - поддерживает x16, но работает в x4 downgrade. Это означает, что часть линий не используется.
lspci -vv -s адрес_устройства
LnkCap: Port #0, Speed 8GT/s, Width x16
LnkSta: Speed 2.5GT/s, Width x4 (downgraded)
Осмотр платы показал наличие разводки под дополнительные линии. Разделительные конденсаторы на TX линиях не установлены после x4. Измерение падения напряжения показало, что диффпары разведены до GPU и предварительно исправны (0.8v).


После установки 220нФ кондеров в линии ширина PCIe ожидаемо увеличилась. Увеличение до х8 считаю достаточным. Пропускная способность на карту выросла с 1Гбит/сек до 2 соответственно. Где-то писали, что так модифицировать можно только карты уровнем ниже, что 90-серия заблокирована на 4x, что в играх подобные манипуляции не давали прироста, но имхо, использовать такие карты для игр это извращение, а проблем с увеличением пропускной способности линий я никаких не испытал.

Энергопотребление. В простое карты потребляли около 100 ватт. Начал копаться в причинах. P104-100 спокойно уходили в энергосбережение и потребляли пару ватт без нагрузки, а тут что-то неадекватное. Режим обогрева помещения. Проблема нарисовалась в том, как карты управляют частотами и питанием. Почти 10ГГц на память в ПРОСТОЕ – это мега не рационально, а еще мега-дорого в условиях домашнего сервера. У NVIDIA режимы частот называются P-state.

Режимы P-state можно описать кратко по уровням:
P0 — максимальная производительность. Частоты GPU и памяти максимальные, напряжение высокое, потребление тоже. Используется при полной нагрузке и вычислениях.
P2 — высокий уровень производительности. Частоты немного ниже, чем в P0, но все еще высокие. Часто применяется в compute-задачах на обычных картах.
P5 — средняя нагрузка. Частоты и напряжение снижены. Используется как переходное состояние при умеренной активности.
P8 — низкая нагрузка. Частоты ядра и памяти заметно снижены, напряжение низкое. Типичный режим простоя у игровых видеокарт.
P12 — минимальное потребление. Частоты и напряжение на минимуме. Глубокий idle, практически нет нагрузки и минимальный расход энергии.
Общая логика простая: чем меньше номер состояния, тем выше производительность и энергопотребление. В нормальной ситуации GPU автоматически переключается между этими режимами. В CMP-картах это поведение часто ограничено, и они остаются в P0 даже без нагрузки, что и дает высокий расход энергии в простое, так как рассчитаны карты на фермы и дата-центры, где нагрузка в 100% непрерывная, не стоит задачи экономии, и нужно мгновенно раздупляться для подхвата следующей задачи.
Карта не дала редактировать application clocks (это когда сам задаешь пары, на какой частоте хочешь ГПУ, на какой – память). Однако на мое счастье, позволяет редактировать частоты из заранее определенных пар память-ГПУ, и тут как раз есть что-то типа режима P8 – почти standby.

При снижении частоты памяти до 405 МГц потребление снизилось. GPU работает на низкой частоте, нагрузка минимальна.


Таким образом, проблема большого поедания лектрической ваты в простое решилась ручным переводом карт в P8, путем фиксации частоты памяти на 405MHz (и при желании GPU на минимальном 210MHz, хотя без нагрузки она выше и не поднимается). Позднее можно автоматизировать переходы P0-P8 и обратно, раз уж китайцы не додумались.
В итоге система доведена до рабочего состояния.. После настройки система работает в расчетных режимах и используется для различных вычислительных задач. Проблемы возникшие по ходу считаю решенными. Открыт для критики, предложений, мнений. Дальнейшие модификации тоже буду описывать здесь, когда они соберутся в стоящую рассказа пачку.
Стоимость системы составила:
Плата + процессоры + блок питания (который не использовал в итоге) + корпус - 20 тыс
Память DDR4 ECC 2x16GB - 11 тыс
Охлаждение суммарно (крутиляторы, термоинтерфейс) - 8 тыс
Видеокарты + блок питания 30 тыс
Итого: 69.000 российских рублей.
При полном загрузе 24/7 и стандартном тарифе на ЭЭ цена работы машины ~6500 руб.
При условии перевода карт в P8 в период простоя стоимость ЭЭ в месяц ~1500 руб.

P.S. Результаты бенчмарка такой системы, прикреплю в комменты.

