Обучение, когда данные не влезают в узел

Training beyond one node

Кейс проверяет главное умение: отличить «не влезает модель» от «не влезает выборка». Это разные проблемы с разными решениями, и путаница между ними стоит недель работы.

Senior 5 шагов разбора · 3 развилки · 5 поломок из прода

Вводная

Команда дообучает языковую модель на 7 млрд параметров на внутреннем корпусе: документация, тикеты, переписка поддержки.

Корпус — 50 ТБ сырого текста в объектном хранилище, после фильтрации остаётся около 8 ТБ.

Есть кластер: 8 узлов по 8 карт. Первая попытка запуска упала по памяти, вторая работает, но карты загружены на 60 %.

Требования и ограничения
ЧтоЗначениеОткуда
Модель7 млрд параметровДообучение целиком, не адаптеры.
Данные8 ТБ после фильтрацииВ память одного узла не помещается ни при каком раскладе.
Железо8 узлов × 8 GPU (80 ГБ)Внутри узла NVLink, между узлами — сеть кластера.
Срокодна эпоха за 5 сутокДальше окно кластера занимает другая команда.
Отказыузел падает примерно раз в суткиОбычная статистика для кластера такого размера.
Воспроизводимостьперезапуск даёт тот же результатИначе сравнение экспериментов бессмысленно.

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

Разбор по шагам

Понять, что именно не влезает

Данные и модель упираются в разные ресурсы, и лечатся они по-разному.

Что означает каждый компонент
  • состояние обучения без активаций — те зависят от размера батча и длины последовательности
  • 2 байта на вес FP16 + 2 на градиент + 4 на мастер-копию FP32 + 8 на два момента Adam
  • число параметров модели — здесь 7 млрд
7 млрд × 16 байт ≈ 112 ГБ, тогда как сами веса в FP16 — всего 14 ГБ

Для 7 млрд параметров это примерно 112 ГБ без учёта активаций — то есть в карту на 80 ГБ состояние обучения не помещается, хотя сама модель в FP16 занимает всего 14 ГБ. Отсюда вывод: проблема здесь не в данных, а в состоянии .

Что не влезаетРешение
ВыборкаДанные не помещаются на диск узлаШардирование и потоковое чтение из хранилища
OOM при увеличении Накопление , gradient checkpointing
Состояние обученияOOM сразу после первого шага ZeRO / FSDP: шардирование состояния по картам
Сама модельOOM при загрузке весовТензорный и конвейерный параллелизм
На практике

Классическая ошибка — начать с конвейерного параллелизма там, где хватило бы FSDP. Сложность выкатки вырастает на порядок, а выигрыша нет.

Шардирование состояния: DDP → FSDP

Обычный DDP держит полную копию состояния на каждой карте — здесь это невозможно.

  • DDP реплицирует модель, и состояние на каждую карту. Просто и быстро — пока состояние влезает.
  • ZeRO / FSDP режет состояние , и параметры между картами: 112 ГБ на 8 карт узла превращаются в 14 ГБ на карту плюс .
  • Плата — обмен: параметры собираются перед вычислением слоя и раскидываются обратно. На NVLink внутри узла это дёшево, через сеть между узлами — заметно.

Практическое следствие: шардировать в первую внутри узла, где связь быстрая, а между узлами оставлять обычный обмен . Гибридная схема почти всегда быстрее наивной «шардируем всё по всем 64 картам».

Загрузка данных: обычная причина простоя карт

Карты на 60 % — почти всегда не про вычисления, а про то, чем их кормят.

  • Формат: миллионы мелких файлов в объектном хранилище убивают пропускную способность. Данные пакуют в шарды по 100–500 МБ (webdataset, parquet) и читают последовательно.
  • Шардирование по воркерам: каждый процесс читает свой набор шардов, без пересечений и без похода в общий индекс.
  • Предзагрузка и предобработка идут параллельно вычислениям: пока карта считает шаг, следующий уже собирается.
  • Токенизация — офлайн, один раз. Токенизировать текст на лету в цикле обучения — гарантированный простой карт.
На практике

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

Считать масштабируемость, а не число карт

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

Что означает каждый компонент
  • эффективность масштабирования: 1.0 — идеальное ускорение, 0.5 — половина кластера работает вхолостую
  • время шага на одной карте
  • число карт, умноженное на время шага на этих N картах
0.85 при 64 картах — хороший результат, 0.5 — повод искать узкое место
  • Обмен градиентами (all-reduce) растёт с размером модели и падает с пропускной способностью сети — на медленной сети он съедает весь выигрыш от лишних узлов.
  • Перекрытие обмена с вычислениями — стандартный приём: нижних слоёв отправляются, пока считаются верхние.
  • Смешанная точность BF16 даёт 1.5–3× скорости и вдвое меньше памяти; BF16 предпочтительнее FP16, потому что не требует масштабирования лосса.
  • Накопление градиента позволяет получить нужный эффективный без роста памяти — ценой пропорционально более долгого шага.

При изменении эффективного меняют и : правило линейного масштабирования плюс разогрев на первых итерациях. Без этого «ускорение» оборачивается расходящимся обучением.

Отказы и воспроизводимость

На пятидневном прогоне узел упадёт обязательно — это проектное требование, а не авария.

  • Чекпоинт по времени, а не по эпохам: раз в 20–30 минут. Стоимость записи против стоимости потерянных часов считается заранее.
  • В чекпоинт входит всё: веса, состояние , планировщик, позиция в данных и состояние генератора случайных чисел. Без последних двух перезапуск даёт другую выборку и другой результат.
  • Автоматический перезапуск с последнего чекпоинта: ручной рестарт в три часа ночи — потерянная смена.
  • Фиксация версий: данных, кода, конфигурации и образа. Иначе через месяц эксперимент не повторить.
На практике

Сохранение полного состояния 7-миллиардной модели — это десятки гигабайт на чекпоинт. Асинхронная запись и ротация старых копий обязательны, иначе чекпоинты сами станут узким местом.

Развилки и выбор

На собеседовании ценится не сам выбор, а объяснение, почему отклонены остальные варианты.

DDP, FSDP или конвейерный параллелизм?

FSDP внутри узла, обмен градиентами между узлами

Состояние обучения в 112 ГБ не влезает в карту, но влезает при шардировании по восьми картам узла. Быстрая связь NVLink делает обмен внутри узла дешёвым, а сеть между узлами используется только для градиентов.

Что отклонено и почему
  • Чистый DDPНе работает физически: полная копия состояния не помещается в 80 ГБ.
  • Конвейерный параллелизмНужен, когда модель не влезает даже в узел целиком. Для 7 млрд параметров добавляет пузыри конвейера и сложность без выигрыша.

Как хранить и читать 8 ТБ?

Шарды по 256 МБ в объектном хранилище, потоковое чтение

Последовательное чтение крупных шардов даёт предсказуемую пропускную способность, а перемешивание делается буфером в памяти — этого достаточно для качества обучения.

Что отклонено и почему
  • Скопировать данные на локальные диски узлов8 ТБ × 8 узлов и часы на копирование при каждом изменении набора данных.
  • Случайный доступ к отдельным примерамМиллионы мелких запросов к хранилищу — карты простаивают в ожидании данных.

Как часто писать чекпоинты?

Раз в 25 минут, асинхронно, с ротацией трёх последних

При отказе примерно раз в сутки ожидаемая потеря — около 12 минут работы; запись при этом не встаёт в критический путь.

Что отклонено и почему
  • Раз в эпохуНа пятидневной эпохе один отказ уничтожает весь прогон.
  • Каждые 5 минутДесятки гигабайт на чекпоинт превращают запись в основную статью расхода времени.

Что ломается в проде

«Добавим узлов» не ускоряет

Если эффективность масштабирования 0.5, вторая половина кластера работает вхолостую. Сначала профилирование — обмен, загрузка данных, синхронизация, — и только потом новые узлы.

Размер батча тихо меняет обучение

Больше карт — больше эффективный батч. Без пересчёта скорости обучения и разогрева результат окажется хуже, чем на одной карте, и причину будут искать в данных.

Последний шард ждут все

Неравные по размеру шарды приводят к тому, что 63 карты ждут одну. Шарды выравнивают по числу примеров, а не по объёму в байтах.

Перезапуск даёт другой результат

Если в чекпоинт не попали позиция в данных и состояние генератора, обучение после отказа идёт по другой траектории — и сравнение с предыдущим прогоном теряет смысл.

FP16 расходится там, где BF16 работает

Узкий динамический диапазон FP16 требует масштабирования лосса; без него градиенты обнуляются или уходят в NaN. BF16 при том же размере даёт диапазон FP32 и снимает проблему.

По чему видно, что система здорова

МетрикаЗначениеЗачем
Утилизация GPU> 85 %Ниже — ищите узкое место в загрузке данных или обмене.
Время шагамедиана и p95Разброс указывает на неравномерность шардов или сетевые всплески.
Эффективность масштабированияT₁ / (N × T_N)Меряется прогоном на 1, 8 и 64 картах.
Пропускная способность данныхГБ/с на узелСравнивается с тем, сколько успевает съесть карта.
Потери от отказовчасы, потерянные на перезапускахОпределяет частоту чекпоинтов.

Что спрашивают по этому кейсу

  1. Модель на 7 млрд параметров не влезает в карту на 80 ГБ, хотя веса весят 14 ГБ. Объясните почему.
  2. Карты загружены на 60 %. Как искать причину по порядку?
  3. Чем FSDP отличается от DDP и когда он не нужен?
  4. Вы увеличили число узлов вдвое, а обучение ускорилось на 20 %. Что проверяете?
  5. Что должно попасть в чекпоинт, чтобы перезапуск был честным?

Проверить себя: тест «Глубокое обучение», тест «MLOps и инженерия», тест «SQL и инженерия данных». Открытые задачи там же — под тестом.

Темы атласа, из которых собран кейс

Distributed Training

Распределённое обучениеиз «Вычислительная инфраструктура»

DDP, ZeRO, FSDP и виды параллелизма.

Collective Operations

Коллективные операциииз «Вычислительная инфраструктура»

All-reduce и почему он упирается в сеть.

Cluster Networking

Сеть кластераиз «Вычислительная инфраструктура»

Чем связь внутри узла отличается от связи между узлами.

Training Throughput

Ускорение обученияиз «Вычислительная инфраструктура»

Как считают утилизацию и эффективность масштабирования.

GPU in PyTorch

GPU в PyTorchиз «Вычислительная инфраструктура»

Смешанная точность и работа с памятью на практике.

Mixed Precision

Смешанная точностьиз «Оптимизация обучения»

FP16 против BF16 и масштабирование лосса.

Batch size

Размер батчаиз «Оптимизация обучения»

Связь размера батча и скорости обучения.

File Formats

Форматы храненияиз «Инженерия данных»

Форматы и шарды для потокового чтения.

Experiment Tracking

Трекинг экспериментовиз «MLOps»

Воспроизводимость: версии данных, кода и конфигурации.