Spec-Zone.ru › PyTorch 2.14

BackwardCFunction

class torch.autograd.function.BackwardCFunction [исходный код]

Этот класс используется для внутренних операций autograd. Не используйте его.

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

Метод apply, используемый при выполнении этого узла в ходе обратного прохода.

Вызывается движком autograd (неупакованный путь) и при прямых вызовах grad_fn.apply(). Если boxed_grads_call равно True, градиенты помещаются в изменяемый список перед вызовом пользовательского метода backward.

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

Метод apply, вызываемый движком autograd, когда boxed_grads_call равно True. Градиенты передаются одним аргументом в виде изменяемого списка, что позволяет методу backward освобождать отдельные градиенты во время выполнения.

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

Метод apply, используемый при выполнении прямого режима автоматического дифференцирования во время прямого прохода

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(), ваша пользовательская Function может не поддерживать двойное дифференцирование. Пользовательские Function, не поддерживающие двойное дифференцирование, должны декорировать свой метод backward() с помощью @once_differentiable, чтобы при попытке выполнить двойное дифференцирование возникала ошибка. Если требуется поддержка двойного дифференцирования, промежуточные значения можно либо пересчитать по входным данным во время обратного прохода, либо вернуть как выходные данные пользовательской Function. Подробнее см. в руководстве по двойному обратному проходу.

В 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) [исходный код]

Указать тип данных градиента для каждого выходного значения этой Function.

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

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

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

Например:

>>> @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"

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

© 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.BackwardCFunction.html

Spec-Zone.ru

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