Драйверы Neural Networks API

На этой странице приведена общая информация о том, как реализовать драйвер API нейронных сетей (NNAPI). Дополнительную информацию можно найти в файлах определений HAL в hardware/interfaces/neuralnetworks. Пример реализации драйвера можно найти в файле frameworks/ml/nn/driver/sample.

Подробнее о Neural Networks API…

HAL для нейронных сетей

HAL нейронных сетей определяет абстракцию различных устройств, таких как графические процессоры (GPU) и цифровые сигнальные процессоры (DSP), которые находятся в продукте (например, телефоне или планшете). Драйверы этих устройств должны соответствовать NN HAL. Интерфейс указан в файлах определений HAL в hardware/interfaces/neuralnetworks.

На рисунке 1 показано, как фреймворк взаимодействует с драйвером.

Процесс работы нейронных сетей

Рисунок 1. Поток нейронных сетей

Инициализация

При инициализации фреймворк запрашивает у драйвера его возможности, используя IDevice::getCapabilities_1_3. Структура @1.3::Capabilities включает все типы данных и представляет производительность без послаблений в виде вектора.

Чтобы определить, как распределить вычисления между доступными устройствами, фреймворк использует возможности, чтобы понять, насколько быстро и энергоэффективно каждый драйвер может выполнять код. Чтобы предоставить эту информацию, драйвер должен предоставить стандартизированные показатели производительности, основанные на выполнении эталонных рабочих нагрузок.

Чтобы определить значения, которые драйвер возвращает в ответ на запрос IDevice::getCapabilities_1_3, используйте приложение для тестирования NNAPI, чтобы измерить производительность для соответствующих типов данных. Для оценки производительности при работе с 32-битными значениями с плавающей запятой рекомендуется использовать модели MobileNet v1 и v2, asr_float и tts_float, а для оценки производительности при работе с 8-битными квантованными значениями – квантованные модели MobileNet v1 и v2. Подробнее о наборе тестов для машинного обучения в Android…

В Android 9 и более ранних версиях структура Capabilities содержит информацию о производительности драйвера только для тензоров с плавающей запятой и квантованных тензоров и не включает скалярные типы данных.

В процессе инициализации фреймворк может запросить дополнительную информацию, используя IDevice::getType, IDevice::getVersionString, IDevice:getSupportedExtensions и IDevice::getNumberOfCacheFilesNeeded.

Между перезагрузками продукта фреймворк ожидает, что все запросы, описанные в этом разделе, всегда будут возвращать одни и те же значения для определенного драйвера. В противном случае приложение, использующее этот драйвер, может работать медленнее или неправильно.

Сборник

Платформа определяет, какие устройства использовать, когда получает запрос от приложения. В Android 10 приложения могут обнаруживать и указывать устройства, которые выбирает платформа. Подробнее о обнаружении и назначении устройств…

Во время компиляции модели фреймворк отправляет ее каждому подходящему драйверу, вызывая функцию IDevice::getSupportedOperations_1_3. Каждый драйвер возвращает массив логических значений, указывающих, какие операции модели поддерживаются. Драйвер может определить, что он не может поддерживать данную операцию по ряду причин. Пример:

  • Драйвер не поддерживает этот тип данных.
  • Драйвер поддерживает операции только с определенными входными параметрами. Например, драйвер может поддерживать операции свертки 3x3 и 5x5, но не 7x7.
  • У драйвера недостаточно памяти для обработки больших графов или входных данных.

Во время компиляции входные, выходные и внутренние операнды модели, как описано в OperandLifeTime, могут иметь неизвестные размеры или ранг. Подробнее о форме выходных данных…

Фреймворк дает каждому выбранному драйверу команду подготовиться к выполнению части модели, вызывая функцию IDevice::prepareModel_1_3. После этого каждый драйвер компилирует свой набор. Например, драйвер может сгенерировать код или создать копию весов с измененным порядком. Поскольку между компиляцией модели и выполнением запросов может пройти значительное время, во время компиляции не следует выделять такие ресурсы, как большие фрагменты памяти устройства.

При успешном выполнении драйвер возвращает дескриптор @1.3::IPreparedModel. Если при подготовке подмножества модели драйвер возвращает код ошибки, фреймворк запускает всю модель на центральном процессоре.

Чтобы сократить время компиляции при запуске приложения, драйвер может кешировать артефакты компиляции. Подробнее о кешировании компиляции…

Выполнение

Когда приложение запрашивает у фреймворка выполнение запроса, фреймворк по умолчанию вызывает метод HAL IPreparedModel::executeSynchronously_1_3, чтобы выполнить синхронное выполнение на подготовленной модели. Запрос также можно выполнить асинхронно с помощью метода execute_1_3, метода executeFenced (см. раздел Ограниченное выполнение) или пакетного выполнения.

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

При использовании асинхронного метода execute_1_3 управление возвращается процессу приложения после начала выполнения, и драйвер должен уведомить фреймворк о завершении выполнения с помощью @1.3::IExecutionCallback.

Параметр Request, передаваемый методу execute, содержит список входных и выходных операндов, используемых для выполнения. Память, в которой хранятся данные операнда, должна использовать порядок следования строк, при котором первый параметр изменяется медленнее всего, и не иметь заполнения в конце строк. Подробнее об операндах…

Для драйверов NN HAL версии 1.2 или более поздней после выполнения запроса в фреймворк возвращаются статус ошибки, форма выходных данных и информация о времени. Во время выполнения выходные или внутренние операнды модели могут иметь одно или несколько неизвестных измерений или неизвестный ранг. Если хотя бы один выходной операнд имеет неизвестный размер или ранг, драйвер должен возвращать информацию о динамически изменяемом размере выходных данных.

Для драйверов с NN HAL 1.1 или более ранней версии при выполнении запроса возвращается только статус ошибки. Чтобы выполнение было успешным, необходимо полностью указать размеры входных и выходных операндов. Внутренние операнды могут иметь один или несколько неизвестных параметров, но у них должен быть указан ранг.

Для запросов пользователей, которые охватывают несколько драйверов, фреймворк отвечает за резервирование промежуточной памяти и за последовательность вызовов каждого драйвера.

В одном объекте @1.3::IPreparedModel можно параллельно инициировать несколько запросов. Драйвер может выполнять запросы параллельно или последовательно.

Фреймворк может запросить у драйвера хранение нескольких подготовленных моделей. Например, подготовьте модель m1, подготовьте m2, выполните запрос r1 на m1, выполните r2 на m2, выполните r3 на m1, выполните r4 на m2, выпустите (описано в разделе Очистка) m1 и выпустите m2.

Чтобы избежать медленного первого выполнения, которое может привести к ухудшению качества работы приложения (например, к заиканию первого кадра), драйвер должен выполнить большую часть инициализаций на этапе компиляции. Инициализация при первом выполнении должна быть ограничена действиями, которые негативно влияют на работоспособность системы при раннем выполнении, например резервированием больших временных буферов или увеличением тактовой частоты устройства. Драйверы, которые могут подготовить только ограниченное количество параллельных моделей, могут выполнять инициализацию при первом запуске.

В Android 10 и более поздних версиях, если несколько выполнений с одной и той же подготовленной моделью выполняются быстро одно за другим, клиент может использовать объект пакета выполнения для связи между процессами приложения и драйвера. Дополнительную информацию можно найти в статье Пакетное выполнение и быстрые очереди сообщений.

Чтобы повысить производительность при нескольких последовательных выполнениях, драйвер может удерживать временные буферы или увеличивать тактовую частоту. Рекомендуется создать поток-сторож, чтобы освобождать ресурсы, если новые запросы не создаются в течение определенного периода времени.

Форма выходных данных

Для запросов, в которых у одного или нескольких выходных операндов указаны не все размеры, драйвер должен предоставить список выходных форм, содержащих информацию о размерах для каждого выходного операнда после выполнения. Подробную информацию о параметрах можно найти в разделе OutputShape.

Если выполнение завершается неудачно из-за недостаточного размера выходного буфера, драйвер должен указать, какие выходные операнды имеют недостаточный размер буфера в списке выходных фигур, и должен сообщить как можно больше информации о размерах, используя ноль для неизвестных размеров.

Время

В Android 10 приложение может запросить время выполнения, если оно указало одно устройство для использования в процессе компиляции. Подробнее о том, MeasureTiming и об обнаружении и назначении устройств… В этом случае драйвер NN HAL 1.2 должен измерять продолжительность выполнения или сообщать значение UINT64_MAX (чтобы указать, что продолжительность недоступна) при выполнении запроса. Драйвер должен свести к минимуму снижение производительности, вызванное измерением продолжительности выполнения.

Драйвер сообщает о следующих длительностях в микросекундах в структуре Timing:

  • Время выполнения на устройстве. Не включает время выполнения в драйвере, который работает на центральном процессоре.
  • Время выполнения в драйвере. Включает время выполнения на устройстве.

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

Если драйверу не было предложено измерить продолжительность выполнения или если при выполнении произошла ошибка, драйвер должен сообщить о продолжительности как UINT64_MAX. Даже если водитель должен измерить время выполнения, он может вместо этого указать UINT64_MAX для времени на устройстве, времени в драйвере или и того, и другого. Если драйвер сообщает оба значения, отличные от UINT64_MAX, то время выполнения в драйвере должно быть равно времени на устройстве или превышать его.

Выполнение в изолированной среде

В Android 11 NNAPI позволяет ожидать выполнения списка дескрипторов sync_fence и при необходимости возвращать объект sync_fence, который сигнализирует о завершении выполнения. Это позволяет снизить нагрузку на небольшие модели последовательностей и при использовании потоковой передачи. Ограниченное выполнение также позволяет более эффективно взаимодействовать с другими компонентами, которые могут сигнализировать или ожидать sync_fence. Подробнее sync_fence о фреймворке синхронизации…

При выполнении в изолированной среде фреймворк вызывает метод IPreparedModel::executeFenced, чтобы запустить изолированное асинхронное выполнение на подготовленной модели с вектором синхронизирующих барьеров, которые нужно дождаться. Если асинхронная задача завершится до возврата вызова, для sync_fence может быть возвращен пустой дескриптор. Также необходимо вернуть объект IFencedExecutionCallback, чтобы фреймворк мог запросить информацию о статусе ошибки и продолжительности.

После завершения выполнения можно запросить следующие два значения времени, которые измеряют продолжительность выполнения, с помощью IFencedExecutionCallback::getExecutionInfo.

  • timingLaunched – время от вызова executeFenced до момента, когда executeFenced сигнализирует о возвращенном syncFence.
  • timingFenced: продолжительность периода с момента, когда все барьеры синхронизации, которые ожидает выполнение, получают сигнал, до момента, когда executeFenced сигнализирует возвращенный syncFence.

Управление

На устройствах с Android 11 или более поздней версии NNAPI включает две операции управления потоком: IF и WHILE. Они принимают другие модели в качестве аргументов и выполняют их условно (IF) или многократно (WHILE). Подробнее о том, как реализовать это, рассказывается в разделе Управление потоком.

Качество обслуживания

В Android 11 NNAPI включает улучшенное качество обслуживания (QoS), позволяя приложению указывать относительные приоритеты своих моделей, максимальное количество времени, ожидаемое для подготовки модели, и максимальное количество времени, ожидаемое для завершения выполнения. Дополнительную информацию можно найти в статье Качество обслуживания.

Очистка

Когда приложение завершает работу с подготовленной моделью, фреймворк освобождает ссылку на объект @1.3::IPreparedModel. Когда объект IPreparedModel перестает использоваться, он автоматически удаляется в сервисе драйвера, который его создал. Ресурсы, относящиеся к определенной модели, можно освободить в реализации деструктора драйвера. Если сервис водителя хочет, чтобы объект IPreparedModel автоматически уничтожался, когда он больше не нужен клиенту, он не должен хранить ссылки на объект IPreparedModel после того, как объект IPreparedeModel был возвращен через IPreparedModelCallback::notify_1_3.

Загрузка ЦП

Драйверы должны использовать ЦП для настройки вычислений. Драйверы не должны использовать ЦП для вычислений графа, поскольку это мешает фреймворку правильно распределять работу. Драйвер должен сообщать фреймворку о тех частях, с которыми он не может справиться, и позволять фреймворку обрабатывать остальное.

Фреймворк предоставляет реализацию ЦП для всех операций NNAPI, кроме операций, определенных поставщиком. Подробнее о расширениях поставщиков…

Операции, представленные в Android 10 (API уровня 29), имеют только эталонную реализацию для центрального процессора, чтобы убедиться в правильности тестов CTS и VTS. Оптимизированные реализации, включенные в мобильные фреймворки машинного обучения, предпочтительнее реализации NNAPI CPU.

Вспомогательные функции

База кода NNAPI включает служебные функции, которые могут использоваться сервисами драйверов.

Файл frameworks/ml/nn/common/include/Utils.h содержит различные служебные функции, например для ведения журналов и преобразования между разными версиями NN HAL.

  • VLogging: VLOG – это макрос-оболочка для LOG в Android, который регистрирует сообщение, только если в свойстве debug.nn.vlog задан соответствующий тег. initVLogMask() должен вызываться до любых вызовов VLOG. Макрос VLOG_IS_ON можно использовать, чтобы проверить, включена ли в данный момент функция VLOG. Это позволяет пропустить сложный код регистрации, если он не нужен. Значение свойства должно быть одним из следующих:

    • Пустая строка, указывающая, что ведение журнала не требуется.
    • Токен 1 или all, указывающий, что необходимо выполнить полное ведение журнала.
    • Список тегов, разделенных пробелами, запятыми или двоеточиями, указывающий, какие данные нужно регистрировать. Теги: compilation, cpuexe, driver, execution, manager и model.
  • compliantWithV1_*: возвращает true, если объект NN HAL можно преобразовать в тот же тип другой версии HAL без потери информации. Например, вызов compliantWithV1_0 для V1_2::Model возвращает false, если модель включает типы операций, представленные в NN HAL 1.1 или NN HAL 1.2.

  • convertToV1_* – преобразует объект NN HAL из одной версии в другую. Если при преобразовании данных происходит потеря информации (то есть новое значение типа не может полностью представлять исходное), в журнал записывается предупреждение.

  • Возможности. Функции nonExtensionOperandPerformance и update можно использовать для создания поля Capabilities::operandPerformance.

  • Запрос свойств следующих типов: isExtensionOperandType, isExtensionOperationType, nonExtensionSizeOfData, nonExtensionOperandSizeOfData, nonExtensionOperandTypeIsScalar, tensorHasUnspecifiedDimensions.

Файл frameworks/ml/nn/common/include/ValidateHal.h содержит вспомогательные функции, которые проверяют, соответствует ли объект NN HAL спецификации своей версии HAL.

  • validate*: возвращает значение true, если объект NN HAL действителен в соответствии со спецификацией версии HAL. Типы OEM и расширений не проверяются. Например, validateModel возвращает false, если модель содержит операцию, которая ссылается на индекс операнда, не существующий в модели, или операцию, которая не поддерживается в этой версии HAL.

Файл frameworks/ml/nn/common/include/Tracing.h содержит макросы, которые упрощают добавление информации systracing в код нейронных сетей. Пример можно найти в образце драйвера, где используются макросы NNTRACE_*.

Файл frameworks/ml/nn/common/include/GraphDump.h содержит служебную функцию для вывода содержимого Model в графическом виде для отладки.

  • graphDump: записывает представление модели в формате Graphviz (.dot) в указанный поток (если он предоставлен) или в logcat (если поток не предоставлен).

Проверка

Чтобы проверить реализацию NNAPI, используйте тесты VTS и CTS, включенные в платформу Android. VTS проверяет драйверы напрямую (без использования фреймворка), а CTS – косвенно, через фреймворк. Они проверяют каждый метод API и подтверждают, что все операции, поддерживаемые драйверами, работают правильно и дают результаты, соответствующие требованиям к точности.

Ниже приведены требования к точности для NNAPI в CTS и VTS.

  • Запись с плавающей запятой: abs(ожидаемое – фактическое) <= atol + rtol  * abs(ожидаемое); где:

    • Для fp32: atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
    • Для fp16: atol = rtol = 5.0f * 0.0009765625f
  • Квантование: на единицу меньше (кроме mobilenet_quantized, где на три меньше).

  • Логическое значение: точное соответствие.

Один из способов тестирования NNAPI с помощью CTS – создание фиксированных псевдослучайных графов, которые используются для тестирования и сравнения результатов выполнения каждого драйвера с эталонной реализацией NNAPI. Если результаты не соответствуют критериям точности, CTS сообщает об ошибке и сохраняет файл спецификации для модели, которая не прошла проверку, в каталоге /data/local/tmp. Это относится к драйверам с NN HAL версии 1.2 или более поздней. Подробнее о критериях точности можно узнать в TestRandomGraph.cpp и TestHarness.h.

Фаззинг

Цель фаззинга – обнаружить сбои, утверждения, нарушения памяти или общее неопределенное поведение в тестируемом коде из-за таких факторов, как неожиданные входные данные. Для фаззинга NNAPI в Android используются тесты на основе libFuzzer, которые эффективно выполняют фаззинг, поскольку используют покрытие строк предыдущих тестовых случаев для создания новых случайных входных данных. Например, libFuzzer отдает предпочтение тестовым случаям, которые выполняются на новых строках кода. Это значительно сокращает время, необходимое для поиска проблемного кода.

Чтобы выполнить фаззинг-тестирование для проверки реализации драйвера, измените frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp в тестовой утилите libneuralnetworks_driver_fuzzer, которая находится в AOSP, и включите в нее код драйвера. Подробнее о фаззинге NNAPI рассказывается в frameworks/ml/nn/runtime/test/android_fuzzing/README.md.

Безопасность

Поскольку процессы приложений напрямую взаимодействуют с процессами драйверов, драйверы должны проверять аргументы получаемых вызовов. Эта проверка подтверждается VTS. Код подтверждения отправлен на номер frameworks/ml/nn/common/include/ValidateHal.h.

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

Набор тестов машинного обучения для Android

Набор тестов машинного обучения Android (MLTS) – это контрольный показатель NNAPI, включенный в CTS и VTS для проверки точности реальных моделей на устройствах поставщиков. В ходе сравнительного тестирования оценивается задержка и точность, а результаты работы драйверов сравниваются с результатами, полученными с помощью TF Lite, работающей на ЦП, для одной и той же модели и наборов данных. Это гарантирует, что точность драйвера не будет ниже, чем у эталонной реализации на ЦП.

Разработчики платформы Android также используют MLTS для оценки задержки и точности драйверов.

Тест NNAPI можно найти в двух проектах AOSP:

Модели и наборы данных

В тесте NNAPI используются следующие модели и наборы данных.

  • Модели MobileNetV1 с плавающей точкой и квантованием u8 разных размеров, запущенные на небольшом подмножестве (1500 изображений) набора данных Open Images Dataset v4.
  • Модели MobileNetV2 с плавающей точкой и квантованием u8 разных размеров, запущенные на небольшом подмножестве (1500 изображений) набора данных Open Images Dataset v4.
  • Акустическая модель на основе долгой краткосрочной памяти (LSTM) для преобразования текста в речь, работающая с небольшим подмножеством набора CMU Arctic.
  • Акустическая модель на основе LSTM для автоматического распознавания речи, работающая с небольшой частью набора данных LibriSpeech.

Дополнительную информацию вы найдете в статье platform/test/mlts/models.

Стресс-тестирование

Набор тестов машинного обучения Android включает серию краш-тестов, которые позволяют проверить устойчивость драйверов при интенсивном использовании или в нестандартных ситуациях, связанных с поведением клиентов.

Все тесты на сбои имеют следующие особенности:

  • Обнаружение зависания. Если клиент NNAPI зависает во время теста, тест завершается сбоем с причиной HANG, и набор тестов переходит к следующему тесту.
  • Обнаружение сбоев клиента NNAPI. Тесты не прерываются при сбоях клиента и завершаются с ошибкой CRASH.
  • Обнаружение сбоя драйвера. Тесты могут обнаружить сбой драйвера, который приводит к ошибке при вызове NNAPI. Обратите внимание, что в процессах драйвера могут происходить сбои, которые не приводят к ошибке NNAPI и не вызывают сбоя теста. Чтобы выявить такую проблему, рекомендуется выполнить команду tail в системном журнале, чтобы найти ошибки или сбои, связанные с драйвером.
  • Таргетинг на все доступные ускорители. Тестирование проводится на всех доступных драйверах.

Все краш-тесты имеют четыре возможных результата:

  • SUCCESS: выполнение завершено без ошибок.
  • FAILURE: не удалось выполнить. Обычно возникает при тестировании модели и указывает на то, что драйверу не удалось скомпилировать или выполнить модель.
  • HANG: процесс тестирования перестал отвечать.
  • CRASH: произошел сбой процесса тестирования.

Подробнее о стресс-тестировании и полном списке тестов на сбои можно узнать в разделе platform/test/mlts/benchmark/README.txt.

Как использовать MLTS

Чтобы использовать MLTS:

  1. Подключите целевое устройство к рабочей станции и убедитесь, что оно доступно через adb. Экспортируйте целевое устройство ANDROID_SERIALпеременной среды, если подключено несколько устройств.
  2. cd в каталог с исходными файлами Android верхнего уровня.

    source build/envsetup.sh
    lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available.
    ./test/mlts/benchmark/build_and_run_benchmark.sh
    

    По завершении тестирования результаты представляются в виде HTML-страницы и передаются в xdg-open.

Подробнее platform/test/mlts/benchmark/README.txt…

Версии HAL нейронных сетей

В этом разделе описываются изменения, внесенные в версии Android и Neural Networks HAL.

Android 11

В Android 11 представлен NN HAL 1.3, который включает в себя следующие заметные изменения.

  • Поддержка квантования со знаком 8 бит в NNAPI. Добавляет тип операнда TENSOR_QUANT8_ASYMM_SIGNED. Драйверы с NN HAL 1.3, поддерживающие операции с квантованием без знака, также должны поддерживать варианты этих операций со знаком. При выполнении подписанных и неподписанных версий большинства квантованных операций драйверы должны выдавать одинаковые результаты с отклонением не более 128. Из этого требования есть пять исключений: CAST, HASHTABLE_LOOKUP, LSH_PROJECTION, PAD_V2 и QUANTIZED_16BIT_LSTM. Операция QUANTIZED_16BIT_LSTM не поддерживает операнды со знаком, а остальные четыре операции поддерживают квантование со знаком, но не требуют, чтобы результаты были одинаковыми.
  • Поддержка изолированного выполнения, при котором фреймворк вызывает метод IPreparedModel::executeFenced, чтобы запустить изолированное асинхронное выполнение на подготовленной модели с вектором барьеров синхронизации, которые нужно ожидать. Подробнее об изолированном выполнении…
  • Поддержка потока управления. Добавлены операции IF и WHILE, которые принимают другие модели в качестве аргументов и выполняют их условно (IF) или многократно (WHILE). Подробнее об управлении выполнением…
  • Улучшенное качество обслуживания (QoS), поскольку приложения могут указывать относительные приоритеты своих моделей, максимальное время подготовки модели и максимальное время выполнения. Подробнее о качестве обслуживания…
  • Поддержка доменов памяти, предоставляющих интерфейсы распределителя для буферов, управляемых драйвером. Это позволяет передавать собственную память устройства между выполнениями, подавляя ненужное копирование и преобразование данных между последовательными выполнениями на одном и том же драйвере. Подробнее о доменах памяти…

Android 10

В Android 10 представлен NN HAL 1.2, в котором есть следующие важные изменения:

  • Структура Capabilities включает все типы данных, в том числе скалярные, и представляет нерелаксированную производительность с помощью вектора, а не именованных полей.
  • Методы getVersionString и getType позволяют фреймворку получать информацию о типе (DeviceType) и версии устройства. Подробнее об обнаружении и назначении устройств…
  • По умолчанию метод executeSynchronously вызывается для синхронного выполнения. Метод execute_1_2 указывает фреймворку выполнить код асинхронно. Подробнее о выполнении…
  • Параметр MeasureTiming для executeSynchronously, execute_1_2 и пакетного выполнения указывает, должен ли драйвер измерять продолжительность выполнения. Результаты возвращаются в структуре Timing. Время.
  • Поддержка выполнений, в которых один или несколько выходных операндов имеют неизвестный размер или ранг. Подробнее о форме выходных данных…
  • Поддержка расширений поставщиков, которые представляют собой наборы определенных поставщиком операций и типов данных. Драйвер сообщает о поддерживаемых расширениях с помощью метода IDevice::getSupportedExtensions. Подробнее о расширениях поставщиков…
  • Возможность для объекта серийной съемки управлять набором серийных съемок с помощью быстрых очередей сообщений (FMQ) для связи между процессами приложения и драйвера, что снижает задержку. Подробнее о пакетном выполнении и быстрых очередях сообщений…
  • Поддержка AHardwareBuffer, позволяющая драйверу выполнять операции без копирования данных. AHardwareBuffer
  • Улучшена поддержка кеширования артефактов компиляции, чтобы сократить время, затрачиваемое на компиляцию при запуске приложения. Подробнее о кешировании компиляции…

В Android 10 представлены следующие типы операндов и операции.

  • Типы операндов

    • ANEURALNETWORKS_BOOL
    • ANEURALNETWORKS_FLOAT16
    • ANEURALNETWORKS_TENSOR_BOOL8
    • ANEURALNETWORKS_TENSOR_FLOAT16
    • ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
    • ANEURALNETWORKS_TENSOR_QUANT16_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
  • Операции

    • ANEURALNETWORKS_ABS
    • ANEURALNETWORKS_ARGMAX
    • ANEURALNETWORKS_ARGMIN
    • ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
    • ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
    • ANEURALNETWORKS_CAST
    • ANEURALNETWORKS_CHANNEL_SHUFFLE
    • ANEURALNETWORKS_DETECTION_POSTPROCESSING
    • ANEURALNETWORKS_EQUAL
    • ANEURALNETWORKS_EXP
    • ANEURALNETWORKS_EXPAND_DIMS
    • ANEURALNETWORKS_GATHER
    • ANEURALNETWORKS_GENERATE_PROPOSALS
    • ANEURALNETWORKS_GREATER
    • ANEURALNETWORKS_GREATER_EQUAL
    • ANEURALNETWORKS_GROUPED_CONV_2D
    • ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
    • ANEURALNETWORKS_INSTANCE_NORMALIZATION
    • ANEURALNETWORKS_LESS
    • ANEURALNETWORKS_LESS_EQUAL
    • ANEURALNETWORKS_LOG
    • ANEURALNETWORKS_LOGICAL_AND
    • ANEURALNETWORKS_LOGICAL_NOT
    • ANEURALNETWORKS_LOGICAL_OR
    • ANEURALNETWORKS_LOG_SOFTMAX
    • ANEURALNETWORKS_MAXIMUM
    • ANEURALNETWORKS_MINIMUM
    • ANEURALNETWORKS_NEG
    • ANEURALNETWORKS_NOT_EQUAL
    • ANEURALNETWORKS_PAD_V2
    • ANEURALNETWORKS_POW
    • ANEURALNETWORKS_PRELU
    • ANEURALNETWORKS_QUANTIZE
    • ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
    • ANEURALNETWORKS_RANDOM_MULTINOMIAL
    • ANEURALNETWORKS_REDUCE_ALL
    • ANEURALNETWORKS_REDUCE_ANY
    • ANEURALNETWORKS_REDUCE_MAX
    • ANEURALNETWORKS_REDUCE_MIN
    • ANEURALNETWORKS_REDUCE_PROD
    • ANEURALNETWORKS_REDUCE_SUM
    • ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
    • ANEURALNETWORKS_ROI_ALIGN
    • ANEURALNETWORKS_ROI_POOLING
    • ANEURALNETWORKS_RSQRT
    • ANEURALNETWORKS_SELECT
    • ANEURALNETWORKS_SIN
    • ANEURALNETWORKS_SLICE
    • ANEURALNETWORKS_SPLIT
    • ANEURALNETWORKS_SQRT
    • ANEURALNETWORKS_TILE
    • ANEURALNETWORKS_TOPK_V2
    • ANEURALNETWORKS_TRANSPOSE_CONV_2D
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN

В Android 10 обновлены многие существующие операции. Изменения в основном касаются следующего:

  • Поддержка макета памяти NCHW
  • Поддержка тензоров с рангом, отличным от 4, в операциях softmax и нормализации
  • Поддержка расширенных сверток
  • Поддержка входных данных со смешанной квантизацией в ANEURALNETWORKS_CONCATENATION

Ниже перечислены операции, которые были изменены в Android 10. Подробную информацию об изменениях можно найти в разделе OperationCode справочной документации по NNAPI.

  • ANEURALNETWORKS_ADD
  • ANEURALNETWORKS_AVERAGE_POOL_2D
  • ANEURALNETWORKS_BATCH_TO_SPACE_ND
  • ANEURALNETWORKS_CONCATENATION
  • ANEURALNETWORKS_CONV_2D
  • ANEURALNETWORKS_DEPTHWISE_CONV_2D
  • ANEURALNETWORKS_DEPTH_TO_SPACE
  • ANEURALNETWORKS_DEQUANTIZE
  • ANEURALNETWORKS_DIV
  • ANEURALNETWORKS_FLOOR
  • ANEURALNETWORKS_FULLY_CONNECTED
  • ANEURALNETWORKS_L2_NORMALIZATION
  • ANEURALNETWORKS_L2_POOL_2D
  • ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
  • ANEURALNETWORKS_LOGISTIC
  • ANEURALNETWORKS_LSH_PROJECTION
  • ANEURALNETWORKS_LSTM
  • ANEURALNETWORKS_MAX_POOL_2D
  • ANEURALNETWORKS_MEAN
  • ANEURALNETWORKS_MUL
  • ANEURALNETWORKS_PAD
  • ANEURALNETWORKS_RELU
  • ANEURALNETWORKS_RELU1
  • ANEURALNETWORKS_RELU6
  • ANEURALNETWORKS_RESHAPE
  • ANEURALNETWORKS_RESIZE_BILINEAR
  • ANEURALNETWORKS_RNN
  • ANEURALNETWORKS_ROI_ALIGN
  • ANEURALNETWORKS_SOFTMAX
  • ANEURALNETWORKS_SPACE_TO_BATCH_ND
  • ANEURALNETWORKS_SPACE_TO_DEPTH
  • ANEURALNETWORKS_SQUEEZE
  • ANEURALNETWORKS_STRIDED_SLICE
  • ANEURALNETWORKS_SUB
  • ANEURALNETWORKS_SVDF
  • ANEURALNETWORKS_TANH
  • ANEURALNETWORKS_TRANSPOSE

Android 9

В Android 9 представлена версия 1.1 интерфейса HAL для нейронных сетей, в которой есть следующие изменения:

  • IDevice::prepareModel_1_1 включает параметр ExecutionPreference. Водитель может использовать эту информацию, чтобы скорректировать свои действия, зная, что приложение предпочитает экономить заряд батареи или будет выполнять модель в быстрых последовательных вызовах.
  • Добавлено девять новых операций: BATCH_TO_SPACE_ND, DIV, MEAN, PAD, SPACE_TO_BATCH_ND, SQUEEZE, STRIDED_SLICE, SUB, TRANSPOSE.
  • Приложение может указать, что 32-битные вычисления с плавающей запятой могут выполняться с использованием 16-битного диапазона и/или точности с плавающей запятой, задав для параметра Model.relaxComputationFloat32toFloat16 значение true. В Capabilitiesструктуру добавлено поле relaxedFloat32toFloat16Performance, чтобы драйвер мог сообщать фреймворку о снижении производительности.

Android 8.1

Первая версия Neural Networks HAL (1.0) была выпущена в Android 8.1. Дополнительную информацию можно найти в статье /neuralnetworks/1.0/.