Spec-Zone.ru › PyTorch 2

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 внутри), но с несколькими ключевыми отличиями:

  1. Учитывает среду выполнения:

    Таймер выполнит разминку (важно, так как некоторые элементы PyTorch инициализируются лениво), установит размер пула потоков так, чтобы сравнения были корректными, и синхронизирует асинхронные функции CUDA при необходимости.

  2. Фокус на повторениях:

    При измерении кода, особенно сложных ядер/моделей, вариации от запуска к запуску являются существенным фактором. Ожидается, что все измерения должны включать повторения для количественной оценки шума и позволят вычисление медианы, что более устойчиво, чем среднее значение. В этой связи этот класс отличается от API timeit, концептуально объединяя timeit.Timer.repeat и timeit.Timer.autorange. (Точные алгоритмы обсуждаются в строках документации методов.) Метод timeit дублируется для случаев, когда адаптивная стратегия нежелательна.

  3. Необязательные метаданные:

    При определении таймера можно необязательно указать label, sub_label, description и env. (Определены позже). Эти поля включены в представление объекта результата и классом Compare для группировки и отображения результатов для сравнения.

  4. Количество инструкций:

    В дополнение к времени выполнения, таймер может запустить оператор с помощью 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)” для повышения читабельности.
  • sub_label (Optional[str]) –

    Предоставление дополнительной информации для различения измерений с идентичными stmt или label. Например, в нашем примере выше sub_label может быть “float” или “int”, чтобы было легко различить: “ReLU(x + 1): (float)”

    ”ReLU(x + 1): (int)” при печати измерений или обобщении с использованием Compare.

  • description (Optional[str]) –

    Строка для различения измерений с одинаковым 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 во внутреннем цикле. Выбор размера блока важен для качества измерения и должен балансировать две конкурирующие цели:

  1. Малый размер блока приводит к большему количеству повторений и, как правило, лучшим статистикам.
  2. Большой размер блока лучше амортизирует затраты на вызов timer и приводит к менее смещенному измерению. Это важно, потому что время синхронизации CUDA нетривиально (порядка от единиц до нескольких десятков микросекунд) и в противном случае приведет к смещению измерения.

blocked_autorange устанавливает block_size, выполнив этап разминки, увеличивая размер блока до тех пор, пока накладные расходы таймера не станут меньше 0,1% от общей вычислительной работы. Это значение затем используется для основного цикла измерения.

Возвращает

Объект Measurement, который содержит измеренные времена выполнения и количество повторений, и может быть использован для вычисления статистик (среднее, медиана и т.д.).

Тип возвращаемого значения

Measurement

END_OF_DOCUMENT_MARKER
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

Тип возвращаемого значения

Measurement

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 и не будет передавать никакой метаданных. (Так как она может отличаться между репликами)

Тип возвращаемого значения

List[Measurement]

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(...)

Удаление префиксов может смягчить эту проблему, стандартизируя строки и улучшая отмену эквивалентных мест вызова при сравнении.

Тип возвращаемого значения

CallgrindStats

counts(*, denoise=False) [source]

Возвращает общее количество выполненных инструкций.

См. FunctionCounts.denoise() для объяснения аргумента denoise.

Тип возвращаемого значения

int

delta(other, inclusive=False) [source]

Сравнивает два набора счётчиков.

Одна из распространённых причин сбора счётчиков инструкций — определение влияния конкретного изменения на количество инструкций, необходимых для выполнения некоторой единицы работы. Если изменение увеличивает это число, следующим логичным вопросом является «почему». Это, как правило, включает просмотр части кода, увеличившей счётчик инструкций. Эта функция автоматизирует этот процесс, чтобы можно было легко сравнить счётчики как по включительному, так и по исключительному принципу.

Тип возвращаемого значения

FunctionCounts

stats(inclusive=False) [source]

Возвращает подробные счётчики функций.

Можно представить возвращаемые FunctionCounts как кортеж кортежей (счёт, имя_пути_и_функции).

inclusive соответствует семантике callgrind. Если True, счётчики включают инструкции, выполненные дочерними элементами. inclusive=True полезно для определения узких мест в коде; inclusive=False полезно для уменьшения шума при сравнении счётчиков из двух разных запусков. (См. CallgrindStats.delta(…) для получения дополнительных сведений)

Тип возвращаемого значения

FunctionCounts

class torch.utils.benchmark.FunctionCounts(_data, inclusive, truncate_rows=True, _linewidth=None) [source]

Контейнер для манипулирования результатами Callgrind.

Он поддерживает:
  1. Сложение и вычитание для объединения или сравнения результатов.
  2. Индексацию по типу кортежа.
  3. Функцию denoise, которая удаляет вызовы CPython, которые известны как недетерминированные и очень шумные.
  4. Два метода высшего порядка (filter и transform) для пользовательской обработки.
denoise() [source]

Удаление известных шумных инструкций.

Некоторые инструкции в интерпретаторе CPython довольно шумные. Эти инструкции связаны с преобразованием unicode в словари, которые Python использует для сопоставления имён переменных. Функция FunctionCounts, как правило, является контейнером, независимым от содержимого, однако это достаточно важно для получения надёжных результатов, чтобы оправдать исключение.

Тип возвращаемого значения

FunctionCounts

filter(filter_fn) [source]

Сохранение только тех элементов, для которых filter_fn, применённое к имени функции, возвращает True.

Тип возвращаемого значения

FunctionCounts

transform(map_fn) [source]

Применение map_fn ко всем именам функций.

Это можно использовать для стандартизации имён функций (например, удаления неважных частей пути к файлу), объединения записей путём сопоставления нескольких функций одному имени (в этом случае счётчики складываются) и т. д.

Тип возвращаемого значения

FunctionCounts

© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/2.1/benchmark_utils.html

Spec-Zone.ru

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