Esta página fornece uma visão geral de como implementar um driver Neural Networks API (NNAPI). Para obter mais detalhes, consulte a documentação encontrada nos arquivos de definição HAL em hardware/interfaces/neuralnetworks
. Uma implementação de driver de amostra está em frameworks/ml/nn/driver/sample
.
Para obter mais informações sobre a API de redes neurais, consulte API de redes neurais .
Redes Neurais HAL
O HAL de Redes Neurais (NN) define uma abstração dos vários dispositivos , como unidades de processamento gráfico (GPUs) e processadores de sinal digital (DSPs), que estão em um produto (por exemplo, um telefone ou tablet). Os drivers para esses dispositivos devem estar em conformidade com o NN HAL. A interface é especificada nos arquivos de definição HAL em hardware/interfaces/neuralnetworks
.
O fluxo geral da interface entre a estrutura e um driver é ilustrado na figura 1.
Figura 1. Fluxo de redes neurais
Inicialização
Na inicialização, o framework consulta o driver para seus recursos usando IDevice::getCapabilities_1_3
. A estrutura @1.3::Capabilities
inclui todos os tipos de dados e representa o desempenho não relaxado usando um vetor.
Para determinar como alocar cálculos para os dispositivos disponíveis, a estrutura usa os recursos para compreender a rapidez e a eficiência energética de cada driver pode executar uma execução. Para fornecer essas informações, o driver deve fornecer números de desempenho padronizados com base na execução de cargas de trabalho de referência.
Para determinar os valores que o driver retorna em resposta a IDevice::getCapabilities_1_3
, use o aplicativo de referência NNAPI para medir o desempenho dos tipos de dados correspondentes. Os modelos MobileNet v1 e v2, asr_float
e tts_float
são recomendados para medir o desempenho para valores de ponto flutuante de 32 bits e os modelos quantizados MobileNet v1 e v2 são recomendados para valores quantizados de 8 bits. Para obter mais informações, consulte Android Machine Learning Test Suite .
No Android 9 e inferior, a estrutura Capabilities
inclui informações de desempenho do driver apenas para pontos flutuantes e tensores quantizados e não inclui tipos de dados escalares.
Como parte do processo de inicialização, a estrutura pode consultar mais informações, usando IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
e IDevice::getNumberOfCacheFilesNeeded
.
Entre as reinicializações do produto, a estrutura espera que todas as consultas descritas nesta seção sempre relatem os mesmos valores para um determinado driver. Caso contrário, um aplicativo que usa esse driver pode apresentar desempenho reduzido ou comportamento incorreto.
Compilação
A estrutura determina quais dispositivos usar ao receber uma solicitação de um aplicativo. No Android 10, os aplicativos podem descobrir e especificar os dispositivos que a estrutura escolhe. Para obter mais informações, consulte Descoberta e atribuição de dispositivos .
No momento da compilação do modelo, a estrutura envia o modelo para cada driver candidato chamando IDevice::getSupportedOperations_1_3
. Cada driver retorna uma matriz de booleanos indicando quais operações do modelo são suportadas. Um driver pode determinar que não oferece suporte a uma determinada operação por vários motivos. Por exemplo:
- O driver não suporta o tipo de dados.
- O driver suporta apenas operações com parâmetros de entrada específicos. Por exemplo, um driver pode suportar 3x3 e 5x5, mas não operações de convolução 7x7.
- O driver tem restrições de memória que o impedem de lidar com grandes gráficos ou entradas.
Durante a compilação, os operandos de entrada, saída e internos do modelo, conforme descrito em OperandLifeTime
, podem ter dimensões ou classificação desconhecidas. Para obter mais informações, consulte Formato de saída .
A estrutura instrui cada driver selecionado a se preparar para executar um subconjunto do modelo chamando IDevice::prepareModel_1_3
. Cada driver então compila seu subconjunto. Por exemplo, um driver pode gerar código ou criar uma cópia reordenada dos pesos. Como pode haver uma quantidade significativa de tempo entre a compilação do modelo e a execução das solicitações, recursos como grandes blocos de memória do dispositivo não devem ser atribuídos durante a compilação.
Em caso de sucesso, o driver retorna um identificador @1.3::IPreparedModel
. Se o driver retornar um código de falha ao preparar seu subconjunto do modelo, a estrutura executará todo o modelo na CPU.
Para reduzir o tempo usado para compilação quando um aplicativo é iniciado, um driver pode armazenar em cache os artefatos de compilação. Para obter mais informações, consulte Cache de compilação .
Execução
Quando um aplicativo pede à estrutura para executar uma solicitação, a estrutura chama o IPreparedModel::executeSynchronously_1_3
HAL por padrão para realizar uma execução síncrona em um modelo preparado. Uma solicitação também pode ser executada de forma assíncrona usando o método execute_1_3
, o método executeFenced
(consulte Execução Fenced ) ou executada usando uma execução intermitente .
As chamadas de execução síncrona melhoram o desempenho e reduzem a sobrecarga de encadeamento em comparação com as chamadas assíncronas porque o controle é retornado ao processo do aplicativo somente depois que a execução é concluída. Isso significa que o driver não precisa de um mecanismo separado para notificar o processo do aplicativo que uma execução foi concluída.
Com o método assíncrono execute_1_3
, o controle retorna ao processo do aplicativo após o início da execução, e o driver deve notificar o framework quando a execução for concluída, usando o @1.3::IExecutionCallback
.
O parâmetro Request
passado ao método execute lista os operandos de entrada e saída usados para a execução. A memória que armazena os dados do operando deve usar a ordem da linha principal com a primeira dimensão iterando a mais lenta e sem preenchimento no final de qualquer linha. Para obter mais informações sobre os tipos de operandos, consulte Operandos .
Para drivers NN HAL 1.2 ou superior, quando uma solicitação é concluída, o status do erro, o formato de saída e as informações de tempo são retornados à estrutura. Durante a execução, a saída ou operandos internos do modelo podem ter uma ou mais dimensões desconhecidas ou classificação desconhecida. Quando pelo menos um operando de saída tem uma dimensão ou classificação desconhecida, o driver deve retornar informações de saída dimensionadas dinamicamente.
Para drivers com NN HAL 1.1 ou inferior, apenas o status de erro é retornado quando uma solicitação é concluída. As dimensões dos operandos de entrada e saída devem ser totalmente especificadas para que a execução seja concluída com êxito. Operandos internos podem ter uma ou mais dimensões desconhecidas, mas devem ter uma classificação especificada.
Para solicitações de usuários que abrangem vários drivers, o framework é responsável por reservar memória intermediária e por sequenciar as chamadas para cada driver.
Várias solicitações podem ser iniciadas em paralelo no mesmo @1.3::IPreparedModel
. O driver pode executar solicitações em paralelo ou serializar as execuções.
A estrutura pode pedir a um driver para manter mais de um modelo preparado. Por exemplo, prepare o modelo m1
, prepare m2
, execute a solicitação r1
em m1
, execute r2
em m2
, execute r3
em m1
, execute r4
em m2
, libere (descrito em Limpeza ) m1
e libere m2
.
Para evitar uma primeira execução lenta que poderia resultar em uma experiência do usuário ruim (por exemplo, uma falha no primeiro quadro), o driver deve realizar a maioria das inicializações na fase de compilação. A inicialização na primeira execução deve ser limitada a ações que afetam negativamente a integridade do sistema quando realizadas antecipadamente, como reservar grandes buffers temporários ou aumentar a taxa de clock de um dispositivo. Drivers que podem preparar apenas um número limitado de modelos simultâneos podem ter que fazer sua inicialização na primeira execução.
No Android 10 ou superior, nos casos em que várias execuções com o mesmo modelo preparado são executadas em rápida sucessão, o cliente pode escolher usar um objeto de burst de execução para se comunicar entre os processos do aplicativo e do driver. Para obter mais informações, consulte Burst Executions and Fast Message Queues .
Para melhorar o desempenho de várias execuções em rápida sucessão, o driver pode manter buffers temporários ou aumentar as taxas de clock. A criação de um thread de watchdog é recomendada para liberar recursos se nenhuma nova solicitação for criada após um período fixo de tempo.
Forma de saída
Para solicitações em que um ou mais operandos de saída não têm todas as dimensões especificadas, o driver deve fornecer uma lista de formas de saída contendo as informações de dimensão para cada operando de saída após a execução. Para obter mais informações sobre dimensões, consulte OutputShape
.
Se uma execução falhar devido a um buffer de saída subdimensionado, o driver deve indicar quais operandos de saída têm tamanho de buffer insuficiente na lista de formas de saída e deve relatar o máximo de informações dimensionais possível, usando zero para dimensões que são desconhecidas.
Cronometragem
No Android 10, um aplicativo pode solicitar o tempo de execução se o aplicativo tiver especificado um único dispositivo para usar durante o processo de compilação. Para obter detalhes, consulte MeasureTiming
e Device Discovery and Assignment . Nesse caso, um driver NN HAL 1.2 deve medir a duração da execução ou relatar UINT64_MAX
(para indicar que a duração não está disponível) ao executar uma solicitação. O driver deve minimizar qualquer penalidade de desempenho resultante da medição da duração da execução.
O driver relata as seguintes durações em microssegundos na estrutura de Timing
:
- Tempo de execução no dispositivo: Não inclui o tempo de execução no driver, que roda no processador host.
- Tempo de execução no driver: Inclui o tempo de execução no dispositivo.
Essas durações devem incluir o tempo em que a execução é suspensa, por exemplo, quando a execução foi interrompida por outras tarefas ou quando está esperando um recurso ficar disponível.
Quando o driver não foi solicitado a medir a duração da execução, ou quando há um erro de execução, o driver deve relatar as durações como UINT64_MAX
. Mesmo quando o driver foi solicitado a medir a duração da execução, ele pode relatar UINT64_MAX
para tempo no dispositivo, tempo no driver ou ambos. Quando o driver relata ambas as durações como um valor diferente de UINT64_MAX
, o tempo de execução no driver deve ser igual ou superior ao tempo no dispositivo.
Execução cercada
No Android 11, a NNAPI permite que as execuções aguardem uma lista de sync_fence
de sync_fence
e, opcionalmente, retornem um objeto sync_fence
, que é sinalizado quando a execução é concluída. Isso reduz a sobrecarga para modelos de sequência pequena e casos de uso de streaming. A execução protegida também permite uma interoperabilidade mais eficiente com outros componentes que podem sinalizar ou esperar por sync_fence
. Para obter mais informações sobre sync_fence
, consulte Synchronization Framework .
Em uma execução protegida, a estrutura chama o método IPreparedModel::executeFenced
para lançar uma execução cercada e assíncrona em um modelo preparado com um vetor de cercas de sincronização para aguardar. Se a tarefa assíncrona for concluída antes do retorno da chamada, um identificador vazio pode ser retornado para sync_fence
. Um objeto IFencedExecutionCallback
também deve ser retornado para permitir que a estrutura consulte o status do erro e as informações de duração.
Após a conclusão de uma execução, os dois seguintes valores de tempo medindo a duração da execução podem ser consultados por meio de IFencedExecutionCallback::getExecutionInfo
.
-
timingLaunched
: Duração de quandoexecuteFenced
é chamado até quandoexecuteFenced
sinaliza osyncFence
retornado. -
timingFenced
: Duração de quando todos os sync fences que a execução espera são sinalizados até quandoexecuteFenced
sinaliza osyncFence
retornado.
Controle de fluxo
Para dispositivos que executam o Android 11 ou superior, a NNAPI inclui duas operações de fluxo de controle, IF
e WHILE
, que usam outros modelos como argumentos e os executam condicionalmente ( IF
) ou repetidamente ( WHILE
). Para obter mais informações sobre como implementar isso, consulte Fluxo de controle .
Qualidade de serviço
No Android 11, a NNAPI inclui melhor qualidade de serviço (QoS), permitindo que um aplicativo indique as prioridades relativas de seus modelos, a quantidade máxima de tempo esperada para um modelo ser preparado e a quantidade máxima de tempo esperada para uma execução para ser concluído. Para obter mais informações, consulte Qualidade de serviço .
Limpar
Quando um aplicativo termina de usar um modelo preparado, o framework libera sua referência para o objeto @1.3::IPreparedModel
. Quando o objeto IPreparedModel
não é mais referenciado, ele é automaticamente destruído no serviço do driver que o criou. Os recursos específicos do modelo podem ser recuperados neste momento na implementação do destruidor pelo driver. Se o serviço do driver quiser que o objeto IPreparedModel
seja destruído automaticamente quando não for mais necessário pelo cliente, ele não deve conter nenhuma referência ao objeto IPreparedModel
após o objeto IPreparedeModel
ter sido retornado por IPreparedModelCallback::notify_1_3
.
utilização do CPU
Os drivers devem usar a CPU para configurar os cálculos. Os drivers não devem usar a CPU para realizar cálculos gráficos porque isso interfere na capacidade do framework de alocar trabalho corretamente. O driver deve relatar as partes que ele não pode manipular para a estrutura e deixar que a estrutura faça o resto.
A estrutura fornece uma implementação de CPU para todas as operações NNAPI, exceto para operações definidas pelo fornecedor. Para obter mais informações, consulte Extensões do fornecedor .
As operações introduzidas no Android 10 (API de nível 29) têm apenas uma implementação de CPU de referência para verificar se os testes CTS e VTS estão corretos. As implementações otimizadas incluídas em estruturas de aprendizado de máquina móvel são preferidas em vez da implementação de CPU NNAPI.
Funções utilitárias
A base de código NNAPI inclui funções de utilitário que podem ser usadas por serviços de driver.
O arquivo frameworks/ml/nn/common/include/Utils.h
contém funções utilitárias variadas, como aquelas usadas para registro e conversão entre diferentes versões do NN HAL.
VLogging:
VLOG
é uma macro wrapper em torno doLOG
do Android que registra apenas a mensagem se a tag apropriada for definida na propriedadedebug.nn.vlog
.initVLogMask()
deve ser chamado antes de qualquer chamada paraVLOG
. A macroVLOG_IS_ON
pode ser usada para verificar se oVLOG
está habilitado no momento, permitindo que códigos de registro complicados sejam ignorados se não forem necessários. O valor da propriedade deve ser um dos seguintes:- Uma string vazia, indicando que nenhum registro deve ser feito.
- O token
1
ouall
, indicando que todo o registro deve ser feito. - Uma lista de tags, delimitada por espaços, vírgulas ou dois pontos, indicando qual registro deve ser feito. As tags são
compilation
,cpuexe
,driver
,execution
,manager
emodel
.
compliantWithV1_*
: Retornatrue
se um objeto NN HAL pode ser convertido para o mesmo tipo de uma versão de HAL diferente sem perder informações. Por exemplo, chamarcompliantWithV1_0
em umV1_2::Model
retornafalse
se o modelo inclui tipos de operação introduzidos em NN HAL 1.1 ou NN HAL 1.2.convertToV1_*
: Converte um objeto NN HAL de uma versão para outra. Um aviso é registrado se a conversão resultar em perda de informações (ou seja, se a nova versão do tipo não puder representar totalmente o valor).Capacidades: As funções
nonExtensionOperandPerformance
eupdate
podem ser usadas para ajudar a construir o campoCapabilities::operandPerformance
.Consultando propriedades de tipos:
isExtensionOperandType
,isExtensionOperationType
,nonExtensionSizeOfData
,nonExtensionOperandSizeOfData
,nonExtensionOperandTypeIsScalar
,tensorHasUnspecifiedDimensions
.
O arquivo frameworks/ml/nn/common/include/ValidateHal.h
contém funções utilitárias para validar se um objeto NN HAL é válido de acordo com a especificação de sua versão HAL.
-
validate*
: Retornatrue
se o objeto NN HAL for válido de acordo com a especificação de sua versão HAL. Tipos de OEM e tipos de extensão não são validados. Por exemplo,validateModel
retornafalse
se o modelo contém uma operação que faz referência a um índice de operando que não existe ou uma operação que não é compatível com essa versão de HAL.
O arquivo frameworks/ml/nn/common/include/Tracing.h
contém macros para simplificar a adição de informações de systracing ao código de redes neurais. Para obter um exemplo, consulte as NNTRACE_*
macro NNTRACE_*
no driver de amostra .
O arquivo frameworks/ml/nn/common/include/GraphDump.h
contém uma função de utilitário para despejar o conteúdo de um Model
em formato gráfico para fins de depuração.
-
graphDump
: Grava uma representação do modelo no formato Graphviz (.dot
) para o fluxo especificado (se fornecido) ou para o logcat (se nenhum fluxo for fornecido).
Validação
Para testar sua implementação da NNAPI, use os testes VTS e CTS incluídos na estrutura Android. O VTS exercita seus drivers diretamente (sem usar a estrutura), enquanto o CTS os exerce indiretamente por meio da estrutura. Eles testam cada método API e verificam se todas as operações suportadas pelos drivers funcionam corretamente e fornecem resultados que atendem aos requisitos de precisão.
Os requisitos de precisão em CTS e VTS para a NNAPI são os seguintes:
Ponto flutuante: abs (esperado - real) <= atol + rtol * abs (esperado); Onde:
- Para fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
- Para fp16, atol = rtol = 5.0f * 0,0009765625f
Quantized: off-by-one (exceto para
mobilenet_quantized
, que é off-by-three)Booleano: correspondência exata
Uma das maneiras pelas quais o CTS testa a NNAPI é gerando gráficos pseudo-aleatórios fixos usados para testar e comparar os resultados da execução de cada driver com a implementação de referência da NNAPI. Para drivers com NN HAL 1.2 ou superior, se os resultados não atenderem aos critérios de precisão, o CTS reporta um erro e despeja um arquivo de especificação para o modelo com falha em /data/local/tmp
para depuração. Para obter mais detalhes sobre os critérios de precisão, consulte TestRandomGraph.cpp
e TestHarness.h
.
Teste Fuzz
O objetivo do teste de difusão é encontrar travamentos, asserções, violações de memória ou comportamento indefinido geral no código em teste devido a fatores como entradas inesperadas. Para o teste de difusão NNAPI, o Android usa testes baseados em libFuzzer , que são eficientes em difusão porque usam cobertura de linha de casos de teste anteriores para gerar novas entradas aleatórias. Por exemplo, libFuzzer favorece casos de teste que rodam em novas linhas de código. Isso reduz muito a quantidade de tempo que os testes levam para encontrar códigos problemáticos.
Para realizar o teste fuzz para validar a implementação do driver, modifique frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
no utilitário de teste libneuralnetworks_driver_fuzzer
encontrado no AOSP para incluir o código do driver. Para obter mais informações sobre o teste de difusão NNAPI, consulte frameworks/ml/nn/runtime/test/android_fuzzing/README.md
.
Segurança
Como os processos do aplicativo se comunicam diretamente com o processo de um driver, os drivers devem validar os argumentos das chamadas que recebem. Esta validação é verificada pelo VTS. O código de validação está em frameworks/ml/nn/common/include/ValidateHal.h
.
Os drivers também devem garantir que os aplicativos não interfiram com outros aplicativos ao usar o mesmo dispositivo.
Pacote de teste de aprendizado de máquina Android
O Android Machine Learning Test Suite (MLTS) é um benchmark NNAPI incluído no CTS e VTS para validar a precisão de modelos reais em dispositivos de fornecedores. O benchmark avalia a latência e a precisão e compara os resultados dos drivers com os resultados usando TF Lite rodando na CPU, para o mesmo modelo e conjuntos de dados. Isso garante que a precisão do driver não seja pior do que a implementação de referência da CPU.
Os desenvolvedores da plataforma Android também usam MLTS para avaliar a latência e a precisão dos drivers.
O benchmark NNAPI pode ser encontrado em dois projetos no AOSP:
-
platform/test/mlts/benchmark
(aplicativo de benchmark) -
platform/test/mlts/models
(modelos e conjuntos de dados)
Modelos e conjuntos de dados
O benchmark NNAPI usa os seguintes modelos e conjuntos de dados.
- MobileNetV1 float e u8 quantizados em tamanhos diferentes, executados em um pequeno subconjunto (1500 imagens) do Open Images Dataset v4.
- MobileNetV2 float e u8 quantizados em tamanhos diferentes, executados em um pequeno subconjunto (1500 imagens) do Open Images Dataset v4.
- Modelo acústico baseado em memória longa de curto prazo (LSTM) para conversão de texto em fala, executado em um pequeno subconjunto do conjunto CMU Arctic.
- Modelo acústico baseado em LSTM para reconhecimento automático de fala, executado em um pequeno subconjunto do conjunto de dados LibriSpeech.
Para obter mais informações, consulte platform/test/mlts/models
.
Teste de estresse
O Android Machine Learning Test Suite inclui uma série de testes de colisão para validar a resiliência dos drivers sob condições de uso pesado ou em casos extremos do comportamento dos clientes.
Todos os testes de falha fornecem os seguintes recursos:
- Detecção de travamento : Se o cliente NNAPI travar durante um teste, o teste falha com o motivo da falha
HANG
e o conjunto de testes passa para o próximo teste. - Detecção de travamento do cliente NNAPI: Os testes sobrevivem a travamentos do cliente e os testes falham com o motivo da falha
CRASH
. - Detecção de falha de driver: os testes podem detectar uma falha de driver que causa uma falha em uma chamada NNAPI. Observe que pode haver travamentos nos processos do driver que não causam uma falha de NNAPI e não fazem com que o teste falhe. Para cobrir esse tipo de falha, é recomendado executar o comando
tail
no log do sistema para erros ou travamentos relacionados ao driver. - Direcionamento de todos os aceleradores disponíveis: os testes são executados em todos os drivers disponíveis.
Todos os testes de colisão têm os seguintes quatro resultados possíveis:
-
SUCCESS
: Execução concluída sem erro. -
FAILURE
: A execução falhou. Normalmente causado por uma falha ao testar um modelo, indicando que o driver falhou ao compilar ou executar o modelo. -
HANG
: O processo de teste parou de responder. -
CRASH
: o processo de teste travou.
Para obter mais informações sobre testes de estresse e uma lista completa de testes de travamento, consulte platform/test/mlts/benchmark/README.txt
.
Usando MLTS
Para usar o MLTS:
- Conecte um dispositivo de destino à sua estação de trabalho e certifique-se de que pode ser acessado por meio do adb . Exporte a variável de ambiente
ANDROID_SERIAL
dispositivo de destino se mais de um dispositivo estiver conectado. cd
no diretório de origem de nível superior do Android.source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
No final de uma execução de benchmark, os resultados são apresentados como uma página HTML e passados para o
xdg-open
.
Para obter mais informações, consulte platform/test/mlts/benchmark/README.txt
.
Versões HAL de redes neurais
Esta seção descreve as alterações introduzidas nas versões HAL do Android e redes neurais.
Android 11
O Android 11 apresenta o NN HAL 1.3, que inclui as seguintes mudanças notáveis.
- Suporte para quantização de 8 bits assinada em NNAPI. Adiciona o tipo de operando
TENSOR_QUANT8_ASYMM_SIGNED
. Drivers com NN HAL 1.3 que suportam operações com quantização não assinada também devem suportar as variantes assinadas dessas operações. Ao executar versões assinadas e não assinadas da maioria das operações quantizadas, os drivers devem produzir os mesmos resultados até um deslocamento de 128. Existem cinco exceções a este requisito:CAST
,HASHTABLE_LOOKUP
,LSH_PROJECTION
,PAD_V2
eQUANTIZED_16BIT_LSTM
. A operaçãoQUANTIZED_16BIT_LSTM
não suporta operandos assinados e as outras quatro operações suportam quantização assinada, mas não exigem que os resultados sejam os mesmos. - Suporte para execuções protegidas em que a estrutura chama o método
IPreparedModel::executeFenced
para lançar uma execução cercada e assíncrona em um modelo preparado com um vetor de cercas de sincronização para esperar. Para obter mais informações, consulte Execução cercada . - Suporte para controle de fluxo. Adiciona as operações
IF
eWHILE
, que tomam outros modelos como argumentos e os executam condicionalmente (IF
) ou repetidamente (WHILE
). Para obter mais informações, consulte Fluxo de controle . - Melhoria da qualidade de serviço (QoS), pois os aplicativos podem indicar as prioridades relativas de seus modelos, a quantidade máxima de tempo esperada para um modelo ser preparado e a quantidade máxima de tempo esperada para a conclusão de uma execução. Para obter mais informações, consulte Qualidade de serviço .
- Suporte para domínios de memória que fornecem interfaces de alocador para buffers gerenciados por driver. Isso permite a passagem de memórias nativas do dispositivo entre as execuções, suprimindo a cópia e transformação desnecessária de dados entre execuções consecutivas no mesmo driver. Para obter mais informações, consulte Domínios de memória .
Android 10
O Android 10 apresenta o NN HAL 1.2, que inclui as seguintes mudanças notáveis.
- A estrutura
Capabilities
inclui todos os tipos de dados, incluindo tipos de dados escalares, e representa o desempenho não relaxado usando um vetor em vez de campos nomeados. - Os métodos
getVersionString
egetType
permitem que a estrutura recupere o tipo de dispositivo (DeviceType
) e as informações de versão. Consulte Descoberta e atribuição de dispositivos . - O método
executeSynchronously
é chamado por padrão para realizar uma execução síncrona. O métodoexecute_1_2
diz ao framework para realizar uma execução de forma assíncrona. Veja Execução . - O parâmetro
MeasureTiming
paraexecuteSynchronously
,execute_1_2
e burstexecuteSynchronously
especifica se o driver deve medir a duração da execução. Os resultados são relatados na estrutura deTiming
. Veja Timing . - Suporte para execuções onde um ou mais operandos de saída têm uma dimensão ou classificação desconhecida. Consulte Formato de saída .
- Suporte para extensões do fornecedor, que são coleções de operações definidas pelo fornecedor e tipos de dados. O driver relata extensões com suporte por meio do método
IDevice::getSupportedExtensions
. Consulte Extensões do fornecedor . - Capacidade de um objeto burst de controlar um conjunto de execuções burst usando filas de mensagens rápidas (FMQs) para se comunicar entre os processos do aplicativo e do driver, reduzindo a latência. Consulte Execuções em rajada e Filas de mensagens rápidas .
- Suporte para AHardwareBuffer para permitir que o driver execute execuções sem copiar dados. Consulte AHardwareBuffer .
- Suporte aprimorado para armazenamento em cache de artefatos de compilação para reduzir o tempo usado para compilação quando um aplicativo é iniciado. Consulte Cache de compilação .
O Android 10 apresenta os seguintes tipos de operando e operações.
-
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
-
O Android 10 apresenta atualizações para muitas das operações existentes. As atualizações estão principalmente relacionadas ao seguinte:
- Suporte para o layout de memória NCHW
- Suporte para tensores com classificação diferente de 4 em softmax e operações de normalização
- Suporte para convoluções dilatadas
- Suporte para entradas com quantização mista em
ANEURALNETWORKS_CONCATENATION
A lista abaixo mostra as operações que são modificadas no Android 10. Para obter detalhes completos sobre as mudanças, consulte OperationCode na documentação de referência da 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 é introduzido no Android 9 e inclui as seguintes alterações notáveis.
-
IDevice::prepareModel_1_1
inclui um parâmetroExecutionPreference
. Um motorista pode usar isso para ajustar sua preparação, sabendo que o aplicativo prefere economizar bateria ou estará executando o modelo em chamadas sucessivas rápidas. - Nove novas operações foram adicionadas:
BATCH_TO_SPACE_ND
,DIV
,MEAN
,PAD
,SPACE_TO_BATCH_ND
,SQUEEZE
,STRIDED_SLICE
,SUB
,TRANSPOSE
. - Um aplicativo pode especificar que cálculos de flutuação de 32 bits podem ser executados usando intervalo de flutuação de 16 bits e / ou precisão configurando
Model.relaxComputationFloat32toFloat16
comotrue
. A estruturaCapabilities
tem o campo adicionalrelaxedFloat32toFloat16Performance
para que o driver possa relatar seu desempenho relaxado à estrutura.
Android 8.1
O HAL de redes neurais inicial (1.0) foi lançado no Android 8.1. Para obter mais informações, consulte /neuralnetworks/1.0/
.