Экосистема TensorFlow содержит ряд компиляторов и оптимизаторов, работающих на различных уровнях программного и аппаратного стека. Для тех, кто использует Tensorflow ежедневно, этот многоуровневый стек может порождать трудные для понимания ошибки, как времени компиляции, так и в рантайме, связанные с использованием разного рода железа (GPU, TPU, мобильных платформ и пр.)
Эти компоненты, начиная с графа Tensorflow, могут быть представлены в виде такой диаграммы:

На самом деле всё сложнее
На этой диаграмме мы можем видеть, что графы Tensorflow могут быть запущены несколькими разными способами
Например:
Также существуют более сложные способы, включающие в себя множество проходов оптимизации на каждом слое, как, например, в фреймворке Grappler, который оптимизирует операции в TensorFlow.
Несмотря на то, что эти различные реализации компиляторов и промежуточных представлений улучшают производительность, их разнообразие представляет проблему для конечных пользователей, такие, как сбивающие с толку сообщения об ошибках при сопряжении этих подсистем. Также создатели новых программных и аппаратных стеков должны подстраивать проходы оптимизации и преобразования для каждого нового случая.
И в силу всего этого, мы рады анонсировать MLIR, Многоуровненвое Промежуточное Представление (Multi-Level Intermediate Representation). Это формат промежуточ��ого представления и библиотеки компиляции, предназначенные для использования между представлением модели и низкоуровневым компилятором, генерирующим аппаратно-зависимый код. Представляя MLIR, мы хотим дать дорогу новым исследованиям в разработке оптимизирующих компиляторов и реализациям компиляторов, построенных на компонентах промышленного качества.
Мы ожидаем, что MLIR будет интересен многим группам, включая:
MLIR, по сути, гибкая инфраструктура для современных оптимизирующих компиляторов. Это значит, что она состоит из спецификации промежуточного представления (IR) и набора инструментов для преобразования этого представления. Когда мы говорим о компиляторах, переход от более высокоуровневого представления к более низкоуровневому называется «спуском» (lowering), и мы будем использовать этот термин в дальнейшем.
MLIR построен под влиянием LLVM и беззастенчиво заимствует многие хорошие идеи из него. Он имеет гибкую систему типов, и предназначен для представления, анализа и преобразования графов, объединяя множество уровней абстракции в одном уровне компиляции. Эти абстракции включают в себя операции Tensorflow, вложенные регионы полиэдральных циклов, инструкции LLVM, а также операции и типы с фиксированной точкой.
Для того, чтобы разделить различные программные и аппаратные таргеты, MLIR имеет «диалекты», включающие в себя:
Каждый диалект содержит набор определённых операций, с использованием инвариантов, таких, как: «это бинарный оператор, и его вход и выход имеют один и тот же тип».
MLIR не имеет фиксированного и встроенного списка глобальных intrinsic-операций. Диалекты могут определять полностью кастомные типы, и таким образом MLIR может моделировать такие вещи, как систему типов LLVM IR (имеющую агрегаты первого класса), абстракции доменных языков, такие, как квантизованные типы, важные для оптимизированных под ML ускорителей, и, в будущем, даже систему типов Swift или Clang.
Если вы хотите присоединить к этой системе новый низкоуровневый компилятор, вы можете создать новый диалект и спуск с диалекта графа TensorFlow на ваш диалект. Это упрощает путь для разработчиков аппаратного обеспечения и разработчиков компилятора. Вы можете нацелить диалект на различные уровни одной и той же модели, высокоуровневые оптимизаторы будут отвечать за специфические части IR.
Для исследователей компиляторов и разработчиков фреймворков, MLIR позволяет вам создать преобразования на каждом уровне, вы можете определять свои собственные операции и абстракции в IR, позволяя вам лучше моделировать ваши прикладные задачи. Таким образом, MLIR — это нечто большее, чем чистая инфраструктура компилятора, которой является LLVM.
Хотя MLIR работает как компилятор для ML, он также позволяет использовать технологии машинного обучения! Это очень важно для инже��еров, разрабатывающих численные библиотеки, и не могут обеспечить поддержку всего многообразия ML-моделей и аппаратного обеспечения. Гибкость MLIR облегчает исследования стратегий спуска кода при переходе между уровнями абстракции.
Мы открыли GitHub-репозиторий и приглашаем всех заинтересованных (изучите наше руководство!). Мы будем выпускать нечто большее, чем этот набор инструментов — спецификации диалектов TensorFlow и TF Lite, в ближайшие месяцы. Мы можем рассказать вам больше, для того, чтобы узнать подробности, см. презентацию Криса Латтнера и наш README на Github.
Если вы хотите быть в курсе всех вещей, относящихся к MLIR, присоединяйтесь к нашему новому списку рассылки, который в ближайшее время будет сфокусирован на анонсах будущих релизов нашего проекта. Оставайтесь с нами!
Эти компоненты, начиная с графа Tensorflow, могут быть представлены в виде такой диаграммы:

На самом деле всё сложнее
На этой диаграмме мы можем видеть, что графы Tensorflow могут быть запущены несколькими разными способами
примечание
В TensorFlow 2.0, графы могут быть неявными, жадное исполнение может запускать операции индивидуально, по группам, или на полном графе. Эти графы или фрагменты графа должны быть оптимизированы и выполнены.
Например:
- Посылаем графы исполнителю Tensorflow, который вызывает написанные вручную специализированные ядра
- Преобразуем их в XLA HLO (XLA High-Level Optimizer representation) — высокоуровневое представление оптимизатора XLA, который, в свою очередь, может вызывать компилятор LLVM для CPU или GPU, или продолжать использовать XLA для TPU, или комбинировать их.
- Преобразуем их в TensorRT, nGraph, или другой формат для специализированного набора инструкций, реализованного в железе.
- Преобразуем их в формат TensorFlow Lite, выполняемый в рантайме TensorFlow Lite, или преобразуемый в код для запуска на GPU или DSP через Android Neural Networks API (NNAPI) или подобным образом.
Также существуют более сложные способы, включающие в себя множество проходов оптимизации на каждом слое, как, например, в фреймворке Grappler, который оптимизирует операции в TensorFlow.
Несмотря на то, что эти различные реализации компиляторов и промежуточных представлений улучшают производительность, их разнообразие представляет проблему для конечных пользователей, такие, как сбивающие с толку сообщения об ошибках при сопряжении этих подсистем. Также создатели новых программных и аппаратных стеков должны подстраивать проходы оптимизации и преобразования для каждого нового случая.
И в силу всего этого, мы рады анонсировать MLIR, Многоуровненвое Промежуточное Представление (Multi-Level Intermediate Representation). Это формат промежуточ��ого представления и библиотеки компиляции, предназначенные для использования между представлением модели и низкоуровневым компилятором, генерирующим аппаратно-зависимый код. Представляя MLIR, мы хотим дать дорогу новым исследованиям в разработке оптимизирующих компиляторов и реализациям компиляторов, построенных на компонентах промышленного качества.
Мы ожидаем, что MLIR будет интересен многим группам, включая:
- исследователям компиляторов, а также практикам, желающим оптимизировать производительность и потребление памяти моделей машинного обучения;
- производителям аппаратного обеспечения, ищущим способ объединить с Tensorflow своё железо, такое, как TPU, мобильные нейропроцессоры в смартфонах, и другие кастомные ASIC-и;
- людям, которые хотят дать языкам программирования преимущества, предоставляемые оптимизирущими компиляторами и аппаратными ускорителями;
Что такое MLIR?
MLIR, по сути, гибкая инфраструктура для современных оптимизирующих компиляторов. Это значит, что она состоит из спецификации промежуточного представления (IR) и набора инструментов для преобразования этого представления. Когда мы говорим о компиляторах, переход от более высокоуровневого представления к более низкоуровневому называется «спуском» (lowering), и мы будем использовать этот термин в дальнейшем.
MLIR построен под влиянием LLVM и беззастенчиво заимствует многие хорошие идеи из него. Он имеет гибкую систему типов, и предназначен для представления, анализа и преобразования графов, объединяя множество уровней абстракции в одном уровне компиляции. Эти абстракции включают в себя операции Tensorflow, вложенные регионы полиэдральных циклов, инструкции LLVM, а также операции и типы с фиксированной точкой.
Диалекты MLIR
Для того, чтобы разделить различные программные и аппаратные таргеты, MLIR имеет «диалекты», включающие в себя:
- TensorFlow IR, включающий в себя всё то, что возможно сделать в графах TensorFlow
- XLA HLO IR, разработанный для того, чтобы получить все преимущества, предоставляемые компилятором XLA, на выходе которого мы можем получит код для TPU, и не только.
- Экспериментальный аффинный диалект, предназначенный специально для полиэдральных представлений и оптимизаций
- LLVM IR, 1:1 совпадающий с собственным представлением LLVM, позволяющий MLIR генерировать код для GPU и CPU с помощью LLVM.
- TensorFlow Lite, предназначенный для генерации кода для мобильных платформ
Каждый диалект содержит набор определённых операций, с использованием инвариантов, таких, как: «это бинарный оператор, и его вход и выход имеют один и тот же тип».
Расширения MLIR
MLIR не имеет фиксированного и встроенного списка глобальных intrinsic-операций. Диалекты могут определять полностью кастомные типы, и таким образом MLIR может моделировать такие вещи, как систему типов LLVM IR (имеющую агрегаты первого класса), абстракции доменных языков, такие, как квантизованные типы, важные для оптимизированных под ML ускорителей, и, в будущем, даже систему типов Swift или Clang.
Если вы хотите присоединить к этой системе новый низкоуровневый компилятор, вы можете создать новый диалект и спуск с диалекта графа TensorFlow на ваш диалект. Это упрощает путь для разработчиков аппаратного обеспечения и разработчиков компилятора. Вы можете нацелить диалект на различные уровни одной и той же модели, высокоуровневые оптимизаторы будут отвечать за специфические части IR.
Для исследователей компиляторов и разработчиков фреймворков, MLIR позволяет вам создать преобразования на каждом уровне, вы можете определять свои собственные операции и абстракции в IR, позволяя вам лучше моделировать ваши прикладные задачи. Таким образом, MLIR — это нечто большее, чем чистая инфраструктура компилятора, которой является LLVM.
Хотя MLIR работает как компилятор для ML, он также позволяет использовать технологии машинного обучения! Это очень важно для инже��еров, разрабатывающих численные библиотеки, и не могут обеспечить поддержку всего многообразия ML-моделей и аппаратного обеспечения. Гибкость MLIR облегчает исследования стратегий спуска кода при переходе между уровнями абстракции.
Что дальше
Мы открыли GitHub-репозиторий и приглашаем всех заинтересованных (изучите наше руководство!). Мы будем выпускать нечто большее, чем этот набор инструментов — спецификации диалектов TensorFlow и TF Lite, в ближайшие месяцы. Мы можем рассказать вам больше, для того, чтобы узнать подробности, см. презентацию Криса Латтнера и наш README на Github.
Если вы хотите быть в курсе всех вещей, относящихся к MLIR, присоединяйтесь к нашему новому списку рассылки, который в ближайшее время будет сфокусирован на анонсах будущих релизов нашего проекта. Оставайтесь с нами!
