Spec-Zone.ru › PyTorch 1

Средства для бенчмаркинга - 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))”, можно установить label в «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, выполняя разогрев, увеличивая block_size, пока накладные расходы таймера не станут меньше 0,1% от общей вычислительной работы. Это значение используется для основного цикла измерения.

Возвращает:

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

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

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

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

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

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

Список[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/1.13/benchmark_utils.html

Spec-Zone.ru

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