Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Controladores de API de redes neuronales

Esta página proporciona una descripción general de cómo implementar un controlador de API de redes neuronales (NNAPI). Para más detalles, consulte la documentación encontrada en los archivos de definición de HAL en hardware/interfaces/neuralnetworks . Una implementación del controlador de la muestra es en frameworks/ml/nn/driver/sample .

Para obtener más información sobre la API de redes neuronales, consulte API de Redes Neuronales .

Redes neuronales HAL

El Neural Networks (NN) HAL define una abstracción de los diversos dispositivos, tales como el procesamiento de gráficos (GPU) unidades y procesadores de señales digitales (DSP), que se encuentran en un producto (por ejemplo, un teléfono o tableta). Los controladores para estos dispositivos deben cumplir con la NN HAL. La interfaz se especifica en los archivos de definición de HAL en hardware/interfaces/neuralnetworks .

El flujo general de la interfaz entre el marco y un controlador se muestra en la figura 1.

Flujo de redes neuronales

Flujo de la Figura 1. Redes Neuronales

Inicialización

En la inicialización, el marco consulta al controlador por sus capacidades utilizando IDevice::getCapabilities_1_3 . El @1.3::Capabilities estructura incluye todos los tipos de datos y representa el rendimiento nonrelaxed utilizando un vector.

Para determinar cómo asignar los cálculos a los dispositivos disponibles, el marco utiliza las capacidades para comprender qué tan rápido y con qué eficiencia energética cada controlador puede realizar una ejecución. Para proporcionar esta información, el controlador debe proporcionar números de rendimiento estandarizados basados ​​en la ejecución de cargas de trabajo de referencia.

Para determinar los valores que el controlador devuelve en respuesta a IDevice::getCapabilities_1_3 , utilizan la aplicación NNAPI punto de referencia para medir el rendimiento de los tipos de datos correspondientes. El MobileNet v1 y v2, asr_float y tts_float se recomiendan los modelos para medir el rendimiento de los valores de punto flotante de 32 bits y el MobileNet v1 y v2 cuantificados se recomienda para los modelos de 8 bits valores cuantificados. Para obtener más información, consulte la máquina androide aprendizaje del conjunto de pruebas .

En Android 9 e inferior, el Capabilities estructura incluye información sobre el rendimiento conductor sólo para el punto y tensores cuantificados flotante y no incluye los tipos de datos escalares.

Como parte del proceso de inicialización, el marco puede consultar más información, utilizando IDevice::getType , IDevice::getVersionString , IDevice:getSupportedExtensions y IDevice::getNumberOfCacheFilesNeeded .

Entre reinicios del producto, el marco espera que todas las consultas descritas en esta sección siempre informen los mismos valores para un controlador determinado. De lo contrario, una aplicación que utilice ese controlador puede presentar un rendimiento reducido o un comportamiento incorrecto.

Compilacion

El marco determina qué dispositivos usar cuando recibe una solicitud de una aplicación. En Android 10, las aplicaciones pueden descubrir y especificar los dispositivos de los que elige el marco. Para obtener más información, consulte Detección de dispositivos y asignación .

En tiempo de compilación modelo, el marco envía el modelo a cada conductor candidato llamando IDevice::getSupportedOperations_1_3 . Cada controlador devuelve una matriz de valores booleanos que indican qué operaciones del modelo son compatibles. Un controlador puede determinar que no puede admitir una operación determinada por varias razones. Por ejemplo:

  • El controlador no admite el tipo de datos.
  • El controlador solo admite operaciones con parámetros de entrada específicos. Por ejemplo, un controlador puede admitir operaciones de convolución 3x3 y 5x5, pero no 7x7.
  • El controlador tiene limitaciones de memoria que le impiden manejar grandes gráficos o entradas.

Durante la compilación, la entrada, salida, y operandos interna del modelo, como se describe en OperandLifeTime , puede tener dimensiones o rango desconocidos. Para obtener más información, consulte la forma de salida .

El marco instruye a cada controlador seleccionado para preparar para ejecutar un subconjunto del modelo llamando IDevice::prepareModel_1_3 . Luego, cada controlador compila su subconjunto. Por ejemplo, un controlador puede generar código o crear una copia reordenada de los pesos. Debido a que puede haber una cantidad de tiempo significativa entre la compilación del modelo y la ejecución de las solicitudes, no se deben asignar recursos como grandes porciones de memoria del dispositivo durante la compilación.

En caso de éxito, el controlador devuelve un @1.3::IPreparedModel mango. Si el controlador devuelve un código de falla al preparar su subconjunto del modelo, el marco ejecuta todo el modelo en la CPU.

Para reducir el tiempo utilizado para la compilación cuando se inicia una aplicación, un controlador puede almacenar en caché los artefactos de compilación. Para obtener más información, véase Recopilación de almacenamiento en caché .

Ejecución

Cuando una aplicación solicita al marco para ejecutar una solicitud, el marco llama al IPreparedModel::executeSynchronously_1_3 método HAL por defecto para realizar una ejecución sincrónica en un modelo preparado. A petición también se puede ejecutar de forma asincrónica con el execute_1_3 método, el executeFenced método (ver la ejecución cerrado ), o ejecutado utilizando una ejecución de ráfaga .

Las llamadas de ejecución sincrónica mejoran el rendimiento y reducen la sobrecarga de subprocesos en comparación con las llamadas asincrónicas porque el control se devuelve al proceso de la aplicación solo después de que se completa la ejecución. Esto significa que el controlador no necesita un mecanismo separado para notificar al proceso de la aplicación que se completó una ejecución.

Con el asíncrona execute_1_3 método, el control vuelve al proceso de aplicación después de la ejecución ha comenzado, y el conductor debe notificar al marco cuando se haya completado la ejecución, utilizando el @1.3::IExecutionCallback .

La Request parámetro pasado a las listas método de ejecución los operandos de entrada y salida utilizados para la ejecución. La memoria que almacena los datos del operando debe usar el orden de fila principal con la primera dimensión iterando más lentamente y sin relleno al final de ninguna fila. Para obtener más información sobre los tipos de operandos, ver Operandos .

Para NN HAL 1.2 o superior conductores, cuando una solicitud se ha completado, el estado de error, de forma de salida , y la información de temporización son devueltos al marco. Durante la ejecución, la salida o los operandos internos del modelo pueden tener una o más dimensiones desconocidas o rango desconocido. Cuando al menos un operando de salida tiene una dimensión o rango desconocido, el controlador debe devolver información de salida de tamaño dinámico.

Para los controladores con NN HAL 1.1 o inferior, solo se devuelve el estado de error cuando se completa una solicitud. Las dimensiones de los operandos de entrada y salida deben especificarse completamente para que la ejecución se complete correctamente. Los operandos internos pueden tener una o más dimensiones desconocidas, pero deben tener un rango especificado.

Para las solicitudes de los usuarios que abarcan varios controladores, el marco es responsable de reservar la memoria intermedia y de secuenciar las llamadas a cada controlador.

Solicitudes múltiples se pueden iniciar en paralelo en la misma @1.3::IPreparedModel . El controlador puede ejecutar solicitudes en paralelo o serializar las ejecuciones.

El marco puede pedirle a un conductor que mantenga más de un modelo preparado. Por ejemplo, preparar modelo m1 , preparar m2 , ejecutar la solicitud r1 en m1 , ejecutar r2 en m2 , ejecutar r3 en m1 , ejecutar r4 en m2 , la liberación (descrito en Cleanup ) m1 , y la liberación m2 .

Para evitar una primera ejecución lenta que podría resultar en una mala experiencia del usuario (por ejemplo, una tartamudez en el primer fotograma), el controlador debe realizar la mayoría de las inicializaciones en la fase de compilación. La inicialización en la primera ejecución debe limitarse a acciones que afecten negativamente al estado del sistema cuando se realizan antes, como reservar grandes búferes temporales o aumentar la frecuencia de reloj de un dispositivo. Los controladores que pueden preparar solo un número limitado de modelos simultáneos pueden tener que inicializarlos en la primera ejecución.

En Android 10 o superior, en los casos en los que se ejecutan varias ejecuciones con el mismo modelo preparado en rápida sucesión, el cliente puede optar por utilizar un objeto de ráfaga de ejecución para comunicarse entre los procesos de la aplicación y el controlador. Para obtener más información, consulte Ejecuciones y rápido colas mensaje de ráfaga .

Para mejorar el rendimiento de varias ejecuciones en rápida sucesión, el controlador puede retener búferes temporales o aumentar la frecuencia del reloj. Se recomienda crear un hilo de vigilancia para liberar recursos si no se crean nuevas solicitudes después de un período de tiempo fijo.

Forma de salida

Para las solicitudes en las que uno o más operandos de salida no tienen todas las dimensiones especificadas, el controlador debe proporcionar una lista de formas de salida que contengan la información de dimensión para cada operando de salida después de la ejecución. Para obtener más información sobre las dimensiones, consulte OutputShape .

Si una ejecución falla debido a un búfer de salida de tamaño insuficiente, el controlador debe indicar qué operandos de salida tienen un tamaño de búfer insuficiente en la lista de formas de salida y debe informar tanta información dimensional como sea posible, utilizando cero para las dimensiones desconocidas.

Momento

En Android 10, una aplicación puede solicitar el tiempo de ejecución si la aplicación ha especificado un solo dispositivo para usar durante el proceso de compilación. Para más detalles, véase MeasureTiming y detección de dispositivos y asignación . En este caso, un conductor NN HAL 1.2 debe medir la duración de la ejecución o informe UINT64_MAX (para indicar que la duración no está disponible) al ejecutar una solicitud. El conductor debe minimizar cualquier penalización de rendimiento resultante de medir la duración de la ejecución.

El controlador informa de los siguientes períodos de duración en microsegundos en el Timing estructura:

  • El tiempo de ejecución en el dispositivo: no incluye el tiempo de ejecución en el conductor, que se ejecuta en el procesador host.
  • El tiempo de ejecución en el conductor: Incluye el tiempo de ejecución en el dispositivo.

Estas duraciones deben incluir el momento en que se suspende la ejecución, por ejemplo, cuando la ejecución ha sido reemplazada por otras tareas o cuando está esperando que un recurso esté disponible.

Cuando no se ha pedido al conductor para medir la duración de la ejecución, o cuando hay un error de ejecución, el conductor debe informar duraciones como UINT64_MAX . Incluso cuando se ha pedido al conductor para medir la duración de la ejecución, en su lugar puede reportar UINT64_MAX por el tiempo en el dispositivo, el tiempo en el controlador, o ambos. Cuando el conductor informa ambas duraciones como un valor distinto de UINT64_MAX , el tiempo de ejecución en el controlador debe ser igual o exceder el tiempo en el dispositivo.

Ejecución vallada

En Android 11, NNAPI permite ejecuciones que esperar a una lista de sync_fence manijas y, opcionalmente, devuelven un sync_fence objeto, que se señala cuando se completa la ejecución. Esto reduce la sobrecarga para modelos de secuencia pequeña y casos de uso de transmisión. Ejecución vallado también permite una mayor interoperabilidad eficiente con otros componentes que pueden señalar o esperar a que sync_fence . Para obtener más información sobre sync_fence , véase el marco de sincronización .

En una ejecución cercado, el marco llama al IPreparedModel::executeFenced método para poner en marcha un vallado, ejecución asíncrona en un modelo preparado con un vector de vallas de sincronización para esperar. Si la tarea asincrónica ha terminado antes de que vuelva la llamada, un mango de vacío puede ser devuelto para sync_fence . Un IFencedExecutionCallback objeto también debe ser devuelto para permitir que el marco de estado de error de consulta e información de duración.

Después de que se ha completado una ejecución, los siguientes dos temporización valores de medición de la duración de la ejecución se pueden consultar a través de IFencedExecutionCallback::getExecutionInfo .

  • timingLaunched : Duración de cuando executeFenced se llama a cuando executeFenced señala el vuelto syncFence .
  • timingFenced : Duración de cuando todas las cercas de la sincronización que espera la ejecución para cuando se señalizan a executeFenced señala el vuelto syncFence .

Flujo de control

Para dispositivos con Android 11 o superior, el NNAPI incluye dos operaciones de control de flujo, IF y WHILE , que tienen otros modelos como argumentos y ejecutarlos condicional ( IF ) o repetidamente ( WHILE ). Para obtener más información sobre cómo implementar esto, ver el flujo de control .

Calidad de servicio

En Android 11, la NNAPI incluye una calidad de servicio mejorada (QoS) al permitir que una aplicación indique las prioridades relativas de sus modelos, la cantidad máxima de tiempo que se espera para que se prepare un modelo y la cantidad máxima de tiempo que se espera para una ejecución. a completar. Para obtener más información, consulte Calidad de Servicio .

Limpiar

Cuando una aplicación se termina mediante un modelo de preparado, el marco libera su referencia a la @1.3::IPreparedModel objeto. Cuando el IPreparedModel ya no se hace referencia a objeto, se destruye automáticamente en el servicio de conductor que lo creó. Los recursos específicos del modelo se pueden reclamar en este momento en la implementación del controlador del destructor. Si el servicio de conductor quiere que el IPreparedModel objeto que se destruye automáticamente cuando ya no sea necesario por el cliente, no debe contener ninguna referencia a la IPreparedModel objeto después del IPreparedeModel objeto ha sido devuelto a través IPreparedModelCallback::notify_1_3 .

uso de CPU

Se espera que los controladores utilicen la CPU para configurar los cálculos. Los controladores no deberían usar la CPU para realizar cálculos gráficos porque eso interfiere con la capacidad del marco para asignar correctamente el trabajo. El controlador debe informar las partes que no puede manejar al marco y dejar que el marco maneje el resto.

El marco proporciona una implementación de CPU para todas las operaciones de NNAPI, excepto para las operaciones definidas por el proveedor. Para obtener más información, ver Vendor Extensions .

Las operaciones introducidas en Android 10 (nivel de la API 29) sólo tienen una implementación de referencia de la CPU para comprobar que las pruebas de CTS y VTS son correctos. Se prefieren las implementaciones optimizadas incluidas en los marcos de aprendizaje automático móvil sobre la implementación de CPU NNAPI.

Funciones de utilidad

El código base de NNAPI incluye funciones de utilidad que pueden ser utilizadas por los servicios del conductor.

La frameworks/ml/nn/common/include/Utils.h archivo contiene funciones de utilidad variados, tales como los utilizados para el registro y para la conversión entre diferentes versiones NN HAL.

  • Vlogging: VLOG es una macro envoltura alrededor de Android LOG que sólo registra el mensaje si la etiqueta apropiada se encuentra en el debug.nn.vlog propiedad. initVLogMask() debe llamarse antes de cualquier llamada a VLOG . El VLOG_IS_ON macro se puede utilizar para comprobar si VLOG está habilitada actualmente, lo que permite código de registro complicado que hay que saltar si no es necesario. El valor de la propiedad debe ser uno de los siguientes:

    • Una cadena vacía, que indica que no se debe realizar ningún registro.
    • El token 1 o all , lo que indica que todos los registros que se debe hacer.
    • Una lista de etiquetas, delimitadas por espacios, comas o dos puntos, que indica qué registro se debe realizar. Las etiquetas son compilation , cpuexe , driver , execution , manager , y el model .
  • compliantWithV1_* : Devuelve true si un objeto NN HAL se puede convertir en el mismo tipo de HAL una versión diferente sin perder información. Por ejemplo, llamar compliantWithV1_0 en un V1_2::Model devuelve false si el modelo incluye tipos de operación introducidos en NN NN HAL 1.1 o 1.2 HAL.

  • convertToV1_* : Convierte un objeto NN HAL de una versión a otra. Se registra una advertencia si la conversión da como resultado una pérdida de información (es decir, si la nueva versión del tipo no puede representar completamente el valor).

  • Capacidades: El nonExtensionOperandPerformance y update funciones se pueden utilizar para ayudar a construir las Capabilities::operandPerformance campo.

  • Consulta de propiedades de los tipos: isExtensionOperandType , isExtensionOperationType , nonExtensionSizeOfData , nonExtensionOperandSizeOfData , nonExtensionOperandTypeIsScalar , tensorHasUnspecifiedDimensions .

La frameworks/ml/nn/common/include/ValidateHal.h archivo contiene funciones de utilidad para la validación de que un objeto NN HAL es válido según la especificación del su versión HAL.

  • validate* : Devuelve true si el objeto NN HAL es válida según la especificación del su versión HAL. Los tipos de extensión y los tipos de OEM no están validados. Por ejemplo, validateModel devuelve false si el modelo contiene una operación que hace referencia a un índice de operando que no existe, o una operación que no es compatible en esa versión HAL.

La frameworks/ml/nn/common/include/Tracing.h archivo contiene macros para simplificar la adición de systracing información de código de Redes Neuronales. Para un ejemplo, véase los NNTRACE_* invocaciones macro en el controlador de ejemplo .

La frameworks/ml/nn/common/include/GraphDump.h archivo contiene una función de utilidad para volcar el contenido de un Model en forma gráfica para la depuración.

  • graphDump : escribe una representación del modelo en Graphviz ( .dot formato) a la corriente especificada (si se proporciona) o a la logcat (si no se proporciona ninguna corriente).

Validación

Para probar su implementación de la NNAPI, use las pruebas VTS y CTS incluidas en el marco de Android. VTS ejercita sus controladores directamente (sin usar el marco), mientras que CTS los ejercita indirectamente a través del marco. Éstos prueban cada método de API y verifican que todas las operaciones admitidas por los controladores funcionen correctamente y proporcionen resultados que cumplan con los requisitos de precisión.

Los requisitos de precisión en CTS y VTS para el NNAPI son los siguientes:

  • De punto flotante: abs (esperado - real) <= atol + rtol * abs (esperado); dónde:

    • Para fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
    • Para fp16, atol = rtol = 5.0f * 0.0009765625f
  • Cuantificados: off-by-one (excepto para mobilenet_quantized , que es off-by-tres)

  • Boole: coincidencia exacta

Una forma en que CTS prueba NNAPI es generando gráficos pseudoaleatorios fijos que se utilizan para probar y comparar los resultados de ejecución de cada controlador con la implementación de referencia de NNAPI. Para los conductores con NN HAL 1.2 o superior, si los resultados no cumplen con los criterios de precisión, CTS informa del error y vuelca un archivo de especificación del modelo fracasado bajo /data/local/tmp para la depuración. Para más detalles sobre los criterios de precisión, consulte TestRandomGraph.cpp y TestHarness.h .

Prueba de fuzz

El propósito de las pruebas de fuzz es encontrar fallas, afirmaciones, violaciones de memoria o comportamiento general indefinido en el código bajo prueba debido a factores como entradas inesperadas. Para la prueba de pelusa NNAPI, Android utiliza pruebas basadas en libFuzzer , que son eficientes en la fuzzing debido a que utilizan la cobertura de líneas de casos de prueba anteriores para generar nuevas entradas aleatorias. Por ejemplo, libFuzzer favorece los casos de prueba que se ejecutan en nuevas líneas de código. Esto reduce en gran medida la cantidad de tiempo que tardan las pruebas en encontrar código problemático.

Para llevar a cabo la pelusa pruebas para validar la implementación del controlador, Modificar frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp en el libneuralnetworks_driver_fuzzer utilidad de prueba encuentra en AOSP de incluir su código de controlador. Para obtener más información sobre las pruebas de pelusa NNAPI, consulte frameworks/ml/nn/runtime/test/android_fuzzing/README.md .

Seguridad

Debido a que los procesos de la aplicación se comunican directamente con el proceso de un controlador, los controladores deben validar los argumentos de las llamadas que reciben. Esta validación es verificada por VTS. El código de validación es en frameworks/ml/nn/common/include/ValidateHal.h .

Los conductores también deben asegurarse de que las aplicaciones no puedan interferir con otras aplicaciones cuando utilicen el mismo dispositivo.

Conjunto de pruebas de aprendizaje automático de Android

Android Machine Learning Test Suite (MLTS) es un punto de referencia NNAPI incluido en CTS y VTS para validar la precisión de modelos reales en dispositivos de proveedores. Las evalúa referencia latencia y exactitud, y compara los resultados de los pilotos con los resultados utilizando TF Lite se ejecuta en la CPU, para el mismo modelo y conjuntos de datos. Esto asegura que la precisión de un controlador no sea peor que la implementación de referencia de la CPU.

Los desarrolladores de la plataforma Android también utilizan MLTS para evaluar la latencia y la precisión de los controladores.

El punto de referencia NNAPI se puede encontrar en dos proyectos en AOSP:

Modelos y conjuntos de datos

El punto de referencia NNAPI utiliza los siguientes modelos y conjuntos de datos.

  • MobileNetV1 float y u8 cuantificados en diferentes tamaños, se ejecutan en un pequeño subconjunto (1500 imágenes) de Open Images Dataset v4.
  • MobileNetV2 float y u8 cuantificados en diferentes tamaños, se ejecutan en un pequeño subconjunto (1500 imágenes) de Open Images Dataset v4.
  • Modelo acústico basado en memoria a largo plazo a corto plazo (LSTM) para conversión de texto a voz, que se ejecuta en un pequeño subconjunto del conjunto CMU Arctic.
  • Modelo acústico basado en LSTM para el reconocimiento automático de voz, que se ejecuta en un pequeño subconjunto del conjunto de datos LibriSpeech.

Para obtener más información, consulte platform/test/mlts/models .

Pruebas de estrés

El conjunto de pruebas de aprendizaje automático de Android incluye una serie de pruebas de choque para validar la resistencia de los controladores en condiciones de uso intensivo o en casos extremos de comportamiento de los clientes.

Todas las pruebas de choque ofrecen las siguientes características:

  • Detección Colgar: Si se bloquea el cliente NNAPI durante una prueba, la prueba falla con la causa de fallo HANG y la suite de prueba se desplaza a la siguiente prueba.
  • NNAPI detección de accidentes cliente: Pruebas sobreviven cliente se bloquea y pruebas fallan con la causa de fallo CRASH .
  • Detección de accidentes del conductor: Las pruebas pueden detectar un accidente conductor que causa un fallo en una llamada NNAPI. Tenga en cuenta que puede haber bloqueos en los procesos del controlador que no provoquen una falla de NNAPI y no provoquen que la prueba falle. Para cubrir este tipo de fallo, se recomienda ejecutar la tail de comandos en el registro del sistema para errores o accidentes relacionados con el conductor.
  • La orientación de todos los aceleradores disponibles: Las pruebas se ejecutan en contra de todos los controladores disponibles.

Todas las pruebas de choque tienen los siguientes cuatro resultados posibles:

  • SUCCESS : Ejecución completado sin error.
  • FAILURE : Ejecución fallado. Por lo general, se debe a una falla al probar un modelo, lo que indica que el controlador no pudo compilar o ejecutar el modelo.
  • HANG : proceso de prueba dejó de responder.
  • CRASH : proceso de prueba se estrelló.

Para obtener más información sobre la prueba de esfuerzo y una lista completa de las pruebas de choque, consulte platform/test/mlts/benchmark/README.txt .

Usando MLTS

Para usar MLTS:

  1. Conectar un dispositivo de destino a la estación de trabajo y asegúrese de que es accesible a través de adb . Exportar el dispositivo de destino ANDROID_SERIAL variable de entorno si está conectado más de un dispositivo.
  2. cd en el directorio de más alto nivel Android.

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

    Al final de una ejecución de referencia, los resultados se presentan como una página HTML y se pasan a xdg-open .

Para obtener más información, consulte platform/test/mlts/benchmark/README.txt .

Versiones HAL de redes neuronales

Esta sección describe los cambios introducidos en las versiones HAL de Android y Neural Networks.

Android 11

Android 11 presenta NN HAL 1.3, que incluye los siguientes cambios notables.

  • Soporte para cuantificación firmada de 8 bits en NNAPI. Agrega el TENSOR_QUANT8_ASYMM_SIGNED tipo de operando. Los controladores con NN HAL 1.3 que admiten operaciones con cuantificación sin firmar también deben admitir las variantes firmadas de esas operaciones. Cuando se ejecuta versiones con y sin signo de la mayoría de las operaciones cuantificados, los conductores deben producir los mismos resultados hasta un desplazamiento de 128. Hay cinco excepciones a este requisito: CAST , HASHTABLE_LOOKUP , LSH_PROJECTION , PAD_V2 y QUANTIZED_16BIT_LSTM . El QUANTIZED_16BIT_LSTM operación no es compatible con operandos firmados y las otras cuatro operaciones de apoyo a la cuantificación firmado, pero no necesita resultados a ser el mismo.
  • El apoyo a las ejecuciones vallado donde el marco llama al IPreparedModel::executeFenced método para poner en marcha un vallado, ejecución asíncrona en un modelo preparado con un vector de vallas de sincronización para esperar. Para obtener más información, consulte la ejecución cercado .
  • Soporte para control de flujo. Añade los IF y WHILE operaciones, que tienen otros modelos como argumentos y ejecutarlas de forma condicional ( IF ) o repetidamente ( WHILE ). Para obtener más información, consulte el flujo de control .
  • Calidad de servicio (QoS) mejorada, ya que las aplicaciones pueden indicar las prioridades relativas de sus modelos, la cantidad máxima de tiempo que se espera para que se prepare un modelo y la cantidad máxima de tiempo que se espera para que se complete una ejecución. Para obtener más información, consulte Calidad de Servicio .
  • Soporte para dominios de memoria que proporcionan interfaces de asignación para búferes administrados por controladores. Esto permite pasar las memorias nativas del dispositivo a través de ejecuciones, suprimiendo la copia y transformación de datos innecesarias entre ejecuciones consecutivas en el mismo controlador. Para obtener más información, consulte los dominios de memoria .

Android 10

Android 10 presenta NN HAL 1.2, que incluye los siguientes cambios notables.

  • El Capabilities estructura incluye todos los tipos de datos que incluyen tipos de datos escalares, y representa el rendimiento nonrelaxed utilizando un vector en vez de campos nombrados.
  • Los getVersionString y getType métodos permiten el marco para recuperar el tipo de dispositivo ( DeviceType ) y la información de versión. Ver detección de dispositivos y asignación .
  • El executeSynchronously método es llamado por defecto para realizar una ejecución sincrónica. El execute_1_2 método indica el marco para llevar a cabo una ejecución asíncrona. Ver ejecución .
  • El MeasureTiming parámetro para executeSynchronously , execute_1_2 especifica, y ejecución de ráfaga si el controlador es para medir la duración de ejecución. Los resultados se presentan en la Timing estructura. Ver Timing .
  • Soporte para ejecuciones donde uno o más operandos de salida tienen una dimensión o rango desconocido. Ver la forma de salida .
  • Soporte para extensiones de proveedor, que son colecciones de operaciones y tipos de datos definidos por el proveedor. Los informes de controladores extensiones soportadas a través de la IDevice::getSupportedExtensions método. Ver Vendor Extensions .
  • Capacidad para que un objeto de ráfaga controle un conjunto de ejecuciones de ráfaga utilizando colas de mensajes rápidos (FMQ) para comunicarse entre los procesos de aplicación y controlador, lo que reduce la latencia. Ver las ejecuciones de ráfaga y colas de mensajes rápidos .
  • Soporte para AHardwareBuffer para permitir que el controlador realice ejecuciones sin copiar datos. Ver AHardwareBuffer .
  • Soporte mejorado para el almacenamiento en caché de artefactos de compilación para reducir el tiempo utilizado para la compilación cuando se inicia una aplicación. Ver Compilación de almacenamiento en caché .

Android 10 presenta los siguientes tipos de operandos y operaciones.

  • Tipos de operandos

    • 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
  • Operaciones

    • 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 presenta actualizaciones para muchas de las operaciones existentes. Las actualizaciones están relacionadas principalmente con lo siguiente:

  • Soporte para el diseño de memoria NCHW
  • Soporte para tensores con rango diferente a 4 en softmax y operaciones de normalización
  • Soporte para convoluciones dilatadas
  • Soporte para las entradas con la cuantificación mixta en ANEURALNETWORKS_CONCATENATION

La siguiente lista muestra las operaciones que se han modificado en Android 10. Para los detalles completos de los cambios, ver operationCode en la documentación de referencia 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

NN HAL 1.1 se introduce en Android 9 e incluye los siguientes cambios notables.

  • IDevice::prepareModel_1_1 incluye un ExecutionPreference parámetro. Un conductor puede usar esto para ajustar su preparación, sabiendo que la aplicación prefiere ahorrar batería o ejecutará el modelo en llamadas sucesivas rápidas.
  • Se han añadido nueve nuevas operaciones: BATCH_TO_SPACE_ND , DIV , MEAN , PAD , SPACE_TO_BATCH_ND , SQUEEZE , STRIDED_SLICE , SUB , TRANSPOSE .
  • Una aplicación puede especificar que los cálculos flotantes de 32 bits se pueden ejecutar con rango y / o precisión flotante de 16 bits mediante el establecimiento de Model.relaxComputationFloat32toFloat16 de true . El Capabilities estructura tiene el campo adicional relaxedFloat32toFloat16Performance de manera que el conductor puede reportar su desempeño relajado para el marco.

Android 8.1

El HAL de redes neuronales inicial (1.0) se lanzó en Android 8.1. Para obtener más información, consulte /neuralnetworks/1.0/ .