NPU-Manager

Android 17 und höher unterstützt den NPU-Manager (Neural Processing Unit, com.android.npumanager), der die Zuweisung und Planung von NPU-Ressourcen für Systemdienste und Anwendungsworkloads koordiniert. Durch die Verlagerung der Ressourcenvermittlung von benutzerdefinierten Anbieter-Daemons auf die Android-Plattform erhöht der NPU-Manager die Vorhersagbarkeit, verhindert Ressourcenmangel, verwaltet thermische Grenzwerte und verbessert die Gesamtleistung des Geräts.

Hintergrund und Motivation

Vor dem NPU-Manager haben Apps und Systemmodule Workloads direkt an Anbietertreiber oder proprietäre Dienste gesendet. Dieser Ansatz hatte mehrere Nachteile:

  • Ineffizienter Ressourcenwettbewerb:Umfangreiche Machine-Learning-Workloads (z. B. Inferenz-Engines für Large Language Models (LLMs) oder On-Device-Vision-Systeme) konkurrierten direkt mit anderen Systemen mit hoher Priorität um begrenzte NPU-Ressourcen (z. B. SRAM, Gewichtsspeicher und Ausführungskanäle).
  • Systeminstabilität:Nicht koordinierte Workloads konnten thermische Drosselung, Speicherseitenfehler oder den Low Memory Killer Daemon (LMKD) auslösen, wenn die Anforderungen die Hardwarekapazität überstiegen.
  • Ineffiziente Priorisierung:Der Systemserver kann die NPU-Priorität nicht an Kontextänderungen anpassen, z. B. wenn eine Hintergrundaufgabe ein großes Modell lädt, während im Vordergrund eine latenzempfindliche Kamerapipeline oder ein Nutzerassistent aktiv ist.

Der NPU-Manager begegnet diesen Herausforderungen, indem er als Vermittler auf Systemebene fungiert, der das Laden von Modellen steuert und Ausführungsprioritäten dynamisch an den aktuellen Gerätezustand und App-Status anpasst.

Systemarchitektur

Der NPU-Manager wird als Systemdienst mit dem Namen npu im Android-Framework implementiert. Der NPU-Manager isoliert die übergeordnete Koordination von Planungsrichtlinien von der Low-Level-Implementierung des Anbietertreibers.

Das folgende Diagramm veranschaulicht die Umgebungsebenen des NPU-Managers:

NPU Manager-Umgebungsebenen

Abbildung 1 : Umgebungsebenen des NPU-Managers.

Schlüsselkomponenten

  • Framework-API-Client (android.npumanager.NpuManager) : Der Einstiegspunkt, über den Clients Reservierungen für das Laden von Modellen anfordern
  • Systemdienst (npu) : Ein Systemdienst, der Genehmigungen für das Laden von Modellen steuert und Vorrangbefehle basierend auf Regeln für die Planungspriorität verwaltet
  • NPU-Planungs-HAL (android.hardware.npu) : Eine AIDL-basierte Schnittstelle, die Rückrufe für Android-App-Prioritäten zwischen dem Framework und dem Treiber weiterleitet
  • Anbietertreiber:Ein Low-Level-Treiber, der die Hardware-Ausführungsblöcke steuert und Low-Level-Priorisierungsmechanismen implementiert

SDK- und Framework-API

Bevor Framework-Clients Low-Level-Bibliotheken für neuronale Netze aufrufen oder Modelldateien laden, müssen sie mit dem Dienst NpuManager interagieren. Dazu definieren Clients zuerst eine Anfrage zum Laden eines Modells und führen dann den Anfrage- und Genehmigungsablauf aus.

Anfrage zum Laden eines Modells

Eine Anfrage zum Laden eines Modells wird durch ModelLoadRequest dargestellt. Dieses Objekt enthält:

  • Eindeutige Anfrage-ID
  • Geschätzte Modellgrößenklasse, z. B. NPU_MODEL_SIZE_LESS_THAN_1GB oder NPU_MODEL_SIZE_GREATER_THAN_2G
  • Beabsichtigte Priorität, z. B. NPU_MODEL_PRIORITY_BACKGROUND, NPU_MODEL_PRIORITY_NORMAL oder NPU_MODEL_PRIORITY_OPPORTUNISTIC

Im folgenden Codebeispiel wird ein ModelLoadRequest mit einem Größenlimit von mehr als 2 GB und normaler Ausführungspriorität erstellt:

ModelLoadRequest request = new ModelLoadRequest.Builder(requestId)
        .setSize(NPU_MODEL_SIZE_GREATER_THAN_2G)
        .setPriority(NPU_MODEL_PRIORITY_NORMAL)
        .build();

Anfrage- und Genehmigungsablauf

Clients rufen requestCanLoadModel asynchron auf:

npuManager.requestCanLoadModel(request, callback, executor);

Wenn NPU-Ressourcen verfügbar sind, antwortet das Framework mit ModelLoadRequestCallback mit den folgenden Ereignissen:

  • onCanLoadModel(request, status, listener): Wird ausgelöst, wenn die Anfrage genehmigt wurde. Der Client erhält ein NpuManager.ModelLoadStatusListener-Token. Nachdem der Client das Modell vollständig in den Treiberspeicher geladen hat, muss er listener.notifyModelLoaded(request) aufrufen.
  • onRequestUnloadModel(request) oder onRequestUnloadModel(request, reason): Wird ausgelöst, wenn das System unter Ressourcenmangel leidet (z. B. bei einer eingehenden Vordergrundanfrage oder einem thermischen Anstieg) und der Client sein Modell freigeben muss. Nachdem die NPU-Ressourcen zurückgefordert wurden, ruft der Client listener.notifyModelUnloaded(request) auf.
  • onModelLoadRequestComplete(request, status): Informiert den Client über endgültige Änderungen im Lebenszyklus der Anfrage, z. B. die Stornierung.

Clients können ausstehende Einladungen mit cancelModelLoad(request) stornieren.

HAL- und Anbieterintegration

Um den NPU-Manager zu unterstützen, müssen gerätespezifische Anbieterimplementierungen den AIDL-Dienstschnittstellen android.hardware.npu entsprechen.

Planungskonfiguration

Das System leitet die App-Priorität über die AIDL die SchedulingConfig AIDL-Struktur weiter, die in IScheduling.aidl definiert ist:

package android.hardware.npu;

@VintfStability
parcelable SchedulingConfig {
    int minPriority;
    int maxPriority;
    int uid;
    int appPriority;
    boolean hasDirectAccess;
    boolean canAttributeOtherUid;
}

Mit dieser Struktur koordiniert der NPU-Manager Prioritätsanpassungen. Wenn beispielsweise eine Hintergrund-App einen Job mit hoher Priorität sendet, wird die Priorität nach unten angepasst, um Störungen der Vordergrundgrafiken zu vermeiden.

Aufgabenstatus und Profilerstellung

Anbietertreiber müssen den Lebenszyklusstatus von NPU-Ausführungsgruppen an den Manager melden. WorkInfo verfolgt die Aufgaben (definiert in 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;
}

Ereignis-Entprellen

Das Planungs-Framework unterstützt das Ereignis-Entprellen mit dem Parameter debounce_duration_ms bei der Registrierung des Planungs-Callbacks. Dadurch werden Log-Überlastungen vermieden und schnelle Benachrichtigungen unterdrückt, z. B. aufeinanderfolgende Start- und Endereignisse für wiederholte Modelle.

Die Lebenszyklusstatus des Callbacks werden so gemeldet:

  • onWorkRequested: Der Workload wird vom Anbieterdienst in die Warteschlange gestellt.
  • onWorkStarted: Die Ausführung des Workloads beginnt.
    • NPU_START_REASON_INITIAL: Erste Ausführung.
    • NPU_START_REASON_RESUMED: Ausführung nach vorzeitiger Beendigung fortgesetzt.
  • onWorkEnded: Die Ausführung des Workloads wurde beendet.
    • NPU_END_REASON_COMPLETED: Ausführung erfolgreich abgeschlossen.
    • NPU_END_REASON_CANCELLED_USER: Vom Client storniert.
    • NPU_END_REASON_CANCELLED_SYSTEM: Durch Systemrichtlinie vorzeitig beendet.
    • NPU_END_REASON_FAILED: Ausführungsfehler oder Treiberfehler.
    • NPU_END_REASON_PAUSED: Vorübergehend für Aufgaben mit höherer Priorität angehalten.

Gerätebereitschaft und Tests

Achten Sie darauf, dass diese Konfigurationen vorhanden sind, bevor Sie den Gerätezustand überprüfen.

Anwendungserklärungen

Clients, die eine NPU-Planungspriorisierung anstreben, müssen die NPU-Hardwarefunktion in ihrer AndroidManifest.xml deklarieren:

<uses-feature android:name="android.hardware.npu" android:required="false" />

Bei Modellen, die auf neueren Generationen von Partnerhardware bereitgestellt werden, ist diese Deklaration möglicherweise für die optimale Engine-Erstellung erforderlich.

VTS-Integrationstests

NPU-HAL-Implementierungen können mit VTS-Funktionstests validiert werden, z. B. VtsHalNpuSchedulingTargetTest.