Выбрать вопрос до открытия трассировки
Трассировка лучше отвечает на конкретный вопрос: вычисление ждёт данные, копирование повторяется или маленький оператор вызывается слишком часто? Определите вход, выход и границы вашего шага. Для обучения уточните, включает ли он backward, обновление оптимизатора и чтение батча. Для инференса разделите загрузку модели и запрос.
Сохраняйте короткий сценарий, корректность которого вам известна. Запишите формы, батч, точность, режим модели, возможную компиляцию и источник данных. Упрощённый вход может помочь изолировать поведение, но он уже не обязательно представляет полную нагрузку. Укажите это различие в отчёте.
Зафиксируйте итоговую единицу: миллисекунды на шаг или обработанные примеры в секунду. Суммы событий не заменяют прошедшее время. Сравнивайте окна с одинаковыми границами чтения и передачи.
Различать время CPU, работу GPU и ожидание
CPU подготавливает и запускает операции; GPU может выполнить их позже. Поэтому интервал Python может содержать запуск, ожидание или и то и другое. Документация PyTorch по CUDA указывает, что точные измерения должны учитывать эту асинхронность, в частности через синхронизацию или события, подходящие для данного периметра.
Для точечного измерения длительности GPU могут подойти события CUDA. Для сквозной задержки дождитесь завершения работы, входящей в эту задержку, и измерьте весь запрос. Не смешивайте эти две единицы. Синхронизация, добавленная между каждой операцией, может устранить реальное перекрытие и изменить программу, которую вы пытаетесь понять.
В профилировщике собственное время оператора и его время с учётом подопераций тоже отвечают на разные вопросы. Посмотрите на временную шкалу, прежде чем суммировать строки таблицы. Одновременные или вложенные активности не являются непересекающимися долями прошедшего времени.
Выделить фазу запуска и активное окно
Первый проход может включать инициализацию, загрузку или компиляцию. Решите, относится ли ваш вопрос к этому запуску или к уже стабилизированной фазе. Сохраняйте оба наблюдения, когда они важны для использования, вместо того чтобы стирать начальную стоимость средней, представленной как общая.
Функция schedule позволяет различать ожидание, подготовку сбора и активное окно. Прогрев профилировщика не доказывает, что ваша модель достигла устойчивого режима. Проверьте также встречающиеся формы и состояние кэшей. Приложение с переменными входами может столкнуться с новыми путями после нескольких итераций.
Предложенный ниже учебный план ожидает один шаг, подготавливает один и захватывает два. Четырёх шагов достаточно, чтобы объяснить механизм, но не чтобы установить распределение производительности. В реальной кампании выберите обоснованное окно и повторите измерение вне профилировщика после анализа.
Предложенный пример: четыре шага с читаемыми границами
Следующий фрагмент не был выполнен. Он предполагает, что model, optimizer, loss_fn, loader и device существуют, модель находится на device, а загрузчик выдаёт как минимум четыре батча пар x, y. Он выполняет обновления: используйте экспериментальное состояние, предназначенное для этого, а не сессию, веса которой вам нужно сохранить.
Метки разделяют чтение на CPU, передачу и обучение. Итератор создаётся до окна, что исключает часть его запуска из области измерения. Файл выбирается новый, чтобы не перезаписать существующую трассировку. Пример отказывается от сбора данных GPU, если он недоступен, вместо того чтобы незаметно выдать трассировку CPU за анализ GPU.
Сигнал step() продвигает расписание после каждого шага. Официальное руководство описывает эту связь между итерациями и сбором данных. На стеке ROCm устройство PyTorch по-прежнему называется cuda; тем не менее доступность сбора данных ускорителя зависит от сборки и её инструментов. Проверьте, какие активности действительно присутствуют в результате.
from pathlib import Path
import torch
from torch.profiler import (
profile, schedule, record_function,
ProfilerActivity, supported_activities,
)
trace = Path("trace-etape.json")
if trace.exists():
raise FileExistsError("Choisissez un nouveau nom de trace")
activities = [ProfilerActivity.CPU]
if device.type == "cuda":
if ProfilerActivity.CUDA not in supported_activities():
raise RuntimeError("Collecte GPU indisponible dans ce build")
activities.append(ProfilerActivity.CUDA)
iterator = iter(loader)
model.train()
with profile(
activities=activities,
schedule=schedule(wait=1, warmup=1, active=2, repeat=1),
record_shapes=False, profile_memory=False, with_stack=False,
on_trace_ready=lambda p: p.export_chrome_trace(str(trace)),
) as prof:
for _ in range(4):
with record_function("lecture_batch_cpu"):
x, y = next(iterator)
with record_function("transfert"):
x, y = x.to(device), y.to(device)
with record_function("entrainement"):
optimizer.zero_grad(set_to_none=True)
loss = loss_fn(model(x), y)
loss.backward()
optimizer.step()
prof.step()
print(prof.key_averages().table(
sort_by="self_cpu_time_total", row_limit=8,
))Преобразование наблюдения в проверяемую гипотезу
Начните с активного окна и проверьте, что ожидаемые метки появляются. Затем изучите промежутки между активностями, копирования и повторы. Долгое ожидание в lecture_batch_cpu указывает на конвейер ввода; оно не измеряет напрямую хранилище. Частое копирование побуждает изучить размещение тензоров, но не доказывает, что оно бесполезно.
Сформулируйте одну гипотезу и затем предложите контролируемое изменение. Например, если константа пересоздаётся и передаётся на каждом шаге, проверьте, может ли её время жизни охватывать несколько шагов без изменения результата. Если какой-то оператор кажется доминирующим, изучите его формы и число вызовов, прежде чем искать ему замену.
Приведённые ниже строки — это возможные интерпретации, а не выводы, сделанные из выполненной трассировки. Никакая длительность или ускорение не заявляются. Полезный вывод — это следующий эксперимент, который может подтвердить или опровергнуть предложенную причину.
Прокрутите таблицу, чтобы увидеть все столбцы.| Возможное наблюдение | Гипотеза | Следующая проверка |
|---|---|---|
| GPU без активности во время чтения | Конвейер ввода не успевает | Тот же расчёт с уже подготовленным батчем |
| Повторяющиеся копирования константы | Неподходящее размещение или время жизни | Переместить один раз, проверить выходные данные |
| Множество мелких запусков | Фрагментированная работа | Изучить группировку и общую стоимость |
| Один длительный оператор | Определяющая форма или алгоритм | Сравнить тот же оператор и его входные данные |
Ограничение стоимости и объёма информации инструментирования
Начните с короткого сбора данных и небольшого числа опций. Включайте формы, стеки или память только если этого требует какой-то вопрос. API PyTorch уточняет, что эта информация добавляет стоимость; сбор форм может даже удерживать ссылки на тензоры. Поэтому подробный профиль может изменить длительности или потребление памяти программой.
Трассировка может содержать имена операторов, формы и, в зависимости от параметров, пути к коду. Изучите её перед тем, как делиться. Метка зоны должна описывать этап, не включая email, токен, приватный путь или содержимое входных данных. Выберите просмотрщик трассировок, подходящий вашей среде, и держите сбор под своим контролем.
Если ожидаемые события GPU отсутствуют, не заполняйте их время нулём. Укажите, что они не наблюдались, и проверьте поддержку сбора. Отсутствие события в инструменте не является доказательством отсутствия вычислений.
Проверка оптимизации вне профилировщика
Начните с того же релевантного состояния и сравните корректность до и после изменения. Для обучения дополнительный шаг меняет веса; два последовательно выполненных снимка не обязательно дают эквивалентное сравнение. Сохраните код, параметры и точку старта, чтобы можно было объяснить разницу.
Затем измерьте сценарий без детального сбора, с тем же прогревом и несколькими проходами. Укажите охват, необработанные значения и их разброс. Локальное улучшение может исчезнуть в полном цикле или ухудшить качество: и то и другое должно остаться в решении.
Наконец, используйте наблюдения, чтобы уточнить действительно необходимые ресурсы. Трассировка вашей машины не упорядочивает предложения Kernodeck и не доказывает ни характеристики хост-процессора, ни сеть арендованного сервера. Сравнение GPU требует сопоставимой нагрузки, условий и результатов на рассматриваемых ресурсах.