Ta strona zawiera omówienie sposobu implementacji sterownika interfejsu API sieci neuronowych (NNAPI). Więcej informacji można znaleźć w dokumentacji znajdującej się w plikach definicji HAL w katalogu hardware/interfaces/neuralnetworks
. Przykładowa implementacja sterownika znajduje się w frameworks/ml/nn/driver/sample
.
Aby uzyskać więcej informacji na temat interfejsu API sieci neuronowych, zobacz Interfejs API sieci neuronowych .
Sieci neuronowe HAL
Sieci neuronowe (NN) HAL definiuje abstrakcję różnych urządzeń , takich jak procesory graficzne (GPU) i cyfrowe procesory sygnałowe (DSP), które znajdują się w produkcie (na przykład telefonie lub tablecie). Sterowniki dla tych urządzeń muszą być zgodne z NN HAL. Interfejs jest określony w plikach definicji HAL w hardware/interfaces/neuralnetworks
.
Ogólny przepływ interfejsu między platformą a sterownikiem przedstawiono na rysunku 1.
Rysunek 1. Przebieg sieci neuronowych
Inicjalizacja
Podczas inicjalizacji struktura wysyła zapytanie do sterownika o jego możliwości przy użyciu IDevice::getCapabilities_1_3
. Struktura @1.3::Capabilities
zawiera wszystkie typy danych i reprezentuje nierelaksowaną wydajność przy użyciu wektora.
Aby określić, w jaki sposób przydzielić obliczenia do dostępnych urządzeń, struktura wykorzystuje możliwości, aby zrozumieć, jak szybko i jak wydajnie energetycznie każdy sterownik może wykonać wykonanie. Aby dostarczyć te informacje, kierowca musi podać znormalizowane wartości wydajności w oparciu o wykonanie obciążeń referencyjnych.
Aby określić wartości zwracane przez sterownik w odpowiedzi na IDevice::getCapabilities_1_3
, użyj aplikacji porównawczej NNAPI do pomiaru wydajności dla odpowiednich typów danych. Modele MobileNet v1 i v2, asr_float
i tts_float
są zalecane do pomiaru wydajności dla 32-bitowych wartości zmiennoprzecinkowych, a skwantyzowane modele MobileNet v1 i v2 są zalecane dla 8-bitowych skwantyzowanych wartości. Aby uzyskać więcej informacji, zobacz pakiet testów usługi Android Machine Learning .
W systemie Android 9 i niższych struktura Capabilities
zawiera informacje o wydajności sterownika tylko dla tensorów zmiennoprzecinkowych i skwantyzowanych i nie obejmuje skalarnych typów danych.
W ramach procesu inicjowania struktura może wysyłać zapytania o więcej informacji przy użyciu IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
i IDevice::getNumberOfCacheFilesNeeded
.
Pomiędzy ponownymi uruchomieniami produktu struktura oczekuje, że wszystkie zapytania opisane w tej sekcji będą zawsze zgłaszać te same wartości dla danego sterownika. W przeciwnym razie aplikacja korzystająca z tego sterownika może wykazywać zmniejszoną wydajność lub nieprawidłowe działanie.
Kompilacja
Struktura określa, których urządzeń użyć, gdy otrzyma żądanie z aplikacji. W Androidzie 10 aplikacje mogą wykrywać i określać urządzenia, z których wybiera platforma. Aby uzyskać więcej informacji, zobacz Wykrywanie i przypisywanie urządzeń .
W czasie kompilacji modelu struktura wysyła model do każdego kandydata na sterownik, wywołując IDevice::getSupportedOperations_1_3
. Każdy sterownik zwraca tablicę wartości logicznych wskazujących, które operacje modelu są obsługiwane. Sterownik może stwierdzić, że nie może obsłużyć danej operacji z wielu powodów. Na przykład:
- Sterownik nie obsługuje typu danych.
- Sterownik obsługuje tylko operacje z określonymi parametrami wejściowymi. Na przykład sterownik może obsługiwać operacje splotu 3x3 i 5x5, ale nie 7x7.
- Sterownik ma ograniczenia pamięci, które uniemożliwiają mu obsługę dużych wykresów lub danych wejściowych.
Podczas kompilacji operandy wejściowe, wyjściowe i wewnętrzne modelu, zgodnie z opisem w OperandLifeTime
, mogą mieć nieznane wymiary lub rangę. Aby uzyskać więcej informacji, zobacz Kształt wyjściowy .
Struktura instruuje każdy wybrany sterownik, aby przygotował się do wykonania podzestawu modelu, wywołując IDevice::prepareModel_1_3
. Następnie każdy sterownik kompiluje swój podzbiór. Na przykład kierowca może wygenerować kod lub utworzyć zmienioną kolejność kopii wag. Ponieważ między kompilacją modelu a wykonaniem żądań może upłynąć znaczna ilość czasu, podczas kompilacji nie należy przypisywać zasobów, takich jak duże fragmenty pamięci urządzenia.
W przypadku powodzenia sterownik zwraca uchwyt @1.3::IPreparedModel
. Jeśli sterownik zwróci kod błędu podczas przygotowywania swojego podzbioru modelu, struktura uruchomi cały model na procesorze.
Aby skrócić czas kompilacji podczas uruchamiania aplikacji, sterownik może buforować artefakty kompilacji. Aby uzyskać więcej informacji, zobacz Buforowanie kompilacji .
Wykonanie
Gdy aplikacja prosi platformę o wykonanie żądania, struktura domyślnie wywołuje metodę IPreparedModel::executeSynchronously_1_3
HAL w celu wykonania synchronicznego wykonania na przygotowanym modelu. Żądanie może być również wykonywane asynchronicznie przy użyciu metody execute_1_3
, metody executeFenced
(zobacz Wykonywanie chronione ) lub wykonywane przy użyciu wykonywania seryjnego .
Synchroniczne wywołania wykonania poprawiają wydajność i zmniejszają obciążenie wątków w porównaniu z wywołaniami asynchronicznymi, ponieważ kontrola jest zwracana do procesu aplikacji dopiero po zakończeniu wykonywania. Oznacza to, że sterownik nie potrzebuje osobnego mechanizmu do powiadamiania procesu aplikacji o zakończeniu wykonywania.
W przypadku asynchronicznej metody execute_1_3
kontrola powraca do procesu aplikacji po rozpoczęciu wykonywania, a sterownik musi powiadomić platformę o zakończeniu wykonywania przy użyciu @1.3::IExecutionCallback
.
Parametr Request
przekazany do metody execute zawiera listę operandów wejściowych i wyjściowych używanych do wykonania. Pamięć, w której przechowywane są dane operandów, musi wykorzystywać kolejność głównych wierszy, przy czym pierwszy wymiar iteruje najwolniej i nie może zawierać dopełnienia na końcu żadnego wiersza. Aby uzyskać więcej informacji na temat typów operandów, zobacz Operandy .
W przypadku sterowników NN HAL 1.2 lub nowszych po wykonaniu żądania stan błędu, kształt danych wyjściowych i informacje o taktowaniu są zwracane do struktury. Podczas wykonywania operandy wyjściowe lub wewnętrzne modelu mogą mieć jeden lub więcej nieznanych wymiarów lub nieznanej rangi. Gdy co najmniej jeden operand wyjściowy ma nieznany wymiar lub rangę, sterownik musi zwrócić informacje wyjściowe o dynamicznym rozmiarze.
W przypadku sterowników z NN HAL 1.1 lub niższym po zakończeniu żądania zwracany jest tylko stan błędu. Wymiary operandów wejściowych i wyjściowych muszą być w pełni określone, aby wykonanie zakończyło się pomyślnie. Argumenty wewnętrzne mogą mieć jeden lub więcej nieznanych wymiarów, ale muszą mieć określoną rangę.
W przypadku żądań użytkowników, które obejmują wiele sterowników, struktura jest odpowiedzialna za rezerwację pamięci pośredniej i sekwencjonowanie wywołań do każdego sterownika.
Wiele żądań można zainicjować równolegle na tym samym @1.3::IPreparedModel
. Sterownik może wykonywać żądania równolegle lub serializować wykonania.
Ramka może poprosić kierowcę o zachowanie więcej niż jednego przygotowanego modelu. Na przykład przygotuj model m1
, przygotuj m2
, wykonaj żądanie r1
na m1
, wykonaj r2
na m2
, wykonaj r3
na m1
, wykonaj r4
na m2
, zwolnij (opisane w Czyszczenie ) m1
i zwolnij m2
.
Aby uniknąć powolnego pierwszego wykonania, które mogłoby spowodować złe wrażenia użytkownika (na przykład zacinanie się pierwszej klatki), sterownik powinien wykonać większość inicjalizacji w fazie kompilacji. Inicjalizacja przy pierwszym uruchomieniu powinna być ograniczona do działań, które mają negatywny wpływ na kondycję systemu, jeśli są wykonywane wcześnie, takich jak rezerwowanie dużych buforów tymczasowych lub zwiększanie częstotliwości zegara urządzenia. Sterowniki, które mogą przygotować tylko ograniczoną liczbę modeli współbieżnych, mogą być zmuszone do inicjalizacji przy pierwszym uruchomieniu.
W systemie Android 10 lub nowszym, w przypadkach, gdy wiele wykonań z tym samym przygotowanym modelem jest wykonywanych w krótkich odstępach czasu, klient może zdecydować się na użycie obiektu serii wykonania do komunikacji między aplikacjami a procesami sterownika. Aby uzyskać więcej informacji, zobacz Wykonywanie serii i Kolejki szybkich komunikatów .
Aby poprawić wydajność wielu wykonań w krótkich odstępach czasu, sterownik może zatrzymać tymczasowe bufory lub zwiększyć częstotliwość taktowania. Zaleca się utworzenie wątku nadzorującego w celu zwolnienia zasobów, jeśli po określonym czasie nie zostaną utworzone żadne nowe żądania.
Kształt wyjściowy
W przypadku żądań, w których jeden lub więcej operandów wyjściowych nie ma określonych wszystkich wymiarów, sterownik musi dostarczyć listę kształtów wyjściowych zawierającą informacje o wymiarach dla każdego operandu wyjściowego po wykonaniu. Aby uzyskać więcej informacji na temat wymiarów, zobacz OutputShape
.
Jeśli wykonanie nie powiedzie się z powodu zbyt małego bufora wyjściowego, sterownik musi wskazać, które operandy wyjściowe mają niewystarczający rozmiar bufora na liście kształtów wyjściowych i powinien zgłosić jak najwięcej informacji o wymiarach, używając zera dla wymiarów, które są nieznane.
wyczucie czasu
W systemie Android 10 aplikacja może zapytać o czas wykonania, jeśli określiła jedno urządzenie do użycia podczas procesu kompilacji. Aby uzyskać szczegółowe informacje, zobacz MeasureTiming
oraz Wykrywanie i przypisywanie urządzeń . W takim przypadku sterownik NN HAL 1.2 musi mierzyć czas trwania wykonania lub zgłaszać UINT64_MAX
(aby wskazać, że czas trwania jest niedostępny) podczas wykonywania żądania. Kierowca powinien zminimalizować wszelkie straty wydajności wynikające z pomiaru czasu wykonania.
Sterownik zgłasza następujące czasy trwania w mikrosekundach w strukturze Timing
:
- Czas wykonania na urządzeniu: nie obejmuje czasu wykonania w sterowniku, który działa na procesorze hosta.
- Czas wykonania w sterowniku: Obejmuje czas wykonania na urządzeniu.
Te czasy trwania muszą obejmować czas, w którym wykonanie jest zawieszone, na przykład, gdy wykonanie zostało wywłaszczone przez inne zadania lub gdy oczekuje na udostępnienie zasobu.
Gdy sterownik nie został poproszony o zmierzenie czasu trwania wykonania lub wystąpił błąd wykonania, sterownik musi zgłaszać czasy trwania jako UINT64_MAX
. Nawet jeśli sterownik został poproszony o zmierzenie czasu trwania wykonania, może zamiast tego zgłosić UINT64_MAX
dla czasu na urządzeniu, czasu w sterowniku lub obu. Gdy sterownik zgłasza oba czasy trwania jako wartość inną niż UINT64_MAX
, czas wykonania w sterowniku musi być równy lub przekraczać czas na urządzeniu.
Ogrodzona egzekucja
W Androidzie 11 NNAPI pozwala egzekucjom czekać na listę uchwytów sync_fence
i opcjonalnie zwracać obiekt sync_fence
, który jest sygnalizowany po zakończeniu wykonywania. Zmniejsza to obciążenie w przypadku małych modeli sekwencji i przypadków użycia przesyłania strumieniowego. Wykonywanie chronione pozwala również na wydajniejsze współdziałanie z innymi składnikami, które mogą sygnalizować lub czekać na sync_fence
. Aby uzyskać więcej informacji na temat sync_fence
, zobacz Struktura synchronizacji .
W wykonywaniu chronionym struktura wywołuje metodę IPreparedModel::executeFenced
w celu uruchomienia zabezpieczonego, asynchronicznego wykonywania na przygotowanym modelu z wektorem ogrodzeń synchronizacji, na które należy czekać. Jeśli zadanie asynchroniczne zostanie zakończone przed zwróceniem wywołania, można zwrócić puste dojście dla sync_fence
. Należy również zwrócić obiekt IFencedExecutionCallback
, aby umożliwić platformie zapytanie o stan błędu i informacje o czasie trwania.
Po zakończeniu wykonywania następujące dwie wartości chronometrażu mierzące czas trwania wykonania można zapytać za pomocą IFencedExecutionCallback::getExecutionInfo
.
-
timingLaunched
: Czas trwania od momentuexecuteFenced
do momentu, gdyexecuteFenced
zasygnalizuje zwróceniesyncFence
. -
timingFenced
: Czas od momentu, w którym wszystkie ogrodzenia synchronizacji, na które czeka wykonanie, zostaną zasygnalizowane, gdyexecuteFenced
zasygnalizuje zwróconysyncFence
.
Kontrola przepływu
W przypadku urządzeń z systemem Android 11 lub nowszym NNAPI obejmuje dwie operacje przepływu sterowania, IF
i WHILE
, które przyjmują inne modele jako argumenty i wykonują je warunkowo ( IF
) lub wielokrotnie ( WHILE
). Aby uzyskać więcej informacji o tym, jak to zaimplementować, zobacz Przepływ sterowania .
Jakość usługi
W Androidzie 11 NNAPI obejmuje ulepszoną jakość usług (QoS), umożliwiając aplikacji wskazanie względnych priorytetów jej modeli, maksymalnego czasu oczekiwanego na przygotowanie modelu oraz maksymalnego czasu oczekiwanego na wykonanie do ukończenia. Aby uzyskać więcej informacji, zobacz Jakość usług .
Sprzątać
Gdy aplikacja zostanie zakończona przy użyciu przygotowanego modelu, struktura zwalnia odwołanie do @1.3::IPreparedModel
obiektu. Gdy obiekt IPreparedModel
nie jest już przywoływany, jest automatycznie niszczony w usłudze sterownika, która go utworzyła. Zasoby specyficzne dla modelu można odzyskać w tym momencie w implementacji destruktora przez sterownik. Jeśli usługa sterownika chce, aby obiekt IPreparedModel
był automatycznie niszczony, gdy nie jest już potrzebny klientowi, nie może przechowywać żadnych odwołań do obiektu IPreparedModel
po IPreparedeModel
obiektu IPreparedeModel przez IPreparedModelCallback::notify_1_3
.
użycie procesora
Oczekuje się, że sterowniki będą używać procesora do konfigurowania obliczeń. Sterowniki nie powinny używać procesora do wykonywania obliczeń wykresów, ponieważ zakłóca to zdolność struktury do prawidłowego przydzielania pracy. Sterownik powinien zgłosić części, których nie może obsłużyć, do struktury i pozwolić ramowi zająć się resztą.
Struktura zapewnia implementację procesora dla wszystkich operacji NNAPI z wyjątkiem operacji zdefiniowanych przez dostawcę. Aby uzyskać więcej informacji, zobacz Rozszerzenia dostawców .
Operacje wprowadzone w Androidzie 10 (API poziom 29) mają jedynie referencyjną implementację CPU do weryfikacji poprawności testów CTS i VTS. Zoptymalizowane implementacje zawarte w ramach mobilnego uczenia maszynowego są preferowane w stosunku do implementacji procesora NNAPI.
Funkcje użytkowe
Baza kodów NNAPI zawiera funkcje użytkowe, z których mogą korzystać usługi kierowców.
Plik frameworks/ml/nn/common/include/Utils.h
zawiera różne funkcje narzędziowe, takie jak te używane do rejestrowania i konwertowania między różnymi wersjami NN HAL.
VLogging:
VLOG
to makro otaczająceLOG
Androida, które rejestruje komunikat tylko wtedy, gdy we właściwościdebug.nn.vlog
jest ustawiony odpowiedni tag.initVLogMask()
musi zostać wywołana przed wywołaniemVLOG
.VLOG_IS_ON
można użyć do sprawdzenia, czyVLOG
jest aktualnie włączony, umożliwiając pominięcie skomplikowanego kodu rejestrowania, jeśli nie jest potrzebny. Wartość nieruchomości musi być jedną z następujących:- Pusty ciąg znaków wskazujący, że nie ma być wykonywane żadne rejestrowanie.
- Token
1
luball
, wskazujący, że należy wykonać całe logowanie. - Lista znaczników rozdzielona spacjami, przecinkami lub dwukropkami, wskazująca, które rejestrowanie ma zostać wykonane. Tagi to
compilation
,cpuexe
,driver
,execution
,manager
imodel
.
compliantWithV1_*
: Zwraca wartośćtrue
, jeśli obiekt NN HAL można przekonwertować na ten sam typ innej wersji HAL bez utraty informacji. Na przykład wywołaniecompliantWithV1_0
naV1_2::Model
zwraca wartośćfalse
, jeśli model zawiera typy operacji wprowadzone w NN HAL 1,1 lub NN HAL 1,2.convertToV1_*
: Konwertuje obiekt NN HAL z jednej wersji na inną. Ostrzeżenie jest rejestrowane, jeśli konwersja powoduje utratę informacji (to znaczy, jeśli nowa wersja typu nie może w pełni reprezentować wartości).Możliwości: Funkcje
nonExtensionOperandPerformance
iupdate
mogą być używane do tworzenia polaCapabilities::operandPerformance
.Zapytanie dotyczące właściwości typów:
isExtensionOperandType
,isExtensionOperationType
,nonExtensionSizeOfData
,nonExtensionOperandSizeOfData
,nonExtensionOperandTypeIsScalar
,tensorHasUnspecifiedDimensions
.
Plik frameworks/ml/nn/common/include/ValidateHal.h
zawiera funkcje narzędziowe do sprawdzania poprawności obiektu NN HAL zgodnie ze specyfikacją jego wersji HAL.
-
validate*
: Zwraca wartośćtrue
, jeśli obiekt NN HAL jest ważny zgodnie ze specyfikacją jego wersji HAL. Typy OEM i typy rozszerzeń nie są sprawdzane. Na przykładvalidateModel
zwraca wartośćfalse
, jeśli model zawiera operację odwołującą się do nieistniejącego indeksu operandu lub operację, która nie jest obsługiwana w tej wersji warstwy HAL.
Plik frameworks/ml/nn/common/include/Tracing.h
zawiera makra upraszczające dodawanie informacji systracing do kodu sieci neuronowych. Przykład można znaleźć w wywołaniach makr NNTRACE_*
w przykładowym sterowniku .
Plik frameworks/ml/nn/common/include/GraphDump.h
zawiera funkcję narzędzia do zrzutu zawartości Model
w formie graficznej do celów debugowania.
-
graphDump
: Zapisuje reprezentację modelu w formacie Graphviz (.dot
) do określonego strumienia (jeśli został podany) lub do logcata (jeśli nie podano strumienia).
Walidacja
Aby przetestować implementację NNAPI, użyj testów VTS i CTS zawartych w środowisku Android. VTS sprawdza Twoich kierowców bezpośrednio (bez użycia frameworka), podczas gdy CTS ćwiczy ich pośrednio poprzez framework. Testują one każdą metodę API i sprawdzają, czy wszystkie operacje obsługiwane przez sterowniki działają poprawnie i dostarczają wyniki spełniające wymagania dotyczące precyzji.
Wymagania dotyczące precyzji w CTS i VTS dla NNAPI są następujące:
Zmiennoprzecinkowy: abs(oczekiwany - rzeczywisty) <= atol + rtol * abs(oczekiwany); gdzie:
- Dla fp32, atol = 1e-5f, rtol = 5,0f * 1,1920928955078125e-7
- Dla fp16 atol = rtol = 5.0f * 0.0009765625f
Kwantyzacja : różnica o jeden (z wyjątkiem
mobilenet_quantized
, która jest różnicą o trzy)Wartość logiczna: dokładne dopasowanie
Jednym ze sposobów testowania NNAPI przez CTS jest generowanie ustalonych wykresów pseudolosowych używanych do testowania i porównywania wyników wykonania każdego sterownika z implementacją referencyjną NNAPI. W przypadku sterowników z NN HAL 1.2 lub nowszym, jeśli wyniki nie spełniają kryteriów precyzji, CTS zgłasza błąd i zrzuca plik specyfikacji dla uszkodzonego modelu w katalogu /data/local/tmp
w celu debugowania. Aby uzyskać więcej informacji na temat kryteriów precyzji, zobacz TestRandomGraph.cpp
i TestHarness.h
.
Testowanie rozmycia
Celem testów rozmytych jest znalezienie awarii, stwierdzeń, naruszeń pamięci lub ogólnego niezdefiniowanego zachowania w testowanym kodzie z powodu czynników, takich jak nieoczekiwane dane wejściowe. Do testowania rozmytego NNAPI system Android używa testów opartych na libFuzzer , które są wydajne w rozmywaniu, ponieważ wykorzystują pokrycie linii z poprzednich przypadków testowych do generowania nowych losowych danych wejściowych. Na przykład libFuzzer faworyzuje przypadki testowe, które działają na nowych liniach kodu. To znacznie skraca czas potrzebny na znalezienie problematycznego kodu podczas testów.
Aby przeprowadzić testy rozmyte w celu zweryfikowania implementacji sterownika, zmodyfikuj frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
w narzędziu testowym libneuralnetworks_driver_fuzzer
znajdującym się w AOSP, aby uwzględnić kod sterownika. Aby uzyskać więcej informacji na temat testowania fuzz NNAPI, zobacz frameworks/ml/nn/runtime/test/android_fuzzing/README.md
.
Bezpieczeństwo
Ponieważ procesy aplikacji komunikują się bezpośrednio z procesem kierowcy, kierowcy muszą weryfikować argumenty odbieranych połączeń. Ta walidacja jest weryfikowana przez VTS. Kod weryfikacyjny znajduje się w frameworks/ml/nn/common/include/ValidateHal.h
.
Kierowcy powinni również upewnić się, że aplikacje nie mogą kolidować z innymi aplikacjami podczas korzystania z tego samego urządzenia.
Pakiet testowy uczenia maszynowego na Androida
Android Machine Learning Test Suite (MLTS) to test porównawczy NNAPI zawarty w CTS i VTS do sprawdzania poprawności rzeczywistych modeli na urządzeniach dostawców. Benchmark ocenia opóźnienie i dokładność oraz porównuje wyniki sterowników z wynikami przy użyciu TF Lite działającego na procesorze, dla tego samego modelu i zestawów danych. Gwarantuje to, że dokładność sterownika nie jest gorsza niż implementacja referencyjna procesora.
Twórcy platformy Android również używają MLTS do oceny opóźnienia i dokładności sterowników.
Benchmark NNAPI można znaleźć w dwóch projektach w AOSP:
-
platform/test/mlts/benchmark
(aplikacja do testów porównawczych) -
platform/test/mlts/models
(modele i zbiory danych)
Modele i zbiory danych
Test porównawczy NNAPI wykorzystuje następujące modele i zestawy danych.
- MobileNetV1 float i u8 skwantyzowane w różnych rozmiarach, działają na małym podzbiorze (1500 obrazów) Open Images Dataset v4.
- MobileNetV2 float i u8 skwantyzowane w różnych rozmiarach, działają na małym podzbiorze (1500 obrazów) Open Images Dataset v4.
- Model akustyczny oparty na pamięci długoterminowej (LSTM) dla zamiany tekstu na mowę, uruchomiony na małym podzbiorze zestawu CMU Arctic.
- Model akustyczny oparty na LSTM do automatycznego rozpoznawania mowy, uruchamiany na niewielkim podzbiorze zbioru danych LibriSpeech.
Aby uzyskać więcej informacji, zobacz platform/test/mlts/models
.
Test naprężeń
Pakiet testowy usługi Android Machine Learning obejmuje serię testów zderzeniowych w celu sprawdzenia odporności sterowników w warunkach intensywnego użytkowania lub w skrajnych przypadkach zachowań klientów.
Wszystkie testy zderzeniowe zapewniają następujące funkcje:
- Wykrywanie zawieszenia: jeśli klient NNAPI zawiesi się podczas testu, test kończy się niepowodzeniem z przyczyną niepowodzenia
HANG
, a zestaw testów przechodzi do następnego testu. - Wykrywanie awarii klienta NNAPI: testy przetrwają awarie klienta, a testy kończą się niepowodzeniem z przyczyną niepowodzenia
CRASH
. - Wykrywanie awarii sterownika: testy mogą wykryć awarię sterownika, która powoduje awarię wywołania NNAPI. Należy pamiętać, że mogą wystąpić awarie procesów sterownika, które nie powodują awarii NNAPI i nie powodują niepowodzenia testu. Aby pokryć tego rodzaju awarię, zaleca się uruchomienie polecenia
tail
w dzienniku systemowym w przypadku błędów lub awarii związanych ze sterownikami. - Kierowanie na wszystkie dostępne akceleratory: testy są przeprowadzane na wszystkich dostępnych sterownikach.
Wszystkie testy zderzeniowe mają następujące cztery możliwe wyniki:
-
SUCCESS
: Wykonanie zakończone bez błędu. -
FAILURE
: Wykonanie nie powiodło się. Zazwyczaj spowodowane niepowodzeniem podczas testowania modelu, wskazujące, że sterownik nie mógł skompilować lub wykonać modelu. -
HANG
: Proces testowy przestał odpowiadać. -
CRASH
: Proces testowy uległ awarii.
Aby uzyskać więcej informacji na temat testów warunków skrajnych i pełną listę testów zderzeniowych, zobacz platform/test/mlts/benchmark/README.txt
.
Korzystanie z MLTS
Aby użyć MLTS:
- Podłącz urządzenie docelowe do swojej stacji roboczej i upewnij się, że jest osiągalne przez adb . Wyeksportuj zmienną środowiskową
ANDROID_SERIAL
urządzenia docelowego, jeśli podłączonych jest więcej niż jedno urządzenie. cd
do katalogu źródłowego najwyższego poziomu systemu Android.source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
Na koniec testu porównawczego wyniki są prezentowane jako strona HTML i przekazywane do
xdg-open
.
Aby uzyskać więcej informacji, zobacz platform/test/mlts/benchmark/README.txt
.
Wersje HAL sieci neuronowych
W tej sekcji opisano zmiany wprowadzone w wersjach Android i Neural Networks HAL.
Androida 11
Android 11 wprowadza NN HAL 1.3, który zawiera następujące znaczące zmiany.
- Obsługa podpisanej 8-bitowej kwantyzacji w NNAPI. Dodaje typ operandu
TENSOR_QUANT8_ASYMM_SIGNED
. Sterowniki z NN HAL 1.3 obsługujące operacje z kwantyzacją bez znaku muszą również obsługiwać podpisane warianty tych operacji. Podczas uruchamiania wersji ze znakiem i bez znaku większości operacji skwantyzowanych sterowniki muszą dawać takie same wyniki do przesunięcia 128. Istnieje pięć wyjątków od tego wymagania:CAST
,HASHTABLE_LOOKUP
,LSH_PROJECTION
,PAD_V2
iQUANTIZED_16BIT_LSTM
. OperacjaQUANTIZED_16BIT_LSTM
nie obsługuje operandów ze znakiem, a pozostałe cztery operacje obsługują kwantyzację ze znakiem, ale nie wymagają, aby wyniki były takie same. - Obsługa ogrodzonych wykonań, w których struktura wywołuje metodę
IPreparedModel::executeFenced
w celu uruchomienia ogrodzonego, asynchronicznego wykonania na przygotowanym modelu z wektorem ogrodzeń synchronizacji, na które należy czekać. Aby uzyskać więcej informacji, zobacz Wykonywanie zabezpieczone . - Wsparcie dla przepływu sterowania. Dodaje operacje
IF
iWHILE
, które przyjmują inne modele jako argumenty i wykonują je warunkowo (IF
) lub wielokrotnie (WHILE
). Aby uzyskać więcej informacji, zobacz Przepływ sterowania . - Poprawiona jakość usług (QoS), ponieważ aplikacje mogą wskazywać względne priorytety swoich modeli, maksymalny oczekiwany czas na przygotowanie modelu oraz maksymalny oczekiwany czas na ukończenie wykonania. Aby uzyskać więcej informacji, zobacz Jakość usług .
- Obsługa domen pamięci, które zapewniają interfejsy alokatorów dla buforów zarządzanych przez sterowniki. Pozwala to na przekazywanie natywnych pamięci urządzenia między wykonaniami, eliminując niepotrzebne kopiowanie danych i transformację między kolejnymi wykonaniami na tym samym sterowniku. Aby uzyskać więcej informacji, zobacz Domeny pamięci .
Androida 10
Android 10 wprowadza NN HAL 1.2, który zawiera następujące znaczące zmiany.
- Struktura
Capabilities
obejmuje wszystkie typy danych, w tym typy danych skalarnych, i reprezentuje niezrelaksowaną wydajność przy użyciu wektora, a nie nazwanych pól. - Metody
getVersionString
igetType
umożliwiają platformie pobieranie informacji o typie urządzenia (DeviceType
) i wersji. Zobacz Wykrywanie i przypisywanie urządzeń . - Metoda
executeSynchronously
jest wywoływana domyślnie w celu synchronicznego wykonywania wykonania. Metodaexecute_1_2
mówi platformie, aby wykonała wykonanie asynchronicznie. Zobacz Wykonanie . - Parametr
MeasureTiming
doexecuteSynchronously
,execute_1_2
i seryjne wykonanie określa, czy sterownik ma mierzyć czas trwania wykonania. Wyniki są raportowane w strukturzeTiming
. Zobacz Timing . - Obsługa wykonań, w których jeden lub więcej operandów wyjściowych ma nieznany wymiar lub rangę. Zobacz Kształt wyjściowy .
- Obsługa rozszerzeń dostawcy, które są zbiorami operacji i typów danych zdefiniowanych przez dostawcę. Sterownik zgłasza obsługiwane rozszerzenia za pomocą metody
IDevice::getSupportedExtensions
. Zobacz Rozszerzenia dostawcy . - Zdolność obiektu burst do kontrolowania zestawu wykonań burst przy użyciu szybkich kolejek komunikatów (FMQ) do komunikacji między aplikacjami a procesami sterownika, zmniejszając opóźnienia. Zobacz Wykonywanie serii i kolejki szybkich komunikatów .
- Wsparcie dla AHardwareBuffer, aby umożliwić sterownikowi wykonywanie wykonań bez kopiowania danych. Zobacz AHardwareBuffer .
- Ulepszona obsługa buforowania artefaktów kompilacji w celu skrócenia czasu kompilacji podczas uruchamiania aplikacji. Zobacz Buforowanie kompilacji .
Android 10 wprowadza następujące typy operandów i operacje.
-
ANEURALNETWORKS_BOOL
-
ANEURALNETWORKS_FLOAT16
-
ANEURALNETWORKS_TENSOR_BOOL8
-
ANEURALNETWORKS_TENSOR_FLOAT16
-
ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
-
ANEURALNETWORKS_TENSOR_QUANT16_SYMM
-
ANEURALNETWORKS_TENSOR_QUANT8_SYMM
-
ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
-
-
ANEURALNETWORKS_ABS
-
ANEURALNETWORKS_ARGMAX
-
ANEURALNETWORKS_ARGMIN
-
ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
-
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
-
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
-
ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
-
ANEURALNETWORKS_CAST
-
ANEURALNETWORKS_CHANNEL_SHUFFLE
-
ANEURALNETWORKS_DETECTION_POSTPROCESSING
-
ANEURALNETWORKS_EQUAL
-
ANEURALNETWORKS_EXP
-
ANEURALNETWORKS_EXPAND_DIMS
-
ANEURALNETWORKS_GATHER
-
ANEURALNETWORKS_GENERATE_PROPOSALS
-
ANEURALNETWORKS_GREATER
-
ANEURALNETWORKS_GREATER_EQUAL
-
ANEURALNETWORKS_GROUPED_CONV_2D
-
ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
-
ANEURALNETWORKS_INSTANCE_NORMALIZATION
-
ANEURALNETWORKS_LESS
-
ANEURALNETWORKS_LESS_EQUAL
-
ANEURALNETWORKS_LOG
-
ANEURALNETWORKS_LOGICAL_AND
-
ANEURALNETWORKS_LOGICAL_NOT
-
ANEURALNETWORKS_LOGICAL_OR
-
ANEURALNETWORKS_LOG_SOFTMAX
-
ANEURALNETWORKS_MAXIMUM
-
ANEURALNETWORKS_MINIMUM
-
ANEURALNETWORKS_NEG
-
ANEURALNETWORKS_NOT_EQUAL
-
ANEURALNETWORKS_PAD_V2
-
ANEURALNETWORKS_POW
-
ANEURALNETWORKS_PRELU
-
ANEURALNETWORKS_QUANTIZE
-
ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
-
ANEURALNETWORKS_RANDOM_MULTINOMIAL
-
ANEURALNETWORKS_REDUCE_ALL
-
ANEURALNETWORKS_REDUCE_ANY
-
ANEURALNETWORKS_REDUCE_MAX
-
ANEURALNETWORKS_REDUCE_MIN
-
ANEURALNETWORKS_REDUCE_PROD
-
ANEURALNETWORKS_REDUCE_SUM
-
ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
-
ANEURALNETWORKS_ROI_ALIGN
-
ANEURALNETWORKS_ROI_POOLING
-
ANEURALNETWORKS_RSQRT
-
ANEURALNETWORKS_SELECT
-
ANEURALNETWORKS_SIN
-
ANEURALNETWORKS_SLICE
-
ANEURALNETWORKS_SPLIT
-
ANEURALNETWORKS_SQRT
-
ANEURALNETWORKS_TILE
-
ANEURALNETWORKS_TOPK_V2
-
ANEURALNETWORKS_TRANSPOSE_CONV_2D
-
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
-
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN
-
Android 10 wprowadza aktualizacje do wielu dotychczasowych operacji. Aktualizacje dotyczą głównie:
- Obsługa układu pamięci NCHW
- Obsługa tensorów o randze innej niż 4 w operacjach softmax i normalizacji
- Obsługa rozszerzonych splotów
- Obsługa wejść z mieszaną kwantyzacją w
ANEURALNETWORKS_CONCATENATION
Poniższa lista przedstawia operacje zmodyfikowane w systemie Android 10. Aby uzyskać szczegółowe informacje o zmianach, zobacz OperationCode w dokumentacji referencyjnej NNAPI.
-
ANEURALNETWORKS_ADD
-
ANEURALNETWORKS_AVERAGE_POOL_2D
-
ANEURALNETWORKS_BATCH_TO_SPACE_ND
-
ANEURALNETWORKS_CONCATENATION
-
ANEURALNETWORKS_CONV_2D
-
ANEURALNETWORKS_DEPTHWISE_CONV_2D
-
ANEURALNETWORKS_DEPTH_TO_SPACE
-
ANEURALNETWORKS_DEQUANTIZE
-
ANEURALNETWORKS_DIV
-
ANEURALNETWORKS_FLOOR
-
ANEURALNETWORKS_FULLY_CONNECTED
-
ANEURALNETWORKS_L2_NORMALIZATION
-
ANEURALNETWORKS_L2_POOL_2D
-
ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
-
ANEURALNETWORKS_LOGISTIC
-
ANEURALNETWORKS_LSH_PROJECTION
-
ANEURALNETWORKS_LSTM
-
ANEURALNETWORKS_MAX_POOL_2D
-
ANEURALNETWORKS_MEAN
-
ANEURALNETWORKS_MUL
-
ANEURALNETWORKS_PAD
-
ANEURALNETWORKS_RELU
-
ANEURALNETWORKS_RELU1
-
ANEURALNETWORKS_RELU6
-
ANEURALNETWORKS_RESHAPE
-
ANEURALNETWORKS_RESIZE_BILINEAR
-
ANEURALNETWORKS_RNN
-
ANEURALNETWORKS_ROI_ALIGN
-
ANEURALNETWORKS_SOFTMAX
-
ANEURALNETWORKS_SPACE_TO_BATCH_ND
-
ANEURALNETWORKS_SPACE_TO_DEPTH
-
ANEURALNETWORKS_SQUEEZE
-
ANEURALNETWORKS_STRIDED_SLICE
-
ANEURALNETWORKS_SUB
-
ANEURALNETWORKS_SVDF
-
ANEURALNETWORKS_TANH
-
ANEURALNETWORKS_TRANSPOSE
Androida 9
NN HAL 1.1 został wprowadzony w systemie Android 9 i zawiera następujące znaczące zmiany.
-
IDevice::prepareModel_1_1
zawiera parametrExecutionPreference
. Kierowca może to wykorzystać do dostosowania swojego przygotowania, wiedząc, że aplikacja woli oszczędzać baterię lub będzie wykonywać model w szybkich, następujących po sobie wywołaniach. - Dodano dziewięć nowych operacji:
BATCH_TO_SPACE_ND
,DIV
,MEAN
,PAD
,SPACE_TO_BATCH_ND
,SQUEEZE
,STRIDED_SLICE
,SUB
,TRANSPOSE
. - Aplikacja może określić, że 32-bitowe obliczenia zmiennoprzecinkowe mogą być uruchamiane przy użyciu 16-bitowego zakresu zmiennoprzecinkowego i/lub precyzji przez ustawienie
Model.relaxComputationFloat32toFloat16
natrue
. StrukturaCapabilities
ma dodatkowe polerelaxedFloat32toFloat16Performance
, dzięki czemu kierowca może zgłosić swoje zrelaksowane działanie do struktury.
Androida 8.1
Początkowa warstwa HAL sieci neuronowych (1.0) została wydana w systemie Android 8.1. Aby uzyskać więcej informacji, zobacz /neuralnetworks/1.0/
.