Controladores de la API de Neural Networks

En esta página, se proporciona una descripción general sobre cómo implementar una API de Neural Networks (NNAPI) controlador. Para obtener más detalles, consulta la documentación incluida en la definición de HAL. archivos en hardware/interfaces/neuralnetworks Una implementación de controlador de muestra está en frameworks/ml/nn/driver/sample

Para obtener más información sobre la API de Neural Networks, consulta API de redes neuronales.

HAL de redes neuronales

La HAL de redes neuronales (NN) define una abstracción de los distintos dispositivos, como unidades de procesamiento gráfico (GPU) y procesadores de señal digital (DSP), contenido de un producto (por ejemplo, un teléfono o una tablet). Los impulsores de estos los dispositivos deben cumplir con la NN HAL. La interfaz se especifica en la HAL archivos de definición en hardware/interfaces/neuralnetworks

Se representa el flujo general de la interfaz entre el framework y un controlador. de la figura 1.

Flujo de redes neuronales

Figura 1: Flujo de redes neuronales

Inicialización

En la inicialización, el framework consulta al controlador para conocer sus capacidades mediante IDevice::getCapabilities_1_3 La estructura @1.3::Capabilities incluye todos los tipos de datos y representa el rendimiento sin relajación mediante el uso de un vector.

Para determinar cómo asignar cálculos a los dispositivos disponibles, el de la nube usa las capacidades para comprender qué tan rápido y cómo de manera eficiente 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 muestra el controlador en respuesta a IDevice::getCapabilities_1_3, usa la app comparativa de la NNAPI para medir para los tipos de datos correspondientes. MobileNet v1 y v2, asr_float, se recomiendan los modelos tts_float y tts_float para medir el rendimiento los valores de punto flotante y los modelos cuantizados de MobileNet v1 y v2 se recomienda para valores cuantificados de 8 bits. Para obtener más información, consulta Conjunto de pruebas de aprendizaje automático de Android.

En Android 9 y versiones anteriores, la estructura Capabilities incluye el rendimiento del controlador. información solo para punto flotante y tensores cuantificados, y no incluye tipos de datos escalares.

Como parte del proceso de inicialización, el framework podría consultar más información mediante IDevice::getType: IDevice::getVersionString: IDevice:getSupportedExtensions y IDevice::getNumberOfCacheFilesNeeded.

Entre los reinicios del producto, el framework espera todas las consultas descritas en este a fin de informar siempre los mismos valores para un controlador determinado. De lo contrario, una app usar ese controlador puede reducir el rendimiento o generar un comportamiento incorrecto.

Compilación

El framework determina qué dispositivos usar cuando recibe una solicitud de un . En Android 10, las apps pueden descubrir y especifica los dispositivos entre las que se selecciona el framework. Para obtener más información, consulta Descubrimiento y asignación de dispositivos.

En el momento de la compilación del modelo, el framework envía el modelo a cada candidato. al conductor llamando IDevice::getSupportedOperations_1_3 Cada controlador devuelve un array de booleanos que indican qué se admiten las operaciones del modelo. Un conductor puede determinar que no puede respaldar 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. Para Por ejemplo, un controlador podría admitir 3 × 3 y 5 × 5, pero no convolución de 7 × 7 las operaciones.
  • El controlador tiene restricciones de memoria que le impiden manejar grandes grafos o entradas.

Durante la compilación, la entrada, la salida y los operandos internos del modelo, como descritos en OperandLifeTime: pueden tener dimensiones o clasificaciones desconocidas. Para obtener más información, consulta Forma de la salida.

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

Si se ejecuta de forma correcta, el controlador muestra un @1.3::IPreparedModel. o un controlador de políticas. Si el controlador muestra un código de falla cuando prepara su subconjunto de la modelo, el framework ejecuta todo el modelo en la CPU.

Para reducir el tiempo que se usa para la compilación cuando se inicia una app, un controlador puede artefactos de compilación en caché. Para obtener más información, consulta Compilación Almacenamiento en caché.

Ejecución

Cuando una app le solicita al framework que ejecute una solicitud, este llama a el IPreparedModel::executeSynchronously_1_3 Es el método HAL de forma predeterminada para realizar una ejecución síncrona en un modelo preparado. Una solicitud también se puede ejecutar de forma asíncrona con el execute_1_3 executeFenced (consulta Ejecución cercada), o ejecutado con una ejecución en ráfaga.

Las llamadas de ejecución síncronas mejoran el rendimiento y reducen los subprocesos en comparación con las llamadas asíncronas, ya que el control se devuelve el proceso de la app solo después de que se complete la ejecución. Esto significa que el no necesita un mecanismo separado para notificarle al proceso de la app que se completa una ejecución.

Con el método execute_1_3 asíncrono, el control vuelve a la proceso de la app una vez iniciada la ejecución, y el controlador debe notificar el framework cuando se completa la ejecución, con el @1.3::IExecutionCallback

El parámetro Request que se pasa al método de ejecución enumera la entrada y la salida operandos usados para la ejecución. La memoria que almacena los datos del operando se debe usar el orden de fila mayor en el que la primera dimensión itera la más lenta y no tiene relleno al final de cualquier fila. Para obtener más información sobre los tipos de operandos, ver Operandos.

Para controladores NN HAL 1.2 o superiores, cuando se inicia una solicitud, completado, el estado del error, la forma de salida y se devuelven información de tiempo. al framework. Durante la ejecución, la salida o los operandos internos del modelo pueden tienen una o más dimensiones desconocidas o clasificación desconocida. Cuando al menos una salida el operando tiene una dimensión o clasificación desconocida, el controlador debe mostrar tamaño de la información de salida de forma dinámica.

En el caso de los conductores con NN HAL 1.1 o anterior, solo se muestra el estado de error cuando un cuando se complete la solicitud. Las dimensiones de los operandos de entrada y salida deben ser especificadas para que la ejecución se complete correctamente. Los operandos internos pueden tienen una o más dimensiones desconocidas, pero deben tener una clasificación específica.

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

Varias solicitudes pueden iniciarse en paralelo en la misma @1.3::IPreparedModel El controlador puede ejecutar solicitudes en paralelo o serializar las ejecuciones.

El framework puede pedirle al controlador que mantenga más de un modelo preparado. Para ejemplo, preparar modelo m1, preparar m2, ejecutar solicitud r1 en m1, ejecutar r2 en m2, ejecuta r3 en m1, ejecuta r4 en m2, versión (descrita en Limpiar) m1 y libera m2.

Para evitar una primera ejecución lenta que podría dar lugar a una mala experiencia del usuario (por ejemplo, un primer entretejido de fotograma), el controlador debería 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 afectan negativamente el estado del sistema cuando se realizan de forma temprana, como reservar grandes búferes temporales o aumentar la frecuencia de reloj de un dispositivo. Los controladores que pueden preparar solo una cantidad limitada de modelos simultáneos podrían tener para que haga la inicialización en la primera ejecución.

En Android 10 o versiones posteriores, si hay varios ejecuciones con el mismo modelo preparado se ejecuten en sucesión rápida, el cliente puede optar por usar una un objeto de ráfaga para comunicarse entre los procesos de la app y del controlador. Para ver más información, consulta Ejecuciones en ráfaga y colas de mensajes rápidos.

Para mejorar el rendimiento de varias ejecuciones seguidas con rapidez, el controlador pueden conservar los búferes temporales o aumentar la frecuencia del reloj. Crea un perro guardián subproceso para liberar recursos si no se crean solicitudes nuevas después un período de tiempo fijo.

Forma de la salida

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

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

Tiempos

En Android 10, una app puede solicitar la ejecución tiempo si la app especificó un solo dispositivo para usar durante el proceso de compilación. Para en detalle, consulta MeasureTiming y Descubrimiento y asignación de dispositivos. En este caso, un El controlador NN HAL 1.2 debe medir la duración de la ejecución o informar UINT64_MAX (a indicar que la duración no está disponible) cuando se ejecuta una solicitud. El conductor Deben minimizar cualquier penalización de rendimiento que resulte de la medición de la ejecución. y el tiempo de actividad.

El controlador informa las siguientes duraciones en microsegundos en la Timing estructura:

  • Tiempo de ejecución en el dispositivo: No se incluye el tiempo de ejecución en la que se ejecuta en el procesador del host.
  • Tiempo de ejecución en el controlador: Incluye el tiempo de ejecución en el dispositivo.

Estas duraciones deben incluir el momento en que se suspende la ejecución, por por ejemplo, cuando otras tareas interrumpieron la ejecución o cuando a que un recurso esté disponible.

Cuando no se le solicita al conductor que mida la duración de la ejecución o cuando Se produjo un error de ejecución, el conductor debe informar las duraciones como UINT64_MAX Incluso cuando se le haya solicitado al conductor que mida la ejecución duración, puede informar UINT64_MAX para la hora en el dispositivo, la hora en la 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 superior al tiempo del el dispositivo.

Ejecución cercada

En Android 11, NNAPI permite que las ejecuciones esperen una una lista de controladores sync_fence y, de manera opcional, mostrar un objeto sync_fence, que se indica cuando finaliza la ejecución. Esto reduce la sobrecarga de operaciones pequeñas de secuencias y casos de uso de transmisión. La ejecución cercada también permite más una interoperabilidad eficiente con otros componentes que pueden indicar o esperar sync_fence Para obtener más información sobre sync_fence, consulta Framework de sincronización.

En una ejecución cercada, el framework llama a la IPreparedModel::executeFenced método para iniciar una ejecución cercada y asíncrona en un modelo preparado con una vector de vallas de sincronización que hay que esperar. Si la tarea asíncrona finaliza antes de si se muestra la llamada, se puede mostrar un identificador vacío para sync_fence. Los También se debe mostrar el objeto IFencedExecutionCallback para permitir el framework para consultar información sobre el estado del error y la duración.

Cuando se completa una ejecución, las siguientes dos opciones Valores de timing La medición de la duración de la ejecución se puede consultar IFencedExecutionCallback::getExecutionInfo

  • timingLaunched: Duración desde el momento en que se llama a executeFenced hasta el momento en executeFenced indica el objeto syncFence que se muestra.
  • timingFenced: Duración desde el momento en que se aplican todas las vallas de sincronización a las que se señala la ejecución cuando executeFenced indica el objeto syncFence que se muestra.

Flujo de control

En dispositivos con Android 11 o versiones posteriores, la NNAPI incluye dos operaciones de flujo de control, IF y WHILE, que toman otros modelos como argumentos y ejecutarlos de forma condicional (IF) o repetidamente (WHILE). Para para obtener más información sobre cómo implementarlo, consulta Flujo de control.

Calidad de servicio

En Android 11, la NNAPI incluye una calidad mejorada de de servicio (QoS), ya que permite que una app indique las prioridades relativas de su modelos de AA, la cantidad máxima de tiempo que se espera para que un modelo esté preparado y la cantidad máxima de tiempo esperado para que se complete una ejecución. Para más información, consulta Calidad de Servicio.

Limpieza

Cuando una app termina de usar un modelo preparado, el framework se lanza su referencia al @1.3::IPreparedModel . Cuando ya no se hace referencia al objeto IPreparedModel, se se destruye automáticamente en el servicio del controlador que lo creó. Específico del modelo recursos pueden recuperarse en este momento en la implementación del controlador del destructor. Si el servicio del controlador desea que el objeto IPreparedModel se destruye automáticamente cuando el cliente ya no lo necesita, no debe contener cualquier referencia al objeto IPreparedModel después del objeto IPreparedeModel se devolvió mediante IPreparedModelCallback::notify_1_3

Uso de CPU

Se espera que los controladores usen la CPU para configurar los procesamientos. Los conductores no deben usan la CPU para realizar cálculos de grafos porque interfieren del framework para asignar correctamente el trabajo. El conductor debería informar lo siguiente: las partes que no puede controlar en el framework y deja que este se encargue del el resto.

El framework proporciona una implementación de CPU para todas las operaciones de la NNAPI, excepto las las operaciones definidas por el proveedor. Para obtener más información, consulta Extensiones de proveedores.

El operaciones que se introdujeron en Android 10 (nivel de API 29) solo tienen una implementación de CPU de referencia para verificar que las pruebas de CTS y VTS son correctas. Las implementaciones optimizadas incluidas en el aprendizaje automático para dispositivos móviles se prefieren los frameworks en lugar de la implementación de CPU de la NNAPI.

Funciones de utilidad

La base de código de la NNAPI incluye funciones de utilidad que el controlador puede utilizar de Google Cloud.

El frameworks/ml/nn/common/include/Utils.h contiene varias funciones de utilidad, como las que se usan para registrar y para la conversión entre diferentes versiones de NN HAL.

  • VLogging: VLOG es una macro wrapper alrededor del LOG de Android que solo registra el mensaje si la etiqueta adecuada está configurada en el debug.nn.vlog propiedad. initVLogMask() se debe llamar antes de cualquier llamada a VLOG. La macro VLOG_IS_ON puede ser se usa para verificar si VLOG está habilitado, lo que habilita un registro complicado que se omita si no es necesario. El valor de la propiedad debe ser una de las siguientes opciones:

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

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

  • Funciones: nonExtensionOperandPerformance y update se pueden usar para ayudar a crear la Capabilities::operandPerformance .

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

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

  • validate*: Muestra true si el objeto NN HAL es válido. según la especificación de su versión de HAL. Tipos de OEM y tipos de extensiones no están validados. Por ejemplo, validateModel muestra false si la contiene una operación que hace referencia a un índice de operando que no o una operación que no es compatible con esa versión del HAL.

El frameworks/ml/nn/common/include/Tracing.h contiene macros para simplificar la adición información de seguimiento del sistema al código de redes neuronales. Por ejemplo, consulta las invocaciones de la macro NNTRACE_* en la controlador de muestra.

El frameworks/ml/nn/common/include/GraphDump.h contiene una función de utilidad para volcar el contenido de un Model en un gráfico para fines de depuración.

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

Validación

Para probar tu implementación de la NNAPI, usa las pruebas de VTS y CTS incluidas en el framework de Android. El VTS evalúa a tus conductores directamente (sin usar el {i>framework <i}), mientras que el CTS las aplica indirectamente a través del framework. Estos probar cada método de API y verificar que todas las operaciones admitidas por el los controladores funcionan correctamente y proporcionan resultados que cumplen con los requisitos de precisión.

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

  • Punto flotante: abs(previsto - real) <= atol + rtol * absoluto(previsto); En el ejemplo anterior, se ilustra lo siguiente:

    • Para fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
    • Para fp16, atol = rtol = 5.0f * 0.0009765625f
  • Cuantizada: una por una (excepto por mobilenet_quantized, que tiene una diferencia de tres)

  • Booleano: concordancia exacta

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

Prueba de Fuzz

El propósito de las pruebas de Fuzz es encontrar fallas, aserciones, incumplimientos de memoria, o comportamiento indefinido general en el código que se prueba debido a factores, como entradas inesperadas. Para la prueba de Fuzz sobre la NNAPI, Android usa pruebas basadas en libFuzzer, que son son eficaces en el fuzzing porque usan la cobertura 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 el tiempo que tardan las pruebas en encontrar código problemático.

Para realizar pruebas de fuzzing a fin de validar la implementación de tu controlador, modifica frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp en la utilidad de prueba libneuralnetworks_driver_fuzzer que se encuentra en el AOSP para incluir tu código de conductor. Para obtener más información sobre las pruebas de Fuzz sobre la NNAPI, consulta frameworks/ml/nn/runtime/test/android_fuzzing/README.md

Seguridad

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

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

Paquete de pruebas de aprendizaje automático de Android

El Conjunto de pruebas de aprendizaje automático (MLTS) de Android es una comparativa de la NNAPI incluida en CTS y VTS para validar la precisión de modelos reales en dispositivos de proveedores. El evalúa la latencia y la exactitud, y compara resultados con los resultados con TF Lite que se ejecuta en la CPU para el mismo modelo y conjuntos de datos. Esto garantiza que la precisión del conductor no sea es peor que la implementación de referencia de la CPU.

Los desarrolladores de la plataforma de Android también usan MLTS para evaluar la latencia y la precisión de conductores.

Las comparativas de la NNAPI se pueden encontrar en dos proyectos en AOSP:

Modelos y conjuntos de datos

Las comparativas de la NNAPI usan los siguientes modelos y conjuntos de datos.

  • MobileNetV1 float y u8 cuantificados en distintos tamaños, ejecutados frente a un subconjunto pequeño (1,500 imágenes) de Open Images Dataset v4.
  • float de MobileNetV2 y u8 cuantificados en distintos tamaños, ejecutados frente a un subconjunto pequeño (1,500 imágenes) de Open Images Dataset v4.
  • Modelo acústico basado en memoria a corto plazo (LSTM) para texto a voz. se ejecuta en un pequeño subconjunto del conjunto CMU Arctic.
  • Modelo acústico basado en LSTM para reconocimiento de voz automático, ejecutado contra un pequeño subconjunto del conjunto de datos de LibriSpeech.

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

Pruebas de esfuerzo

El paquete de pruebas de aprendizaje automático de Android incluye una serie de pruebas de fallas para validar la resiliencia de los conductores en condiciones de uso intensivo o en las esquinas casos de clientes el comportamiento de los usuarios.

Todas las pruebas de fallas incluyen las siguientes funciones:

  • Detección de bloqueo: Si el cliente NNAPI se bloquea durante una prueba, el la prueba falla con el motivo de la falla HANG y el paquete de pruebas pasa a la siguiente prueba.
  • Detección de fallas del cliente de la NNAPI: Las pruebas sobreviven a las fallas y pruebas del cliente. falla con el motivo CRASH.
  • Detección de accidentes del conductor: Las pruebas pueden detectar un accidente del conductor. que provoca una falla en una llamada a la NNAPI. Ten en cuenta que puede haber fallas en procesos del controlador que no causan una falla en la NNAPI y no generan la prueba a fracasar. Para cubrir este tipo de falla, se recomienda ejecutar tail en el registro del sistema para detectar fallas o errores relacionados con el controlador.
  • Segmentación de todos los aceleradores disponibles: Las pruebas se ejecutan en todos los de los controladores disponibles.

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

  • SUCCESS: Se completó la ejecución sin un error.
  • FAILURE: No se pudo ejecutar. Por lo general, se debe a una falla cuando probar un modelo, lo que indica que el controlador no se pudo compilar o ejecutar el modelo.
  • HANG: El proceso de prueba dejó de responder.
  • CRASH: Falló el proceso de prueba.

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

Usa MLTS

Para usar MLTS, haz lo siguiente:

  1. Conecta un dispositivo de destino a tu estación de trabajo y asegúrate de que esté accesible a través de adb. Exporta el dispositivo de destino ANDROID_SERIAL si hay más de un dispositivo conectado.
  2. cd al directorio del código fuente de nivel superior de Android.

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

    Cuando termina la ejecución de la comparativa, los resultados se presentan como una página HTML. y se pasan a xdg-open.

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

Versiones de HAL de redes neuronales

En esta sección, se describen los cambios introducidos en Android y Neural Versiones de HAL de redes

Android 11

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

  • Compatibilidad con la cuantización de 8 bits con firma en la NNAPI. Agrega el TENSOR_QUANT8_ASYMM_SIGNED tipo de operando. Controladores con NN HAL 1.3 compatibles Las operaciones con cuantización sin firma también deben admitir las variantes firmadas de esas operaciones. Cuando se ejecutan versiones firmadas y sin firmar de la mayoría o cuantificadas, los controladores deben producir los mismos resultados hasta con un desplazamiento de 128. Existen cinco excepciones a este requisito: CAST, HASHTABLE_LOOKUP, LSH_PROJECTION, PAD_V2 y QUANTIZED_16BIT_LSTM. La operación QUANTIZED_16BIT_LSTM no admite operandos con signo y las otras cuatro operaciones admiten la cuantización con firma, pero no requieren resultados sean los mismos.
  • Compatibilidad con ejecuciones cercadas en las que el framework llama al IPreparedModel::executeFenced método para iniciar una ejecución cercada y asíncrona en un modelo preparado con una vector de vallas de sincronización que hay que esperar. Para obtener más información, consulta Ejecución cercada.
  • Compatibilidad con el flujo de control Agrega las operaciones IF y WHILE, que toman otros modelos como argumentos y ejecutarlos condicionalmente (IF) o repetidamente (WHILE). Para obtener más información, consulta Flujo de control.
  • Una mejor calidad de servicio (QoS), ya que las apps pueden indicar prioridades de sus modelos, la cantidad máxima de tiempo esperado para un que el modelo esté preparado y la cantidad máxima de tiempo que se espera para la ejecución del proyecto. Para obtener más información, consulta Calidad de Servicio.
  • Compatibilidad con dominios de memoria que proporcionan interfaces asignables para búferes administrados por controladores. Esto permite pasar memorias nativas del dispositivo entre ejecuciones, lo que evita la transformación y copia innecesarias de datos entre ejecuciones consecutivas en el mismo controlador. Para obtener más información, consulta Dominios de memoria.

Android 10

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

  • El struct Capabilities incluye todos los tipos de datos, incluidos los escalares tipos de datos y representa el rendimiento no relajado mediante un vector en lugar en lugar de campos con nombre.
  • Los métodos getVersionString y getType permiten que el framework realice las siguientes acciones: recuperar información sobre el tipo de dispositivo (DeviceType) y la versión Consulta Descubrimiento y asignación de dispositivos.
  • Se llama al método executeSynchronously de forma predeterminada para realizar una ejecución de forma síncrona. El método execute_1_2 le indica al framework realizar una ejecución de forma asíncrona. Consulta Ejecución.
  • El parámetro MeasureTiming para executeSynchronously, execute_1_2 y la ejecución en ráfaga especifica si el controlador debe medir la ejecución y el tiempo de actividad. Los resultados se informan en la estructura Timing. Consulta Tiempo.
  • Compatibilidad con ejecuciones en las que uno o más operandos de salida tienen un valor desconocido dimensión o clasificación. Consulta Forma de salida.
  • Compatibilidad con extensiones de proveedores, que son conjuntos de plantillas definidas por las operaciones y los tipos de datos. El conductor informa las extensiones compatibles mediante el método IDevice::getSupportedExtensions Consulta Extensiones de proveedores.
  • Es la capacidad de un objeto de ráfaga para controlar un conjunto de ejecuciones de ráfaga usando colas de mensajes rápidas (FMQ) para la comunicación entre la app y el controlador reduciendo la latencia. Consulta Ejecuciones en ráfaga y colas de mensajes rápidos.
  • Compatibilidad con AHardwareBuffer para permitir que el controlador realice ejecuciones sin copiar datos. Consulta AHardwareBuffer.
  • Se mejoró la compatibilidad con el almacenamiento en caché de artefactos de compilación para reducir el tiempo que se usa para la compilación cuando se inicia una app. Consulta Almacenamiento en caché de Compilación.

Android 10 introduce los siguientes tipos de operandos y las 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 introduce actualizaciones a muchos de los las operaciones. Las actualizaciones son se relacionan principalmente con lo siguiente:

  • Compatibilidad con el diseño de memoria NCHW
  • Se admiten tensores con una clasificación diferente a 4 en softmax y las operaciones de normalización
  • Compatibilidad con convoluciones dilatadas
  • Compatibilidad con entradas con cuantización mixta ANEURALNETWORKS_CONCATENATION

La siguiente lista muestra las operaciones que se modifican en Android 10 Total de los cambios, consulta Código de operación en la documentación de referencia de la 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 presenta en Android 9 e incluye las siguientes funciones cambios.

  • IDevice::prepareModel_1_1 incluye un ExecutionPreference. parámetro. Un conductor puede usar esto para ajustar su preparación, sabiendo que la app prefiere ahorrar batería o ejecutará el modelo en llamadas sucesivas y rápidas.
  • Se agregaron nueve operaciones nuevas: BATCH_TO_SPACE_ND, DIV, MEAN, PAD, SPACE_TO_BATCH_ND, SQUEEZE, STRIDED_SLICE, SUB y TRANSPOSE.
  • Una app puede especificar que se puedan ejecutar cálculos de número de punto flotante de 32 bits con el rango de número de punto flotante de 16 bits o la precisión estableciendo De Model.relaxComputationFloat32toFloat16 a true. El Capabilities struct tiene el campo adicional relaxedFloat32toFloat16Performance, por lo que que el controlador pueda informar su rendimiento relajado al framework.

Android 8.1

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