Spec-Zone.ru › PyTorch 2.14

Интеграция профилировщика

Создано: 26 декабря 2025 г. | Последнее обновление: 7 июля 2026 г.

Общие сведения

PyTorch поставляется с не зависящим от устройства профилировщиком, который инструментирует диспетчеризацию операторов на стороне CPU, координирует работу со средствами сбора данных ускорителя, записывает стеки вызовов Python и экспортирует агрегированную статистику или трассировки Chrome/Perfetto. О базовой архитектуре см. torch/csrc/profiler/README.md.

Существует два основных способа интеграции ускорителей:

  1. Устаревший профилировщик autograd:

    • Позволяет подключать специфичные для бэкенда хуки через ProfilerStubs для записи событий устройства и вычисления длительности.
    • Работает без Kineto; подходит для бэкендов PrivateUse1, которым нужен минимальный автономный механизм.
  2. Плагин Kineto IActivityProfiler:

    • Регистрирует в Kineto полноценный профилировщик активности через REGISTER_PRIVATEUSE1_PROFILER.
    • Настраивает сеансы Kineto и передачу идентификаторов корреляции; поставщики расширяют его, добавляя события ядер, связи потоков и совместимость с трассировками Chrome/Perfetto.
    • Требует наличия Kineto во время сборки бэкенда (kineto_LIBRARY из find_package(Torch), с проверкой через USE_KINETO).

Способ

API Python

Состояние профилировщика

Предоставляемые возможности

Устаревший (1)

torch.autograd.profiler.profile(use_device="openreg") (по умолчанию use_kineto=False)

KINETO_PRIVATEUSE1_FALLBACK

Измерение времени на уровне операторов с помощью событий устройства ProfilerStubs

Плагин Kineto (2)

profile(activities=[ProfilerActivity.CPU, ProfilerActivity.PrivateUse1])

KINETO_PRIVATEUSE1

Сеанс Kineto и передача идентификаторов корреляции; поставщики добавляют события ядер и связи потоков

Оба способа могут использоваться одновременно, если расширение бэкенда собрано с доступным Kineto (kineto_LIBRARY из find_package(Torch)). Механизм с устаревшими заглушками работает всегда; для способа с плагином Kineto требуется USE_KINETO во время сборки бэкенда. В ядре PyTorch уже есть REGISTER_PRIVATEUSE1_PROFILER; поставщики реализуют и регистрируют собственные IActivityProfiler в расширении бэкенда.

Проектирование

Обзор архитектуры

Уровень

Назначение

Исходный код

Уровень управления Python

Управляет жизненным циклом профилировщика (prepare → start → stop → step) и предоставляет пользовательские API, например torch.autograd.profiler.profile.

torch/autograd/profiler.py

Заглушки профилировщика

Реализуют torch::profiler::impl::ProfilerStubs, чтобы профилировщик мог записывать события устройства, выполнять синхронизацию, перебирать устройства и вычислять длительность.

torch/csrc/profiler/stubs/

Среда выполнения устройства

Предоставляет потоки, события и контексты устройств, используемые заглушками; реализация зависит от бэкенда.

Расширение бэкенда (код поставщика)

Такое разделение позволяет PyTorch оставаться независимым от устройства: Python управляет сеансом, ProfilerStubs преобразуют запросы профилировщика в вызовы среды выполнения бэкенда, а среда выполнения взаимодействует с ускорителем.

Основные соглашения

  • Хуки записи: record() должны получить (при наличии) индекс устройства, создать событие бэкенда, при необходимости сохранить временную метку CPU и поставить событие в очередь активного потока.
  • Время выполнения: elapsed() отвечает за синхронизацию отдельных событий и возврат длительности в микросекундах.
  • Хуки синхронизации: synchronize() и onEachDevice() обеспечивают согласование переходов между фазами (например, разогрев → активная фаза) на всех устройствах.
  • Аннотации: mark, rangePush и rangePop можно реализовать для обогащения трассировок; в противном случае их можно оставить пустыми.

Реализация (устаревший способ)

Здесь для иллюстрации минимального набора хуков, которые должен предоставлять ускоритель PrivateUse1, чтобы профилировщик мог сопоставлять операции ATen, диапазоны record_function и пользовательский код с активностью устройства, используется OpenReg (Open Registration). OpenReg не требует изменений кода вышестоящего проекта: он преобразует запросы профилировщика в вызовы своей среды выполнения, как это делал бы промышленный ускоритель внутри внешнего расширения.

OpenReg поддерживает оба способа: устаревший профилировщик autograd (use_kineto=False, по умолчанию) для измерения времени на уровне операторов с помощью заглушек и современный API torch.profiler.profile (use_kineto=True) для способа с плагином Kineto, описанного ниже.

Заглушки профилировщика (C++)

torch::profiler::impl::OpenRegMethods наследуется от ProfilerStubs и связывает описанные выше хуки:

Метод

Назначение

record

Получает текущий OpenRegStream, создает orEvent, при необходимости фиксирует временную метку CPU с помощью c10::getTime() и записывает событие в поток.

elapsed

Синхронизирует оба события, вызывает orEventElapsedTime и преобразует миллисекунды в микросекунды для профилировщика.

onEachDevice

Использует c10::DeviceGuard(DeviceType::PrivateUse1) для перебора torch.openreg.device_count(), чтобы планировщики могли выполнять настройку или очистку для каждого устройства.

synchronize

Вызывает orDeviceSynchronize() для согласования работы устройства с фазами планирования CPU.

enabled и адаптеры аннотаций

Сообщают о доступности и предоставляют заглушки для методов mark/push/pop.

Конструктор однократно регистрирует методы с помощью registerPrivateUse1Methods(&methods);, делая их доступными, когда профилировщик включен с параметром use_device="openreg".

Уровень управления Python

На стороне Python новая точка входа не требуется — разработчики используют стандартный профилировщик autograd:

from torch.autograd.profiler import profile as autograd_profile
from torch.profiler import record_function

with autograd_profile(use_device="openreg", record_shapes=True) as prof:
    with record_function("matmul"):
        x = torch.randn(512, 512, device="openreg")
        y = torch.randn(512, 512, device="openreg")
        z = x @ y

print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))
prof.export_chrome_trace("openreg_trace.json")

Поток сбора данных

  1. Пользовательский код входит в autograd_profile(use_device="openreg").
  2. Профилировщик переходит в состояние ProfilerState.KINETO_PRIVATEUSE1_FALLBACK.
  3. Профилировщик запрашивает у активного бэкенда запись события с помощью record().
  4. Заглушки OpenReg создают объекты orEvent, связывают их с текущим потоком и сохраняют временные метки CPU.
  5. По завершении событий профилировщик вызывает elapsed() для вычисления длительности.

Реализация (плагин Kineto)

Примечание

В этом разделе описан способ с плагином Kineto IActivityProfiler для трассировки на уровне ядер. Он требует наличия USE_KINETO во время сборки. Весь код, зависящий от Kineto, необходимо защитить с помощью #ifdef USE_KINETO.

Способ с плагином состоит из двух уровней: компонента библиотеки устройства (аналога CUPTI) и уровня интеграции с PyTorch. В OpenReg они четко разделены.

Библиотека устройства: отслеживание корреляции

Библиотека устройства предоставляет openreg::profiler::OpenRegTracer (third_party/openreg/csrc/tracer.h/.cpp) — синглтон со стеком идентификаторов корреляции, локальным для потока, и атомарным флагом включения/отключения, с помощью которого сеанс профилировщика управляет окном записи.

Kineto помещает идентификаторы корреляции в стек и извлекает их из него через сеанс. Сеанс вызывает API активности в стиле C из openreg.h (по аналогии с CUPTI):

  • orActivityEnableTracing() / orActivityDisableTracing() — управляют окном записи
  • orActivityPushExternalCorrelationId() / orActivityPopExternalCorrelationId() — управляют стеком корреляции

Эквивалентом у реального поставщика будет его SDK для трассировки устройства (например, CUPTI для CUDA).

Интеграция с PyTorch: IActivityProfiler и IActivityProfilerSession

Реализуйте два интерфейса Kineto из third_party/kineto/libkineto/include/IActivityProfiler.h. В OpenReg они находятся в torch_openreg/csrc/profiler/ — уровне интеграции расширения бэкенда.

  • IActivityProfiler — фабрика без состояния. Обе перегрузки configure() создают и возвращают сеанс:

    • configure(activity_types, config) — синхронная перегрузка, обязательная для интерфейса. Заглушка OpenReg реализует ее как основной путь создания сеанса.
    • configure(ts_ms, duration_ms, activity_types, config) — дочерний профилировщик Kineto вызывает эту перегрузку для всех трассировок (включая запускаемые по запросу), передавая profileStartTime() эпохи в миллисекундах и profileDuration() в миллисекундах. Заглушка OpenReg игнорирует планирование и делегирует вызов первой перегрузке; поставщики используют ts_ms/duration_ms, чтобы отложить активацию SDK устройства.
  • IActivityProfilerSession — сеанс для отдельной трассировки. start()/stop() управляют окном профилирования и переключают трассировку активности через orActivityEnableTracing()/orActivityDisableTracing(); getTraceBuffer() возвращает буфер в Kineto.

    • Эталонная заглушка: processTrace() только задает интервал трассировки (traceBuffer_.span = TraceSpan(startTs_, endTs_, "openreg")); записи ядер не создаются.
    • Расширение поставщика: замените processTrace(), чтобы сбрасывать записи из SDK трассировки устройства и создавать элементы GenericTraceActivity с временными метками (мкс), идентификаторами корреляции и связями потоков (flow.id = correlationId, flow.type = kLinkAsyncCpuGpu, flow.start = 0).

Регистрация и сборка

Для регистрации достаточно одной строки: REGISTER_PRIVATEUSE1_PROFILER(OpenRegActivityProfiler). Макрос (определенный в torch/csrc/profiler/standalone/privateuse1_profiler.h) создает статический объект регистрации, который передает фабрику в Kineto при инициализации профилировщика.

По умолчанию Kineto включен в PyTorch; специальные флаги сборки не нужны, если только он явно не отключен с помощью USE_KINETO=0. В расширении бэкенда find_package(Torch) задает kineto_LIBRARY; свяжите код с kineto и torch_cpu_library и защитите код Kineto с помощью #ifdef USE_KINETO. Без Kineto плагин компилируется как пустая реализация, и доступен только способ с устаревшими заглушками.

Использование

import torch
from torch.profiler import profile, ProfilerActivity

with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.PrivateUse1]) as prof:
    x = torch.randn(512, 512, device="openreg")
    y = torch.randn(512, 512, device="openreg")
    z = x @ y

prof.export_chrome_trace("kernel_trace.json")

© 2026, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://docs.pytorch.org/docs/2.14/accelerator/profiler.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API