Современный мир стремительно движется в сторону внедрения искусственного интеллекта в самые разные сферы, и одним из важнейших направлений развития является «edge AI» — выполнение обработки и вывода данных непосредственно на устройстве, без отправки информации на удалённые серверы. Такой подход даёт преимущество в скорости отклика, автономности и безопасности. Однако настоящим вызовом становится реализация ИИ на микроконтроллерах — устройствах с очень ограниченными ресурсами по вычислительной мощности, памяти и энергетическим ресурсам. Микроконтроллеры часто используются в бытовых приборах, носимых устройствах, системах мониторинга, медицинском оборудовании и многих других местах, где важна энергоэффективность и компактность. Несмотря на скромные характеристики, развитие аппаратуры и программных сред позволяет выполнять на них достаточно сложные задачи, включая выполнение нейронных сетей и других моделей ИИ.
Чтобы понять, как именно это достигается, следует подробно остановиться на ключевых компонентах, которые обеспечивают работу искусственного интеллекта на микроконтроллерах — операторах и ядрах (kernels). Модель искусственного интеллекта, как правило, представлена набором параметров — весов, которые задают обученную логику. Но веса сами по себе недостаточны для выполнения вывода (inference). Помимо них нужна информация о последовательности вычислительных операций и способах их исполнения. Для микроконтроллеров наиболее популярным исполнительным окружением является Tensorflow Lite for Microcontrollers (tflite-micro), представляющий собой облегченную и оптимизированную версию Tensorflow Lite.
Важным аспектом работы tflite-micro является использование формата .tflite, который помимо весов включает описание вычислительного графа модели. Этот граф задаёт, какие операции необходимо выполнить и в каком порядке. Операторы — это разновидность инструкций, которые описывают базовые вычислительные действия, необходимые для реализации модели. Их можно сравнить с набором команд процессора, где каждая операция реализует конкретную задачу, например, сложение, умножение, свертку в нейронной сети.
Tensorflow Lite поддерживает определённый ограниченный набор операторов, адаптированных для небольших устройств. Для каждого оператора существует конкретное программное исполнение — ядро, или kernel. Ядра отвечают за непосредственное выполнение операций на платформе. Само ядро может существовать в нескольких реализациях — от универсального кода на языке C, который работает на любом процессоре, до оптимизированных версий, использующих специальные процессорные инструкции и аппаратные ускорители. Рассмотрим на примере операции сложения (Add operator).
В простейшем случае ядро берет два входных массива данных (тензоров) и последовательно складывает соответствующие элементы. Эта реализация максимально универсальна, не требует поддержки каких-либо особых команд процессора. Однако у неё есть недостаток — выполнение операции происходит последовательно, что занимает значительное количество тактов процессора. Некоторые операции в нейронных сетях являются «очень» параллельными, то есть их можно распараллелить на множество блоков данных и выполнить одновременно. Такое преимущество позволяет использовать специализированные инструкции для параллельных вычислений, например SIMD (Single Instruction Multiple Data).
Многие современные микроконтроллеры на базе архитектуры Arm Cortex-M имеют поддержку таких расширений, например DSP extension и более продвинутого Vector Extension (также известного как Helium). Использование этих аппаратных возможностей позволяет значительно ускорить исполнение операций. Пример использования аппаратного ускорения виден в библиотеке CMSIS-NN, поддерживаемой Arm. Она предоставляет оптимизированные ядра для распространённых операторов, включая сложение, которые используют DSP и Vector Extension для параллельной обработки данных. При наличии таких расширений операция может выполняться с меньшим количеством итераций и более высокой скоростью, что крайне важно для ограниченных микроконтроллеров.
Для случая сложения квантизированных данных (8-битные целочисленные значения) существует отдельная реализация, которая в зависимости от возможностей процессора может использовать либо базовый C-код, либо специальные инструкции, повышающие производительность. Эти оптимизации прозрачны для разработчика и не требуют изменений в модели, позволяя однажды написанному коду эффективно работать на разном оборудовании. Помимо ускорений на уровне инструкций, существуют микроконтроллеры с выделенной нейронной процессорной единицей (NPU), например устройства с Arm Ethos-U. Такие NPUs способны обрабатывать команды вывода нейронных сетей гораздо быстрее и энергозатратнее, разгружая основной процессор. Модели, оптимизированные специально для таких NPU, преобразуются компилятором, например Vela, который заменяет последовательности операторов на единый специализированный оператор с командным потоком.
Это позволяет максимально использовать потенциал аппаратного ускорителя, однако такие модели не совместимы с оборудованием без NPU. Для работы с такими моделями tflite-micro включает реализацию соответствующих операторов, которые передают вычисления на NPU, управляя выделением ресурсов, обращением к памяти и синхронизацией. Благодаря этому разработчики могут создавать приложения для микроконтроллеров с подсистемами ИИ, не вдаваясь в сложности взаимодействия с аппаратурой NPUs. Таким образом, экосистема выполнения ИИ на микроконтроллерах включает в себя несколько ключевых слоев: от описания модели и операторов в файловом формате .tflite, через ядра, реализующие эти операторы в программном коде, до аппаратных средств, обеспечивающих ускорение.
Гибкость архитектуры Tensorflow Lite позволяет адаптировать ядра под конкретные аппаратные возможности, обеспечивая баланс между портируемостью и производительностью. Перед разработчиками также стоят задачи оптимизации моделей с точки зрения размера, точности, потребления памяти и времени отклика. Квантизация модели, замена некоторых операций более простыми аналогами и использование оптимизированных библиотек — всё это практические методы для повышения эффективности ИИ на микроконтроллерах. В будущем развитие аппаратных расширений и инструментов программирования будет ещё более тесно интегрировано с исполнением моделей на крайних устройствах, позволяя расширять возможности ИИ в устройствах с низким энергопотреблением и небольшим «железом». Понимание основ работы операторов и ядер станет ключевым для разработчиков, стремящихся создавать передовые решения в сфере маломощного искусственного интеллекта.
Итогом можно сказать, что работа искусственного интеллекта на микроконтроллерах — это комплексный процесс, основанный на взаимодействии модели и программных реализаций операторов, которые, в свою очередь, используют все доступные аппаратные возможности. Операторы и ядра определяют эффективность исполнения, а аппаратные ускорения выводят производительность на качественно новый уровень. От исследований устройства моделей до внедрения оптимальных ядер лежит путь, который позволяет реализовать современные ИИ на самых скромных устройствах, расширяя горизонты применения этой технологии.