Изучить PyTorch легко, но можете ли вы изучить внутренности PyTorch? Недавно Кристиан, имеющий 14-летний опыт работы с машинным обучением, представил механизм ядра PyTorch. Хотя эти знания не требуются в реальном использовании, изучение ядра PyTorch может значительно улучшить нашу интуицию и понимание кода, и именно великие боги копают нижний слой~
Разработчики PyTorch заявили, чтоPytorchФилософия состоит в том, чтобы решить насущную проблему, состоящую в том, чтобы построить и запустить наш вычислительный граф на лету. Это как раз подходит для философии программирования Python, которую можно запустить в Jupyter Notebook, как только она будет определена, поэтому рабочий процесс PyTorch очень близок к библиотеке научных вычислений Python.NumPy.
Кристиан показывает, что многое из того, что делает PyTorch таким удобным, связано с его «генами» — внутренней работой. В этом отчете не описывается, как использовать базовые модули PyTorch или как обучать нейронную сеть с помощью PyTorch, Кристиан фокусируется на том, как представить основной механизм PyTorch в интуитивно понятной форме, то есть на том, как работает каждый модуль.
Кристиан сказал на Reddit, что этот отчет не может загрузить видео речи из-за проблемы с записью видео, поэтому на данный момент можно поделиться только речью PPT. Но недавно Кристиан выступит с другим докладом на эту тему, так что мы можем с нетерпением ждать следующего видео, знакомящего с PyTorch.
Адрес выступления PPT:Speaker deck.com/per one/py to…
Облачный адрес Baidu:disk.baidu.com/yes/1AA E0i1…
Основная повестка дня этого доклада состоит в следующем: в основном он знакомит с лежащим в основе операционным механизмом с точки зрения тензоров и JIT-компилятора:
Прежде чем обсуждать механизм каждого компонента PyTorch, нам нужно понять общий рабочий процесс. PyTorch использует парадигму под названием императив/нетерпеливый, где каждая строка кода требует построения графа для определения части полного вычислительного графа. Даже если полный вычислительный граф не был построен, мы можем выполнять эти небольшие вычислительные графы как компоненты независимо друг от друга.Этот динамический вычислительный граф называется подходом «определение за выполнением».
На самом деле, новички могут научиться использовать после понимания всего процесса, но лежащий в основе механизм помогает понять и контролировать код.
Тензор
Концептуально тензор — это обобщение векторов и матриц, а тензор в PyTorch — это многомерная матрица, элементы которой имеют один и тот же тип данных. Хотя интерфейс PyTorch — это Python, нижний уровень в основном реализован на C++, а в Python интеграция кода C++ обычно называется «расширением».
Потому что тензоры в основном несут данные и выполняют вычисления. Для вычисления тензора в PyTorch используется самая низкоуровневая и базовая библиотека тензорных операций ATen, а для автоматического дифференцирования используется Autograd, который также построен на платформе ATen.
Объект Python
Чтобы определить новый тип объекта Python в C/C++, вам необходимо определить следующую структуру, подобную THPVariable. Первый из них, макрос PyObject_HEAD, направлен на стандартизацию объектов Python и расширяется до другой структуры, содержащей указатель на объект типа и поле со счетчиком ссылок.
В Python API есть два дополнительных макроса, называемые Py_INCREF() и Py_DECREF(), которые можно использовать для увеличения и уменьшения счетчика ссылок на объекты Python.
В PyThon все является объектом, например, переменные, структуры данных и функции.
НУЛЕВОЕ КОПИРОВАНИЕ Тензор
Поскольку использование массивов Numpy настолько распространено, нам нужно конвертировать между тензорами Numpy и PyTorch. Таким образом, PyTorch предоставляет два метода from_numpy() и numpy() для преобразования между массивами NumPy и тензорами PyTorch.
Поскольку стоимость тензорного хранилища относительно велика, если мы скопируем данные во время описанного выше процесса преобразования, использование памяти будет очень большим. Одним из преимуществ тензора PyTorch является то, что он хранит указатель на внутренний массив NumPy, а не копирует его напрямую. Это означает, что PyTorch будет владеть этими данными и использовать ту же область памяти, что и объект массива NumPy.
Форма Zero-Copying действительно экономит много памяти, но различие между операциями на месте и стандартными операциями может быть немного размытым, как показано выше. Если вы используете np_array = np_array +1.0, память torch_array не изменится, но если вы используете np_array += 1.0, память torch_array изменится.
Распределение памяти CPU/GPU
Фактические необработанные данные тензора сохраняются не сразу в структуре тензора, а в том, что мы называем «хранилищем», которое является частью структуры тензора. Как правило, тензорное хранилище может храниться в памяти компьютера (ЦП) или видеопамяти (ГП) через Распределитель.
THE BIG PICTURE
Наконец, структура THTensor объема требований PyTorch может быть показана на следующем рисунке. Основной структурой THTensor являются тензорные данные, которые сохраняют такую информацию, как размер/шаги/размеры/смещения/, а также хранят THStorage.
JIT
Поскольку PyTorch находится в режиме «точно в срок», это означает, что его легко отлаживать или проверять код и т. д. В PyTorch 1.0 он впервые представил torch.jit, набор инструментов компиляции, основная цель которых — преодолеть разрыв между исследовательским и производственным развертыванием. JIT включает в себя язык Torch Script, который является подъязыком Python. Код, использующий Torch Script, может быть очень сильно оптимизирован и может быть сериализован для использования в последующих API-интерфейсах C++.
Ниже приведен общий режим Eager, работающий с Python, который также может работать в режиме сценария. Режим Eager подходит для создания прототипов и экспериментов, а режим Script подходит для оптимизации и развертывания.
Так зачем использовать TORCHSCRIPT? Кристиан приводит следующие причины:
Основной JIT-процесс PyTorch
Как показано ниже, JIT в основном будет вводить код или абстрактное синтаксическое дерево Python (AST), где AST будет использовать древовидную структуру для представления синтаксической структуры исходного кода Python. Синтаксический анализ может заключаться в анализе синтаксических структур и вычислительных графов, затем обнаружении синтаксиса с последующей оптимизацией кода и, наконец, просто компиляции и выполнения.
Где оптимизация может использоваться для моделирования вычислительных графов, таких как развертывание циклов и т. д. В приведенной ниже оптимизации Peephole компилятор повышает производительность за счет объединения характеристик инструкций ЦП и некоторых правил преобразования сгенерированного кода только в одном или нескольких базовых блоках. Оптимизация глазка также может повысить производительность кода за счет общего анализа и перевода инструкций.
Удвоенное среднее значение матрицы, показанной ниже, равно самой матрице, которую необходимо оптимизировать.
воплощать в жизнь
Так же, как интерпретатор Python может выполнять код, PyTorch также имеет интерпретатор, который выполняет инструкции промежуточного представления во время процесса JIT:
Наконец, Кристиан также представил множество внутренних операционных механизмов, но, поскольку все они сложны, и пока нет видеообъяснения, читатели могут взглянуть на конкретный контент PPT.