Интеграция профилировщика
Создано: 26 декабря 2025 г. | Последнее обновление: 7 июля 2026 г.
Общие сведения
PyTorch поставляется с не зависящим от устройства профилировщиком, который инструментирует диспетчеризацию операторов на стороне CPU, координирует работу со средствами сбора данных ускорителя, записывает стеки вызовов Python и экспортирует агрегированную статистику или трассировки Chrome/Perfetto. О базовой архитектуре см. torch/csrc/profiler/README.md.
Существует два основных способа интеграции ускорителей:
-
Устаревший профилировщик autograd:
- Позволяет подключать специфичные для бэкенда хуки через
ProfilerStubsдля записи событий устройства и вычисления длительности. - Работает без Kineto; подходит для бэкендов PrivateUse1, которым нужен минимальный автономный механизм.
- Позволяет подключать специфичные для бэкенда хуки через
-
Плагин Kineto
IActivityProfiler:- Регистрирует в Kineto полноценный профилировщик активности через
REGISTER_PRIVATEUSE1_PROFILER. - Настраивает сеансы Kineto и передачу идентификаторов корреляции; поставщики расширяют его, добавляя события ядер, связи потоков и совместимость с трассировками Chrome/Perfetto.
- Требует наличия Kineto во время сборки бэкенда (
kineto_LIBRARYизfind_package(Torch), с проверкой черезUSE_KINETO).
- Регистрирует в Kineto полноценный профилировщик активности через
Способ | API Python | Состояние профилировщика | Предоставляемые возможности |
|---|---|---|---|
Устаревший (1) |
|
| Измерение времени на уровне операторов с помощью событий устройства |
Плагин Kineto (2) |
|
| Сеанс Kineto и передача идентификаторов корреляции; поставщики добавляют события ядер и связи потоков |
Оба способа могут использоваться одновременно, если расширение бэкенда собрано с доступным Kineto (kineto_LIBRARY из find_package(Torch)). Механизм с устаревшими заглушками работает всегда; для способа с плагином Kineto требуется USE_KINETO во время сборки бэкенда. В ядре PyTorch уже есть REGISTER_PRIVATEUSE1_PROFILER; поставщики реализуют и регистрируют собственные IActivityProfiler в расширении бэкенда.
Проектирование
Обзор архитектуры
Уровень | Назначение | Исходный код |
|---|---|---|
Уровень управления Python | Управляет жизненным циклом профилировщика ( |
|
Заглушки профилировщика | Реализуют |
|
Среда выполнения устройства | Предоставляет потоки, события и контексты устройств, используемые заглушками; реализация зависит от бэкенда. | Расширение бэкенда (код поставщика) |
Такое разделение позволяет 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 и связывает описанные выше хуки:
Метод | Назначение |
|---|---|
| Получает текущий |
| Синхронизирует оба события, вызывает |
| Использует |
| Вызывает |
| Сообщают о доступности и предоставляют заглушки для методов 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")
Поток сбора данных
- Пользовательский код входит в
autograd_profile(use_device="openreg"). - Профилировщик переходит в состояние
ProfilerState.KINETO_PRIVATEUSE1_FALLBACK. - Профилировщик запрашивает у активного бэкенда запись события с помощью
record(). - Заглушки OpenReg создают объекты
orEvent, связывают их с текущим потоком и сохраняют временные метки CPU. - По завершении событий профилировщик вызывает
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