Spec-Zone.ru › PyTorch 2

Автоматическое дифференцирование - пакет torch.autograd

torch.autograd предоставляет классы и функции для реализации автоматического дифференцирования произвольных скалярных функций. Он требует минимальных изменений в существующем коде — вам нужно только объявить Tensor для вычисления градиентов с помощью ключевого слова requires_grad=True. На данный момент мы поддерживаем autograd только для типов с плавающей точкой Tensor (half, float, double и bfloat16) и комплексных Tensor типов (cfloat, cdouble).

backward

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

grad

Вычисляет и возвращает сумму градиентов выходов по отношению к входам.

Дифференцирование по прямой

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

Этот API находится в стадии бета-тестирования. Несмотря на то, что сигнатуры функций вряд ли изменятся, перед тем как мы сочтём его стабильным, планируется улучшить охват операторов.

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

forward_ad.dual_level

Менеджер контекста, который включает дифференцирование по прямой.

forward_ad.make_dual

Связывает значение тензора с градиентом по прямой, касательной, чтобы создать «дуальный тензор», который используется для вычисления градиентов по прямой.

forward_ad.unpack_dual

Распаковывает «дуальный тензор», чтобы получить как его значение Tensor, так и его градиент по прямой.

Функциональный API высокого уровня

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

Этот API находится в стадии бета-тестирования. Несмотря на то, что сигнатуры функций вряд ли изменятся, перед тем как мы сочтём его стабильным, планируется существенно улучшить производительность.

Этот раздел содержит API высокого уровня для autograd, который построен на основе базового API выше и позволяет вычислять якобианы, гессианы и т. д.

Этот API работает с функциями, предоставляемыми пользователем, которые принимают только тензоры в качестве входных данных и возвращают только тензоры. Если ваша функция принимает другие аргументы, которые не являются тензорами или тензорами, у которых не задано requires_grad, вы можете использовать лямбда-функцию для их захвата. Например, для функции f, которая принимает три входа, тензор, для которого требуется якобиан, другой тензор, который следует рассматривать как константу, и логический флаг в качестве f(input, constant, flag=flag) вы можете использовать её как functional.jacobian(lambda x: f(x, constant, flag=flag), input).

functional.jacobian

Функция, которая вычисляет якобиан заданной функции.

functional.hessian

Функция, которая вычисляет гессиан заданной скалярной функции.

functional.vjp

Функция, которая вычисляет скалярное произведение вектора v и якобиана данной функции в точке, заданной входами.

functional.jvp

Функция, которая вычисляет скалярное произведение якобиана заданной функции в точке, заданной входами, и вектора v.

functional.vhp

Функция, которая вычисляет скалярное произведение вектора v и гессиана заданной скалярной функции в точке, заданной входами.

functional.hvp

Функция, которая вычисляет скалярное произведение гессиана заданной скалярной функции и вектора v в точке, заданной входами.

Локальное отключение вычисления градиента

См. Локальное отключение вычисления градиента для получения дополнительной информации о различиях между режимами no-grad и inference, а также о других связанных механизмах, которые могут быть спутаны с двумя из них. Также см. Локальное отключение вычисления градиента для списка функций, которые можно использовать для локального отключения градиентов.

По умолчанию планировки градиентов

Когда неразреженный param получает неразреженный градиент во время torch.autograd.backward() или torch.Tensor.backward() param.grad накапливается следующим образом.

Если param.grad изначально None:

  1. Если память param не перекрывается и является плотной, .grad создается со шагами, соответствующими param (тем самым соответствующими планировке param).
  2. В противном случае .grad создается с пошаговым расположением rowmajor-contiguous.

Если param уже имеет атрибут неразреженный .grad:

  1. Если create_graph=False, backward() накапливается в .grad непосредственно, что сохраняет его шаги.
  2. Если create_graph=True, backward() заменяет .grad новым тензором .grad + new grad, что пытается (но не гарантирует) соответствие предварительно существующим шагам .grad.

Рекомендуется поведение по умолчанию (позволяющее .grad быть None перед первым backward(), таким образом, что их планировка создается в соответствии с 1 или 2 и сохраняется со временем в соответствии с 3 или 4) для наилучшей производительности. Вызовы model.zero_grad() или optimizer.zero_grad() не повлияют на планировки .grad.

Фактически, сброс всех .grad в None перед каждой фазой накопления, например:

for iterations...
    ...
    for param in model.parameters():
        param.grad = None
    loss.backward()

таким образом, что они будут создаваться в соответствии с 1 или 2 каждый раз, является допустимой альтернативой model.zero_grad() или optimizer.zero_grad() , которая может улучшить производительность для некоторых сетей.

Ручные планировки градиентов

Если вам нужен ручной контроль над шагами .grad , присвойте param.grad = нулевому тензору с желаемыми шагами перед первым backward(), и никогда не сбрасывайте его в None. 3 гарантирует, что ваша планировка сохранится, пока create_graph=False. 4 указывает, что ваша планировка, вероятно, сохранится, даже если create_graph=True.

Операции на месте с тензорами

Поддержка операций на месте в autograd — сложная задача, и мы не рекомендуем их использовать в большинстве случаев. Автоматическое дифференцирование агрессивно освобождает и повторно использует буферы, что делает его очень эффективным, и есть очень мало случаев, когда операции на месте фактически снижают использование памяти на значительную величину. Если вы не работаете в условиях сильного дефицита памяти, вам, возможно, никогда не понадобится их использовать.

Проверки правильности операций на месте

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

Переменная (устарела)

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

API Variable устарел: переменные больше не нужны для использования autograd с тензорами. Autograd автоматически поддерживает тензоры с requires_grad , установленным в True. Ниже приведен краткий обзор изменений:

  • Variable(tensor) и Variable(tensor, requires_grad) по-прежнему работают как ожидается, но возвращают тензоры вместо переменных.
  • var.data — то же самое, что и tensor.data.
  • Методы, такие как var.backward(), var.detach(), var.register_hook() теперь работают с тензорами с теми же именами методов.

Кроме того, теперь можно создавать тензоры с requires_grad=True с помощью методов-фабрик, таких как torch.randn(), torch.zeros(), torch.ones() и другие, подобные следующим:

autograd_tensor = torch.randn((2, 3, 4), requires_grad=True)

Функции тензора autograd

torch.Tensor.grad

Этот атрибут по умолчанию None и превращается в тензор при первом вызове backward() для вычисления градиентов для self.

torch.Tensor.requires_grad

Будет True если для этого тензора нужно вычислить градиенты, False в противном случае.

torch.Tensor.is_leaf

Все тензоры, имеющие requires_grad, который False будут листом тензоров по умолчанию.

torch.Tensor.backward([gradient, ...])

Вычисляет градиент текущего тензора относительно листьев графа.

torch.Tensor.detach

Возвращает новый тензор, отсоединённый от текущего графа.

torch.Tensor.detach_

Отсоединяет тензор от графа, который его создал, превращая его в лист.

torch.Tensor.register_hook(hook)

Регистрирует обратный хук.

torch.Tensor.register_post_accumulate_grad_hook(hook)

Регистрирует обратный хук, который выполняется после накопления градиентов.

torch.Tensor.retain_grad()

Разрешает этому тензору иметь заполненные grad во время backward().

Функция

class torch.autograd.Function(*args, **kwargs) [source]

Базовый класс для создания пользовательских autograd.Function

Чтобы создать пользовательскую autograd.Function, подклассируйте этот класс и реализуйте статические методы forward() и backward(). Затем, чтобы использовать ваш пользовательский оператор в прямом проходе, вызовите метод класса apply. Не вызывайте forward() напрямую.

Чтобы обеспечить корректность и лучшую производительность, убедитесь, что вы вызываете правильные методы для ctx и проверяете свою обратную функцию с помощью torch.autograd.gradcheck().

См. Расширение torch.autograd для получения более подробной информации о том, как использовать этот класс.

Примеры:

>>> class Exp(Function):
>>>     @staticmethod
>>>     def forward(ctx, i):
>>>         result = i.exp()
>>>         ctx.save_for_backward(result)
>>>         return result
>>>
>>>     @staticmethod
>>>     def backward(ctx, grad_output):
>>>         result, = ctx.saved_tensors
>>>         return grad_output * result
>>>
>>> # Use it by calling the apply method:
>>> output = Exp.apply(input)

Function.forward

Эта функция должна быть переопределена всеми подклассами.

Function.backward

Определяет формулу для дифференцирования операции с обратным режимом автоматического дифференцирования (псевдоним для функции vjp).

Function.jvp

Определяет формулу для дифференцирования операции с прямым режимом автоматического дифференцирования.

Function.vmap

Определяет правило для поведения этого autograd.Function в рамках torch.vmap().

Смеси методов контекста

При создании нового Function, следующие методы доступны ctx.

function.FunctionCtx.mark_dirty

Помечает указанные тензоры как изменённые в операции на месте.

function.FunctionCtx.mark_non_differentiable

Помечает выходы как недифференцируемые.

function.FunctionCtx.save_for_backward

Сохраняет заданные тензоры для будущего вызова backward().

function.FunctionCtx.set_materialize_grads

Устанавливает, нужно ли материализовать тензоры grad.

Проверка численного градиента

gradcheck

Проверяет градиенты, вычисленные с помощью малых конечных разностей, по отношению к аналитическим градиентам по тензорам в inputs, которые имеют тип с плавающей запятой или комплексный тип и с requires_grad=True.

gradgradcheck

Проверяет градиенты градиентов, вычисленные с помощью малых конечных разностей, по отношению к аналитическим градиентам по тензорам в inputs и grad_outputs, которые имеют тип с плавающей запятой или комплексный тип и с requires_grad=True.

Профилировщик

Autograd включает в себя профилировщик, который позволяет вам изучить затраты различных операторов внутри вашей модели - как на процессоре, так и на графическом процессоре. В настоящее время реализованы три режима - только процессор с использованием profile, nvprof (регистрирует активность как процессора, так и графического процессора) с использованием emit_nvtx, и профилировщик vtune с использованием emit_itt.

END_OF_DOCUMENT_MARKER
class torch.autograd.profiler.profile(enabled=True, *, use_cuda=False, use_device=None, record_shapes=False, with_flops=False, profile_memory=False, with_stack=False, with_modules=False, use_kineto=False, use_cpu=True, use_mtia=False, experimental_config=None) [source]

Менеджер контекста, который управляет состоянием профилировщика autograd и содержит сводку результатов. Внутри он просто записывает события выполнения функций в C++ и предоставляет эти события Python. Вы можете обернуть любой код в него, и он будет сообщать только время выполнения функций PyTorch. Примечание: профилировщик является локальным для потока и автоматически распространяется на асинхронные задачи

Параметры
  • enabled (bool, необязательно) – Установка этого значения в False превращает менеджер контекста в бесполезную операцию.
  • use_cuda (bool, необязательно) – Включает измерение времени событий CUDA с помощью API cudaEvent. Добавляет примерно 4 мкс накладных расходов на каждую операцию с тензором.
  • record_shapes (bool, необязательно) – Если включена запись форм, информация о размерностях ввода будет собираться. Это позволяет увидеть, какие размерности использовались внутри и далее группировать их с помощью prof.key_averages(group_by_input_shape=True). Обратите внимание, что запись форм может исказить данные профилирования. Рекомендуется проводить отдельные замеры с включенной и выключенной записью форм, чтобы проверить время. Скорее всего, искажение будет незначительным для событий самого нижнего уровня (в случае вложенных вызовов функций). Но для функций более высокого уровня общее время выполнения на CPU может быть искусственно увеличено из-за сбора форм.
  • with_flops (bool, необязательно) – Если with_flops установлен, профилировщик оценит значение FLOPs (операций с плавающей запятой) с использованием формы ввода оператора. Это позволяет оценить производительность оборудования. В настоящее время этот параметр работает только для операций умножения матриц и двумерных свёртки.
  • profile_memory (bool, необязательно) – отслеживание выделения/освобождения памяти тензоров.
  • with_stack (bool, необязательно) – регистрировать информацию об источнике (файл и номер строки) для операций.
  • with_modules (bool) – регистрировать иерархию модулей (включая имена функций), соответствующую стеку вызовов операции. Например, если вызов метода forward модуля A вызывает метод forward модуля B, который содержит операцию aten::add, то иерархия модулей aten::add - A.B. Обратите внимание, что эта поддержка в настоящее время существует только для моделей TorchScript, а не для моделей в режиме eager.
  • use_kineto (bool, необязательно) – экспериментальная возможность, включить профилирование с помощью профилировщика Kineto.
  • use_cpu (bool, необязательно) – профилировать события CPU; установка в False требует use_kineto=True и может использоваться для уменьшения накладных расходов при профилировании только GPU.
  • experimental_config (_ExperimentalConfig) – набор экспериментальных параметров, используемых библиотеками профилирования, такими как Kineto. Обратите внимание, что обратная совместимость не гарантируется.

Пример

>>> x = torch.randn((1, 1), requires_grad=True)
>>> with torch.autograd.profiler.profile() as prof:
>>>     for _ in range(100):  # any normal python code, really!
>>>         y = x ** 2
>>>         y.backward()
>>> # NOTE: some columns were removed for brevity
>>> print(prof.key_averages().table(sort_by="self_cpu_time_total"))
-----------------------------------  ---------------  ---------------  ---------------
Name                                 Self CPU total   CPU time avg     Number of Calls
-----------------------------------  ---------------  ---------------  ---------------
mul                                  32.048ms         32.048ms         200
pow                                  27.041ms         27.041ms         200
PowBackward0                         9.727ms          55.483ms         100
torch::autograd::AccumulateGrad      9.148ms          9.148ms          100
torch::autograd::GraphRoot           691.816us        691.816us        100
-----------------------------------  ---------------  ---------------  ---------------

profiler.profile.export_chrome_trace

Экспортирует список событий в виде файла трассировки Chrome.

profiler.profile.key_averages

Среднее значение всех событий функции по их ключам.

profiler.profile.self_cpu_time_total

Возвращает общее время, затраченное на CPU, как сумму всех собственных времен по всем событиям.

profiler.profile.total_average

Среднее значение всех событий.

class torch.autograd.profiler.emit_nvtx(enabled=True, record_shapes=False) [source]

Менеджер контекста, который заставляет каждую операцию autograd генерировать диапазон NVTX.

Полезно при запуске программы с nvprof:

nvprof --profile-from-start off -o trace_name.prof -- <regular command here>

К сожалению, нет способа заставить nvprof сбросить собранные данные на диск, поэтому для профилирования CUDA нужно использовать этот менеджер контекста для аннотирования трасс nvprof и дождаться завершения процесса перед их проверкой. Затем можно использовать NVIDIA Visual Profiler (nvvp) для визуализации временной шкалы, или torch.autograd.profiler.load_nvprof() загрузить результаты для проверки, например, в интерактивной оболочке Python.

Параметры
  • enabled (bool, необязательно) – Установка enabled=False делает этот менеджер контекста бесполезной операцией. По умолчанию: True.
  • record_shapes (bool, необязательно) – Если record_shapes=True, диапазон nvtx, охватывающий каждую операцию autograd, будет дополнять информацию о размерах аргументов Tensor, полученных этой операцией, в следующем формате: [[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...] Аргументы, не являющиеся тензорами, будут представлены []. Аргументы будут перечислены в том порядке, в котором они были получены операцией back-end. Обратите внимание, что этот порядок может не соответствовать порядку, в котором эти аргументы были переданы на стороне Python. Также обратите внимание, что запись форм может увеличить накладные расходы на создание диапазона nvtx. По умолчанию: False

Пример

>>> with torch.cuda.profiler.profile():
...     model(x)  # Warmup CUDA memory allocator and profiler
...     with torch.autograd.profiler.emit_nvtx():
...         model(x)

Корреляция вперёд-назад

При просмотре профиля, созданного с помощью emit_nvtx в Nvidia Visual Profiler, корреляция каждой операции обратного прохода с соответствующей операцией прямого прохода может быть сложной. Для упрощения этой задачи emit_nvtx добавляет информацию о номере последовательности в генерируемые им диапазоны.

Во время прямого прохода каждый диапазон функции обозначается seq=<N>. seq — это счётчик, увеличивающийся каждый раз при создании и сохранении нового объекта функции обратного прохода. Таким образом, аннотация seq=<N> в каждом диапазоне функции прямого прохода говорит о том, что если объект функции обратного прохода создаётся этой функцией прямого прохода, объект обратного прохода получит номер последовательности N. Во время обратного прохода верхний уровень диапазона, охватывающий вызов метода apply() каждого объекта C++ функции обратного прохода, обозначается stashed seq=<M>. M - это номер последовательности, с которым был создан объект обратного прохода. Сравнивая номера stashed seq в обратном проходе с номерами seq в прямом проходе, вы можете отследить, какая операция прямого прохода создала каждый объект функции обратного прохода.

Все функции, выполняемые во время обратного прохода, также обозначаются seq=<N>. Во время стандартного обратного прохода (с create_graph=False) эта информация не имеет значения, и на самом деле N может просто быть 0 для всех таких функций. Полезны только верхние диапазоны, связанные с методами apply() объектов функции обратного прохода, как способ корреляции этих объектов функции с предыдущим прямым проходом.

Двойной обратный проход

Если, с другой стороны, происходит обратный проход с create_graph=True (другими словами, если вы готовитесь к двойному обратному проходу), выполнение каждой функции во время обратного прохода получает ненулевой, полезный seq=<N> номер последовательности. Эти функции сами могут создавать объекты функций для выполнения позже во время двойного обратного прохода, так же, как и исходные функции в прямом проходе. Взаимосвязь между обратным и двойным обратным проходом концептуально такая же, как взаимосвязь между прямым и обратным: функции по-прежнему излучают диапазоны с текущим номером последовательности, объекты функции, которые они создают, по-прежнему сохраняют эти номера последовательности, а во время последующего двойного обратного прохода диапазоны apply() объектов функции по-прежнему обозначаются номерами stashed seq, которые можно сравнить с номерами seq из обратного прохода.

class torch.autograd.profiler.emit_itt(enabled=True, record_shapes=False) [source]

Менеджер контекста, который заставляет каждую операцию autograd генерировать диапазон ITT.

Полезно при запуске программы под Intel(R) VTune Profiler:

vtune <--vtune-flags> <regular command here>

API технологии Instrumentation and Tracing Technology (ITT) позволяет вашему приложению генерировать и управлять сбором данных трассировки во время выполнения на различных инструментах Intel. Этот менеджер контекста предназначен для аннотирования трассировки Intel(R) VTune Profiling. С помощью этого менеджера контекста вы сможете увидеть помеченные диапазоны в графическом интерфейсе Intel(R) VTune Profiler.

Parameters
  • enabled (bool, optional) – Установка enabled=False делает этот менеджер контекста бесполезным. По умолчанию: True.
  • record_shapes (bool, optional) – Если record_shapes=True, диапазон itt, охватывающий каждую операцию autograd, будет добавлять информацию о размерах аргументов Tensor, полученных этой операцией, в следующем формате: [[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...] Аргументы, не являющиеся тензорами, будут представлены []. Аргументы будут перечислены в том порядке, в котором они были получены операцией backenda. Обратите внимание, что этот порядок может не совпадать с порядком, в котором эти аргументы были переданы на стороне Python. Также обратите внимание, что запись формы может увеличить накладные расходы на создание диапазона itt. По умолчанию: False

Пример

>>> with torch.autograd.profiler.emit_itt():
...     model(x)

profiler.load_nvprof

Открывает файл трассировки nvprof и анализирует аннотации autograd.

Обнаружение аномалий

class torch.autograd.detect_anomaly(check_nan=True) [source]

Менеджер контекста, который включает обнаружение аномалий для движка autograd.

Это делает две вещи:

  • Запуск прямого прохода с включенным обнаружением позволит обратной проходу напечатать трассировку прямого действия, которое создало неисправную обратную функцию.
  • Если check_nan имеет значение True, любая обратная вычисление, генерирующая значение «nan», вызовет ошибку. По умолчанию True.

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

Этот режим следует включать только для отладки, так как разные тесты замедлит выполнение вашей программы.

Пример

>>> import torch
>>> from torch import autograd
>>> class MyFunc(autograd.Function):
...     @staticmethod
...     def forward(ctx, inp):
...         return inp.clone()
...     @staticmethod
...     def backward(ctx, gO):
...         # Error during the backward pass
...         raise RuntimeError("Some error in backward")
...         return gO.clone()
>>> def run_fn(a):
...     out = MyFunc.apply(a)
...     return out.sum()
>>> inp = torch.rand(10, 10, requires_grad=True)
>>> out = run_fn(inp)
>>> out.backward()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/your/pytorch/install/torch/_tensor.py", line 93, in backward
        torch.autograd.backward(self, gradient, retain_graph, create_graph)
      File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward
        allow_unreachable=True)  # allow_unreachable flag
      File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply
        return self._forward_cls.backward(self, *args)
      File "<stdin>", line 8, in backward
    RuntimeError: Some error in backward
>>> with autograd.detect_anomaly():
...     inp = torch.rand(10, 10, requires_grad=True)
...     out = run_fn(inp)
...     out.backward()
    Traceback of forward call that caused the error:
      File "tmp.py", line 53, in <module>
        out = run_fn(inp)
      File "tmp.py", line 44, in run_fn
        out = MyFunc.apply(a)
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
      File "/your/pytorch/install/torch/_tensor.py", line 93, in backward
        torch.autograd.backward(self, gradient, retain_graph, create_graph)
      File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward
        allow_unreachable=True)  # allow_unreachable flag
      File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply
        return self._forward_cls.backward(self, *args)
      File "<stdin>", line 8, in backward
    RuntimeError: Some error in backward
class torch.autograd.set_detect_anomaly(mode, check_nan=True) [source]

Менеджер контекста, который устанавливает включение или выключение обнаружения аномалий для движка автографа.

set_detect_anomaly включит или отключит обнаружение аномалий autograd на основе ее аргумента mode. Его можно использовать как менеджер контекста или как функцию.

См. detect_anomaly выше для получения подробностей о поведении обнаружения аномалий.

Parameters
  • mode (bool) – Флаг, определяющий, включить ли обнаружение аномалий (True), или отключить (False).
  • check_nan (bool) – Флаг, определяющий, вызывать ли ошибку, когда обратная функция генерирует «nan».

Граф Autograd

Autograd предоставляет методы, которые позволяют просматривать граф и вставлять поведение во время обратного прохода.

Атрибут grad_fn torch.Tensor содержит torch.autograd.graph.Node, если тензор является результатом операции, которая была записана автоградом (т.е. режим grad включен и по крайней мере один из входов требует градиенты), или None в противном случае.

graph.Node.name

Возвращает имя.

graph.Node.metadata

Возвращает метаданные.

graph.Node.next_functions

graph.Node.register_hook

Регистрирует обратный хук.

graph.Node.register_prehook

Регистрирует предварительный обратный хук.

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

>>> a = torch.tensor([0., 0., 0.], requires_grad=True)
>>> b = a.exp()
>>> print(isinstance(b.grad_fn, torch.autograd.graph.Node))
True
>>> print(dir(b.grad_fn))
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_raw_saved_result', '_register_hook_dict', '_saved_result', 'metadata', 'name', 'next_functions', 'register_hook', 'register_prehook', 'requires_grad']
>>> print(torch.allclose(b.grad_fn._saved_result, b))
True

Вы также можете определить, как эти сохраненные тензоры должны быть упакованы/распакованы с помощью хуков. Распространенное применение — торговля вычислениями на память, сохраняя эти промежуточные результаты на диске или на ЦП, вместо того, чтобы оставлять их на графическом процессоре. Это особенно полезно, если вы заметили, что ваша модель помещается на графическом процессоре во время оценки, но не во время обучения. Также см. Хук для сохраненных тензоров.

class torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook) [source]

Менеджер контекста, который устанавливает пару хуков для упаковки/распаковки сохраненных тензоров.

Используйте этот менеджер контекста, чтобы определить, как промежуточные результаты операции должны быть упакованы перед сохранением и распакованы при получении.

В этом контексте функция pack_hook будет вызываться каждый раз, когда операция сохраняет тензор для обратного прохода (это включает промежуточные результаты, сохраненные с помощью save_for_backward(), но также и те, которые записаны операцией, определенной PyTorch). Затем вывод pack_hook хранится в вычислительном графе вместо исходного тензора.

Функция unpack_hook вызывается, когда необходимо получить сохраненный тензор, а именно при выполнении torch.Tensor.backward() или torch.autograd.grad(). Она принимает в качестве аргумента объект packed, возвращенный функцией pack_hook, и должна возвращать тензор, который имеет то же содержимое, что и исходный тензор (переданный в качестве входного параметра соответствующему pack_hook).

Хук должен иметь следующие подписи:

pack_hook(tensor: Tensor) -> Any

unpack_hook(Any) -> Tensor

где возвращаемое значение pack_hook является допустимым входом для unpack_hook.

В общем случае, вы хотите, чтобы unpack_hook(pack_hook(t)) был равен t по значению, размеру, типу и устройству.

Пример:

>>> def pack_hook(x):
...     print("Packing", x)
...     return x
>>>
>>> def unpack_hook(x):
...     print("Unpacking", x)
...     return x
>>>
>>> a = torch.ones(5, requires_grad=True)
>>> b = torch.ones(5, requires_grad=True) * 2
>>> with torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook):
...     y = a * b
Packing tensor([1., 1., 1., 1., 1.], requires_grad=True)
Packing tensor([2., 2., 2., 2., 2.], grad_fn=<MulBackward0>)
>>> y.sum().backward()
Unpacking tensor([1., 1., 1., 1., 1.], requires_grad=True)
Unpacking tensor([2., 2., 2., 2., 2.], grad_fn=<MulBackward0>)

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

Выполнение операции inplace над входными данными для любого из хуков может привести к неопределенному поведению.

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

Разрешена только одна пара хуков за раз. При рекурсивном вложенном использовании этого менеджера контекста будет применена только самая внутренняя пара хуков.

class torch.autograd.graph.save_on_cpu(pin_memory=False, device_type='cuda') [source]

Менеджер контекста, в рамках которого тензоры, сохраненные в прямом проходе, будут храниться на ЦП, а затем извлечены для обратного прохода.

При выполнении операций в рамках этого менеджера контекста промежуточные результаты, сохраненные в графе во время прямого прохода, будут перемещены на ЦП, а затем скопированы обратно в исходное устройство при необходимости для обратного прохода. Если граф уже находился на ЦП, никакой копии тензора не выполняется.

Используйте этот менеджер контекста, чтобы обменять вычисления на использование памяти GPU (например, когда ваша модель не помещается в память GPU во время обучения).

Parameters

pin_memory (bool) – Если True тензоры будут сохранены в закрепленной памяти ЦП во время упаковки и скопированы на GPU асинхронно во время распаковки. По умолчанию False. Также см. Использование буферов с закрепленной памятью.

Пример:

>>> a = torch.randn(5, requires_grad=True, device="cuda")
>>> b = torch.randn(5, requires_grad=True, device="cuda")
>>> c = torch.randn(5, requires_grad=True, device="cuda")
>>>
>>> def f(a, b, c):
...     prod_1 = a * b           # a and b are saved on GPU
...     with torch.autograd.graph.save_on_cpu():
...         prod_2 = prod_1 * c  # prod_1 and c are saved on CPU
...     y = prod_2 * a           # prod_2 and a are saved on GPU
...     return y
>>>
>>> y = f(a, b, c)
>>> del a, b, c  # for illustration only
>>> # the content of a, b, and prod_2 are still alive on GPU
>>> # the content of prod_1 and c only live on CPU
>>> y.sum().backward()  # all CPU tensors are moved back to GPU, for backward
>>> # all intermediary tensors are released (deleted) after the call to backward
class torch.autograd.graph.disable_saved_tensors_hooks(error_message) [source]

Менеджер контекста, отключающий стандартные хуки сохранённых тензоров.

Полезно, если вы создаёте функцию, которая не работает со стандартными хуками сохранённых тензоров.

Параметры

error_message (str) – Если стандартные хуки сохранённых тензоров используются, когда они отключены, будет поднята ошибка RuntimeError с этим сообщением.

Пример:

>>> message = "saved tensors default hooks are disabled"
>>> with torch.autograd.graph.disable_saved_tensors_hooks(message):
...     # Raises RuntimeError: saved tensors default hooks are disabled
...     with torch.autograd.graph.save_on_cpu():
...         pass
class torch.autograd.graph.register_multi_grad_hook(tensors, fn) [source]

Регистрирует хук обратного распространения для нескольких градиентов.

Хук будет вызван после вычисления градиентов по отношению ко всем тензорам в tensors. Если тензор находится в tensors , но не является частью графа, или если тензор не нужен для вычисления градиентов по любому из inputs , указанных для текущего .backward() или .grad() вызова, этот тензор будет проигнорирован, и хук не будет ждать вычисления его градиента.

После вычисления градиента каждого неигнорированного тензора, fn будет вызван с этими градиентами. None будет передан для тензоров, у которых не были вычислены градиенты.

Хук не должен изменять свои аргументы.

Эта функция возвращает обработчик с методом handle.remove() , который удаляет хук.

Примечание

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

Пример:

>>> import torch
>>>
>>> a = torch.rand(2, 3, requires_grad=True)
>>> b = torch.rand(2, 3, requires_grad=True)
>>> c = a * b
>>> d = a * b
>>>
>>> def fn(grads):
...     print([g is not None for g in grads])
...
>>> torch.autograd.graph.register_multi_grad_hook((a, b, c, d), fn)
>>>
>>> c.sum().backward(retain_graph=True)
[True, True, True, False]
>>> c.sum().backward(inputs=(a,), retain_graph=True)
[True, False, True, False]
>>>
class torch.autograd.graph.allow_mutation_on_saved_tensors [source]

Менеджер контекста, в котором разрешается изменение тензоров, сохранённых для обратного распространения.

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

Для обеспечения корректной работы и прямой, и обратная проход должны выполняться в рамках одного менеджера контекста.

Возвращает

Объект _AllowMutationOnSavedContext, хранящий состояние, управляемое этим менеджером контекста. Этот объект может быть полезен для отладки. Состояние, управляемое менеджером контекста, автоматически очищается при выходе.

Пример:

>>> import torch
>>> with torch.autograd.graph.allow_mutation_on_saved_tensors():
...     # forward
...     a = torch.ones(2, 3, requires_grad=True)
...     b = a.clone()
...     out = (b**2).sum()
...     b.sin_()
...     # backward
...     out.sum().backward()
...
tensor([[0.8415, 0.8415, 0.8415],
        [0.8415, 0.8415, 0.8415]], grad_fn=<SinBackward0>)

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

Spec-Zone.ru

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