Как разогнать GPU до предела: ищем узкие места ИИ-инфраструктуры

Представьте, что вы запустили обучение модели в облаке или на собственном кластере, выбрав A100, H100, L40S или даже RTX 4090. Ожидаете максимальной загрузки GPU, но в панели мониторинга видите лишь 40–60% или меньше.

Причина не в «кривом» коде и не в «слабых» картах, а в самом медленном звене I/O-цепочки. Даже самый мощный ускоритель простаивает, если ему не успевают доставлять данные.

В этом материале расскажем, почему для высокопроизводительного обучения важны не только SSD, но и CPU, RAM и сетевая архитектура, а также как построить сбалансированную инфраструктуру при ограниченном бюджете.

Основные «бутылочные горлышки» I/O-конвейера

Передача данных от хранилища до GPU проходит через три ключевых узла — и любой из них способен тормозить работу всей системы:

  1. Дисковая подсистема: при работе с миллионами мелких файлов время уходит на поиск и открытие метаданных, а GPU ждет следующий батч.

  2. Сеть: в распределённом обучении по одному каналу передаются и данные, и градиенты; недостаточная пропускная способность или высокие задержки сводят на нет преимущества масштабирования.

  3. CPU и оперативная память: именно они выполняют загрузку, декодирование, аугментации и формирование батчей; слабый процессор или медленная RAM не успевают «кормить» даже одну RTX 4090.

Далее разберём каждую из этих зон подробнее.

Хранилище и локальные NVMe

Миллионы мелких файлов (JPEG, TXT, JSON) тормозят систему: чтение метаданных отнимает больше времени, чем передача самих данных. Объединение их в крупные контейнеры — WebDataset (.tar) или TFRecord — даёт рост пропускной способности в 3–10×.

Формат хранения Пример Скорость чтения (NVMe) Загрузка GPU Комментарий
Миллион JPEG-файлов ImageNet ~0,8 ГБ/с 50–60% Высокий IOPS, низкая эффективность
WebDataset/TFRecord ImageNet-shard ~2,5–3,5 ГБ/с 85–95% Последовательное чтение, минимум системных вызовов
Parquet Kaggle-таблицы ~1,5–2 ГБ/с ≈80% Колоночное хранение, встроенное сжатие
Сырые .txt Новостной корпус ~0,3 ГБ/с <50% Множество операций open()/read()
.tar.zstd Новостной корпус ~1,2 ГБ/с ≈80% CPU распаковывает, диск разгружен

Часто данные хранят централизованно (Ceph, MinIO, NAS) с пропускной способностью 1–2 ГБ/с на клиента. Для высокой загрузки GPU их сначала копируют на локальный NVMe-инстанса, как это делают в облаках.

  • Максимальная скорость: NVMe Gen4 — 5–7 ГБ/с, Gen5 — до 12+ ГБ/с, что «кормит» RTX 4090 или L40S.
  • Стабильность производительности: отсутствуют сетевые задержки и конкуренция за ресурсы СХД.

Сетевая архитектура распределённого обучения

На одном узле и одной GPU весь цикл локален: чтение с NVMe, предобработка CPU и передача в GPU. Внешняя сеть нужна лишь для скачивания данных.

При масштабировании на 2–4 узла по сети ходят и данные, и градиенты. Если канал не выдерживает нагрузки, обучение «задерживается».

Сценарий Задача Требования к сети
1 узел, 1 GPU CV / финотюнинг LLM 1–10 Гбит/с для скачивания
2–4 узла Data Parallel для ResNet, BERT 10–25 Гбит/с
5+ узлов Обучение «с нуля», ZeRO-3/FSDP 100–200+ Гбит/с

Роль CPU и оперативной памяти

Даже одна GPU простаивает, если CPU и RAM не успевают обрабатывать данные:

  • Считывание с NVMe → в RAM → декодирование JPEG/PNG, аугментации → формирование батчей → передача в GPU.
  • CPU с <16 ядер или частотой <3,5 ГГц не справляется.
  • Медленная DDR4-RAM с низкой частотой и высокими таймингами ограничивает пропускную способность.

В итоге GPU простаивает, а вы платите за неиспользованные ресурсы.

Практические рекомендации при ограниченном бюджете

Не гнаться за самыми топовыми компонентами, а подбирать под конкретную задачу:

CV и небольшие NLP-модели (до 20 млрд параметров) комфортно работают на GPU с 24–48 ГБ.

Если модель >48 ГБ, используйте GPU с 96 ГБ или объединяйте несколько карт, либо арендуйте A100/H100 с 80 ГБ.

  • Запускайте на локальных NVMe для 3–12 ГБ/с на узел и полной загрузки GPU.
  • При нескольких серверах обеспечьте высокоскоростную локальную сеть.
  • CPU ≥3,5 ГГц (лучше ≥4 ГГц) и ≥16 ядер ускорит предобработку.

В BIOS:

  1. Настройте NUMA (AMD EPYC: NPS = 1 или 2) для минимальных задержек доступа к RAM.
  2. Отключите IOMMU (без виртуализации) для быстрого P2P-обмена по PCIe.
  3. Подключите GPU и NVMe к разным PCIe-контроллерам, чтобы не делить полосу.

Диагностика производительности

Компонент Инструмент Норма Признак проблемы
GPU nvidia-smi dmon Util ≥85–95% Util ≤60%, простои
CPU htop, perf Загрузка 50–70% 100% user/iowait
Диск iostat -x 1 %util <70%, await <2 мс %util = 100%, await >10 мс
Сеть nccl-tests, ib_write_bw ≥85% от теории <50% пропускной, высокий jitter
DataLoader torch.profiler Время загрузки <10% шага >30% шага

Чек-лист первоочередных действий:

  1. Конвертируйте мелкие файлы в контейнеры (.tar/TFRecord/WebDataset) для 3–10× прироста скорости.
  2. Настройте DataLoader: num_workers=4–8, pin_memory=True, prefetch_factor=2–4.

Если загрузка GPU <85%, ищите «узкое место» в I/O-конвейере.

Подход TCO: оптимизация вместо покупки

При бюджете до 150 000 ₽/мес важнее не количество GPU, а эффективность уже имеющихся. Оптимизация I/O-пайплайна даёт 2–3× ускорение, как будто вы получили «бесплатные» GPU. Покупка ещё одного ускорителя при медленном CPU или SSD не даст линейного эффекта.

Перед расширением железа проверьте загрузку GPU: если она <85%, вы платите за простой, а не за вычисления.

Заключение

Мощный GPU — лишь часть уравнения. Без быстрого хранилища, корректной внутриузловой топологии и надёжной сети ускорители простаивают, а бюджет уходит впустую. На практике именно I/O-узкие места, а не терафлопсы, определяют реальную скорость обучения — от суперкомпьютеров до «домашних» RTX 4090 с NVMe.

Даже при ограниченных ресурсах достаточно перейти от миллионов мелких файлов к крупным архивам, включить RoCE или добавить второй NVMe — и загрузка GPU вырастет с 50 до 90%, обеспечив вдвое более быстрое обучение без покупки нового ускорителя.

Какие узкие места встречались в вашей инфраструктуре и как вы их устраняли? Делитесь в комментариях!

 

Источник

Читайте также