Qualité de service

À partir d'Android 11, NNAPI offre une meilleure qualité de service (QoS) en permettant à une application d'indiquer les priorités relatives de ses modèles, le temps maximal attendu pour préparer un modèle donné et le temps maximal attendu pour une exécution donnée. De plus, Android 11 introduit des valeurs d'erreur NNAPI supplémentaires permettant à un service d'indiquer plus précisément ce qui s'est mal passé en cas de défaillance, afin que l'application cliente puisse mieux réagir et récupérer.

Priorité

Pour Android 11 ou version ultérieure, les modèles sont préparés avec une priorité dans le NN HAL 1.3. Cette priorité dépend des autres modèles préparés appartenant à la même application. Les exécutions à priorité plus élevée peuvent utiliser plus de ressources de calcul que les exécutions de priorité inférieure, et peuvent préempter ou priver les exécutions de priorité inférieure.

L'appel NN HAL 1.3 qui inclut Priority comme argument explicite est IDevice::prepareModel_1_3. Notez que IDevice::prepareModelFromCache_1_3 inclut implicitement Priority dans les arguments de cache.

Il existe de nombreuses stratégies possibles pour répondre aux priorités en fonction des capacités du pilote et de l'accélérateur. Voici plusieurs stratégies:

  • Pour les pilotes compatibles avec les priorités intégrées, propager directement le champ Priority à l'accélérateur.
  • Utilisez une file d'attente de priorités par application pour prendre en charge différentes priorités avant même qu'une exécution atteigne l'accélérateur.
  • Mettez en veille ou annulez les modèles à faible priorité en cours d'exécution afin de libérer l'accélérateur d'exécuter des modèles à priorité élevée. Pour ce faire, vous pouvez insérer des points de contrôle dans les modèles à faible priorité qui, une fois atteints, interrogent un indicateur pour déterminer si l'exécution en cours doit être interrompue prématurément, ou partitionnez le modèle en sous-modèles et interrogez l'indicateur entre les exécutions de sous-modèles. Notez que l'utilisation de points de contrôle ou de sous-modèles dans les modèles préparés avec une priorité peut entraîner des frais généraux supplémentaires qui ne sont pas présents pour les modèles sans priorité dans les versions inférieures à NN HAL 1.3.

    • Pour permettre la préemption, préservez le contexte d'exécution, y compris l'opération ou le sous-modèle à exécuter, ainsi que toutes les données d'opérande intermédiaires pertinentes. Utilisez ce contexte d'exécution pour reprendre l'exécution ultérieurement.
    • La prise en charge complète de la préemption n'est pas nécessaire. Le contexte d'exécution n'a donc pas besoin d'être conservé. Les exécutions du modèle NNAPI étant déterministes, elles peuvent être redémarrées à partir de zéro ultérieurement.

Android permet aux services de différencier les différentes applications appelantes grâce à l'utilisation d'un AID (UID Android). HIDL dispose de mécanismes intégrés permettant de récupérer l'UID de l'application appelante via la méthode ::android::hardware::IPCThreadState::getCallingUid. Vous trouverez la liste des AID dans libcutils/include/cutils/android_filesystem_config.h.

Délais

À partir d'Android 11, la préparation et les exécutions du modèle peuvent être lancées avec un argument de délai OptionalTimePoint. Pour les pilotes qui peuvent estimer la durée d'une tâche, ce délai lui permet d'annuler la tâche avant qu'elle ne commence s'il estime qu'elle ne peut pas être terminée avant l'échéance. De même, la date limite permet au conducteur d'abandonner une tâche en cours qu'il estime qu'elle ne sera pas terminée avant la date limite. L'argument "délai" ne force pas un pilote à annuler une tâche si celle-ci n'est pas terminée dans le délai imparti ou si le délai est écoulé. L'argument "délai" peut être utilisé pour libérer des ressources de calcul dans le pilote et rendre le contrôle à l'application plus rapidement qu'il n'est possible sans délai.

Les appels NN HAL 1.3 qui incluent des délais OptionalTimePoint comme argument sont les suivants:

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

Pour voir une implémentation de référence de la fonctionnalité de délai pour chacune des méthodes ci-dessus, consultez l'exemple de pilote NNAPI sur la page frameworks/ml/nn/driver/sample/SampleDriver.cpp.

Codes d'erreur

Android 11 inclut quatre valeurs de code d'erreur dans NN HAL 1.3 pour améliorer les rapports d'erreurs, ce qui permet aux pilotes de mieux communiquer leur état et aux applications d'effectuer une récupération plus fluide. Voici les valeurs du code d'erreur dans ErrorStatus.

  • MISSED_DEADLINE_TRANSIENT
  • MISSED_DEADLINE_PERSISTENT
  • RESOURCE_EXHAUSTED_TRANSIENT
  • RESOURCE_EXHAUSTED_PERSISTENT

Dans Android 10 ou version antérieure, un pilote ne pouvait indiquer un échec qu'à travers le code d'erreur GENERAL_FAILURE. À partir d'Android 11, les deux codes d'erreur MISSED_DEADLINE peuvent être utilisés pour indiquer que la charge de travail a été annulée, car le délai a été atteint ou parce que le pilote a prédit que la charge de travail ne se terminerait pas dans le délai imparti. Les deux codes d'erreur RESOURCE_EXHAUSTED peuvent être utilisés pour indiquer que la tâche a échoué en raison d'une limitation de ressources dans le pilote, telle que le manque de mémoire du pilote pour l'appel.

La version TRANSIENT des deux erreurs indique que le problème est temporaire et que les futurs appels à la même tâche peuvent aboutir après un court délai. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote est occupé par une tâche de longue durée ou exigeante en ressources, mais que la nouvelle tâche serait terminée si le pilote n'était pas occupé par le travail précédent. La version PERSISTENT des deux erreurs indique que les futurs appels à la même tâche sont toujours susceptibles d'échouer. Par exemple, ce code d'erreur doit être renvoyé lorsque le conducteur estime que la tâche ne serait pas terminée dans des conditions parfaites, ou que le modèle est intrinsèquement trop volumineux et dépasse ses ressources.

Validation

La fonctionnalité de qualité de service est testée dans les tests VTS de NNAPI (VtsHalNeuralnetworksV1_3Target). Cela inclut un ensemble de tests de validation (TestGenerated/ValidationTest#Test/) pour s'assurer que le pilote rejette les priorités non valides, ainsi qu'un ensemble de tests appelés DeadlineTest (TestGenerated/DeadlineTest#Test/) pour s'assurer que le pilote gère correctement les délais.