English translation is not available yet. Showing Russian content.
Профилировать GPU utilization падение
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Профилировать GPU utilization падение
1. Цель задачи
Научиться выявлять причины низкой утилизации GPU (ниже 50%) в процессе инференса или обучения модели с помощью профилировщиков NVIDIA Nsight Systems (nsys) и Nsight Compute (ncu). Найти коренную причину простоя GPU, разработать и применить исправление (например, увеличение batch size, оптимизация DataLoader, пересылка тензоров) и добиться роста средней утилизации GPU как минимум на 30% от исходного значения.
Ключевой результат Зафиксированная начальная утилизация GPU (через nvidia-smi или nsys), выявленный bottleneck (CPU-bound, memory-bound, kernel-launch overhead и т.д.), реализованный fix, повторное измерение с подтверждением прироста утилизации ≥ 30%.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Рабочее окружение с доступом к GPU (NVIDIA) | Локальный сервер / облачная VM (AWS p3/p4, GCP, Colab Pro) |
| Модель для инференса или обучения | Hugging Face модели (BERT, GPT, ResNet) или своя |
| Нагрузочный скрипт (вызов forward/backward) | Написать самому (PyTorch / TensorFlow) |
nsys и ncu | Установить NVIDIA Nsight Systems и Nsight Compute (можно через conda) |
Логи nvidia-smi с метками времени | nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv -l 1 |
Если нет реального инструмента — симулируем:
- Создайте Python-скрипт имитации низкой утилизации GPU:
- Используйте маленький batch size (1–4) с частым копированием данных с CPU на GPU.
- Добавьте искусственные задержки на CPU (например, time.sleep(0.01) внутри DataLoader).
- Для инференса — запускайте модель на очень маленьких тензорах, вызывая много мелких ядер.
- Запустите nsys profile и ncu --set full на этом скрипте, чтобы получить характерные профили низкой утилизации.
- Зафиксируйте baseline: средняя utilization.gpu за 1 минуту (команда nvidia-smi каждые 0.5 секунды).
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Профилирование GPU | NVIDIA Nsight Systems (nsys), Nsight Compute (ncu) | Захват трассировки, идентификация узких мест в kernel и потоках |
| Мониторинг GPU | nvidia-smi, watch -n 0.5 nvidia-smi | Онлайн-измерение утилизации, памяти, температуры |
| Модель | PyTorch / TensorFlow + предобученная модель | Генерация нагрузки на GPU |
| Анализ данных | Python (pandas, matplotlib), Jupyter Notebook | Обработка логов, построение графиков утилизации |
| Оптимизация | torch.compile, DataLoader(num_workers=...), torch.cuda.amp | Применение типичных fix'ов для повышения occupancy |
4. Этапы выполнения
Этап 1: Baseline и трассировка с nsys (1 час)
Действия
- Напишите минимальный нагрузочный скрипт (
infer_bad.py), который: - Запустите nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv -l 0.5 > baseline.csv в фоне на 5 минут.
Рассчитайте среднюю утилизацию: awk -F',' '{sum+=$1} END {print sum/NR}' baseline.csv (удалите заголовки). - Выполните профилирование с nsys
Откройтеnsys profile --trace-fork-before-exec=true -o profile_infer.qdsh python infer_bad.py.qdshв Nsight Systems GUI (или используйте nsys stats). - С помощью GUI определите процент времени, когда GPU простаивал (idle), а CPU был занят; время на передачу данных CPU→GPU; частоту запуска kernel.
Ожидаемый результат этапа
- Численное значение средней утилизации GPU (baseline).
- Таблица/визуализация, показывающая, что GPU занят менее 40% времени.
- Выявленные «узкие места» (например, длинные паузы между kernels из-за
sleepили медленного DataLoader).
Этап 2: Deep dive с ncu (1 час)
Действия
- Выполните профилирование ядер с
ncuncu --set full -o kernel_report python infer_bad.py - Откройте отчёт в Nsight Compute
Обратите внимание на метрики:- Occupancy (% активных warp на SM).
- Memory bandwidth utilization.
- Compute utilization (в частности,
SM Busy). - Launch statistics (количество мелких ядер, частота запуска).
- Идентифицируйте основной bottleneck
- Сравните с эталонными значениями (для вашей модели, GPU). Запишите выводы.
Ожидаемый результат этапа
- Список причин низкой утилизации (например: «60% времени GPU простаивает из-за ожидания данных от CPU», «Occupancy ядра attention составляет 25%»).
- Скриншоты/заметки из Nsight Compute.
Этап 3: Разработка и применение fix (1–2 часа)
Действия
- Исходя из результатов этапов 1-2, выберите одно или несколько исправлений:
- Увеличить batch size (например, с 1 до 64), если это позволяет память.
- Убрать
time.sleepи использовать асинхронную загрузку (DataLoaderсnum_workers>0иpin_memory=True). - Упаковать мелкие тензоры в один большой батч или использовать
torch.bmm. - Включить
torch.cuda.amp(automatic mixed precision) для повышения пропускной способности. - Использовать
torch.compile(если PyTorch 2.x) или@torch.jit.scriptдля сокращения kernel launch overhead.
- Модифицируйте скрипт (
infer_good.py), применив fix. Задокументируйте изменения в комментариях. - Проведите повторное профилирование
- Запустите
nvidia-smiещё на 5 минут для новых условий →good.csv. - Запустите
nsys profileиncuдля нового скрипта.
- Запустите
- Сравните метрики
- Рассчитайте новую среднюю утилизацию. Вычислите прирост:
(new_util - baseline_util) / baseline_util * 100. - Убедитесь, что прирост ≥ 30%.
- Рассчитайте новую среднюю утилизацию. Вычислите прирост:
Ожидаемый результат этапа
- Рабочий скрипт
infer_good.pyс применёнными оптимизациями. - Файл
good.csvс показателями утилизации. - Прирост утилизации GPU не менее 30%.
Этап 4: Документирование и анализ (1 час)
Действия
- Составьте отчёт в формате Jupyter Notebook (или Markdown) с разделами:
- Постановка задачи (цель, оборудование).
- Методика измерений (команды, скрипты).
- Baseline график утилизации GPU по времени, среднее значение, вывод.
- Результаты профилирования ключевые показатели из
nsysиncu. - Выявленные проблемы (например, «из-за batch size=1 и CPU-задержки средняя утилизация была 18%»).
- Применённый fix описание изменений, почему они должны помочь.
- Результаты после фикса новый график, средняя утилизация 85% (прирост +370%).
- Выводы и рекомендации (например, «всегда использовать num_workers >= 4 для загрузки данных»).
- Приложите все исходные данные (csv, log, профили) в отдельную папку.
Ожидаемый результат этапа
- Отчётный документ (
.ipynbили.md) с анализом и визуализациями. - Подтверждение, что fix дал прирост ≥ 30%.
5. Критерии приемки (Definition of Done)
- Написан нагрузочный скрипт с искусственно низкой утилизацией GPU.
- Снят baseline средней утилизации GPU (минимум 1 минута измерений).
- Выполнено профилирование с
nsysиncu, сохранены отчёты. - Идентифицирована коренная причина низкой утилизации (bottleneck описан текстом).
- Разработан и реализован хотя бы один оптимизирующий fix.
- Проведены повторные замеры: средняя утилизация GPU повысилась на ≥ 30% относительно baseline.
- Составлен отчётный документ (Jupyter Notebook или Markdown) с анализом и графиками.
- Весь код (скрипты) и данные (csv, профили) загружены в git-репозиторий.
6. Ожидаемый результат
Основной артефакт
- Файл
report.md(илиreport.ipynb), содержащий:- baseline и новую утилизацию (число, график).
- Скриншоты/выдержки из профилировщиков, показывающие bottleneck.
- Описание fix.
- Вычисленный прирост (в процентах).
Дополнительные артефакты
infer_bad.py,infer_good.py— скрипты до и после оптимизации.baseline.csv,good.csv— логиnvidia-smi.profile_infer.qdsh,kernel_report.ncu-rep— файлы профилей.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Нет доступа к реальной модели с заведомо низкой утилизацией | Создать синтетический скрипт с маленьким batch size и CPU-задержками (описано в п.2) |
nsys или ncu не установлены / нет прав на установку | Использовать Docker-образ NVIDIA nvcr.io/nvidia/nsight-systems:latest или nvidia/cuda |
| Профилирование занимает слишком много времени (1000 шагов) | Уменьшить количество итераций до 100, усреднить по 5 прогонам |
| Высокая утилизация GPU уже на baseline (например, 70%) | Усложнить задачу – добавить ещё больше CPU-нагрузки (много numpy на CPU) или уменьшить batch size до 1 и использовать большую модель (LLaMA, ViT) |
Непонятно, как интерпретировать результаты nsys / ncu | Использовать встроенные рекомендации (Wizard в Nsight Compute) или документацию NVIDIA |
Измерение утилизации через nvidia-smi даёт зашумлённый сигнал (кратковременные пики) | Собирать данные раз в 0.5 с и усреднять за >1 минуты; использовать nvidia-smi dmon с агрегацией |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
Этап 1: Baseline + nsys | 1 |
Этап 2: Deep dive с ncu | 1 |
| Этап 3: Разработка и применение fix | 1.5 |
| Этап 4: Документирование | 1 |
| Запас на настройку окружения | 0.5 |
| Итого | 5 часов |
Примечание: Для первого выполнения рекомендуется закладывать 6–7 часов, особенно если профилировщики используются впервые.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 89 | Метрики GPU utilisation (SM Occupancy, Mem BW) |
| 93 | Разница между nsys и ncu |
| 94 | Профилирование PyTorch моделей |
| 95 | DataLoader bottlenecks и CPU-GPU синхронизация |
| 97 | Оптимизация batch size и памяти |
| 123 | Mixed Precision Training (AMP) |
| 201 | Kernel launch overhead (CPU side) |
| 345 | Уменьшение времени передачи данных CPU→GPU |
| 402 | Инструменты NVIDIA Nsight Systems |
| 503 | Occupancy и регулирование числа потоков блока |
10. Чек-лист самопроверки
- Я убедился, что на моей системе установлены
nsys,ncuиnvidia-smi. - Я создал репродуцируемый сценарий с низкой утилизацией GPU (батч 1 + CPU-задержка).
- Я засёк baseline утилизации (не менее 1 минуты).
- Я выполнил профилирование с
nsysиncuи сохранил отчёты. - Я идентифицировал хотя бы один bottleneck и записал его.
- Я применил fix и подтвердил прирост утилизации ≥ 30% на тех же данных.
- Я оформил результаты в виде отчёта со сравнением графиков «до» и «после».
- Я загрузил всё (скрипты, csv, профили) в репозиторий или папку задания.