Глубокое обучение
Фреймворки: PyTorch vs TensorFlow
2019 год. Google публично признаёт что PyTorch побеждает в research и выпускает TensorFlow 2.0 с полностью переработанным API. Tesla Autopilot мигрирует с TF на PyTorch. Hugging Face строит весь хаб на PyTorch. Кажется, исход решён. Но TFLite работает на 3 миллиардах мобильных устройств, а TF Serving держит production в Google - и его оттуда никто не выкидывает.
- **Meta (Facebook):** PyTorch используется для рекомендательной системы, обрабатывающей триллион inference'ов в день
- **Google:** TensorFlow работает в поиске, Gmail, Google Photos, YouTube - миллиарды запросов ежедневно
- **Tesla Autopilot:** начинали на TensorFlow, перешли на PyTorch - показательная история миграции в индустрии
Ян Лекун и борьба за динамический граф
В 2016 году Сумит Чинтала из FAIR написал PyTorch за несколько недель, опираясь на идеи Torch (библиотека на Lua) и Chainer (японский фреймворк с define-by-run). Вся команда FAIR была уверена: исследователи не хотят Sessions и placeholder'ов - они хотят писать Python. Оказалось, что интуиция верная. За два года PyTorch вышел на первое место в академических публикациях. Это стандартный паттерн в ML: побеждает не самый производительный инструмент, а самый эргономичный.
Предварительные знания
PyTorch: define-by-run
**2016 год. Facebook AI Research выпускает PyTorch** - фреймворк, который перевернул представление о том, как должен выглядеть код нейронных сетей. Вместо описания графа вычислений на специальном языке (как в TensorFlow 1.x), PyTorch позволил писать нейронные сети как обычный Python-код. Этот подход называется **define-by-run**: граф вычислений строится на лету при каждом forward pass.
**Философия PyTorch** - «Python first». Стандартные конструкции Python (if, for, print) работают внутри модели. Можно ставить breakpoints, использовать pdb, печатать промежуточные значения. Для исследователей это была революция после «чёрного ящика» TensorFlow 1.x. К 2023 году - более 80% статей на NeurIPS и ICML написаны на PyTorch.
**Экосистема PyTorch:** torchvision (компьютерное зрение), torchaudio (аудио), torchtext (NLP), PyTorch Lightning (высокоуровневая обёртка), Hugging Face Transformers (предобученные модели). Meta использует PyTorch для рекомендательной системы, обрабатывающей триллион inference'ов в день.
**model.train() и model.eval()** - не забывать переключать! В train-режиме dropout случайно зануляет нейроны, batch norm использует статистику текущего batch'а. В eval-режиме dropout отключён, batch norm использует накопленную статистику. Без переключения результаты валидации будут нестабильными.
Что означает подход define-by-run в PyTorch?
TensorFlow: от графа к Keras
**TensorFlow появился в 2015 году из недр Google Brain.** В первой версии (TF 1.x) философия была противоположна PyTorch: сначала опишите computational graph на специальном языке, потом запустите его в Session. Этот подход - **define-and-run** - давал возможности для оптимизации, но делал отладку мучительной.
**TensorFlow 2.0 (2019) кардинально изменил подход.** Google признал, что ergonomics PyTorch победил, и сделал три ключевых изменения: eager execution по умолчанию, Keras как основной API, и упрощение кода. Tesla Autopilot начинали на TensorFlow, перешли на PyTorch - показательная история миграции.
| Компонент | Назначение | Аналог PyTorch |
|---|---|---|
| TensorFlow Core | Низкоуровневые операции с тензорами | torch |
| Keras | Высокоуровневый API для моделей | torch.nn + Lightning |
| TFLite | Деплой на мобильные устройства | PyTorch Mobile / ExecuTorch |
| TF.js | Запуск в браузере | ONNX.js |
| TF Serving | Production inference сервер | TorchServe |
| TFX | ML pipeline (от данных до деплоя) | MLflow + Kubeflow |
**Главное преимущество TensorFlow - экосистема для production.** TFLite работает на миллиардах мобильных устройств. TF.js - в браузере без сервера. TF Serving обрабатывает миллионы запросов в секунду в Google. Google Search, Gmail, Google Photos, YouTube - всё на TensorFlow.
**Не путать TF 1.x и TF 2.x** - это практически разные фреймворки. Многие жалобы на TensorFlow относятся к версии 1.x. TF 2 с Keras - современный и удобный инструмент. При чтении старых туториалов обращать внимание на версию.
Какое главное изменение принёс TensorFlow 2.0?
Eager Execution: вычисляй сразу
**Eager execution** - режим, при котором операции выполняются немедленно, как обычный Python. Написали `a + b` - получили результат прямо сейчас, а не описание будущего вычисления. PyTorch работал так с самого начала. TensorFlow перешёл на этот режим по умолчанию в версии 2.0.
**Главное преимущество eager execution - отладка.** Можно вставить print() в любое место модели и увидеть реальные значения. Поставить breakpoint в pdb. Использовать стандартные инструменты Python для профилирования. Это критически важно для research, где модели экспериментальные и полные багов.
| Свойство | Eager Execution | Graph Mode |
|---|---|---|
| Вычисление | Немедленное | Отложенное (compile -> run) |
| Отладка | print, pdb, breakpoints | Сложнее - нужны специальные инструменты |
| Python control flow | if/for работают нативно | Нужны tf.cond / tf.while_loop (TF1) |
| Скорость | Базовая | Оптимизированная (operator fusion и т.д.) |
| Использование | Research, прототипирование | Production, деплой |
**Правило большого пальца:** использовать eager execution при разработке и отладке. Переходить на graph mode (torch.compile, tf.function) когда модель готова к production. Большинство исследователей никогда не покидают eager mode - оптимизация нужна только при масштабировании.
Почему eager execution удобнее для отладки нейронных сетей?
Graph Mode: оптимизация для production
**Eager execution удобен, но медленнее.** Каждая операция вызывает Python-интерпретатор, создаёт промежуточные тензоры, отправляет команды на GPU поодиночке. **Graph mode** анализирует весь computational graph целиком и оптимизирует его: объединяет операции (operator fusion), убирает лишние вычисления, оптимизирует использование памяти.
**Какие оптимизации делает компилятор?** Operator fusion - объединение нескольких операций в одну (Linear + ReLU = одно ядро GPU вместо двух). Memory planning - переиспользование памяти тензоров, которые больше не нужны. Constant folding - предвычисление статических выражений. Эти оптимизации невозможны в eager mode, потому что фреймворк видит только одну операцию за раз.
**torch.compile() не всегда ускоряет.** Первый вызов медленнее из-за компиляции (может занять минуты). Для маленьких моделей overhead компиляции может не окупиться. Динамические формы тензоров (разная длина batch'а) могут вызвать recompilation. Начинать без compile, добавлять когда нужна скорость.
**Практический совет 2026 года:** для нового проекта начинать с PyTorch. Для деплоя на мобильных - рассмотреть ONNX или ExecuTorch. Для браузера - TensorFlow.js или ONNX Runtime Web. Для максимальной inference скорости на NVIDIA - TensorRT. «Войны фреймворков» закончились - использовать то, что подходит задаче.
PyTorch - для research, TensorFlow - для production. Каждый фреймворк подходит только для своей ниши.
Это утверждение устарело. PyTorch 2.0 с torch.compile(), TorchServe и ExecuTorch закрыл разрыв в production. TensorFlow 2.x с Keras и eager execution стал удобнее для research. Оба фреймворка могут использоваться для полного цикла.
Исторически (2016-2019) PyTorch был удобнее для экспериментов, а TensorFlow имел более зрелую production-экосистему. Но с 2020 года оба фреймворка активно заимствовали лучшие идеи друг у друга. Meta и Google используют свои фреймворки для обоих сценариев.
Что делает torch.compile() под капотом?
Ключевые идеи
- **PyTorch** - define-by-run, pythonic API, стандарт для research (80%+ статей). Код читается как обычный Python
- **TensorFlow** - от статического графа (TF1) к eager execution и Keras (TF2). Сильная production-экосистема (TFLite, TF.js, TF Serving)
- **Eager execution** - операции выполняются сразу. Удобно для отладки и research. По умолчанию в обоих фреймворках
- **Graph mode** (torch.compile, tf.function) - оптимизирует вычисления: operator fusion, memory planning. Нужен для production
Связанные темы
Выбор фреймворка - решение, которое потом тянется через весь pipeline:
- Backpropagation — PyTorch autograd и TF GradientTape - разные реализации одного алгоритма
- CNN архитектуры — В следующих уроках строятся свёрточные сети на PyTorch
- MLOps Pipeline — Деплой модели зависит от фреймворка: TorchServe vs TF Serving vs ONNX
Вопросы для размышления
- Почему PyTorch победил в research, несмотря на то что TensorFlow вышел раньше и имел поддержку Google?
- torch.compile() и tf.function() конвертируют eager code в оптимизированный граф. Зачем тогда вообще нужен eager mode - почему бы всегда не компилировать?
- Если начинать новый ML-проект сегодня, какой фреймворк выбрать и почему?
Связанные уроки
- dl-02 — Backpropagation - алгоритм, который PyTorch autograd и TF GradientTape реализуют по-разному
- dl-04 — CNN архитектуры строятся на PyTorch в последующих уроках
- ml-09-gradient-descent — Оптимизаторы Adam/SGD - конкретные реализации gradient descent в этих фреймворках
- ml-45-mlops-pipeline — Деплой модели зависит от фреймворка: TorchServe vs TF Serving vs ONNX
- dl-01 — Понятие computational graph введено в первом уроке DL
- ml-28-optimizers — Оптимизаторы помогают выбрать нужный API фреймворка
- ml-25-neural-networks