GPU для ваших проєктів · оплата криптою без KYC Як орендувати
Українська
Відкрити консоль
Практичний посібник / KERNODECK

Профілюйте крок PyTorch, щоб зрозуміти, куди витрачається час

Спочатку визначте крок для спостереження, відокремте завантаження, передавання, обчислення та оновлення, а потім захопіть короткий репрезентативний інтервал за допомогою torch.profiler. Читайте разом хронологію CPU та доступні активності GPU. Час запуску Python — це не час завершеного виконання на прискорювачі, і інструментована траса сама по собі не є бенчмарком.

6 хв читання · Посібник для розробників

Вибір питання перед відкриттям траси

Траса краще відповідає на конкретне питання: чи обчислення чекає на дані, чи копія повторюється, чи маленький оператор викликається занадто часто? Визначте вхід, вихід і межі вашого кроку. Для тренування уточніть, чи він містить backward, оновлення оптимізатора та читання батчу. Для інференсу відокремте завантаження моделі та запит.

Тримайте короткий сценарій, правильність якого ви знаєте. Занотуйте форми, батч, точність, режим моделі, можливу компіляцію та джерело даних. Спрощений вхід може допомогти ізолювати поведінку, але він уже не обов’язково відображає повне навантаження. Зазначте цю різницю у звіті.

Зафіксуйте підсумкову одиницю: мілісекунди на крок або оброблені приклади за секунду. Суми подій не замінюють фактично витраченого часу. Порівнюйте інтервали з однаковими межами читання та передавання.

Розрізнення часу CPU, роботи GPU та очікування

CPU готує та запускає операції; GPU може виконувати їх пізніше. Тому інтервал Python може містити запуск, очікування або і те, і те. Документація PyTorch щодо CUDA зазначає, що точні вимірювання повинні враховувати цю асинхронність, зокрема через синхронізацію або відповідні події для відповідних меж.

Для цільового вимірювання тривалості GPU можуть підійти події CUDA. Для наскрізної затримки дочекайтеся завершення роботи, що входить у цю затримку, і виміряйте весь запит. Не змішуйте ці дві одиниці. Синхронізація, додана між кожною операцією, може усунути реальне перекриття та змінити програму, яку ви намагаєтеся зрозуміти.

У профілювальнику власний час оператора та час із підопераціями також відповідають на різні питання. Подивіться на хронологію, перш ніж підсумовувати рядки таблиці. Одночасні або вкладені активності не є частинами витраченого часу, що не перетинаються.

Виділення фази запуску та активного інтервалу

Перший прохід може містити ініціалізацію, завантаження або компіляцію. Вирішіть, чи ваше питання стосується цього запуску, чи вже стабілізованої фази. Збережіть обидва спостереження, якщо вони важливі для використання, замість того щоб стирати початкову вартість усередненням, поданим як загальне.

Функція schedule дозволяє розрізнити очікування, підготовку збору та активний інтервал. Прогрів профілювальника не є доказом того, що ваша модель досягла стабільного режиму. Перевіряйте також форми, які трапляються, та стан кешів. Застосунок із змінними входами може натрапляти на нові шляхи після кількох ітерацій.

Навчальний план, запропонований нижче, очікує один крок, готує один і захоплює два. Чотирьох кроків достатньо, щоб пояснити механізм, але не щоб встановити розподіл продуктивності. У справжній кампанії виберіть обґрунтований інтервал і повторіть вимірювання поза профілювальником після аналізу.

Пропонований приклад: чотири кроки з чіткими межами

Наведений фрагмент не виконувався. Він припускає, що model, optimizer, loss_fn, loader і device існують, що модель розміщена на device, а завантажувач надає щонайменше чотири batch-і пар 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 без активності під час читанняКонвеєр вхідних даних не встигаєТой самий розрахунок із уже підготовленим batch
Повторювані копії константиНевідповідне розміщення або час життяПеремістити один раз, перевірити вихідні дані
Багато дрібних запусківФрагментована роботаРозглянути групування та загальну вартість
Один тривалий операторВизначальна форма або алгоритмПорівняти той самий оператор та його вхідні дані

Обмеження вартості та обсягу інформації від інструментування

Почніть із короткого збору даних і небагатьох опцій. Увімкніть форми, стеки чи пам'ять лише тоді, коли це потрібно для якогось питання. API PyTorch зазначає, що ця інформація додає витрат; збір форм може навіть утримувати посилання на тензори. Тому детальний профіль може змінити тривалість або використання пам'яті програми.

Трасування може містити назви операторів, форми та, залежно від налаштувань, шляхи до коду. Перегляньте його перед поширенням. Мітка зони має описувати крок, не вміщуючи email, токен, приватний шлях чи вміст вхідних даних. Виберіть читач трасування, що відповідає вашому середовищу, і тримайте збір даних під своїм контролем.

Якщо очікувані події GPU відсутні, не заповнюйте їхній час нулями. Зазначте, що їх не спостерігали, і перевірте підтримку збору даних. Відсутність події в інструменті не є доказом відсутності обчислень.

Перевірка оптимізації поза профілювальником

Почніть із того самого відповідного стану й порівняйте правильність до та після зміни. Для навчання додатковий крок змінює ваги; два послідовно запущені знімки не обов'язково є еквівалентним порівнянням. Збережіть код, параметри та початкову точку, щоб могти пояснити різницю.

Потім виміряйте сценарій без детального збору даних, з тим самим прогрівом і кількома проходами. Наведіть обсяг, сирі значення та їхній розкид. Локальне покращення може зникнути в повному циклі або погіршити якість: і те, і те має залишатися в рішенні.

Зрештою використайте спостереження, щоб уточнити ресурси, які справді потрібні. Трасування з вашої робочої станції не впорядковує пропозиції Kernodeck і не доводить ані процесор хоста, ані мережу орендованого сервера. Порівняння GPU вимагає зіставного навантаження, умов і результатів на відповідних ресурсах.

Ваші запитання

Чи найбільший час CPU вказує на найповільніший оператор GPU?

Ні. Він може включати запуск, обробку на боці хоста чи очікування. Дивіться на події GPU та їхню хронологію, коли збір даних їх надає. Таблиця, відсортована за часом CPU, відповідає лише на цю перспективу.

Чи маю я додавати всі часи CUDA з таблиці?

Не для того, щоб автоматично отримати загальну тривалість. Активності можуть перекриватися, а події можуть бути вкладеними. Визначте вікно часу, що минув, і використайте трасування, щоб пояснити його вміст.

Чи достатньо двох активних кроків, щоб опублікувати продуктивність?

Ні. Запропонований маленький графік ілюструє API. Придатний результат вимагає репрезентативного вікна, повторів, явного прогріву та фінального вимірювання без накладних витрат детального збору даних.

Чи може трасування CPU діагностувати ROCm?

Воно може пролити світло на роботу на боці хоста, але не замінює активності GPU. PyTorch також використовує назву cuda на ROCm; перевірте бекенд, підтримувані активності та ті, що справді були записані, перш ніж інтерпретувати трасування.