Перейти к содержанию
Публикация AiManual

Когда GPU-хостинг подводит: диагностика, чекпоинты и восстановление

Как проверить GPU-инстанс, разобраться с CUDA и I/O, измерить PyTorch без ложных эталонов и сохранить чекпоинты для восстановления на другом сервере.

Коротко

Что будет в материале

  1. 01

    Когда обучение прерывается: сначала сохраняем факты

  2. 02

    Типичные симптомы и возможные причины

  3. 03

    Чек-лист при старте GPU-инстанса

  4. 04

    RunPod, Vast.ai и другие провайдеры: что сравнивать

Когда обучение прерывается: сначала сохраняем факты

Потеря SSH-соединения, ошибка CUDA или падение скорости не всегда означают неисправный GPU. Причина может быть в приложении, драйвере, сети, диске или жизненном цикле арендуемого инстанса. Задача диагностики — отделить эти варианты и сохранить данные до перезапуска.

Разберём проверки при старте GPU-хоста, небольшой тест PyTorch и план восстановления. Это не рейтинг надёжности провайдеров и не обещание найти любую неисправность за пять минут.

Типичные симптомы и возможные причины

  • SSH недоступен: проверьте состояние инстанса, сетевые правила, маршрут и консоль провайдера. Статус Running сам по себе не подтверждает работоспособность SSH.
  • CUDA out of memory: сопоставьте ошибку с размером модели, batch size, контекстом и другими процессами. Свободная память после сбоя не доказывает, что её хватало в момент выделения.
  • Driver version is insufficient: проверьте совместимость драйвера и CUDA-библиотек окружения.
  • Illegal memory access: сохраните воспроизводимый пример и версию библиотек; ошибка не доказывает аппаратный дефект.
  • Процесс D: ожидает непрерываемую операцию, часто I/O. Сигнал может исполниться только после завершения ожидания. Процесс Z уже завершён и ждёт, пока родитель получит его статус; убивать сам zombie бессмысленно.
  • Падение скорости или I/O ошибки: сравните частоты, температуру, загрузку, свободное место и логи с исправным запуском.

Не начинайте с принудительного reboot. Сначала определите, можно ли безопасно сохранить чекпоинт, какие тома переживут перезапуск и какие процессы работают на узле.

Как интерпретировать аппаратные показатели

Повышение температуры, ошибки ECC и Xid-сообщения требуют внимания, но конкретное действие зависит от модели GPU, типа ошибки и документации. Не всякий ненулевой накопительный счётчик означает новый отказ. Сравнивайте время события, динамику и влияние на задачу; передавайте эти данные поддержке. Значение N/A может означать, что метрика не поддерживается в этой среде.

Чек-лист при старте GPU-инстанса

Сначала выполните read-only проверки. Нагрузочные тесты запускайте отдельно от полезной задачи, только на выделенных вам ресурсах и с учётом правил провайдера.

1 Быстрая проверка здоровья GPU

# Список устройств и доступная информация
nvidia-smi -L
nvidia-smi
nvidia-smi -q

# Поддерживаемые поля можно проверить через --help-query-gpu
nvidia-smi --query-gpu=index,name,uuid,driver_version,memory.total,memory.used,temperature.gpu --format=csv

# Если CUDA Toolkit установлен: версия компилятора, а не драйвера
command -v nvcc >/dev/null && nvcc --version
💡
Поле CUDA Version в сводке nvidia-smi показывает поддерживаемую драйвером версию CUDA, а не наличие соответствующего Toolkit. Углублённые тесты памяти выполняются отдельными средствами, например NVIDIA DCGM на поддерживаемом оборудовании; сначала согласуйте их с оператором и остановите конкурирующую нагрузку. Не сбрасывайте ECC-счётчики и GPU до сбора диагностики.

2 Проверка системных ресурсов и диска

free -h
df -h
df -i
top -b -n 1

# Необязательная запись 64 МиБ: выполните в тестовом каталоге
# с достаточным свободным местом, не на рабочем наборе данных.
(
  set -eu
  f=$(mktemp ./gpu-io-test.XXXXXX)
  trap 'rm -f -- "$f"' EXIT
  dd if=/dev/zero of="$f" bs=1M count=64 conv=fdatasync
)

3 Создание эталонного теста производительности

Запусти маленький, но показательный скрипт. Он должен:

  • Загрузить небольшой тензор в память GPU.
  • Выполнить матричное умножение (операция, сильно нагружающая вычислительные блоки).
  • Измерить время выполнения.
  • Сохранить результат. При следующем запуске на другом инстансе (или после падения) ты сможешь сравнить производительность.
import argparse
import json
import statistics
import time
import torch

parser = argparse.ArgumentParser()
parser.add_argument("--device", type=int, default=0)
parser.add_argument("--size", type=int, default=2048)
args = parser.parse_args()
if not torch.cuda.is_available():
    raise SystemExit("CUDA недоступна в данном окружении")
if not 0 <= args.device < torch.cuda.device_count():
    raise SystemExit("Неверный индекс GPU")
if not 128 <= args.size <= 4096:
    raise SystemExit("Для этого smoke-test размер должен быть от 128 до 4096")

device = torch.device(f"cuda:{args.device}")
torch.cuda.set_device(device)
torch.set_float32_matmul_precision("highest")
props = torch.cuda.get_device_properties(device)
size, iterations = args.size, 20
with torch.inference_mode():
    x = torch.randn(size, size, device=device, dtype=torch.float32)
    y = torch.randn(size, size, device=device, dtype=torch.float32)
    out = torch.empty_like(x)
    for _ in range(5):
        torch.mm(x, y, out=out)
    torch.cuda.synchronize(device)
    samples = []
    for _ in range(5):
        start = time.perf_counter()
        for _ in range(iterations):
            torch.mm(x, y, out=out)
        torch.cuda.synchronize(device)
        samples.append(time.perf_counter() - start)

seconds = statistics.median(samples)
record = {
    "time_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
    "gpu_index": args.device, "gpu_name": props.name,
    "torch": str(torch.__version__), "torch_cuda": torch.version.cuda,
    "dtype": "float32", "matmul_precision": "highest",
    "size": size, "iterations": iterations,
    "median_seconds": seconds,
    "estimated_tflops": 2 * size ** 3 * iterations / seconds / 1e12,
}
print(json.dumps(record, ensure_ascii=False))
with open("gpu_benchmark.jsonl", "a", encoding="utf-8") as f:
    f.write(json.dumps(record, ensure_ascii=False) + "\n")

Запуск: python benchmark_gpu.py --device 0 --size 2048. Это короткий тест матричного умножения, а не проверка всей памяти и не прогноз скорости LLM. Он не гарантирует отсутствие OOM. Сравнивайте одинаковые GPU или MIG-профили, размер, precision, версии и условия нагрузки. Значение ниже прежнего — повод исследовать причину, но не доказательство неисправности. Для каждого GPU запускайте отдельный тест и сохраняйте его UUID из nvidia-smi рядом с результатом.

RunPod, Vast.ai и другие провайдеры: что сравнивать

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

КритерийЧто проверить до запуска
GPU и окружениеМодель, VRAM, MIG/разделение ресурсов, драйвер, допустимые образы и привилегии.
Жизненный циклВозможность прерывания, правила остановки и удаления инстанса, доступность замены.
ХранениеКакие тома эфемерные, какие переживают stop/delete, где находятся резервные копии и как их восстановить.
Сеть и данныеДоступные механизмы изоляции, открытые порты, регион, договорные условия обработки данных. TLS не скрывает открытые данные от процесса, который их обрабатывает.
Поддержка и SLAОфициальные каналы, обязательства по ответу и порядок компенсации. Срок или возврат не гарантируются опытом другого клиента.
БюджетВычисления, простой, диски, трафик, копии, сопровождение и возможный повтор задачи.

Например, RunPod и Vast.ai отдельно описывают виды хранения. Перед остановкой прочитайте правила именно своего типа тома: постоянный том не равен независимой резервной копии.

Для дальнейшего сравнения можно посмотреть материал о специализированных провайдерах и условиях аренды GPU. Актуальную стоимость и наличие проверяйте у самого провайдера.

Когда проблема случилась: план сохранения и восстановления

  1. Сохраните факты: время UTC, ID узла, версии, код ошибки и доступные логи. Удалите токены, персональные данные и содержимое промптов перед передачей поддержке.
  2. Проверьте сохранность: завершите запись чекпоинта, если приложение ещё отвечает. Снапшот активного диска может быть только crash-consistent; он не гарантирует целостный чекпоинт или сохранение RAM.
  3. Подготовьте копию: завершённые чекпоинты отправляйте в отдельное хранилище. Используйте отдельные версии/имена, проверяйте размер и контрольную сумму; не заменяйте последнюю рабочую копию незавершённой загрузкой.
  4. Перезапускайте по плану: сначала проверьте, какие данные переживут stop/delete. Восстановите проверенный образ и последний целый чекпоинт на доступном ресурсе.
  5. Обратитесь в поддержку: опишите симптомы и приложите очищенную диагностику. Компенсация возможна только в рамках применимых условий, а причина сбоя требует проверки.

Для внешних чекпоинтов можно сравнить S3-совместимое хранилище Timeweb Cloud (партнёрская ссылка). Проверьте регион, стоимость хранения и передачи, права доступа и совместимость клиента. Настройте закрытый бакет и отдельный доступ с минимальными правами; сам выбор S3 ещё не создаёт политику резервирования.

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

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

Воспроизводимое окружение для восстановления

Создай себе "золотой образ" – Docker-контейнер или системный снапшот с идеально настроенным окружением для твоих задач. В нём должны быть:

  • Нужная версия Python и всех пакетов (зафиксированная в requirements.txt).
  • Проверенные версии CUDA, cuDNN, PyTorch/TensorFlow.
  • Предустановленные утилиты диагностики (htop, nvtop, iotop).
  • Настроенный крон для периодического запуска health-чекеров.

Сохраните проверенный образ в доступном вам registry, зафиксируйте digest и документируйте запуск. Не встраивайте секреты, данные клиентов и приватные ключи в слои образа. Образ приложения не содержит драйвер хоста и не заменяет совместимость CUDA; проверку нового узла всё равно нужно выполнить.

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

Начните с тестового чекпоинта и одного восстановления. Это даст больше уверенности, чем неподтверждённый рейтинг надёжности провайдеров.