Spec-Zone.ru › PyTorch 2.14

InplaceFunction

class torch.autograd.function.InplaceFunction(inplace=False) [исходный код]

Этот класс существует только для обеспечения обратной совместимости. Для любых новых случаев использования вместо него используйте Function.

static backward(ctx, *grad_outputs) [исходный код]

Определите формулу дифференцирования операции с помощью автоматического дифференцирования в режиме обратного прохода.

Эту функцию необходимо переопределить во всех подклассах. (Определение этой функции эквивалентно определению функции vjp.)

Она должна принимать контекст ctx в качестве первого аргумента, а затем столько выходных значений, сколько вернула функция forward() (для выходных значений прямого прохода, не являющихся тензорами, будет передано None); функция должна возвращать столько тензоров, сколько входных значений было у forward(). Каждый аргумент — это градиент по отношению к соответствующему выходному значению, а каждое возвращаемое значение должно быть градиентом по отношению к соответствующему входному значению. Если входное значение не является Tensor или является Tensor, для которого не требуются градиенты, в качестве градиента для этого входного значения можно передать None.

Контекст можно использовать для получения тензоров, сохранённых во время прямого прохода. Он также содержит атрибут ctx.needs_input_grad — кортеж логических значений, указывающих, для каких входных значений требуется градиент. Например, backward() будет иметь значение ctx.needs_input_grad[0] = True, если для первого входного значения forward() требуется вычислить градиент по отношению к выходному значению.

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

Any

static forward(*args, **kwargs) [исходный код]

Определите прямой проход пользовательской функции autograd.

Эту функцию необходимо переопределить во всех подклассах. Существует два способа определить прямой проход:

Способ 1 (объединённые прямой проход и ctx):

@staticmethod
def forward(ctx: Any, *args: Any, **kwargs: Any) -> Any:
    pass
  • Функция должна принимать контекст ctx в качестве первого аргумента, а затем произвольное количество аргументов (тензоров или значений других типов).
  • Подробнее см. раздел Объединённые или раздельные forward() и setup_context().

Способ 2 (раздельные прямой проход и ctx):

@staticmethod
def forward(*args: Any, **kwargs: Any) -> Any:
    pass


@staticmethod
def setup_context(ctx: Any, inputs: Tuple[Any, ...], output: Any) -> None:
    pass
  • Функция прямого прохода больше не принимает аргумент ctx.
  • Вместо этого необходимо также переопределить статический метод torch.autograd.Function.setup_context() для настройки объекта ctx. output — это результат прямого прохода, а inputs — кортеж входных значений прямого прохода.
  • Подробнее см. раздел Расширение torch.autograd.

Контекст можно использовать для хранения произвольных данных, которые затем можно получить во время обратного прохода. Не следует сохранять тензоры непосредственно в ctx (хотя в настоящее время это не запрещено ради обратной совместимости). Вместо этого тензоры следует сохранять с помощью ctx.save_for_backward(), если они предназначены для использования в backward (эквивалентно vjp), или с помощью ctx.save_for_forward(), если они предназначены для использования в jvp.

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

Any

static jvp(ctx, *grad_inputs) [исходный код]

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

Эту функцию необходимо переопределить во всех подклассах. Она должна принимать контекст ctx в качестве первого аргумента, а затем столько входных значений, сколько получила функция forward() (для входных значений прямого прохода, не являющихся тензорами, будет передано None); функция должна возвращать столько тензоров, сколько выходных значений было у forward(). Каждый аргумент — это градиент по отношению к соответствующему входному значению, а каждое возвращаемое значение должно быть градиентом по отношению к соответствующему выходному значению. Если выходное значение не является Tensor или функция не дифференцируема по этому выходному значению, в качестве градиента для этого входного значения можно передать None.

Для передачи в эту функцию любого значения из прямого прохода можно использовать объект ctx.

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

Any

mark_dirty(*args) [исходный код]

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

Этот метод следует вызывать не более одного раза — в методе setup_context() или forward(); все аргументы должны быть входными значениями.

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

Примеры::
>>> class Inplace(Function):
>>>     @staticmethod
>>>     def forward(ctx, x):
>>>         x_npy = x.numpy() # x_npy shares storage with x
>>>         x_npy += 1
>>>         ctx.mark_dirty(x)
>>>         return x
>>>
>>>     @staticmethod
>>>     @once_differentiable
>>>     def backward(ctx, grad_output):
>>>         return grad_output
>>>
>>> a = torch.tensor(1., requires_grad=True, dtype=torch.double).clone()
>>> b = a * a
>>> Inplace.apply(a)  # This would lead to wrong gradients!
>>>                   # but the engine would not know unless we mark_dirty
>>> b.backward() # RuntimeError: one of the variables needed for gradient
>>>              # computation has been modified by an inplace operation
mark_non_differentiable(*args) [исходный код]

Отметьте выходные значения как недифференцируемые.

Этот метод следует вызывать не более одного раза — в методе setup_context() или forward(); все аргументы должны быть выходными тензорами.

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

Например, это используется для индексов, возвращаемых сортировкой. См. пример::
>>> class Func(Function):
>>>     @staticmethod
>>>     def forward(ctx, x):
>>>         sorted, idx = x.sort()
>>>         ctx.mark_non_differentiable(idx)
>>>         ctx.save_for_backward(x, idx)
>>>         return sorted, idx
>>>
>>>     @staticmethod
>>>     @once_differentiable
>>>     def backward(ctx, g1, g2):  # still need to accept g2
>>>         x, idx = ctx.saved_tensors
>>>         grad_input = torch.zeros_like(x)
>>>         grad_input.index_add_(0, idx, g1)
>>>         return grad_input
save_for_backward(*tensors) [исходный код]

Сохраните указанные тензоры для последующего вызова backward().

Метод save_for_backward следует вызывать не более одного раза — в методе setup_context() или forward() — и только с тензорами.

Все тензоры, предназначенные для использования в обратном проходе, следует сохранять с помощью save_for_backward (а не непосредственно в ctx), чтобы предотвратить некорректное вычисление градиентов и утечки памяти, а также обеспечить возможность применения хуков сохранённых тензоров. См. torch.autograd.graph.saved_tensors_hooks. Подробнее см. раздел Расширение torch.autograd.

Обратите внимание: если для обратного прохода сохраняются промежуточные тензоры — тензоры, которые не являются ни входными, ни выходными значениями forward(), — ваша пользовательская функция может не поддерживать двойное дифференцирование. Пользовательские функции, не поддерживающие двойное дифференцирование, должны декорировать свой метод backward() с помощью @once_differentiable, чтобы при попытке двойного дифференцирования возникала ошибка. Если вы хотите поддерживать двойное дифференцирование, можно либо повторно вычислить промежуточные значения по входным данным во время обратного прохода, либо вернуть промежуточные значения как выходные значения пользовательской функции. Подробнее см. в руководстве по двойному дифференцированию.

В методе backward() к сохранённым тензорам можно обращаться через атрибут saved_tensors. Перед возвратом тензоров пользователю выполняется проверка, чтобы убедиться, что они не использовались в операциях на месте, изменивших их содержимое.

Аргументы также могут быть None. Это не выполняет никаких действий.

Подробнее об использовании этого метода см. в разделе Расширение torch.autograd.

Пример:

>>> class Func(Function):
>>>     @staticmethod
>>>     def forward(ctx, x: torch.Tensor, y: torch.Tensor, z: int):
>>>         w = x * z
>>>         out = x * y + y * z + w * y
>>>         ctx.save_for_backward(x, y, w, out)
>>>         ctx.z = z  # z is not a tensor
>>>         return out
>>>
>>>     @staticmethod
>>>     @once_differentiable
>>>     def backward(ctx, grad_out):
>>>         x, y, w, out = ctx.saved_tensors
>>>         z = ctx.z
>>>         gx = grad_out * (y + y * z)
>>>         gy = grad_out * (x + z + w)
>>>         gz = None
>>>         return gx, gy, gz
>>>
>>> a = torch.tensor(1., requires_grad=True, dtype=torch.double)
>>> b = torch.tensor(2., requires_grad=True, dtype=torch.double)
>>> c = 4
>>> d = Func.apply(a, b, c)
save_for_forward(*tensors) [исходный код]

Сохраните указанные тензоры для последующего вызова jvp().

Метод save_for_forward следует вызывать не более одного раза — в методе setup_context() или forward(); все аргументы должны быть тензорами.

В методе jvp() к сохранённым объектам можно обращаться через атрибут saved_tensors.

Аргументы также могут быть None. Это не выполняет никаких действий.

Подробнее об использовании этого метода см. в разделе Расширение torch.autograd.

Пример:

>>> class Func(torch.autograd.Function):
>>>     @staticmethod
>>>     def forward(ctx, x: torch.Tensor, y: torch.Tensor, z: int):
>>>         ctx.save_for_backward(x, y)
>>>         ctx.save_for_forward(x, y)
>>>         ctx.z = z
>>>         return x * y * z
>>>
>>>     @staticmethod
>>>     def jvp(ctx, x_t, y_t, _):
>>>         x, y = ctx.saved_tensors
>>>         z = ctx.z
>>>         return z * (y * x_t + x * y_t)
>>>
>>>     @staticmethod
>>>     def vjp(ctx, grad_out):
>>>         x, y = ctx.saved_tensors
>>>         z = ctx.z
>>>         return z * grad_out * y, z * grad_out * x, None
>>>
>>>     a = torch.tensor(1., requires_grad=True, dtype=torch.double)
>>>     t = torch.tensor(1., dtype=torch.double)
>>>     b = torch.tensor(2., requires_grad=True, dtype=torch.double)
>>>     c = 4
>>>
>>>     with fwAD.dual_level():
>>>         a_dual = fwAD.make_dual(a, t)
>>>         d = Func.apply(a_dual, b, c)
set_materialize_grads(value) [исходный код]

Укажите, следует ли материализовать тензоры градиентов. По умолчанию задано значение True.

Этот метод следует вызывать только из метода setup_context() или forward().

Если задано значение True, неопределённые тензоры градиентов перед вызовом методов backward() и jvp() будут преобразованы в тензоры, заполненные нулями.

Пример:

>>> class SimpleFunc(Function):
>>>     @staticmethod
>>>     def forward(ctx, x):
>>>         return x.clone(), x.clone()
>>>
>>>     @staticmethod
>>>     @once_differentiable
>>>     def backward(ctx, g1, g2):
>>>         return g1 + g2  # No check for None necessary
>>>
>>> # We modify SimpleFunc to handle non-materialized grad outputs
>>> class Func(Function):
>>>     @staticmethod
>>>     def forward(ctx, x):
>>>         ctx.set_materialize_grads(False)
>>>         ctx.save_for_backward(x)
>>>         return x.clone(), x.clone()
>>>
>>>     @staticmethod
>>>     @once_differentiable
>>>     def backward(ctx, g1, g2):
>>>         x, = ctx.saved_tensors
>>>         grad_input = torch.zeros_like(x)
>>>         if g1 is not None:  # We must check for None now
>>>             grad_input += g1
>>>         if g2 is not None:
>>>             grad_input += g2
>>>         return grad_input
>>>
>>> a = torch.tensor(1., requires_grad=True)
>>> b, _ = Func.apply(a)  # induces g2 to be undefined
set_output_grad_dtype(*dtypes) [исходный код]

Задайте тип данных градиента для каждого выходного значения этой функции.

Этот метод следует вызывать не более одного раза — из метода setup_context() или forward(). Количество объявлений должно совпадать с количеством возвращаемых значений; каждый аргумент соответствует выходному значению с тем же индексом.

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

  • Передайте torch.dtype, и движок гарантирует, что градиент, передаваемый в обратный проход, будет иметь этот тип данных. Это допустимо только для дифференцируемого выходного значения Tensor.
  • Передайте None, и градиент будет передан в обратный проход с тем типом данных, который он уже имеет. Это также единственный допустимый вариант для выходного значения, которое не является Tensor или недифференцируемо и поэтому не имеет градиента.
  • Не вызывайте этот метод (или передайте собственный тип данных выходного значения), и градиент будет передан в обратный проход с типом данных выходного значения; это поведение используется по умолчанию.

Например:

>>> @staticmethod
>>> def forward(ctx, x):
>>>     t1 = x.sin()
>>>     t2 = x.cos()
>>>     t3 = x.tan()
>>>     ctx.set_output_grad_dtype(torch.float32, t2.dtype, None, None)
>>>     return t1, t2, t3, "not a tensor"

Это гарантирует, что обратный проход получит градиент t1 в типе данных float32, сохранит поведение по умолчанию для градиента t2 с помощью t2.dtype, передаст градиент t3 без преобразования типа с помощью None и использует None в качестве заполнителя для последнего выходного значения, не являющегося Tensor.

static setup_context(ctx, inputs, output) [исходный код]

Существует два способа определить прямой проход autograd.Function.

Либо:

  1. Переопределите forward с сигнатурой forward(ctx, *args, **kwargs). setup_context не переопределяется. Настройка ctx для обратного прохода выполняется внутри forward.
  2. Переопределите forward с сигнатурой forward(*args, **kwargs) и переопределите setup_context. Настройка ctx для обратного прохода выполняется внутри setup_context (а не внутри forward).

Подробнее см. разделы torch.autograd.Function.forward() и Расширение torch.autograd.

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

Any

static vjp(ctx, *grad_outputs) [исходный код]

Определите формулу дифференцирования операции с помощью автоматического дифференцирования в режиме обратного прохода.

Эту функцию необходимо переопределить во всех подклассах. (Определение этой функции эквивалентно определению функции vjp.)

Она должна принимать контекст ctx в качестве первого аргумента, а затем столько выходных значений, сколько вернула функция forward() (для выходных значений прямого прохода, не являющихся тензорами, будет передано None); функция должна возвращать столько тензоров, сколько входных значений было у forward(). Каждый аргумент — это градиент по отношению к соответствующему выходному значению, а каждое возвращаемое значение должно быть градиентом по отношению к соответствующему входному значению. Если входное значение не является Tensor или является Tensor, для которого не требуются градиенты, в качестве градиента для этого входного значения можно передать None.

Контекст можно использовать для получения тензоров, сохранённых во время прямого прохода. Он также содержит атрибут ctx.needs_input_grad — кортеж логических значений, указывающих, для каких входных значений требуется градиент. Например, backward() будет иметь значение ctx.needs_input_grad[0] = True, если для первого входного значения forward() требуется вычислить градиент по отношению к выходному значению.

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

Any

static vmap(info, in_dims, *args) [исходный код]

Определите поведение этой autograd.Function при использовании внутри torch.vmap().

Чтобы torch.autograd.Function() поддерживала torch.vmap(), необходимо либо переопределить этот статический метод, либо присвоить generate_vmap_rule значение True (нельзя делать и то и другое).

Если вы решили переопределить этот статический метод, он должен принимать:

  • объект info в качестве первого аргумента. info.batch_size задаёт размерность измерения, по которому выполняется vmap, а info.randomness — параметр случайности, переданный в torch.vmap().
  • кортеж in_dims в качестве второго аргумента. Для каждого аргумента в args в in_dims есть соответствующее значение Optional[int]. Оно равно None, если аргумент не является Tensor или для него не выполняется vmap; в противном случае это целое число, указывающее измерение Tensor, по которому выполняется vmap.
  • *args — это аргументы, совпадающие с аргументами forward().

Статический метод vmap возвращает кортеж из (output, out_dims). Как и in_dims, значение out_dims должно иметь ту же структуру, что и output, и содержать по одному out_dim для каждого выходного значения, указывающему, содержит ли выходное значение измерение vmap и по какому индексу оно находится.

Подробнее см. раздел Расширение torch.func с помощью autograd.Function.

© 2026, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://docs.pytorch.org/docs/2.14/generated/torch.autograd.function.InplaceFunction.html

Spec-Zone.ru

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