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()требуется вычислить градиент по отношению к выходному значению.- Тип возвращаемого значения:
-
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.- Тип возвращаемого значения:
-
static jvp(ctx, *grad_inputs)[исходный код] -
Определите формулу дифференцирования операции с помощью автоматического дифференцирования в режиме прямого прохода.
Эту функцию необходимо переопределить во всех подклассах. Она должна принимать контекст
ctxв качестве первого аргумента, а затем столько входных значений, сколько получила функцияforward()(для входных значений прямого прохода, не являющихся тензорами, будет передано None); функция должна возвращать столько тензоров, сколько выходных значений было уforward(). Каждый аргумент — это градиент по отношению к соответствующему входному значению, а каждое возвращаемое значение должно быть градиентом по отношению к соответствующему выходному значению. Если выходное значение не является Tensor или функция не дифференцируема по этому выходному значению, в качестве градиента для этого входного значения можно передать None.Для передачи в эту функцию любого значения из прямого прохода можно использовать объект
ctx.- Тип возвращаемого значения:
-
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.
Либо:
- Переопределите forward с сигнатурой
forward(ctx, *args, **kwargs).setup_contextне переопределяется. Настройка ctx для обратного прохода выполняется внутриforward. - Переопределите forward с сигнатурой
forward(*args, **kwargs)и переопределитеsetup_context. Настройка ctx для обратного прохода выполняется внутриsetup_context(а не внутриforward).
Подробнее см. разделы
torch.autograd.Function.forward()и Расширение torch.autograd.- Тип возвращаемого значения:
- Переопределите forward с сигнатурой
-
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()требуется вычислить градиент по отношению к выходному значению.- Тип возвращаемого значения:
-
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