À partir d'Android 11, l'API NN 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 la préparation d'un modèle donné et le temps maximal attendu pour l'exécution d'un calcul donné. De plus, Android 11 introduit des valeurs d'erreur NNAPI supplémentaires qui permettent à 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 se rétablir.
Priorité
Pour Android 11 ou 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 celles 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 de 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 quelques stratégies :
- Pour les pilotes qui bénéficient d'une assistance prioritaire intégrée, 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 veille ou annulez les modèles de faible priorité en cours d'exécution pour libérer l'accélérateur et exécuter les 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 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 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, préservez le contexte d'exécution, y compris la prochaine opération ou le prochain sous-modèle à exécuter, ainsi que toutes les données d'opérandes intermédiaires pertinentes. Utilisez ce contexte d'exécution pour reprendre l'exécution ultérieurement.
- La préemption complète 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 différencier les différentes applications d'appel grâce à un AID (UID Android). 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 la liste des AID dans libcutils/include/cutils/android_filesystem_config.h
.
Échéances
À partir d'Android 11, la préparation et l'exécution des modèles peuvent être lancées avec un argument de délai OptionalTimePoint
. Pour les conducteurs qui peuvent estimer la durée d'une tâche, ce délai leur permet d'annuler la tâche avant qu'elle ne commence s'ils estiment qu'elle ne peut pas être terminée avant la date limite. De même, le délai permet au conducteur d'annuler une tâche en cours qu'il estime ne pas pouvoir terminer avant la date limite.
L'argument "deadline" ne force pas un pilote à abandonner une tâche si elle n'est pas terminée à la date limite ou si la date limite est dépassée. L'argument "deadline" peut être utilisé pour libérer des ressources de calcul dans le pilote et rendre le contrôle à l'application plus rapidement que sans la date limite.
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 consulter 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 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 de récupérer plus facilement. Il s'agit des valeurs de code d'erreur dans ErrorStatus
.
MISSED_DEADLINE_TRANSIENT
MISSED_DEADLINE_PERSISTENT
RESOURCE_EXHAUSTED_TRANSIENT
RESOURCE_EXHAUSTED_PERSISTENT
Sous Android 10 ou version antérieure, un pilote ne pouvait indiquer un échec qu'avec 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 était atteint ou parce que le pilote a prédit que la charge de travail ne serait pas terminée dans les délais. 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 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 gourmande en ressources, mais que la nouvelle tâche se terminerait correctement si le pilote n'était pas occupé par la tâche précédente. La version PERSISTENT
des deux erreurs indique que les futurs appels à la même tâche sont toujours censés échouer. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote estime que la tâche ne sera pas terminée dans les délais, 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 NNAPI VTS (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.