À partir d'Android 11, l'API 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 la durée maximale de temps attendu pour effectuer 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 d'échec, afin que l'application cliente puisse mieux réagir et récupérer.
Priorité
Pour Android 11 ou une version ultérieure, les modèles sont préparés avec une priorité dans NN HAL 1.3. Cette priorité est relative aux autres modèles préparés appartenant à la même application. Les exécutions de priorité plus élevée peuvent utiliser plus de ressources de calcul que les exécutions de priorité inférieure, et peuvent préempter ou affamer 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 du cache.
Il existe de nombreuses stratégies possibles pour prendre en charge les priorités, en fonction des capacités du pilote et de l'accélérateur. Voici plusieurs stratégies :
- Pour les pilotes qui disposent d'une prise en charge intégrée des priorités, propagez directement le champ
Priorityà l'accélérateur. - Utilisez une file d'attente de priorité par application pour prendre en charge différentes priorités avant même qu'une exécution n'atteigne l'accélérateur.
Mettez en pause ou annulez les modèles de faible priorité en cours d'exécution pour libérer l'accélérateur afin qu'il puisse exécuter des modèles de priorité élevée. Pour ce faire, insérez des points de contrôle dans les modèles de faible priorité qui, une fois atteints, interrogent un indicateur pour déterminer si l'exécution actuelle doit être arrêtée prématurément ou en partitionnant le modèle en sous-modèles et en interrogeant 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 une surcharge supplémentaire qui n'est pas présente pour les modèles sans priorité dans les versions antérieures à NN HAL 1.3.
- Pour prendre en charge la préemption, conservez le contexte d'exécution, y compris l'opération ou le sous-modèle suivant à exécuter et 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. Il n'est donc pas nécessaire de conserver le contexte d'exécution. Étant donné que les exécutions de modèles NNAPI sont déterministes, elles peuvent être redémarrées à partir de zéro ultérieurement.
Android permet aux services de faire la distinction entre différentes applications appelantes grâce à l'utilisation d'un AID (Android UID). HIDL dispose de mécanismes intégrés pour récupérer l'UID de l'application appelante via la méthode ::android::hardware::IPCThreadState::getCallingUid. Vous trouverez une liste des AID dans
libcutils/include/cutils/android_filesystem_config.h.
Délais
À partir d'Android 11, la préparation et les exécutions de modèles 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 permet au pilote d'abandonner la tâche avant son démarrage s'il estime qu'elle ne peut pas être terminée avant le délai. De même, le délai permet au pilote d'abandonner une tâche en cours qu'il estime ne pas pouvoir être terminée avant le délai.
L'argument de délai ne force pas un pilote à abandonner une tâche si elle n'est pas terminée avant le délai ou si le délai est dépassé. L'argument de délai peut être utilisé pour libérer des ressources de calcul dans le pilote et rendre le contrôle à l'application plus rapidement que sans le délai.
Les appels NN HAL 1.3 qui incluent des délais OptionalTimePoint comme argument sont les suivants :
IDevice::prepareModel_1_3IDevice::prepareModelFromCache_1_3IPreparedModel::execute_1_3IPreparedModel::executeSynchronously_1_3IPreparedModel::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 à l'adresse
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 le signalement des erreurs, ce qui permet aux pilotes de mieux communiquer leur état et aux applications de récupérer plus facilement. Il s'agit des valeurs de code d'erreur dans ErrorStatus.
MISSED_DEADLINE_TRANSIENTMISSED_DEADLINE_PERSISTENTRESOURCE_EXHAUSTED_TRANSIENTRESOURCE_EXHAUSTED_PERSISTENT
Dans Android 10 ou une version antérieure, un pilote ne pouvait indiquer un échec que par 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é abandonnée parce que le délai a été atteint ou parce que le pilote a prédit que la charge de travail ne serait pas terminée avant le délai. Les deux codes d'erreur RESOURCE_EXHAUSTED peuvent être utilisés pour indiquer que la tâche a échoué en raison d'une limitation des ressources dans le pilote, par exemple si le pilote ne dispose pas de suffisamment de mémoire 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 réussir après un court délai. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote est occupé par un travail antérieur de longue durée ou nécessitant beaucoup de ressources, mais que la nouvelle tâche se terminerait correctement 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 devraient toujours échouer. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote estime que la tâche ne sera pas terminée avant le délai, même dans des conditions parfaites, ou que le modèle est intrinsèquement trop volumineux et dépasse les ressources du pilote.
Validation
La fonctionnalité de qualité de service est testée dans les tests VTS 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
et un ensemble de tests appelés DeadlineTest
(TestGenerated/DeadlineTest#Test/) pour s'assurer que le pilote gère correctement les délais.