Автоматическое дифференцирование - пакет torch.autograd
torch.autograd предоставляет классы и функции для реализации автоматического дифференцирования произвольных скалярных функций. Он требует минимальных изменений в существующем коде — вам нужно только объявить Tensor для вычисления градиентов с помощью ключевого слова requires_grad=True. На данный момент мы поддерживаем autograd только для типов с плавающей точкой Tensor (half, float, double и bfloat16) и комплексных Tensor типов (cfloat, cdouble).
backward
| Вычисляет сумму градиентов заданных тензоров по отношению к узлам графа. |
grad
| Вычисляет и возвращает сумму градиентов выходов по отношению к входам. |
Дифференцирование по прямой
Предупреждение
Этот API находится в стадии бета-тестирования. Несмотря на то, что сигнатуры функций вряд ли изменятся, перед тем как мы сочтём его стабильным, планируется улучшить охват операторов.
Обратитесь к руководству по дифференцированию по прямой для получения подробных инструкций по использованию этого API.
Менеджер контекста, который включает дифференцирование по прямой. | |
Связывает значение тензора с градиентом по прямой, касательной, чтобы создать «дуальный тензор», который используется для вычисления градиентов по прямой. | |
Распаковывает «дуальный тензор», чтобы получить как его значение 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).
Функция, которая вычисляет якобиан заданной функции. | |
Функция, которая вычисляет гессиан заданной скалярной функции. | |
Функция, которая вычисляет скалярное произведение вектора | |
Функция, которая вычисляет скалярное произведение якобиана заданной функции в точке, заданной входами, и вектора | |
Функция, которая вычисляет скалярное произведение вектора | |
Функция, которая вычисляет скалярное произведение гессиана заданной скалярной функции и вектора |
Локальное отключение вычисления градиента
См. Локальное отключение вычисления градиента для получения дополнительной информации о различиях между режимами no-grad и inference, а также о других связанных механизмах, которые могут быть спутаны с двумя из них. Также см. Локальное отключение вычисления градиента для списка функций, которые можно использовать для локального отключения градиентов.
По умолчанию планировки градиентов
Когда неразреженный param получает неразреженный градиент во время torch.autograd.backward() или torch.Tensor.backward() param.grad накапливается следующим образом.
Если param.grad изначально None:
- Если память
paramне перекрывается и является плотной,.gradсоздается со шагами, соответствующимиparam(тем самым соответствующими планировкеparam). - В противном случае
.gradсоздается с пошаговым расположением rowmajor-contiguous.
Если param уже имеет атрибут неразреженный .grad:
- Если
create_graph=False,backward()накапливается в.gradнепосредственно, что сохраняет его шаги. - Если
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
| Этот атрибут по умолчанию |
| Будет |
| Все тензоры, имеющие |
| Вычисляет градиент текущего тензора относительно листьев графа. |
| Возвращает новый тензор, отсоединённый от текущего графа. |
| Отсоединяет тензор от графа, который его создал, превращая его в лист. |
| Регистрирует обратный хук. |
| Регистрирует обратный хук, который выполняется после накопления градиентов. |
| Разрешает этому тензору иметь заполненные |
Функция
-
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)
Эта функция должна быть переопределена всеми подклассами. | |
Определяет формулу для дифференцирования операции с обратным режимом автоматического дифференцирования (псевдоним для функции vjp). | |
Определяет формулу для дифференцирования операции с прямым режимом автоматического дифференцирования. | |
Определяет правило для поведения этого autograd.Function в рамках |
Смеси методов контекста
При создании нового Function, следующие методы доступны ctx.
Помечает указанные тензоры как изменённые в операции на месте. | |
Помечает выходы как недифференцируемые. | |
Сохраняет заданные тензоры для будущего вызова | |
Устанавливает, нужно ли материализовать тензоры grad. |
Проверка численного градиента
gradcheck
| Проверяет градиенты, вычисленные с помощью малых конечных разностей, по отношению к аналитическим градиентам по тензорам в |
gradgradcheck
| Проверяет градиенты градиентов, вычисленные с помощью малых конечных разностей, по отношению к аналитическим градиентам по тензорам в |
Профилировщик
Autograd включает в себя профилировщик, который позволяет вам изучить затраты различных операторов внутри вашей модели - как на процессоре, так и на графическом процессоре. В настоящее время реализованы три режима - только процессор с использованием profile, nvprof (регистрирует активность как процессора, так и графического процессора) с использованием emit_nvtx, и профилировщик vtune с использованием emit_itt.
-
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 ----------------------------------- --------------- --------------- ---------------
Экспортирует список событий в виде файла трассировки Chrome. | |
Среднее значение всех событий функции по их ключам. | |
Возвращает общее время, затраченное на CPU, как сумму всех собственных времен по всем событиям. | |
Среднее значение всех событий. |
-
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
-
enabled (bool, необязательно) – Установка
Пример
>>> 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
-
enabled (bool, optional) – Установка
Пример
>>> with torch.autograd.profiler.emit_itt(): ... model(x)
Открывает файл трассировки 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выше для получения подробностей о поведении обнаружения аномалий.
Граф Autograd
Autograd предоставляет методы, которые позволяют просматривать граф и вставлять поведение во время обратного прохода.
Атрибут grad_fn torch.Tensor содержит torch.autograd.graph.Node, если тензор является результатом операции, которая была записана автоградом (т.е. режим grad включен и по крайней мере один из входов требует градиенты), или None в противном случае.
Возвращает имя. | |
Возвращает метаданные. | |
Регистрирует обратный хук. | |
Регистрирует предварительный обратный хук. |
Некоторые операции нуждаются в промежуточных результатах, которые необходимо сохранить во время прямого прохода, чтобы выполнить обратный проход. Эти промежуточные результаты сохраняются как атрибуты в 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