Qualidade de serviço

A partir do Android 11, a NNAPI oferece melhor qualidade de serviço (QoS), permitindo que um aplicativo indique as prioridades relativas de seus modelos, o tempo máximo esperado para um determinado modelo ser preparado e o tempo máximo esperado para uma determinada execução seja concluída. Além disso, o Android 11 introduz valores de erro NNAPI adicionais, permitindo que um serviço indique com mais precisão o que deu errado quando ocorre uma falha, para que o aplicativo cliente possa reagir e se recuperar melhor.

Prioridade

Para Android 11 ou superior, os modelos são preparados com prioridade no NN HAL 1.3. Esta prioridade é relativa a outros modelos preparados pertencentes ao mesmo aplicativo. As execuções de prioridade mais alta podem usar mais recursos de computação do que as execuções de prioridade mais baixa e podem antecipar ou privar execuções de prioridade mais baixa.

A chamada NN HAL 1.3 que inclui Priority como um argumento explícito é IDevice::prepareModel_1_3 . Observe que IDevice::prepareModelFromCache_1_3 inclui implicitamente Priority nos argumentos de cache.

Existem muitas estratégias possíveis para apoiar prioridades, dependendo das capacidades do condutor e do acelerador. Aqui estão várias estratégias:

  • Para drivers que possuem suporte de prioridade integrado, propague diretamente o campo Priority para o acelerador.
  • Use uma fila de prioridade por aplicativo para oferecer suporte a diferentes prioridades, mesmo antes de uma execução atingir o acelerador.
  • Pause ou cancele modelos de baixa prioridade que estão sendo executados para liberar o acelerador para executar modelos de alta prioridade. Faça isso inserindo pontos de verificação em modelos de baixa prioridade que, quando alcançados, consultam um sinalizador para determinar se a execução atual deve ser interrompida prematuramente ou particionando o modelo em submodelos e consultando o sinalizador entre as execuções do submodelo. Observe que o uso de pontos de verificação ou submodelos em modelos preparados com prioridade pode introduzir sobrecarga adicional que não está presente para modelos sem prioridade em versões inferiores a NN HAL 1.3.

    • Para dar suporte à preempção, preserve o contexto de execução, incluindo a próxima operação ou submodelo a ser executado e quaisquer dados de operando intermediários relevantes. Use este contexto de execução para retomar a execução posteriormente.
    • O suporte total à preempção não é necessário, portanto o contexto de execução não precisa ser preservado. Como as execuções do modelo NNAPI são determinísticas, as execuções podem ser reiniciadas do zero posteriormente.

O Android permite que os serviços diferenciem diferentes aplicativos de chamada por meio do uso de um AID (Android UID). HIDL possui mecanismos integrados para recuperar o UID do aplicativo de chamada por meio do método ::android::hardware::IPCThreadState::getCallingUid . Uma lista de AIDs pode ser encontrada em libcutils/include/cutils/android_filesystem_config.h .

Prazos

A partir do Android 11, a preparação e as execuções do modelo podem ser iniciadas com um argumento de prazo OptionalTimePoint . Para motoristas que podem estimar quanto tempo leva uma tarefa, esse prazo permite que o motorista aborte a tarefa antes de seu início se o motorista estimar que a tarefa não pode ser concluída antes do prazo. Da mesma forma, o prazo permite ao driver abortar uma tarefa em andamento que estima não ser concluída antes do prazo. O argumento do prazo não força um driver a abortar uma tarefa se a tarefa não for concluída dentro do prazo ou se o prazo tiver passado. O argumento do prazo pode ser usado para liberar recursos de computação no driver e retornar o controle ao aplicativo mais rápido do que seria possível sem o prazo.

As chamadas NN HAL 1.3 que incluem prazos OptionalTimePoint como argumento são:

  • IDevice::prepareModel_1_3
  • IDevice::prepareModelFromCache_1_3
  • IPreparedModel::execute_1_3
  • IPreparedModel::executeSynchronously_1_3
  • IPreparedModel::executeFenced

Para ver uma implementação de referência do recurso de prazo para cada um dos métodos acima, consulte o driver de amostra NNAPI em frameworks/ml/nn/driver/sample/SampleDriver.cpp .

Códigos de erro

O Android 11 inclui quatro valores de código de erro no NN HAL 1.3 para melhorar o relatório de erros, permitindo que os motoristas comuniquem melhor seu estado e que os aplicativos se recuperem com mais eficiência. Estes são os valores do código de erro em ErrorStatus .

  • MISSED_DEADLINE_TRANSIENT
  • MISSED_DEADLINE_PERSISTENT
  • RESOURCE_EXHAUSTED_TRANSIENT
  • RESOURCE_EXHAUSTED_PERSISTENT

No Android 10 ou inferior, um driver só poderia indicar uma falha por meio do código de erro GENERAL_FAILURE . A partir do Android 11, os dois códigos de erro MISSED_DEADLINE podem ser usados ​​para indicar que a carga de trabalho foi abortada porque o prazo foi atingido ou porque o driver previu que a carga de trabalho não seria concluída dentro do prazo. Os dois códigos de erro RESOURCE_EXHAUSTED podem ser usados ​​para indicar que a tarefa falhou devido a uma limitação de recursos no driver, como o driver não ter memória suficiente para a chamada.

A versão TRANSIENT de ambos os erros indica que o problema é temporário e que chamadas futuras para a mesma tarefa poderão ter êxito após um pequeno atraso. Por exemplo, esse código de erro deve ser retornado quando o driver estiver ocupado com um trabalho anterior de longa execução ou com uso intensivo de recursos, mas que a nova tarefa seria concluída com êxito se o driver não estivesse ocupado com o trabalho anterior. A versão PERSISTENT de ambos os erros indica que sempre se espera que chamadas futuras para a mesma tarefa falhem. Por exemplo, este código de erro deve ser retornado quando o driver estima que a tarefa não seria concluída dentro do prazo, mesmo em condições perfeitas, ou que o modelo é inerentemente muito grande e excede os recursos do driver.

Validação

A funcionalidade de qualidade de serviço é testada nos testes NNAPI VTS ( VtsHalNeuralnetworksV1_3Target ). Isso inclui um conjunto de testes para validação ( TestGenerated/ValidationTest#Test/ ) para garantir que o driver rejeite prioridades inválidas e um conjunto de testes chamado DeadlineTest ( TestGenerated/DeadlineTest#Test/ ) para garantir que o driver lide com os prazos corretamente.