Spec-Zone.ru › PyTorch 2.14

Операторы управления потоком

Создано: 14 февраля 2026 г. | Последнее обновление: 24 июня 2026 г.

Операторы управления потоком — это структурированные операторы в PyTorch, позволяющие выражать сложные шаблоны управления потоком способом, совместимым с torch.compile и torch.export. В отличие от обычного управления потоком в Python, эти операторы сохраняют свою семантику при использовании torch.compile и torch.export, обеспечивая управление потоком, зависящее от данных, в трассируемых программах.

Предупреждение

Операторы управления потоком являются экспериментальными возможностями PyTorch. Их поддержка некоторых типов входных и выходных данных может быть ограниченной, а некоторые из них могут не поддерживать обучение в полном объёме. Подробнее о классификации возможностей: https://pytorch.org/blog/pytorch-feature-classification-changes/#prototype

Зачем использовать операторы управления потоком?

PyTorch позволяет писать модели на обычном Python, в том числе использовать такие конструкции управления потоком, как операторы if, циклы for и циклы while. Это обеспечивает большую гибкость, но создаёт трудности при компиляции.

Рассмотрим простой пример:

if mod.static_config == 0:
    return f(x)
return g(x)

Ветви могут содержать совершенно разные операции. Если бы мы пытались компилировать обе ветви каждый раз при выполнении оператора if, количество путей выполнения росло бы экспоненциально и очень быстро становилось бы неуправляемым.

Для решения этой проблемы torch.compile использует специализацию и защитные проверки. При трассировке модели компилятор выбирает путь выполнения на основе текущего значения предиката (специализация), а затем добавляет защитную проверку, чтобы проверить это предположение во время выполнения. Если проверка не проходит, компилятор выполняет повторную компиляцию.

То же самое относится к циклам: компилятор разворачивает их и добавляет защитную проверку количества итераций. В результате получается линейный вычислительный граф, который легко оптимизировать.

Этот подход хорошо работает для статического управления потоком, но не подходит в нескольких случаях:

  • Управление потоком, зависящее от данных: если предикат зависит от значения тензора, компилятор не может выбрать ветвь во время компиляции, поскольку значение ещё неизвестно. Аналогично, он не может развернуть цикл while, если количество итераций зависит от значений тензора. Компилятор решает эту проблему, разбивая граф и возвращаясь к Python, что также делает невозможным запуск модели без среды выполнения Python (например, на периферийных устройствах).
  • Управление потоком, зависящее от динамической формы: если количество итераций цикла или предикат ветвления зависят от динамического размера тензора, специализация приводит к тому, что скомпилированный код работает только для этого конкретного размера. При каждом изменении размера компилятору приходится выполнять повторную компиляцию.
  • Большие вычислительные графы: даже при статическом количестве итераций разворачивание длинного цикла приводит к тому, что граф растёт линейно с числом итераций, хотя каждая итерация выполняет одни и те же действия. Это увеличивает время компиляции и расход памяти.

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

Доступные операторы

  • Управление потоком — Cond
  • Управление потоком — Switch
  • Управление потоком — While Loop
  • Управление потоком — Scan
  • Управление потоком — Associative Scan
  • Управление потоком — Map

Краткое сравнение

Оператор

Назначение

Пример

cond

Если pred имеет значение True, возвращает true_fn(*operands), иначе возвращает false_fn(*operands).

cond(pred, true_fn, false_fn, operands)

switch

Ветвление по N вариантам: возвращает branches[index](*operands), где index ограничен диапазоном [0, len(branches)-1].

switch(index, branches, operands)

while_loop

Пока cond_fn(*operands) имеет значение True, выполняет body_fn(*operands), который возвращает операнды для следующей итерации.

while_loop(cond_fn, body_fn, operands)

scan

Выполняет накопительные операции над xs с переносимым состоянием

scan(combine_fn, init, xs)

associative_scan

Подобен scan, но требует ассоциативный combine_fn, что позволяет применять дополнительные оптимизации.

associative_scan(add, xs, dim=0)

map

Вычисляет fn для каждого среза xs и возвращает объединённый результат.

map(fn, xs)

© 2026, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://docs.pytorch.org/docs/2.14/higher_order_ops/index.html

Spec-Zone.ru

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