Средства для бенчмаркинга - 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))”, можно установить label в «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, выполняя разогрев, увеличивая 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: они полагаются на 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/1.13/benchmark_utils.html