Production AI сервер за ₽0: полный гайд по сборке ML-станции для Stable Diffusion на б/у комплектующих

Я это сделал. За один день.
Часть 1: Аппаратная часть
Выбор видеокарт: RTX 2060 vs RTX 1060
Когда я начал планировать сборку, первый вопрос был: какие GPU выбрать? У меня лежали две RTX 2060 (2019) и одна RTX 1060 (2017). Интуитивно казалось, что 1060 давно устарела, но я решил проверить.
RTX 1060 — это действительно прошлый век для ML:
-
Нет поддержки NVLINK (не синхронизируются две карты)
-
CUDA Compute Capability 6.1 (старая архитектура, плохая поддержка современных операций)
-
Memory bandwidth всего 192 ГБ/сек
-
Нет Tensor Cores (ускорение операций матричного умножения)
-
На Stable Diffusion генерирует 512×512 за 60+ секунд
RTX 2060 — совершенно другой уровень:
-
CUDA Compute Capability 7.5 (хорошая поддержка современных фреймворков)
-
Встроены Tensor Cores (ускорение ML операций в 2-3 раза)
-
Memory bandwidth 360 ГБ/сек (почти в 2 раза выше)
-
Две карты синхронизируются через PCIe x16 + x4 без проблем
-
На обеих вместе генерируют 512×512 за 35-40 секунд
Вердикт: две RTX 2060 с 12GB VRAM на двух картах — это идеал для локального ML на бюджете. Они работают параллельно: одна генерирует Stable Diffusion, вторая анализирует через YOLOv8.
Материнская плата и BIOS: Gigabyte Z390-D
Выбрал Z390-D потому что она поддерживает dual-GPU без наворотов и имеет встроенную поддержку аппаратного RAID через Intel EZ RAID.
Критичные BIOS настройки:
Menu: Setting → IO Ports ├─ Initial Display Output: PCIEX16 │ (основной монитор подключается к первой карте) └─ Internal Graphics: Disabled (освобождаем ресурсы для GPU) Menu: Setting → Miscellaneous └─ Re-Size BAR: Enabled (BAR = Base Address Register Resizing) (даёт +5-10% производительности GPU) Menu: Tweaker → AI Tweaker └─ XMP Profile 1: Enabled (память DDR4-3000 работает на полной частоте)
Почему это важно:
-
Если не отключить Internal Graphics, система может отдать память встроенному видеоядру вместо выделения памяти GPU
-
Re-Size BAR позволяет CPU полностью адресовать всю VRAM GPU (по умолчанию адресуется только часть)
-
XMP включает профиль XMP 1 для памяти, поднимая её с стоковых ~2133 МГц до 3000 МГц
После этих настроек обе GPU видны в nvidia-smi без конфликтов.
Дисковая система: 6 дисков с аппаратным RAID 1
Это была самая боль часть настройки — инициализация пяти дополнительных дисков и создание RAID 1 через BIOS.
Текущая конфигурация:
|
Диск |
Тип |
Объём |
Назначение |
Паттерн I/O |
|---|---|---|---|---|
|
C: |
SSD |
1ТБ |
Windows 10/11 + Python + PyTorch |
Random I/O (система) |
|
D: |
HDD |
2ТБ |
Архив исходных изображений |
Sequential read |
|
E: |
HDD |
2ТБ |
Архив готовых результатов |
Sequential write |
|
F: |
SSD |
1ТБ |
Кэш ML (временные файлы) |
Random I/O (кэш) |
|
G: |
SSD |
1ТБ |
Рабочие данные ML |
Random read |
|
Intel RAID 1 |
SSD |
2ТБ |
Зеркало (Диск 4+5 в BIOS) |
Аппаратный RAID |
Почему именно такая схема:
-
C: на SSD — Windows и Python нужны быстрый доступ. Если загрузка долгая, всё упирается в дисковый I/O
-
D: и E: на HDD — там гигабайты сырых изображений и результатов. Скорость доступа не критична для архива, но объём нужен
-
F: на отдельном SSD — ML операции пишут кэш параллельно. Если поставить на HDD, это создаст узкое место (IOPS). SSD обработает одновременно и операции чтения из памяти ML
-
G: на SSD — рабочие данные, нужен быстрый доступ
-
Intel RAID 1 — аппаратное зеркало двух SSD на уровне BIOS контроллера
Аппаратный RAID 1 через Intel EZ RAID:
BIOS: Main Menu → EZ RAID ├─ Создаём массив (Array 1) ├─ Выбираем два SSD (физически Диск 4 и Диск 5) ├─ Режим: RAID 1 (зеркало) └─ Применяем Результат: ├─ Два SSD синхронизируются на уровне контроллера ├─ Любые данные пишутся на оба одновременно ├─ Если один выходит из строя — второй продолжает работу ├─ Windows видит это как один логический том └─ RPO (Recovery Point Objective) = 0 (нет потерь данных)
Почему RAID 1, а не другие уровни:
-
RAID 0 — быстрее, но если один диск сломается, всё потеряется
-
RAID 1 — медленнее (нужно писать дважды), зато при отказе одного диска данные остаются
-
RAID 5 — лучше (паритет), но нужно минимум 3 диска
Для критичной системы RAID 1 — компромисс между надёжностью и простотой.
Часть 2: Программная часть
Python 3.12 и экосистема
Почему Python 3.12, а не 3.13/3.14:
-
3.12 — стабильна, все ML фреймворки полностью совместимы, используется в production
-
3.13-3.14 — слишком новые, могут быть проблемы совместимости с PyTorch, TensorFlow и др.
-
3.9-3.10 — уже не поддерживаются, лучше избегать для новых проектов
Установка:
# Скачиваем с https://www.python.org/downloads/ # ОБЯЗАТЕЛЬНО отмечаем «Add Python to PATH» # Проверка python —version # Output: Python 3.12.x
Виртуальное окружение (venv)
Виртуальное окружение изолирует зависимости проекта от системного Python. Это критично, потому что разные проекты могут требовать разные версии одних и тех же пакетов.
# Создание рабочей папки mkdir D:ML cd D:ML # Создание venv python -m venv venv # Активация (Windows) venvScriptsactivate # Результат: (venv) D:ML>
Почему это нужно:
-
Если установить пакеты глобально в Python, они загрязняют системный интерпретатор
-
Разные версии PyTorch для разных GPU или версий CUDA конфликтуют
-
venv позволяет иметь несколько проектов с несовместимыми зависимостями
PyTorch + CUDA: сердце системы
PyTorch свяжет Python с GPU через CUDA (Compute Unified Device Architecture от NVIDIA).
# Обновление pip (критично!) python -m pip install —upgrade pip # Установка PyTorch с CUDA 11.8 pip install torch torchvision torchaudio —index-url https://download.pytorch.org/whl/cu118
Этот шаг займёт 10-15 минут и скачает 2-3GB. Не прерывайте!
Что происходит:
-
PyTorch скачивает бинарики скомпилированные с поддержкой CUDA 11.8
-
Если установить просто pip install torch, по умолчанию скачается CPU-only версия (бесполезная для нас)
-
С флагом —index-url https://download.pytorch.org/whl/cu118 мы принудительно берём GPU версию
-
Скачивается ~800MB основного пакета PyTorch + зависимости
Проверка:
# Проверка доступности CUDA python -c «import torch; print(torch.cuda.is_available())» # Output: True # Количество GPU python -c «import torch; print(f’GPUs: {torch.cuda.device_count()}’)» # Output: GPUs: 2 # Информация о каждой GPU python -c «import torch; print(torch.cuda.get_device_name(0)); print(torch.cuda.get_device_name(1))» # Output: NVIDIA GeForce RTX 2060 # NVIDIA GeForce RTX 2060 # Memory доступная на GPU python -c «import torch; print(f’GPU 0: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f}GB’); print(f’GPU 1: {torch.cuda.get_device_properties(1).total_memory / 1e9:.1f}GB’)» # Output: GPU 0: 6.0GB # GPU 1: 6.0GB
ML библиотеки
# Основной стек pip install diffusers transformers accelerate # Computer Vision pip install ultralytics opencv-python # Утилиты pip install pillow numpy pandas matplotlib scikit-learn # Опционально: для работы с моделями pip install safetensors huggingface-hub # Этот шаг займет 5-10 минут
Что это:
-
diffusers — официальная библиотека HuggingFace для работы с diffusion моделями (Stable Diffusion)
-
transformers — HuggingFace трансформеры (LLM, BERT и др.)
-
accelerate — оптимизация обучения/инференса на нескольких GPU/TPU, автоматическое распределение нагрузки
-
ultralytics — YOLOv8 для детекции объектов, натренирована на COCO dataset
-
opencv-python — обработка изображений (чтение, запись, трансформации)
-
safetensors — безопасный формат хранения весов моделей (быстрее чем pickle)
-
huggingface-hub — скачивание моделей из HuggingFace (где хранятся Stable Diffusion, LLM и т.д.)
Часть 3: Первый тест системы
Создание тестового скрипта
import torch from diffusers import StableDiffusionPipeline from ultralytics import YOLO import time import cv2 import numpy as np print(«=»*60) print(«TESTING DUAL GPU ML SYSTEM») print(«=»*60) # === ДИАГНОСТИКА === print(f»n✓ CUDA Available: {torch.cuda.is_available()}») print(f»✓ GPU Count: {torch.cuda.device_count()}») for i in range(torch.cuda.device_count()): props = torch.cuda.get_device_properties(i) total_memory_gb = props.total_memory / 1e9 print(f» GPU {i}: {props.name}, {total_memory_gb:.1f}GB VRAM») # === ТЕСТ GPU #0: STABLE DIFFUSION === print(«n[GPU 0] Loading Stable Diffusion v1.5…») start = time.time() pipe = StableDiffusionPipeline.from_pretrained( «runwayml/stable-diffusion-v1-5», torch_dtype=torch.float16, safety_checker=None # отключаем проверку безопасности для ускорения ) pipe = pipe.to(«cuda:0″) load_time = time.time() — start print(f»✓ Model loaded in {load_time:.1f}s») # Генерация изображения print(«[GPU 0] Generating image (512×512)…») start = time.time() image = pipe( prompt=»a beautiful laser engraving design with geometric patterns», height=512, width=512, num_inference_steps=20, guidance_scale=7.5 ).images[0] gen_time = time.time() — start image.save(«D:/test_gpu0.png») print(f»✓ Generated in {gen_time:.1f}s») print(f» → Speed: {512*512/gen_time:.0f} pixels/sec») # === ТЕСТ GPU #1: YOLOV8 === print(«n[GPU 1] Loading YOLOv8 nano…») start = time.time() model = YOLO(«yolov8n.pt») # Явно указываем device model.to(«cuda:1″) yolo_load_time = time.time() — start print(f»✓ Model loaded in {yolo_load_time:.1f}s») # Тест детекции print(«[GPU 1] Running inference…») test_frame = np.random.randint(0, 255, (640, 480, 3), dtype=np.uint8) start = time.time() results = model(test_frame, device=»cuda:1″, verbose=False) detect_time = time.time() — start print(f»✓ Detection in {detect_time:.3f}s») print(f» → Throughput: {1/detect_time:.1f} FPS») # === РЕЗУЛЬТАТЫ === print(«n» + «=»*60) print(«PERFORMANCE SUMMARY») print(«=»*60) print(f»Stable Diffusion (GPU 0):») print(f» Load time: {load_time:.1f}s») print(f» Generation: {gen_time:.1f}s for 512×512″) print(f» Throughput: {512*512/gen_time:.0f} px/s») print(f»nYOLOv8 (GPU 1):») print(f» Load time: {yolo_load_time:.1f}s») print(f» Inference: {detect_time*1000:.1f}ms per frame») print(f» Throughput: {1/detect_time:.1f} FPS») print(«n✓ SYSTEM READY FOR PRODUCTION») print(«=»*60)
Запуск теста
# В окне CMD с активированным venv python test_system.py
Ожидаемый результат:
============================================================ TESTING DUAL GPU ML SYSTEM ============================================================ ✓ CUDA Available: True ✓ GPU Count: 2 GPU 0: NVIDIA GeForce RTX 2060, 6.0GB VRAM GPU 1: NVIDIA GeForce RTX 2060, 6.0GB VRAM [GPU 0] Loading Stable Diffusion v1.5… ✓ Model loaded in 12.5s [GPU 0] Generating image (512×512)… ✓ Generated in 38.2s → Speed: 6862 pixels/sec [GPU 1] Loading YOLOv8 nano… ✓ Model loaded in 2.1s [GPU 1] Running inference… ✓ Detection in 0.045s → Throughput: 22.2 FPS ============================================================ PERFORMANCE SUMMARY ============================================================ Stable Diffusion (GPU 0): Load time: 12.5s Generation: 38.2s for 512×512 Throughput: 6862 px/s YOLOv8 (GPU 1): Load time: 2.1s Inference: 45.0ms per frame Throughput: 22.2 FPS ✓ SYSTEM READY FOR PRODUCTION ============================================================
Что это значит:
-
Обе GPU работают без конфликтов параллельно
-
Stable Diffusion генерирует адекватную скорость (38 сек — это нормально для RTX 2060)
-
YOLOv8 готов к real-time обработке видео (22 FPS достаточно для анализа качества)
-
Обе модели загружены в VRAM одновременно (12+3 = 15GB теоретически, но используется ~11GB из 12 доступных)
-
Нет ошибок CUDA, конфликтов памяти или синхронизации
Сравнение: локальное решение vs облако
|
Метрика |
RTX 2060 (локально) |
ChatGPT API |
Google Cloud AI |
|---|---|---|---|
|
Генерация 512×512 |
38 сек |
20-30 сек |
~15 сек |
|
Стоимость 1000 операций |
₽0 (один раз) |
₽50-100 |
₽30-50 |
|
Конфиденциальность |
100% (на машине) |
0% (облако Openai) |
0% (облако Google) |
|
Latency сети |
0мс |
200-500ms |
200-500ms |
|
Работает offline |
Да |
Нет |
Нет |
|
Полный контроль |
Да |
Нет |
Нет |
|
Масштабируемость |
Одна машина |
Неограниченно |
Неограниченно |
|
Гарантия 99.9% uptime |
Нет |
Да |
Да |
Для ACMER P3 локальное решение — идеально:
-
Нет задержек из-за интернета (критично для real-time обработки)
-
Полный контроль над процессом генерации (можно встроить в workflow)
-
Можно встроить в автоматизацию без API лимитов
-
Бесплатно после первоначальной инвестиции
Заключение
За ₽0 и несколько часов работы я собрал production-grade ML сервер, который:
✅ Генерирует дизайны через Stable Diffusion (38 сек/изображение)
✅ Анализирует изображения через YOLOv8 в real-time (22 FPS)
✅ Работает полностью локально (без облака, без API лимитов)
✅ Использует аппаратный RAID 1 для надёжности системы
✅ Готов к интеграции с ACMER P3 для автоматизированной лазерной гравировки
✅ Масштабируется для других ML задач (LLM, компьютерное зрение и т.д.)
Стоимость: ₽0 (всё из хлама)
Время сборки: 1 день
Потенциал: неограниченный
Следующая часть: интеграция с ACMER P3 и первая гравировка.
Кто ещё собирал ML сервер на б/у железе? Какие трудности встретили? Какие модели планируете запускать? Пишите в комментарии!
Подпишитесь на мой Telegram канал!
📢 @gromov_tech_insights
Там я публикую:
-
🤖 Еженедельные обновления про AI и ML
-
🔧 Практические гайды по настройке железа и ПО
-
💡 Инсайты про нейротехнологии и локальные LLM
-
📝 Промежуточные результаты этого проекта и интеграцию с ACMER P3
-
🚀 Ранний доступ к новым статьям и экспериментам
В канале уже обсуждается:
-
Часть 2: Python 3.12 + PyTorch установка (детальный гайд)
-
Оптимизация Stable Diffusion для максимальной скорости
-
Подключение лазера ACMER P3 к ML pipeline
-
Обзор локальных LLM для различных задач
Присоединяйтесь, чтобы не пропустить следующую часть про интеграцию лазера!
Используемые технологии:
-
PyTorch 2.x + CUDA 11.8
-
Stable Diffusion v1.5 (HuggingFace)
-
YOLOv8 (Ultralytics)
-
Python 3.12
-
Gigabyte Z390-D с Intel EZ RAID
-
2x NVIDIA RTX 2060 + 32GB DDR4-3000
Источник: habr.com
Похожие записи
Оцените материал:
Похожие записи
Blue Origin отменяет второй запуск New Glenn из-за погоды и движения круизных лайнеров
10.11.2025
Техно-религия и кризис рациональности: Искусственный интеллект как «новый опиум» в контексте глобальной нестабильности
13.02.2026
«Умные» повязки и стволовые клетки. Актуальные возможности регенеративной медицины
09.11.2025Присоединяйтесь и подпишитесь на рассылку самых свежих новостей по Email
Получайте свежие новости и идеи на почту. Без спама — только самое интересное.
Нажимая «Подписаться», вы соглашаетесь с политикой конфиденциальности.
