Драйверы API нейронных сетей

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

Дополнительную информацию об API нейронных сетей см. в разделе API нейронных сетей .

Нейронные сети HAL

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

Общая схема интерфейса между фреймворком и драйвером изображена на рисунке 1.

Поток нейронных сетей

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

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

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

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

Чтобы определить значения, возвращаемые драйвером в ответ на IDevice::getCapabilities_1_3 , используйте приложение NNAPI Benchmark для измерения производительности соответствующих типов данных. Модели MobileNet v1 и v2, asr_float и tts_float рекомендуются для измерения производительности 32-битных значений с плавающей запятой, а квантованные модели MobileNet v1 и v2 — для 8-битных квантованных значений. Подробнее см. в разделе Android Machine Learning Test Suite .

В 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 и Device Discovery and Assignment . В этом случае драйвер 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), имеют только референтную реализацию на CPU для проверки корректности тестов CTS и VTS. Оптимизированные реализации, включённые в мобильные фреймворки машинного обучения, предпочтительнее реализации на CPU через NNAPI.

Функции полезности

Кодовая база 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 содержит макросы для упрощения добавления информации о системной трассировке в код нейронных сетей. Пример см. в вызовах макроса NNTRACE_* в примере драйвера .

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

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

Проверка

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

Требования к точности CTS и VTS для NNAPI следующие:

  • С плавающей точкой: 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. Для драйверов с NN HAL 1.2 или выше, если результаты не соответствуют критериям точности, CTS сообщает об ошибке и сохраняет файл спецификации для неудавшейся модели в каталоге /data/local/tmp для отладки. Подробнее о критериях точности см. в файлах TestRandomGraph.cpp и TestHarness.h .

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

Цель фаззинга — обнаружение сбоев, утверждений, нарушений памяти или общего неопределённого поведения в тестируемом коде, вызванных такими факторами, как неожиданные входные данные. Для фаззинга 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 Machine Learning Test Suite (MLTS) — это бенчмарк NNAPI, входящий в состав CTS и VTS для проверки точности реальных моделей на устройствах производителей. Тест оценивает задержку и точность, а также сравнивает результаты драйверов с результатами, полученными с помощью TF Lite, работающего на центральном процессоре, для той же модели и наборов данных. Это гарантирует, что точность драйвера не хуже, чем у эталонной реализации на центральном процессоре.

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

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

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

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

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

Более подробную информацию см. platform/test/mlts/models .

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

Тестовый набор Android Machine Learning Test Suite включает в себя серию краш-тестов для проверки устойчивости водителей в условиях интенсивной эксплуатации или в особых случаях поведения клиентов.

Все краш-тесты предусматривают следующие характеристики:

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

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

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

Дополнительную информацию о стресс-тестировании и полный список краш-тестов см. в файле platform/test/mlts/benchmark/README.txt .

Использовать МЛТС

Чтобы использовать 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.

Андроид 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), поскольку приложения могут указывать относительные приоритеты своих моделей, максимальное время, ожидаемое для подготовки модели, и максимальное время, ожидаемое для завершения выполнения. Подробнее см. в разделе «Качество обслуживания» .
  • Поддержка доменов памяти, предоставляющих интерфейсы распределителей для буферов, управляемых драйвером. Это позволяет передавать собственную память устройства между выполнениями, предотвращая ненужное копирование и преобразование данных между последовательными выполнениями на одном драйвере. Подробнее см. в разделе Домены памяти .

Андроид 10

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

  • Структура Capabilities включает все типы данных, включая скалярные типы данных, и представляет нерелаксированную производительность с использованием вектора, а не именованных полей.
  • Методы getVersionString и getType позволяют фреймворку получать информацию о типе устройства ( DeviceType ) и его версии. См. раздел «Обнаружение и назначение устройств» .
  • Метод executeSynchronously вызывается по умолчанию для синхронного выполнения. Метод execute_1_2 сообщает фреймворку о необходимости асинхронного выполнения. См. раздел Выполнение .
  • Параметр MeasureTiming для executeSynchronously , execute_1_2 и burst execution определяет, будет ли драйвер измерять длительность выполнения. Результаты отображаются в структуре Timing . См. Timing .
  • Поддержка выполнения операций, в которых один или несколько выходных операндов имеют неизвестный размер или ранг. См. раздел «Форма выходных данных» .
  • Поддержка расширений поставщика, представляющих собой наборы операций и типов данных, определяемых поставщиком. Драйвер сообщает о поддерживаемых расширениях через метод IDevice::getSupportedExtensions . См. раздел Расширения поставщика .
  • Возможность объекта burst управлять набором пакетных выполнений с помощью быстрых очередей сообщений (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

Андроид 9

NN HAL 1.1 представлен в Android 9 и включает в себя следующие важные изменения.

  • 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 , чтобы драйвер мог сообщать фреймворку о своей производительности в режиме ослабления.

Андроид 8.1

Первая версия Neural Networks HAL (1.0) была выпущена в Android 8.1. Подробнее см. /neuralnetworks/1.0/ .