Android 17 i nowsze wersje obsługują Menedżera jednostki przetwarzania neuronowego (NPU) (com.android.npumanager), który koordynuje przydzielanie i planowanie zasobów NPU w usługach systemowych i obciążeniach aplikacji. Przenosząc arbitraż zasobów z niestandardowych demonów dostawcy na platformę Androida, Menedżer NPU zwiększa przewidywalność, zapobiega brakowi zasobów, zarządza limitami termicznymi i zwiększa ogólną wydajność urządzenia.
Tło i motywacja
Przed wprowadzeniem Menedżera NPU aplikacje i moduły systemowe przesyłały zadania bezpośrednio do sterowników dostawcy lub usług własnych. Takie podejście miało kilka wad:
- Nieefektywna konkurencja o zasoby: duże obciążenia związane z uczeniem maszynowym (takie jak silniki wnioskowania dużych modeli językowych (LLM) lub systemy wizyjne na urządzeniu)konkurowały bezpośrednio z innymi systemami o wysokim priorytecie o ograniczone zasoby NPU (takie jak pamięć SRAM, pamięć wag i kanały wykonywania).
- Niestabilność systemu: nie skoordynowane zbiory zadań mogą powodować ograniczenie termiczne, błędy strony pamięci lub działanie demona LMKD (low memory killer daemon), jeśli zapotrzebowanie przekracza możliwości sprzętowe.
- Nieefektywne określanie priorytetów: serwer systemowy nie może dostosowywać priorytetu NPU w odpowiedzi na zmiany kontekstu, np. gdy zadanie w tle wczytuje duży model, a w pierwszym planie jest aktywny potok kamery wrażliwy na opóźnienia lub asystent użytkownika.
Menedżer NPU rozwiązuje te problemy, pełniąc rolę arbitra na poziomie systemu, który kontroluje wczytywanie modeli i dynamicznie dostosowuje priorytety wykonywania na podstawie aktualnego stanu urządzenia i aplikacji.
Architektura systemu
Menedżer NPU jest zaimplementowany jako usługa systemowa o nazwie npu działająca w ramach Androida. Menedżer NPU izoluje koordynację wysokiego poziomu zasad harmonogramowania od implementacji sterownika dostawcy niskiego poziomu.
Ten diagram przedstawia warstwy środowiska Menedżera NPU:

Rysunek 1. Warstwy środowiska Menedżera NPU.
Kluczowe komponenty
- Klient interfejsu API platformy (
android.npumanager.NpuManager): punkt wejścia używany przez klientów do wysyłania żądań rezerwacji wczytywania modelu. - Usługa systemowa (
npu): usługa systemowa, która kontroluje zatwierdzanie wczytywania modelu i zarządza poleceniami wywłaszczania na podstawie reguł priorytetu harmonogramowania. - NPU Scheduling HAL (
android.hardware.npu): interfejs oparty na AIDL, który przekazuje wywołania zwrotne priorytetów aplikacji na Androida między platformą a sterownikiem. - Sterownik dostawcy: sterownik niskiego poziomu, który kontroluje bloki wykonywania sprzętu i wdraża mechanizmy priorytetyzacji niskiego poziomu.
Interfejs API pakietu SDK i platformy
Przed wywołaniem bibliotek sieci neuronowych niskiego poziomu lub wczytaniem plików modelu klienci platformy muszą komunikować się z usługą NpuManager. Aby to zrobić, klienci najpierw definiują żądanie wczytania modelu, a potem wykonują żądanie i proces zatwierdzania.
Żądanie wczytania modelu
Żądanie wczytania modelu jest reprezentowane przez element ModelLoadRequest. Ten obiekt zawiera:
- Unikalny identyfikator żądania
- Szacowana klasa rozmiaru modelu, np.
NPU_MODEL_SIZE_LESS_THAN_1GBlubNPU_MODEL_SIZE_GREATER_THAN_2G - Zamierzony priorytet, np.
NPU_MODEL_PRIORITY_BACKGROUND,NPU_MODEL_PRIORITY_NORMALlubNPU_MODEL_PRIORITY_OPPORTUNISTIC
Poniższy przykład kodu tworzy ModelLoadRequest z limitem rozmiaru większym niż 2 GB i normalnym priorytetem wykonania:
ModelLoadRequest request = new ModelLoadRequest.Builder(requestId)
.setSize(NPU_MODEL_SIZE_GREATER_THAN_2G)
.setPriority(NPU_MODEL_PRIORITY_NORMAL)
.build();
Przepływ prośby i zatwierdzania
Klienci wywołują requestCanLoadModel asynchronicznie:
npuManager.requestCanLoadModel(request, callback, executor);
Gdy zasoby NPU są dostępne, platforma odpowiada za pomocą
ModelLoadRequestCallback z tymi zdarzeniami:
onCanLoadModel(request, status, listener): wywoływane, gdy żądanie zostanie zatwierdzone. Klient otrzymuje tokenNpuManager.ModelLoadStatusListener. Gdy klient w pełni wczyta model do pamięci sterownika, musi wywołać funkcjęlistener.notifyModelLoaded(request).onRequestUnloadModel(request)lubonRequestUnloadModel(request, reason): wywoływane, gdy system jest obciążony (np. przez przychodzące żądanie na pierwszym planie lub wzrost temperatury) i wymaga zwolnienia modelu przez klienta. Po odzyskaniu zasobów NPU klient wywołuje funkcjęlistener.notifyModelUnloaded(request).onModelLoadRequestComplete(request, status): informuje klienta o ostatecznych zmianach w cyklu życia żądania, np. o jego anulowaniu.
Klienci mogą anulować oczekujące zaproszenia za pomocą ikony cancelModelLoad(request).
Integracja z HAL i dostawcą
Aby obsługiwać Menedżera NPU, implementacje dostawców specyficzne dla urządzenia muszą być zgodne z android.hardware.npu interfejsami usług AIDL.
Konfiguracja harmonogramu
System przekazuje priorytet aplikacji za pomocą interfejsu AIDL SchedulingConfig
struktury AIDL SchedulingConfig zdefiniowanej w IScheduling.aidl:
package android.hardware.npu;
@VintfStability
parcelable SchedulingConfig {
int minPriority;
int maxPriority;
int uid;
int appPriority;
boolean hasDirectAccess;
boolean canAttributeOtherUid;
}
W ramach tej struktury menedżer ds. NPU koordynuje dostosowywanie priorytetów. Jeśli na przykład aplikacja działająca w tle przesyła zadanie o wysokim priorytecie, priorytet jest obniżany, aby zapobiec zakłóceniom grafiki na pierwszym planie.
Stan zadania i profilowanie
Sterowniki dostawców muszą zgłaszać do menedżera stan cyklu życia grup wykonawczych NPU. WorkInfo śledzi zadania (zdefiniowane w 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;
}
Eliminacja drgań klawiszy zdarzeń
Platforma planowania obsługuje usuwanie duplikatów zdarzeń za pomocą parametru debounce_duration_ms w rejestracji wywołania zwrotnego planowania.
Pozwala to uniknąć przepełnienia logów i tłumi szybkie powiadomienia, np. kolejne zdarzenia rozpoczęcia i zakończenia w przypadku powtarzających się modeli.
Stany cyklu życia wywołania zwrotnego są raportowane w ten sposób:
onWorkRequested: Zbiór zadań jest umieszczany w kolejce przez usługę dostawcy.onWorkStarted: rozpoczyna się wykonywanie zadania.NPU_START_REASON_INITIAL: pierwsze uruchomienie wykonania.NPU_START_REASON_RESUMED: Wykonanie wznowiono po przerwaniu.
onWorkEnded: Wykonywanie zadania zostało zakończone.NPU_END_REASON_COMPLETED: pomyślne ukończenie uruchomienia.NPU_END_REASON_CANCELLED_USER: Anulowano przez klienta.NPU_END_REASON_CANCELLED_SYSTEM: wyprzedzone przez zasady systemowe.NPU_END_REASON_FAILED: błąd wykonania lub awaria sterownika.NPU_END_REASON_PAUSED: tymczasowo zawieszone na potrzeby zadań o wyższym priorytecie.
Gotowość i testowanie urządzenia
Zanim sprawdzisz stan urządzenia, upewnij się, że te konfiguracje są prawidłowe.
Deklaracje dotyczące aplikacji
Klienci, którzy chcą, aby harmonogramowanie NPU było traktowane priorytetowo, muszą zadeklarować funkcję sprzętową NPU w AndroidManifest.xml:
<uses-feature android:name="android.hardware.npu" android:required="false" />
W przypadku modeli wdrażanych na nowszych generacjach sprzętu partnera ta deklaracja może być wymagana do optymalnego tworzenia silnika.
Testowanie integracji VTS
Implementacje NPU HAL można weryfikować za pomocą testów funkcjonalnych VTS, np. VtsHalNpuSchedulingTargetTest.