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.
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 aexecuteFenced
hasta el momento enexecuteFenced
indica el objetosyncFence
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 cuandoexecuteFenced
indica el objetosyncFence
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 delLOG
de Android que solo registra el mensaje si la etiqueta adecuada está configurada en eldebug.nn.vlog
propiedad.initVLogMask()
se debe llamar antes de cualquier llamada aVLOG
. La macroVLOG_IS_ON
puede ser se usa para verificar siVLOG
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
oall
, 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
ymodel
.
compliantWithV1_*
: Muestratrue
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 acompliantWithV1_0
en unV1_2::Model
muestrafalse
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
yupdate
se pueden usar para ayudar a crear laCapabilities::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*
: Muestratrue
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
muestrafalse
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:
platform/test/mlts/benchmark
(app de comparativas)platform/test/mlts/models
(modelos y conjuntos de datos)
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:
- 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. 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
yQUANTIZED_16BIT_LSTM
. La operaciónQUANTIZED_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
yWHILE
, 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
ygetType
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étodoexecute_1_2
le indica al framework realizar una ejecución de forma asíncrona. Consulta Ejecución. - El parámetro
MeasureTiming
paraexecuteSynchronously
,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 estructuraTiming
. 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.
-
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 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 unExecutionPreference
. 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
yTRANSPOSE
. - 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
atrue
. ElCapabilities
struct tiene el campo adicionalrelaxedFloat32toFloat16Performance
, 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/