Android 17 et versions ultérieures sont compatibles avec le gestionnaire d'unité de traitement neuronal (NPU, Neural Processing Unit) (com.android.npumanager), qui coordonne l'allocation et la planification des ressources NPU entre les services système et les charges de travail des applications. En transférant l'arbitrage des ressources des daemons de fournisseurs personnalisés vers la plate-forme Android, le gestionnaire NPU améliore la prévisibilité, empêche la pénurie de ressources, gère les limites thermiques et améliore les performances globales de l'appareil.
Contexte et motivation
Avant le gestionnaire NPU, les applications et les modules système envoyaient directement les charges de travail aux pilotes de fournisseurs ou aux services propriétaires. Cette approche présentait plusieurs inconvénients :
- Concurrence inefficace des ressources : les charges de travail de machine learning lourdes (telles que les moteurs d'inférence de grands modèles de langage (LLM) ou les systèmes de vision sur l'appareil) étaient en concurrence directe avec d'autres systèmes à priorité élevée pour les ressources NPU limitées (telles que la mémoire SRAM, la mémoire de poids et les canaux d'exécution).
- Instabilité du système : les charges de travail non coordonnées pouvaient déclencher une limitation thermique, des erreurs de page mémoire ou un daemon de suppression de mémoire insuffisante (LMKD) si les demandes dépassaient la capacité matérielle.
- Priorisation inefficace : le serveur système ne peut pas ajuster la priorité NPU en réponse aux changements de contexte, par exemple lorsqu'une tâche en arrière-plan charge un modèle massif alors qu'un pipeline de caméra sensible à la latence ou un assistant utilisateur est actif au premier plan.
Le gestionnaire NPU résout ces problèmes en agissant comme un arbitre au niveau du système qui contrôle le chargement des modèles et ajuste dynamiquement les priorités d'exécution en fonction de l'état actuel de l'appareil et des états des applications.
Architecture du système
Le gestionnaire NPU est implémenté en tant que service système nommé npu s'exécutant dans le framework Android. Le gestionnaire NPU isole la coordination de haut niveau des stratégies de planification de l'implémentation du pilote de fournisseur de bas niveau.
Le diagramme suivant illustre les couches d'environnement du gestionnaire NPU :

Figure 1. Couches d'environnement du gestionnaire NPU.
Composants clés
- Client de l'API du framework (
android.npumanager.NpuManager) : point d'entrée utilisé par les clients pour demander des réservations de chargement de modèle - Service système (
npu) : service système qui contrôle les approbations de chargement de modèle et gère les commandes de préemption en fonction des règles de priorité de planification - HAL de planification NPU (
android.hardware.npu) : interface basée sur AIDL qui relaie les rappels de priorité des applications Android entre le framework et le pilote - Pilote de fournisseur : pilote de bas niveau qui contrôle les blocs d'exécution matérielle et implémente des mécanismes de priorisation de bas niveau
SDK et API du framework
Avant d'appeler des bibliothèques de réseaux de neurones de bas niveau ou de charger des fichiers de modèle, les clients du framework doivent interagir avec le service NpuManager. Pour ce faire, les clients définissent d'abord une demande de chargement de modèle, puis exécutent le flux de demande et d'approbation.
Demande de chargement de modèle
Une demande de chargement de modèle est représentée par ModelLoadRequest. Cet objet contient les éléments suivants :
- ID de requête unique
- Classe de taille de modèle estimée, telle que
NPU_MODEL_SIZE_LESS_THAN_1GBouNPU_MODEL_SIZE_GREATER_THAN_2G - Priorité prévue, telle que
NPU_MODEL_PRIORITY_BACKGROUND,NPU_MODEL_PRIORITY_NORMALouNPU_MODEL_PRIORITY_OPPORTUNISTIC
L'exemple de code suivant crée un ModelLoadRequest avec une limite de taille supérieure à 2 Go et une priorité d'exécution normale :
ModelLoadRequest request = new ModelLoadRequest.Builder(requestId)
.setSize(NPU_MODEL_SIZE_GREATER_THAN_2G)
.setPriority(NPU_MODEL_PRIORITY_NORMAL)
.build();
Flux de demande et d'approbation
Les clients appellent requestCanLoadModel de manière asynchrone :
npuManager.requestCanLoadModel(request, callback, executor);
Lorsque les ressources NPU sont disponibles, le framework répond à l'aide de ModelLoadRequestCallback avec les événements suivants :
onCanLoadModel(request, status, listener): déclenché lorsque la requête est approuvée. Le client reçoit un jetonNpuManager.ModelLoadStatusListener. Une fois que le client a complètement chargé le modèle dans la mémoire du pilote, il doit appelerlistener.notifyModelLoaded(request).onRequestUnloadModel(request)ouonRequestUnloadModel(request, reason): déclenché lorsque le système rencontre une pression sur les ressources (par exemple, une requête de premier plan entrante ou un pic thermique) et nécessite que le client libère son modèle. Après avoir récupéré les ressources NPU, le client appellelistener.notifyModelUnloaded(request).onModelLoadRequestComplete(request, status): informe le client des modifications finales du cycle de vie de la requête, telles que l'annulation.
Les clients peuvent annuler les invitations en attente à l'aide de cancelModelLoad(request).
HAL et intégration du fournisseur
Pour prendre en charge le gestionnaire NPU, les implémentations de fournisseurs spécifiques à l'appareil doivent être conformes aux interfaces de service AIDL android.hardware.npu.
Configuration de la planification
Le système relaie la priorité de l'application à l'aide de la structure AIDL SchedulingConfig
the SchedulingConfig AIDL structure defined in
IScheduling.aidl :
package android.hardware.npu;
@VintfStability
parcelable SchedulingConfig {
int minPriority;
int maxPriority;
int uid;
int appPriority;
boolean hasDirectAccess;
boolean canAttributeOtherUid;
}
À l'aide de cette structure, le gestionnaire NPU coordonne les alignements de priorité. Par exemple, si une application en arrière-plan envoie un job à priorité élevée, la priorité est ajustée à la baisse pour éviter toute interférence avec les graphiques de premier plan.
État et profilage des tâches
Les pilotes de fournisseurs doivent signaler l'état du cycle de vie des groupes d'exécution NPU au gestionnaire. WorkInfo suit les tâches (définies dans
WorkInfo.aidl) :
package android.hardware.npu;
import android.hardware.npu.NpuUuid;
@VintfStability
parcelable WorkInfo {
int id;
@nullable NpuUuid groupId;
int uid;
int debugPid;
int originalUid;
@nullable String debugFeatureId;
int jobPriority;
int effectivePriority;
long timestampMs;
int deviceNumber;
}
Fonctionnalité anti-rebond d'événements
Le framework de planification est compatible avec la suppression des doublons d'événements à l'aide du paramètre debounce_duration_ms dans l'enregistrement du rappel de planification.
Cela évite l'inondation des journaux et supprime les notifications rapides, par exemple, les événements de début et de fin consécutifs pour les modèles répétitifs.
Les états du cycle de vie du rappel sont signalés comme suit :
onWorkRequested: la charge de travail est mise en file d'attente par le service du fournisseur.onWorkStarted: l'exécution de la charge de travail commence.NPU_START_REASON_INITIAL: première exécution.NPU_START_REASON_RESUMED: exécution reprise après préemption.
onWorkEnded: l'exécution de la charge de travail s'est terminée.NPU_END_REASON_COMPLETED: exécution réussie.NPU_END_REASON_CANCELLED_USER: annulée par le client.NPU_END_REASON_CANCELLED_SYSTEM: préemptée par la stratégie système.NPU_END_REASON_FAILED: erreur d'exécution ou défaillance du pilote.NPU_END_REASON_PAUSED: suspendue temporairement pour les tâches à priorité plus élevée.
Préparation et tests de l'appareil
Assurez-vous que ces configurations sont en place avant de vérifier l'état de l'appareil.
Déclarations d'application
Les clients qui recherchent une priorisation de la planification NPU doivent déclarer la fonctionnalité matérielle NPU dans leur AndroidManifest.xml :
<uses-feature android:name="android.hardware.npu" android:required="false" />
Pour les modèles déployés sur les nouvelles générations de matériel partenaire, cette déclaration peut être requise pour une création optimale du moteur.
Tests d'intégration VTS
Les implémentations HAL NPU peuvent être validées à l'aide de tests fonctionnels VTS, par exemple VtsHalNpuSchedulingTargetTest.