Benchmark Utils - torch.utils.benchmark
-
class torch.utils.benchmark.Timer(stmt='pass', setup='pass', global_setup='', timer=<built-in function perf_counter>, globals=None, label=None, sub_label=None, description=None, env=None, num_threads=1, language=Language.PYTHON)[source] -
Вспомогательный класс для измерения времени выполнения операторов PyTorch.
Полный учебник по использованию этого класса можно найти по адресу: https://pytorch.org/tutorials/recipes/recipes/benchmark.html
Таймер PyTorch основан на
timeit.Timer(и на самом деле используетtimeit.Timerвнутри), но с несколькими ключевыми отличиями:-
- Учитывает среду выполнения:
-
Таймер выполнит разминку (важно, так как некоторые элементы PyTorch инициализируются лениво), установит размер пула потоков так, чтобы сравнения были корректными, и синхронизирует асинхронные функции CUDA при необходимости.
-
- Фокус на повторениях:
-
При измерении кода, особенно сложных ядер/моделей, вариации от запуска к запуску являются существенным фактором. Ожидается, что все измерения должны включать повторения для количественной оценки шума и позволят вычисление медианы, что более устойчиво, чем среднее значение. В этой связи этот класс отличается от API
timeit, концептуально объединяяtimeit.Timer.repeatиtimeit.Timer.autorange. (Точные алгоритмы обсуждаются в строках документации методов.) Методtimeitдублируется для случаев, когда адаптивная стратегия нежелательна.
-
- Необязательные метаданные:
-
При определении таймера можно необязательно указать
label,sub_label,descriptionиenv. (Определены позже). Эти поля включены в представление объекта результата и классомCompareдля группировки и отображения результатов для сравнения.
-
- Количество инструкций:
-
В дополнение к времени выполнения, таймер может запустить оператор с помощью Callgrind и сообщить о количестве выполненных инструкций.
Непосредственно аналогично аргументам конструктора
timeit.Timer:stmt,setup,timer,globalsАргументы конструктора, специфичные для PyTorch Timer:
label,sub_label,description,env,num_threads- Параметры
-
- stmt (str) – фрагмент кода, который будет выполняться в цикле и измеряться.
-
setup (str) – Необязательный код настройки. Используется для определения переменных, используемых в
stmt -
global_setup (str) – (Только C++) Код, который размещается на верхнем уровне файла для таких операций, как
#include. -
timer (Callable[[], float]) – Функция, которая возвращает текущее время. Если PyTorch был собран без CUDA или отсутствует GPU, по умолчанию используется
timeit.default_timer; в противном случае CUDA будет синхронизироваться перед измерением времени. -
globals (Optional[Dict[str, Any]]) – Словарь, который определяет глобальные переменные при выполнении
stmt. Это другой способ предоставления переменных, которые нужныstmt. -
label (Optional[str]) – Строка, которая обобщает
stmt. Например, еслиstmtравно “torch.nn.functional.relu(torch.add(x, 1, out=out))”, можно установить метку на “ReLU(x + 1)” для повышения читабельности. -
Предоставление дополнительной информации для различения измерений с идентичными stmt или label. Например, в нашем примере выше sub_label может быть “float” или “int”, чтобы было легко различить: “ReLU(x + 1): (float)”
”ReLU(x + 1): (int)” при печати измерений или обобщении с использованием
Compare. -
Строка для различения измерений с одинаковым label и sub_label. Основное применение
description— сигнализироватьCompareо столбцах данных. Например, можно задать его на основе размера входных данных, чтобы создать таблицу вида:| n=1 | n=4 | ... ------------- ... ReLU(x + 1): (float) | ... | ... | ... ReLU(x + 1): (int) | ... | ... | ...используя
Compare. Он также включен при печати измерения. -
env (Optional[str]) – Этот тег указывает, что иначе идентичные задачи выполнялись в разных средах и, следовательно, не эквивалентны, например, при A/B-тестировании изменения ядра.
Compareбудет рассматривать измерения с различными спецификациямиenvкак разные при объединении повторяющихся запусков. -
num_threads (int) – Размер пула потоков PyTorch при выполнении
stmt. Однопоточная производительность важна как ключевая рабочая нагрузка для инференции, а также как хороший показатель внутренней эффективности алгоритма, поэтому значение по умолчанию установлено в 1. Это в отличие от размера пула потоков PyTorch по умолчанию, который пытается использовать все ядра.
-
blocked_autorange(callback=None, min_run_time=0.2)[source] -
Измерить множество повторений, сохраняя накладные расходы таймера на минимальном уровне.
В высоком уровне blocked_autorange выполняет следующий псевдокод:
`setup` total_time = 0 while total_time < min_run_time start = timer() for _ in range(block_size): `stmt` total_time += (timer() - start)Обратите внимание на переменную
block_sizeво внутреннем цикле. Выбор размера блока важен для качества измерения и должен балансировать две конкурирующие цели:- Малый размер блока приводит к большему количеству повторений и, как правило, лучшим статистикам.
- Большой размер блока лучше амортизирует затраты на вызов
timerи приводит к менее смещенному измерению. Это важно, потому что время синхронизации CUDA нетривиально (порядка от единиц до нескольких десятков микросекунд) и в противном случае приведет к смещению измерения.
blocked_autorange устанавливает block_size, выполнив этап разминки, увеличивая размер блока до тех пор, пока накладные расходы таймера не станут меньше 0,1% от общей вычислительной работы. Это значение затем используется для основного цикла измерения.
- Возвращает
-
Объект
Measurement, который содержит измеренные времена выполнения и количество повторений, и может быть использован для вычисления статистик (среднее, медиана и т.д.). - Тип возвращаемого значения
-
-
collect_callgrind(number: int, *, repeats: None, collect_baseline: bool, retain_out_file: bool) → CallgrindStats[source] - collect_callgrind(number:int, *, repeats:int, collect_baseline:bool, retain_out_file:bool) Tuple[CallgrindStats,...]
-
Сбор количества инструкций с использованием Callgrind.
В отличие от времени выполнения, количество инструкций является детерминированным (с учетом недетерминизма в самом программе и небольшого количества дрожаний от интерпретатора Python). Это делает их идеальными для подробного анализа производительности. Этот метод выполняет
stmtв отдельном процессе, чтобы Valgrind мог инструментировать программу. Производительность сильно ухудшается из-за инструментации, однако это смягчается тем фактом, что для получения хороших измерений обычно достаточно небольшого числа итераций.Для использования этого метода
valgrind,callgrind_controlиcallgrind_annotateдолжны быть установлены.Поскольку между вызывающей стороной (этим процессом) и
stmtвыполнением существует граница процесса,globalsне может содержать произвольных структур данных в памяти. (В отличие от методов измерения времени) Вместо этого глобальные переменные ограничены встроенными,nn.Modulesи TorchScripted функциями/модулями для уменьшения неожиданностей при сериализации и последующей десериализации. КлассGlobalsBridgeпредоставляет более подробную информацию по этому вопросу. Обратите особое внимание на nn.Modules: они полагаются на pickle, и вам может потребоваться добавить импорт вsetup, чтобы они передавались должным образом.По умолчанию будет собран и кэширован профиль для пустого оператора, чтобы указать, сколько инструкций происходит из цикла Python, который управляет
stmt.- Возвращает
-
Объект
CallgrindStats, который предоставляет количество инструкций и некоторые базовые средства для анализа и манипулирования результатами.
-
timeit(number=1000000)[source] -
Отражает семантику timeit.Timer.timeit().
Выполните оператор (
stmt)numberраз. https://docs.python.org/3/library/timeit.html#timeit.Timer.timeit- Тип возвращаемого значения
-
-
class torch.utils.benchmark.Measurement(number_per_run, raw_times, task_spec, metadata=None)[source] -
Результат измерения Timer.
Этот класс хранит одно или несколько измерений заданного оператора. Он сериализуем и предоставляет несколько удобных методов (включая подробный __repr__) для потребителей на следующих этапах.
-
static merge(measurements)[source] -
Удобный метод для слияния реплик.
Слияние будет экстраполировать время до
number_per_run=1и не будет передавать никакой метаданных. (Так как она может отличаться между репликами)- Тип возвращаемого значения
-
property significant_figures: int -
Приблизительная оценка значащих цифр.
Это свойство предназначено для удобного способа оценки точности измерения. Оно использует только межквартильный диапазон для оценки статистических данных, чтобы попытаться смягчить искажения от хвостов, и использует статическое значение z равное 1.645, поскольку не ожидается, что оно будет использоваться для малых значений
n, поэтому z может приближаться кt.Оценка значащих цифр используется совместно с методом
trim_sigfigдля предоставления более удобочитаемого резюме данных. __repr__ не использует этот метод; он просто отображает исходные значения. Оценка значащих цифр предназначена дляCompare.
-
-
class torch.utils.benchmark.CallgrindStats(task_spec, number_per_run, built_with_debug_symbols, baseline_inclusive_stats, baseline_exclusive_stats, stmt_inclusive_stats, stmt_exclusive_stats, stmt_callgrind_out)[source] -
Основной контейнер для результатов Callgrind, собранных объектом Timer.
Манипуляции, как правило, выполняются с помощью класса FunctionCounts, который получается вызовом
CallgrindStats.stats(…). Также предоставляются несколько удобных методов; наиболее значимый из них —CallgrindStats.as_standardized().-
as_standardized()[source] -
Удаление имён библиотек и некоторых префиксов из строк функций.
При сравнении двух наборов счётчиков инструкций, одной из проблем могут быть префиксы путей. Callgrind включает полное имя файла при отчёте о функции (как и должно быть). Однако это может вызвать проблемы при сравнении профилей. Если ключевой компонент, такой как Python или PyTorch, был скомпилирован в разных местах в двух профилях, это может привести к чему-то подобному:
23234231 /tmp/first_build_dir/thing.c:foo(...) 9823794 /tmp/first_build_dir/thing.c:bar(...) ... 53453 .../aten/src/Aten/...:function_that_actually_changed(...) ... -9823794 /tmp/second_build_dir/thing.c:bar(...) -23234231 /tmp/second_build_dir/thing.c:foo(...)
Удаление префиксов может смягчить эту проблему, стандартизируя строки и улучшая отмену эквивалентных мест вызова при сравнении.
- Тип возвращаемого значения
-
counts(*, denoise=False)[source] -
Возвращает общее количество выполненных инструкций.
См.
FunctionCounts.denoise()для объяснения аргументаdenoise.- Тип возвращаемого значения
-
delta(other, inclusive=False)[source] -
Сравнивает два набора счётчиков.
Одна из распространённых причин сбора счётчиков инструкций — определение влияния конкретного изменения на количество инструкций, необходимых для выполнения некоторой единицы работы. Если изменение увеличивает это число, следующим логичным вопросом является «почему». Это, как правило, включает просмотр части кода, увеличившей счётчик инструкций. Эта функция автоматизирует этот процесс, чтобы можно было легко сравнить счётчики как по включительному, так и по исключительному принципу.
- Тип возвращаемого значения
-
stats(inclusive=False)[source] -
Возвращает подробные счётчики функций.
Можно представить возвращаемые FunctionCounts как кортеж кортежей (счёт, имя_пути_и_функции).
inclusiveсоответствует семантике callgrind. Если True, счётчики включают инструкции, выполненные дочерними элементами.inclusive=Trueполезно для определения узких мест в коде;inclusive=Falseполезно для уменьшения шума при сравнении счётчиков из двух разных запусков. (См. CallgrindStats.delta(…) для получения дополнительных сведений)- Тип возвращаемого значения
-
-
class torch.utils.benchmark.FunctionCounts(_data, inclusive, truncate_rows=True, _linewidth=None)[source] -
Контейнер для манипулирования результатами Callgrind.
- Он поддерживает:
-
- Сложение и вычитание для объединения или сравнения результатов.
- Индексацию по типу кортежа.
- Функцию
denoise, которая удаляет вызовы CPython, которые известны как недетерминированные и очень шумные. - Два метода высшего порядка (
filterиtransform) для пользовательской обработки.
-
denoise()[source] -
Удаление известных шумных инструкций.
Некоторые инструкции в интерпретаторе CPython довольно шумные. Эти инструкции связаны с преобразованием unicode в словари, которые Python использует для сопоставления имён переменных. Функция FunctionCounts, как правило, является контейнером, независимым от содержимого, однако это достаточно важно для получения надёжных результатов, чтобы оправдать исключение.
- Тип возвращаемого значения
-
filter(filter_fn)[source] -
Сохранение только тех элементов, для которых
filter_fn, применённое к имени функции, возвращает True.- Тип возвращаемого значения
-
transform(map_fn)[source] -
Применение
map_fnко всем именам функций.Это можно использовать для стандартизации имён функций (например, удаления неважных частей пути к файлу), объединения записей путём сопоставления нескольких функций одному имени (в этом случае счётчики складываются) и т. д.
- Тип возвращаемого значения
© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/2.1/benchmark_utils.html