newsmode
search
Меню
arrow_back Назад

ML Serving – Hamel’s Blog - Hamel Husain

auto_awesomeКраткое саммари

Статья Hamel Husain посвящена обзору инструментов и подходов к serving (развёртыванию) ML-моделей. Автор разбирает inference-серверы (Torch Serve, TFServe, KServe, Nvidia Triton), отмечая Nvidia Triton как самый популярный по опросу ~20+ специалистов. Большая часть текста посвящена ML-компиляторам: терминологии (kernel fusion, IR, graph lowering, graph breaks), типичным источникам путаницы (например, разница между Triton от Nvidia и Triton от OpenAI), а также конкретным стэкам — TorchDynamo+JIT+TorchInductor, TensorRT, ONNX, OpenAI Triton, ApacheTVM (включая адаптивный autoTVM) и WASM. Автор подчёркивает важность вызова torch.compile() и приводит пример OctoML, чей autoTVM-оптимизатор оказался на ~30% быстрее ручной оптимизации команды Apple Core ML для чипа M1. В конце даны рекомендации, кого читать (Chris Lattner, Horace He, Mark Saroufim), и ссылки на материалы Chip Huyen.

Types of Optimization

Типы оптимизации

This table is inspired by this talk where Mark Saurofim outlines categories of optimization relevant to model serving.

Эта таблица вдохновлена этим докладом, в котором Mark Saurofim описывает категории оптимизации, относящиеся к serving моделей.

When considering model serving, the discussion tends to be focused on inference servers. However, one underrated topic is the importance ML compilers play (which is discussed in later sections).

Когда речь заходит о serving моделей, обсуждение обычно сосредоточено на inference-серверах. Однако одна недооценённая тема — это та роль, которую играют ML-компиляторы (обсуждается в следующих разделах).

Inference Servers

Inference-серверы

Below are the inference servers I would pay attention to. Nvidia Triton seems to be the most popular/robust according to ~20+ professionals I’ve spoken with.

Ниже перечислены inference-серверы, на которые стоит обратить внимание. Nvidia Triton, по мнению ~20+ профессионалов, с которыми я общался, выглядит самым популярным/надёжным.

  • Torch Serve
  • TFServe
  • KServe
  • Nvidia Triton
  • Torch Serve TFServe KServe Nvidia Triton

    Here are detailed notes with code examples on inference servers I’ve explored. I explore two inference servers: TFServing and TorchServe, as well as a general-purpose REST API server for model serving with fastapi.

    Вот подробные заметки с примерами кода по inference-серверам, которые я изучал. Я рассматриваю два inference-сервера: TFServing и TorchServe, а также REST API сервер общего назначения для serving моделей с использованием fastapi.

    ML Compilers

    ML-компиляторы

    Why You Should Care About Compilers

    Почему вам стоит интересоваться компиляторами

  • Computing on edge devices can save you tons of money (and potentially complexity).
  • Re-writing models to work on edge devices is costly b/c that requires specialists to execute – good compilers can make this easy or obviate that transition by helping you translate your high-level framework code into hardware-specific code.
  • Sometimes, cloud computing is not an option (you have to run on a device).
  • New types of architectures can perform very poorly on hardware without the right compilers, even when those models are significantly smaller and simpler than established models. One example is shared by Google researchers who tried to implement capsule networks.
  • Translating framework code to various backend hardware is a non-trivial problem, as illustrated in the below graph (growing number of frameworks + hardware/devices):
  • Вычисления на edge-устройствах могут сэкономить кучу денег (и потенциально снизить сложность). Переписывание моделей под работу на edge-устройствах — дорогостоящая задача, потому что требует специалистов; хорошие компиляторы могут облегчить этот переход или вовсе сделать его ненужным, помогая транслировать код на высокоуровневом фреймворке в код, специфичный для конкретного железа. Иногда облачные вычисления — не вариант (приходится запускаться на устройстве). Новые типы архитектур могут очень плохо работать на железе без подходящих компиляторов, даже если эти модели существенно меньше и проще устоявшихся. Один такой пример описан исследователями из Google, которые пытались реализовать capsule networks. Перевод кода фреймворка на различное бэкенд-железо — нетривиальная задача, что иллюстрирует график ниже (растёт количество фреймворков + железа/устройств):

    From Chip Huyen’s A Freindly Introduction to Machine Learning Compilers

    Terminology

    Терминология

    It’s easy to get lost in the terminology of compilers. Here are some terms that are important to understand:

    В терминологии компиляторов легко запутаться. Вот некоторые важные для понимания термины:

  • Kernel Fusion: this is the process of combining multiple operations into a single operation. For example, a convolution followed by a ReLU can be combined into a single operation.
  • Intermediate Representation (IR): The IR is a representation of a model that’s independent of a framework like Pytorch. These IRs are often JSON, YAML, or a string that encodes model structure, weights, and so on. These IRs are eventually translated into programs that can be executed and are often optimized toward specific hardware.
  • Graph Lowering: This is the process of translating one IR to another. For example, a model represented in the ONNX IR can be lowered to a model in TensorRT IR. The reason for doing this is to translate one IR to one that allows a specific compiler to perform domain/hardware-specific optimizations. Different compilers can optimize different types of things and offer different goals. For example, ONNX’s primary goal is to be a portable IR, while TensorRT’s primary goal is to optimize for inference. The reason it’s called Graph lowering is that a model be represented as a graph, and you “lower” the graph representation consecutively towards something that can be made into machine code. Compilers can process IRs in different phases such that the IR is simplified/optimized, that a back-end will use to generate machine code.
  • Front-End: This refers to part of the Compiler Stack that translates a programming language into an IR.
  • Back-End: This refers to part of the Compiler Stack that translates an IR into machine code. You can compose different front-ends with different back-ends through “middle-ends” that translate IRs from one to another (also known as “lowering” or “graph lowering”).
  • Graph Breaks: When you represent a model as a graph via an intermediate representation (IR) there are pieces of code that might not fit into a graph form, like if/else statements. When this happens, you will have a graph break, where you will have to split your program into several graphs. Only the parts that can be represented as a graph can usually be optimized by the compiler. Depending on the framework you are using, either your or the framework will have to stitch all the graphs together in a way that represents the original program. Graph breaks usually incur a performance penalty, so it’s important to minimize them.
  • Kernel Fusion: процесс объединения нескольких операций в одну. Например, свёртку, за которой следует ReLU, можно объединить в одну операцию. Intermediate Representation (IR): IR — это представление модели, не зависящее от фреймворка вроде PyTorch. Эти IR часто представляют собой JSON, YAML или строку, кодирующую структуру модели, веса и т. д. Эти IR в итоге транслируются в исполняемые программы и часто оптимизируются под конкретное железо. Graph Lowering: процесс перевода одного IR в другой. Например, модель, представленную в IR ONNX, можно понизить (lower) в модель в IR TensorRT. Смысл в том, чтобы перевести один IR в такой, который позволит конкретному компилятору выполнить оптимизации, специфичные для домена/железа. Разные компиляторы могут оптимизировать разные вещи и преследовать разные цели. Например, главная цель ONNX — быть переносимым IR, а главная цель TensorRT — оптимизация inference. «Graph lowering» назван так потому, что модель можно представить в виде графа, и вы последовательно «понижаете» представление этого графа в сторону того, из чего можно сделать машинный код. Компиляторы могут обрабатывать IR в разных фазах, так что IR упрощается/оптимизируется, и бэкенд использует его для генерации машинного кода. Front-End: часть Compiler Stack, которая транслирует язык программирования в IR. Back-End: часть Compiler Stack, которая транслирует IR в машинный код. Можно комбинировать разные фронтенды с разными бэкендами через «middle-end», которые транслируют IR из одного в другой (это также называют «lowering» или «graph lowering»). Graph Breaks: когда вы представляете модель в виде графа через IR, в коде могут быть участки, которые не вписываются в графовую форму, — например, конструкции if/else. В таких случаях возникает graph break, и программу приходится разбивать на несколько графов. Обычно компилятор может оптимизировать только те части, которые представимы в виде графа. В зависимости от используемого фреймворка либо вы, либо сам фреймворк должны будете «сшить» все графы так, чтобы они отражали исходную программу. Graph breaks обычно влекут потерю производительности, поэтому их важно минимизировать.

    Common Sources of Confusion

    Частые источники путаницы

    The Compiler Stack

    Compiler Stack

    It can often be ambiguous when someone refers to a compiler if they are referring to a front-end that generates the IR, the back-end that generates/executes the code, or the entire compiler stack as a whole. For example, ONNX has both an intermediate representation IR and a runtime. The IR is a specification (a string) that allows you to represent a model in a way that’s independent of a framework. The ONNX Runtime is a backend that allows you to execute models represented by the ONNX IR on a variety of hardware and from various languages (Python, C++, Java, JS, etc.).

    Часто бывает неоднозначно, что человек имеет в виду под словом «компилятор»: фронтенд, генерирующий IR, бэкенд, генерирующий/исполняющий код, или весь компиляторный стек целиком. Например, у ONNX есть и IR, и runtime. IR — это спецификация (строка), которая позволяет представить модель независимо от фреймворка. ONNX Runtime — это бэкенд, который позволяет исполнять модели, представленные в ONNX IR, на различном железе и из различных языков (Python, C++, Java, JS и т. д.).

    The term “compiler” is often overloaded. Understanding the context in which the term is used can be helpful for understanding documentation. For example, Torch Dynamo is a front-end (often referred to as a “graph acquisition tool”) that produces an IR. The user can then lower this IR to a back-end to another compiler stack like C++ (for CPUs) or OpenAI Triton (for GPUs) that eventually gets executed.

    Термин «компилятор» часто перегружен. Понимание контекста, в котором используется этот термин, помогает разобраться в документации. Например, Torch Dynamo — это фронтенд (его часто называют «graph acquisition tool»), который производит IR. Пользователь затем может понизить (lower) этот IR в бэкенд другого компиляторного стека, например в C++ (для CPU) или OpenAI Triton (для GPU), который в итоге и будет исполнен.

    Nvidia vs OpenAI Triton

    Nvidia против OpenAI Triton

    Triton by Nvidia is an inference server. Triton by OpenAI is a high-level CUDA programming language and compiler stack. The two are not related.

    Triton от Nvidia — это inference-сервер. Triton от OpenAI — это высокоуровневый язык программирования для CUDA и компиляторный стек. Эти два проекта не связаны.

    Training: TorchDyamo + JIT + Triton

    Обучение: TorchDynamo + JIT + Triton

    Compilers are often thought of as optimizations for inference. However, there are compilers that help with training too. The most notable these days is TorchDynamo + JIT Compiler. TorchDynamo is a front-end that allows you to capture a PyTorch model as an IR1. Since this front-end is maintained by the Pytorch team, it is going to have the greatest support for Pytorch models. The best thing about the TorchDynamo+JIT stack is that it seamlessly handles graph breaks for you (stitches various subgraphs together for you, etc). The JIT compiler supplants the CPython interpreter that normally “eagerly” runs your PyTorch code for faster execution2. It works by dynamically modifying Python bytecode right before it is executed. All you have to do is to call one line of code: torch.compile(...) to see the benefits. Andrej Karpathy is using this in his NanoGPT tutorials:

    Компиляторы часто воспринимают как оптимизацию для inference. Однако есть компиляторы, которые помогают и в обучении. Самый заметный сегодня — TorchDynamo + JIT Compiler. TorchDynamo — это фронтенд, который позволяет захватить модель PyTorch в виде IR1. Поскольку этот фронтенд поддерживается командой PyTorch, у него будет лучшая поддержка моделей PyTorch. Лучшее в стеке TorchDynamo+JIT — то, что он бесшовно обрабатывает graph breaks за вас (сам сшивает разные подграфы и т. п.). JIT-компилятор заменяет интерпретатор CPython, который обычно «эагерно» (eagerly) исполняет ваш PyTorch-код, ускоряя исполнение2. Он работает, динамически модифицируя байткод Python прямо перед его исполнением. Всё, что вам нужно сделать, — вызвать одну строчку кода: torch.compile(...), чтобы получить преимущества. Andrej Karpathy использует это в своих туториалах по NanoGPT:

    This is so underrated! Ridiculous speedup by calling torch.compile(...)

    Code: https://t.co/9mMGGyEcfz

    Related blog posts:
    1. https://t.co/JOLZ8BQdet
    2. https://t.co/ci8KAzLW1p (this blog by @marksaroufim is a real gem, BTW) https://t.co/E0oRVC4Ow8

    — Hamel Husain (@HamelHusain) February 7, 2023

    Это так недооценено! Смешной прирост скорости от вызова torch.compile(...) Код: https://t.co/9mMGGyEcfzСвязанные посты:1. https://t.co/JOLZ8BQdet2. https://t.co/ci8KAzLW1p (этот блог от @marksaroufim — настоящая жемчужина, кстати) https://t.co/E0oRVC4Ow8 — Hamel Husain (@HamelHusain) February 7, 2023

    The JIT Compiler can theoretically leverage different backends for execution, but at this time, the paved path is to use the TorchInductor which lowers the IR to the OpenAI Triton backend. So the entire “compiler stack” looks like this:

    JIT-компилятор теоретически может использовать разные бэкенды для исполнения, но на данный момент проторённый путь — это TorchInductor, который понижает IR до бэкенда OpenAI Triton. Поэтому весь «compiler stack» выглядит так:

  • TorchDynamo acquires a PyTorch model as an IR (FX graphs, multiple graphs if there are graph breaks)
  • The JIT Compiler lowers the FX Graph (through other intermediate compiler stacks) to TorchInductor
  • TorchInductor lowers the IR to OpenAI-Triton for GPU or C++ for CPU
  • OpenAI Triton compiles the IR and executes it (perhaps by first passing it to some other back-end like CUDA)
  • TorchDynamo захватывает модель PyTorch в виде IR (FX-графы, несколько графов, если есть graph breaks) JIT-компилятор понижает FX-граф (через другие промежуточные компиляторные стеки) до TorchInductor TorchInductor понижает IR до OpenAI-Triton для GPU или C++ для CPU OpenAI Triton компилирует IR и исполняет его (возможно, сначала передав его в какой-то другой бэкенд, например CUDA)

    That is a lot of steps! While the end-user doesn’t necessarily need to be aware of all these steps, the documentation on Torch Dynamo can be really confusing unless you are aware of these different things.

    Это много шагов! Хотя конечному пользователю необязательно знать обо всех этих шагах, документация по Torch Dynamo может быть очень запутанной, если не понимать эти разные сущности.

    Notes on Specific Compiler Stacks

    Заметки по конкретным компиляторным стекам

    TensorRT

    TensorRT

    This is a compiler/execution environment. Unlike the JIT (just-in-time), it is an AOT (ahead-of-time) compiler. It is compatible with PyTorch via torch-TensorRT. From the docs: TensorRT’s primary means of importing a trained model from a framework is through the ONNX interchange format, so you need to convert your model to ONNX before getting to TensorRT (this happens automatically when you use torch-TensorRT).

    Это компилятор/среда исполнения. В отличие от JIT (just-in-time), это AOT (ahead-of-time) компилятор. Он совместим с PyTorch через torch-TensorRT. Из документации: основное средство импорта обученной модели из фреймворка в TensorRT — это формат обмена ONNX, поэтому перед использованием TensorRT нужно сконвертировать модель в ONNX (это происходит автоматически при использовании torch-TensorRT).

    ONNX

    ONNX

    ONNX is mainly focused on portability. ONNX provides its own set of ops that are cross-platform and can be run on an ONNX Runtime. The ONNX runtime provides clients in many languages, like Python, C, C++, Java, JS, etc., allowing you to load a model for either inferencing or training. There are hardware-specific clients that are optimized for OS (i.e., Linux, Windows, Mac, etc.), Hardware acceleration (CUDA, CoreML) and so forth. You can select a client from here: https://onnxruntime.ai/.

    ONNX в основном сосредоточен на переносимости. ONNX предоставляет собственный набор операций, которые кросс-платформенны и могут быть запущены на ONNX Runtime. ONNX runtime предоставляет клиенты на множестве языков — Python, C, C++, Java, JS и т. д., позволяя загрузить модель как для inference, так и для обучения. Есть железо-специфичные клиенты, оптимизированные под ОС (Linux, Windows, Mac и т. д.), аппаратное ускорение (CUDA, CoreML) и т. п. Клиента можно выбрать здесь: https://onnxruntime.ai/.

    You can construct your computation graphs with ONNX’s built-in ops; However, this is an impractical way to build a model. In practice, you want to use your favorite ML framework like PyTorch or Tensorflow and use a converter to convert that model to ONNX like torch.onnx

    Вычислительные графы можно строить из встроенных операций ONNX; однако это непрактичный способ построить модель. На практике вы хотите использовать любимый ML-фреймворк вроде PyTorch или Tensorflow и применить конвертер для конвертации модели в ONNX, например torch.onnx

    Pytorch Considerations

    Особенности PyTorch

    However, there is no free lunch. For PyTorch, there is a long list of limitations and gotchas where things can go wrong. You must be careful when exporting a model and should test the exported ONNX model against the native model for consistency. The exported model looks like a JSON file that describes the graph along with weights.

    Однако бесплатных обедов не бывает. Для PyTorch есть длинный список ограничений и подводных камней, где что-то может пойти не так. Нужно быть аккуратным при экспорте модели и проверять экспортированную ONNX-модель на соответствие исходной. Экспортированная модель выглядит как JSON-файл, который описывает граф вместе с весами.

    torch.onnx relies on TorchScript to export the model into an IR. You have to either use Tracing or Scripting depending upon the control flow in your model.

    torch.onnx полагается на TorchScript для экспорта модели в IR. Приходится использовать либо Tracing, либо Scripting в зависимости от потока управления (control flow) в модели.

  • Tracing: If there is no control flow (if statements, loops, etc.) then use Tracing. Tracing works by recording the model during execution. If you have dynamic elements in your graph, then they will be recorded as constants.
  • Scripting: If there is control flow, you want to use Scripting instead.
  • Mixed: if there are modules in your code that do not have control flow and others that do, you can compile these modules separately with either Tracing or Scripting and then combine them into a single model.
  • Tracing: если в модели нет управляющих конструкций (if-выражений, циклов и т. д.), используйте Tracing. Tracing работает за счёт записи модели во время её исполнения. Если в графе есть динамические элементы, они будут записаны как константы. Scripting: если есть управляющие конструкции, используйте Scripting. Mixed: если в коде есть модули без управляющих конструкций и модули с ними, можно скомпилировать эти модули по отдельности с помощью Tracing или Scripting и затем объединить их в одну модель.

    Read the TorchScript Tutorial and Tracing vs. Scripting to learn more.

    Прочитайте туториал по TorchScript и Tracing vs. Scripting, чтобы узнать больше.

    Use Torch-TensorRT instead of ONNX

    Используйте Torch-TensorRT вместо ONNX

    I talked to a trusted source on the Pytorch team, and they said that TorchScript is not actively maintained and that I should look at pytorch - TensorRT instead.

    Я поговорил с надёжным источником из команды PyTorch, и мне сказали, что TorchScript активно не поддерживается и что мне стоит посмотреть в сторону pytorch - TensorRT.

    OpenAI Triton

    OpenAI Triton

    Only for GPUs, from this talk:

    Только для GPU, из этого доклада:

    ApacheTVM

    ApacheTVM

    ApacheTVM is a compiler that seems to have one of the widest ranges of hardware support.

    ApacheTVM — это компилятор, у которого, по всей видимости, один из самых широких диапазонов поддерживаемого железа.

    Adaptive Compilers (TVM)

    Адаптивные компиляторы (TVM)

    autoTVM, part of ApacheTVM compiler framework are part of a class of compilers that are adaptive that run tests on hardware and automatically try to optimize it for the hardware by trying many different graph configurations. From Chip’s intro to compilers:

    autoTVM, входящий в состав фреймворка ApacheTVM, относится к классу адаптивных компиляторов, которые запускают тесты на железе и автоматически пытаются оптимизировать код под него, перебирая множество различных конфигураций графа. Из введения Chip в компиляторы:

    autoTVM measures the actual time it takes to run each path it goes down, which gives it ground truth data to train a cost model to predict how long a future path will take. The pro of this approach is that because the model is trained using the data generated during runtime, it can adapt to any type of hardware it runs on. The con is that it takes more time for the cost model to start improving.

    autoTVM измеряет реальное время выполнения каждого пути, по которому он идёт, что даёт ему ground truth данные для обучения cost model, которая предсказывает, сколько займёт будущий путь. Плюс этого подхода в том, что модель обучается на данных, сгенерированных во время выполнения, и может адаптироваться к любому типу железа, на котором запущена. Минус — cost model требуется больше времени, чтобы начать улучшаться.

    One example is when Apple released their M1 chips in Nov 2020. M1 is an ARM-based system on a chip, and ARM architectures are more or less well-understood. However, M1 still has a lot of novel components of its ARM implementation and requires significant optimization to make various ML models run fast on it. A month after the release, folks at OctoML showed that the optimization made by autoTVM is almost 30% faster than hand-designed optimization by Apple’s Core ML team.

    Один пример — выход чипов M1 от Apple в ноябре 2020 года. M1 — это ARM-based system on a chip, а ARM-архитектуры более или менее хорошо изучены. Однако у M1 много новых компонентов в его реализации ARM, и требуется значительная оптимизация, чтобы различные ML-модели работали на нём быстро. Через месяц после релиза ребята из OctoML показали, что оптимизация autoTVM почти на 30% быстрее, чем ручная оптимизация команды Apple Core ML.

    Quote from a compiler expert:

    Цитата эксперта по компиляторам:

    Pros of dynamic compilers is that we maximize performance across a broader set of models/ops. Downside of dynamic compilers is search time. AutoTVM generally takes hours, even more than a day to compile because it’s trying every possible combination.

    Плюс динамических компиляторов в том, что мы максимизируем производительность для более широкого набора моделей/операций. Минус — время поиска. AutoTVM обычно тратит часы, иногда больше суток, на компиляцию, потому что он перебирает все возможные комбинации.

    ML can also be used to optimize the computation graph, or “ML is optimizing ML”. Below is an illustration from Chen, et.al; TVM: An Automated End-to-End Optimizing Compiler for Deep Learning, where they comment that:

    ML также можно использовать для оптимизации вычислительного графа — то есть «ML оптимизирует ML». Ниже — иллюстрация из работы Chen et al.; TVM: An Automated End-to-End Optimizing Compiler for Deep Learning, где авторы отмечают:

    Possible optimizations form a large space, so we use an ML-based cost model to find optimized operators.

    Возможные оптимизации образуют большое пространство, поэтому мы используем cost model на основе ML для поиска оптимизированных операторов.

    Adaptive compilers are interesting because they do not depend on hand-coded rules like traditional compilers and seem more user-friendly and generalizable to new kinds of hardware. Another adaptive compiler is cuDNN autotune, which you can enable with torch.backends.cudnn.benchmark=True, but apparently this only works with convolutions. The drawback of adaptive compilers is that they can take a long time to “learn” or “search” for good optimizations. However, you can amortize the cost of optimizing the model over many devices on that hardware, and can even take that checkpoint as a starting point for future tuning sessions.

    Адаптивные компиляторы интересны тем, что не зависят от вручную закодированных правил, как традиционные компиляторы, и кажутся более user-friendly и обобщаемыми на новые виды железа. Ещё один адаптивный компилятор — cuDNN autotune, который можно включить через torch.backends.cudnn.benchmark=True, но, видимо, он работает только со свёртками. Недостаток адаптивных компиляторов — то, что им требуется много времени, чтобы «выучить» или «найти» хорошие оптимизации. Однако стоимость оптимизации модели можно амортизировать по многим устройствам с этим железом, а полученный чекпойнт можно даже использовать как стартовую точку для будущих сессий настройки.

    I find adaptive compilation more exciting and promising as a future direction in compilers.

    Я нахожу адаптивную компиляцию более интересным и многообещающим направлением будущего компиляторов.

    WASM

    WASM

    Targeting WASM would theoretically enable you to work on any device that can run a browser - and many devices/hardware can run browsers! However, one drawback is that it’s still slow. See this blog post for a more detailed discussion.

    Таргетирование WASM теоретически позволило бы вам работать на любом устройстве, способном запустить браузер, — а браузеры могут запустить очень многие устройства/железо! Однако один из недостатков — то, что это всё ещё медленно. См. этот пост для более подробного обсуждения.

    People to follow

    За кем стоит следить

    If you want to learn more about compilers, I recommend following these people:

    Если хотите узнать больше о компиляторах, рекомендую следить за этими людьми:

  • Chris Lattner: watch what he is building at Modular
  • Horace He
  • Mark Saroufim
  • Chris Lattner: смотрите, что он строит в Modular Horace He Mark Saroufim

    Resources

    Материалы

  • I learned a lot by reading this great article from Chip Huyen.
  • This post-mortem of trying to get capsule networks to work on modern hardware illuminates the importance of compilers.
  • Я многое узнал, читая эту отличную статью Chip Huyen. Этот post-mortem попытки запустить capsule networks на современном железе хорошо иллюстрирует важность компиляторов.


    Footnotes

    Сноски

  • The IR is called FX, and Inductor (another compiler) translates FX graphs to be executed in one of two environments: OpenAI Triton for GPU and C++/OpenMP for CPU. The docs call inductor a backend, but it is really a middle-layer that lowers the IR to another compiler stack.↩︎

  • Pytorch uses the python interpreter because PyTorch is natively “eager mode” and allows for dynamism and python control flows (which is why people love it because it’s very hackable or debuggable).↩︎

  • IR называется FX, а Inductor (другой компилятор) транслирует FX-графы для исполнения в одной из двух сред: OpenAI Triton для GPU и C++/OpenMP для CPU. Документация называет inductor бэкендом, но на самом деле это middle-layer, который понижает IR до другого компиляторного стека.↩︎ PyTorch использует интерпретатор Python, потому что PyTorch нативно работает в «eager mode» и допускает динамизм и поток управления Python (за что его и любят — он очень хакабельный и удобный для отладки).↩︎