PyTorch

pytorch — библиотека для тензорных вычислений и глубокого обучения

Раздел
Инструменты
Обновлено
11.08.26

PyTorch — open-source библиотека для работы с тензорами, нейросетями и автоматическим дифференцированием. Модель описывается обычным Python-кодом, autograd вычисляет градиенты, а модули обучения и распределённых вычислений помогают собрать полный pipeline. Для ускорения отдельные графы можно компилировать, но результат всегда проверяют на конкретной модели и устройстве.

Коротко

PyTorch даёт Python-интерфейс для тензорных вычислений и обучения нейросетей. Его основной цикл выглядит просто: forward → loss → backward → optimizer.step(). За этой короткой записью стоят граф операций, вычисление градиентов и работа на выбранном устройстве.

Тензор — основная единица

Tensor похож на многомерный массив. У него есть:

  • shape;
  • dtype;
  • device;
  • layout;
  • при необходимости — история операций для autograd.
import torch

x = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
w = torch.randn(2, 1, requires_grad=True)
y = x @ w

Тот же код можно выполнять на CPU или поддерживаемом ускорителе, если операции и типы данных доступны на этом backend. Перенос устройства не гарантирует одинаковую скорость и побитовый результат.

Eager execution

По умолчанию Python-код выполняется по мере вызова операций. Условие остаётся условием, цикл — циклом, а промежуточный tensor можно посмотреть обычным debugger.

Это называют eager или define-by-run. Такой режим удобен для исследования и отладки. Он не означает, что внутренние операции выполняются только по одной: тяжёлые kernels по-прежнему используют параллельное устройство.

Autograd

Если tensor отмечен requires_grad=True, PyTorch отслеживает операции, необходимые для обратного прохода. После вызова loss.backward() градиенты накапливаются в .grad у leaf tensors.

prediction = x @ w
target = torch.zeros_like(prediction)
loss = ((prediction - target) ** 2).mean()

loss.backward()
print(w.grad)

Градиенты накапливаются, а не заменяются автоматически. Поэтому типичный training loop обнуляет их перед следующим backward.

Модель через nn.Module

torch.nn.Module объединяет параметры, подмодули и forward-вычисление:

from torch import nn

class Regressor(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(2, 1)

    def forward(self, x):
        return self.linear(x)

Модуль помогает переносить параметры между устройствами, переключать режимы train/eval и сохранять состояние. Он не навязывает один тип архитектуры.

Training loop

model = Regressor()
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)

for inputs, targets in loader:
    optimizer.zero_grad()
    predictions = model(inputs)
    loss = loss_fn(predictions, targets)
    loss.backward()
    optimizer.step()

Этот пример показывает ритм, а не готовый рецепт. Learning rate, batch, precision и optimizer выбираются по задаче и проверяются на validation.

Train и eval

model.train() и model.eval() переключают поведение слоёв, которым важен режим, например dropout или некоторые normalization. Они не включают и не отключают градиенты.

Для инференса отдельно используют контекст без построения ненужного графа:

model.eval()
with torch.inference_mode():
    output = model(inputs)

Забытый eval() способен сделать результат нестабильным, а забытый inference mode — потратить лишнюю память.

Данные

Dataset описывает получение одного примера, а DataLoader собирает batches, перемешивает данные и может готовить их в нескольких процессах.

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

Устройства и точность

PyTorch поддерживает несколько вычислительных backend. Конкретный набор операций и типов отличается. Код, который запускается на одном устройстве, может потребовать замены операции или другого dtype на другом.

Mixed precision уменьшает объём памяти и ускоряет поддерживаемые kernels, но способна изменить численную устойчивость. Поэтому проверяют loss, градиенты и качество результата, а не только факт запуска.

torch.compile

torch.compile пытается захватить участки Python-программы и оптимизировать их. Это может уменьшить overhead и объединить операции, но эффект зависит от:

  • формы входов;
  • динамического управления;
  • поддерживаемых операций;
  • backend и устройства;
  • стоимости первой компиляции;
  • числа повторных запусков.

Graph breaks и recompilation могут съесть выигрыш. Поэтому eager остаётся удобным baseline, а compile оценивают после прогрева на реальной нагрузке. Семантика некоторых сложных случаев может отличаться, и актуальные ограничения лучше сверять в документации PyTorch.

Распределённое обучение

Когда одна модель или batch не помещается на одном устройстве, вычисления распределяют:

  • data parallel повторяет модель и делит batches;
  • tensor parallel делит отдельные тензоры и операции;
  • pipeline parallel распределяет слои;
  • sharding делит параметры, градиенты и состояния optimizer.

Распределение добавляет обмен данными, синхронизацию и новые точки отказа. Масштабирование измеряют по полезной пропускной способности, а не по числу устройств.

Сохранение модели

state_dict содержит параметры и buffers. Чтобы восстановить модель, приложению всё равно нужна совместимая архитектура и конфигурация.

Форматы на основе pickle могут выполнять код при загрузке недоверенного файла. Для опубликованных весов полезны безопасный тензорный формат, hash и проверка источника. Формат не защищает от намеренно вредоносного поведения самой модели.

PyTorch и ComfyUI

ComfyUI использует PyTorch для тензорных операций и запуска моделей. Ноды собирают pipeline, а библиотека выполняет вычисления под ним.

Поэтому ошибки памяти, dtype, устройства и несовместимых kernels часто приходят из нижнего слоя, даже если видны как ошибка одной ноды. Версии ComfyUI, PyTorch, драйвера и custom nodes рассматриваются вместе.

Экспорт и развёртывание

Для production модель можно оставить в Python runtime или преобразовать в более ограниченное представление для другого движка. Экспорт требует фиксировать поддерживаемые операции, динамические формы и preprocessing.

Успешный export ещё не доказывает эквивалентность. Сравниваются выходы на контрольных данных, производительность после прогрева и поведение на крайних формах входа.

С чем часто путают

  • PyTorch и CUDA. PyTorch — библиотека, CUDA — один из backend для устройств NVIDIA.
  • PyTorch и модель. Библиотека выполняет операции; веса и архитектура приходят отдельно.
  • Eager и медленный. Eager описывает способ исполнения Python-графа, а тяжёлые kernels могут быть хорошо оптимизированы.
  • Compile и export. Compile оптимизирует выполнение, export создаёт представление для развёртывания; маршруты и ограничения различаются.
  • Checkpoint и готовое приложение. Нужны preprocessing, конфигурация, tokenizer или VAE и код инференса.

Частые ошибки

  • Не обнулять градиенты. Они накапливаются между backward.
  • Забыть eval-режим. Dropout и normalization ведут себя иначе.
  • Смешать устройства. Tensor на CPU нельзя без переноса использовать в операции с tensor на другом device.
  • Считать shape «очевидным». Broadcasting может выдать корректный по синтаксису, но неверный по смыслу результат.
  • Мерить первый compiled run. В него входит подготовка и компиляция.
  • Загружать недоверенный pickle. Такой файл может выполнить код.

Частые вопросы

PyTorch работает только с GPU? Нет. CPU — полноценный backend, а доступность других ускорителей зависит от сборки и поддерживаемых операций.

Нужно ли использовать torch.compile? Нет. Он полезен, если измерения показывают выигрыш без регрессий. Для отладки и динамического кода eager может быть проще.

Чем Tensor отличается от NumPy array? Tensor интегрирован с autograd, устройствами и нейросетевыми модулями. Между форматами можно обмениваться данными, но правила памяти и dtype нужно учитывать.

Где искать правильную команду установки? В официальном selector PyTorch для своей ОС, Python и backend. Фиксированная команда в вечной статье быстро устареет.

Главное

PyTorch соединяет тензоры, autograd и обычный Python-код. Он удобен и для исследования, и для production, но каждый следующий слой — mixed precision, compile, distributed или export — добавляет свои условия. Надёжный путь начинается с понятного eager baseline, тестов и измерений на точной модели и устройстве.