Sterowniki API sieci neuronowych

Na tej stronie znajduje się omówienie sposobu implementowania sterownika interfejsu API sieci neuronowych (NNAPI). Dalsze szczegóły 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 .

Więcej informacji na temat interfejsu API sieci neuronowych można znaleźć w artykule Interfejs API sieci neuronowych .

Sieci neuronowe HAL

Sieci neuronowe (NN) HAL definiuje abstrakcję różnych urządzeń , takich jak jednostki przetwarzania grafiki (GPU) i procesory sygnału cyfrowego (DSP), które znajdują się w produkcie (na przykład telefonie lub tablecie). Sterowniki 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 pomiędzy frameworkiem a sterownikiem przedstawiono na rysunku 1.

Przepływ sieci neuronowych

Rysunek 1. Przebieg sieci neuronowych

Inicjalizacja

Podczas inicjalizacji struktura wysyła zapytanie do sterownika o jego możliwości za pomocą IDevice::getCapabilities_1_3 . Struktura @1.3::Capabilities zawiera wszystkie typy danych i reprezentuje niezrelaksowaną wydajność za pomocą wektora.

Aby określić sposób przydzielania obliczeń dostępnym urządzeniom, platforma wykorzystuje możliwości pozwalające zrozumieć, jak szybko i jak efektywnie energetycznie każdy sterownik może wykonać wykonanie. Aby zapewnić te informacje, sterownik musi podać standardowe wartości wydajności w oparciu o wykonanie obciążeń referencyjnych.

Aby określić wartości zwracane przez sterownik w odpowiedzi na polecenie IDevice::getCapabilities_1_3 , użyj aplikacji testowej NNAPI do pomiaru wydajności odpowiednich typów danych. Do pomiaru wydajności w przypadku 32-bitowych wartości zmiennoprzecinkowych zalecane są modele MobileNet v1 i v2, asr_float i tts_float , a w przypadku 8-bitowych wartości skwantowanych zalecane są modele kwantowe MobileNet v1 i v2. Aby uzyskać więcej informacji, zobacz pakiet testów Android Machine Learning .

W systemie Android 9 i starszych struktura Capabilities zawiera informacje o wydajności sterownika tylko dla tensorów zmiennoprzecinkowych i skwantowanych i nie obejmuje skalarnych typów danych.

W ramach procesu inicjalizacji platforma 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 platforma 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 systemie Android 10 aplikacje mogą wykrywać i określać urządzenia, z których wybiera platformę. Aby uzyskać więcej informacji, zobacz Wykrywanie i przypisywanie urządzeń .

W czasie kompilacji modelu platforma wysyła model do każdego potencjalnego sterownika, 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 tego 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 dane wejściowe, wyjściowe i wewnętrzne operandy 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 podzbioru 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ć kopię wag o zmienionej kolejności. Ponieważ między kompilacją modelu a wykonaniem żądań może upłynąć dużo czasu, podczas kompilacji nie należy przypisywać zasobów, takich jak duże fragmenty pamięci urządzenia.

Jeśli operacja się powiedzie, sterownik zwraca uchwyt @1.3::IPreparedModel . Jeśli sterownik zwróci kod błędu podczas przygotowywania podzbioru modelu, platforma uruchomi cały model na procesorze.

Aby skrócić czas kompilacji po uruchomieniu aplikacji, sterownik może buforować artefakty kompilacji. Aby uzyskać więcej informacji, zobacz Buforowanie kompilacji .

Wykonanie

Gdy aplikacja prosi platformę o wykonanie żądania, platforma domyślnie wywołuje metodę HAL IPreparedModel::executeSynchronously_1_3 aby wykonać synchroniczne wykonanie przygotowanego modelu. Żądanie może być również wykonane asynchronicznie przy użyciu metody execute_1_3 , metody executeFenced (zobacz Wykonanie chronione ) lub wykonane przy użyciu wykonania seryjnego .

Wywołania wykonywania synchronicznego 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 powiadamiającego proces aplikacji o zakończeniu wykonywania.

W przypadku asynchronicznej metody execute_1_3 sterowanie powraca do procesu aplikacji po rozpoczęciu wykonywania, a sterownik musi powiadomić platformę o zakończeniu wykonywania za pomocą @1.3::IExecutionCallback .

Parametr Request przekazany do metody wykonywania zawiera listę operandów wejściowych i wyjściowych używanych do wykonania. Pamięć przechowująca dane operandu musi mieć kolejność wierszy głównych, przy czym pierwszy wymiar wykonuje najwolniejszą iterację i nie ma 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 zakończeniu żądania, do struktury zwracany jest stan błędu, kształt danych wyjściowych i informacje o taktowaniu . Podczas wykonywania dane wyjściowe lub wewnętrzne operandy 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ć informację wyjściową o dynamicznym rozmiarze.

W przypadku sterowników z NN HAL w wersji 1.1 lub starszej po zakończeniu żądania zwracany jest tylko status błędu. Aby wykonanie zakończyło się pomyślnie, wymiary operandów wejściowych i wyjściowych muszą być w pełni określone. Operandy wewnętrzne mogą mieć jeden lub więcej nieznanych wymiarów, ale muszą mieć określoną rangę.

W przypadku żądań użytkowników obejmujących wiele sterowników struktura jest odpowiedzialna za rezerwację pamięci pośredniej i sekwencjonowanie wywołań do każdego sterownika.

Wiele żądań można inicjować równolegle w tym samym @1.3::IPreparedModel . Sterownik może wykonywać żądania równolegle lub serializować wykonania.

Framework może poprosić kierowcę o zatrzymanie 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 Oczyszczanie ) 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 wykonywać większość inicjalizacji w fazie kompilacji. Inicjalizacja przy pierwszym wykonaniu powinna ograniczać się do działań, które wykonane wcześniej mają negatywny wpływ na kondycję systemu, takich jak rezerwowanie dużych buforów tymczasowych lub zwiększanie częstotliwości taktowania urządzenia. Sterowniki, które mogą przygotować tylko ograniczoną liczbę jednoczesnych modeli, mogą być zmuszone do przeprowadzenia ich inicjalizacji przy pierwszym uruchomieniu.

W systemie Android 10 lub nowszym, w przypadkach, gdy wiele wykonań tego samego przygotowanego modelu jest wykonywanych w krótkich odstępach czasu, klient może zdecydować się na użycie obiektu serii wykonania do komunikacji pomiędzy procesami aplikacji i sterownika. Aby uzyskać więcej informacji, zobacz Wykonywanie seryjne i szybkie kolejki komunikatów .

Aby poprawić wydajność wielu wykonań w krótkich odstępach czasu, sterownik może zachować tymczasowe bufory lub zwiększyć częstotliwość taktowania. Zaleca się utworzenie wątku nadzorującego w celu zwolnienia zasobów, jeśli po ustalonym 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 po wykonaniu dostarczyć listę kształtów wyjściowych zawierającą informacje o wymiarach dla każdego operandu wyjściowego. 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ć na liście kształtów wyjściowych, które operandy wyjściowe mają niewystarczający rozmiar bufora i powinien zgłosić jak najwięcej informacji o wymiarach, używając zera w przypadku nieznanych wymiarów.

wyczucie czasu

W systemie Android 10 aplikacja może zapytać o czas wykonania, jeśli określiła jedno urządzenie, którego będzie używać 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 zmierzyć czas wykonania lub zgłosić UINT64_MAX (aby wskazać, że czas trwania jest niedostępny) podczas wykonywania żądania. Kierowca powinien zminimalizować wszelkie spadki wydajności wynikające z pomiaru czasu trwania wykonania.

Sterownik raportuje w strukturze Timing następujące czasy trwania w mikrosekundach:

  • Czas wykonania na urządzeniu: nie obejmuje czasu wykonania w sterowniku działającym na procesorze hosta.
  • Czas wykonania w sterowniku: obejmuje czas wykonania na urządzeniu.

Czasy te muszą obejmować czas, w którym wykonanie jest zawieszone, na przykład gdy wykonanie zostało wyprzedzone przez inne zadania lub gdy oczekuje na udostępnienie zasobu.

Jeśli sterownik nie został poproszony o zmierzenie czasu wykonania lub gdy wystąpił błąd wykonania, sterownik musi zgłosić czasy trwania jako UINT64_MAX . Nawet jeśli sterownik został poproszony o zmierzenie czasu 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 większy niż czas na urządzeniu.

Ogrodzona egzekucja

W systemie Android 11 NNAPI umożliwia wykonaniem oczekiwanie na listę uchwytów sync_fence i opcjonalnie zwracanie obiektu sync_fence , który jest sygnalizowany po zakończeniu wykonywania. Zmniejsza to obciążenie w przypadku modeli o małych sekwencjach i przypadków użycia przesyłania strumieniowego. Wykonanie chronione pozwala również na bardziej wydajną interoperacyjność z innymi komponentami, które mogą sygnalizować lub czekać na sync_fence . Aby uzyskać więcej informacji na temat sync_fence , zobacz Struktura synchronizacji .

W przypadku chronionego wykonania framework wywołuje metodę IPreparedModel::executeFenced w celu uruchomienia chronionego, asynchronicznego wykonania na przygotowanym modelu z wektorem ogrodzeń synchronizacji, na który należy czekać. Jeśli zadanie asynchroniczne zostanie zakończone przed powrotem wywołania, dla sync_fence może zostać zwrócony pusty uchwyt. Należy również zwrócić obiekt IFencedExecutionCallback , aby umożliwić platformie wysyłanie zapytań o informacje o stanie błędu i czasie trwania.

Po zakończeniu wykonywania można zapytać o następujące dwie wartości czasu mierzące czas trwania wykonania za pomocą IFencedExecutionCallback::getExecutionInfo .

  • timingLaunched : Czas trwania od wywołania executeFenced do chwili, gdy executeFenced zasygnalizuje zwróconą syncFence .
  • timingFenced : Czas od momentu, w którym wszystkie ogrodzenia synchronizacji, na które czeka wykonanie, zostaną zasygnalizowane, gdy executeFenced zwrócony sygnał syncFence .

Kontrola przepływu

W przypadku urządzeń z systemem Android 11 lub nowszym interfejs NNAPI zawiera 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 na temat sposobu implementacji, zobacz Przepływ sterowania .

Jakość usługi

W systemie Android 11 interfejs NNAPI zapewnia lepszą jakość usług (QoS), umożliwiając aplikacji wskazanie względnych priorytetów modeli, maksymalnego czasu oczekiwanego na przygotowanie modelu oraz maksymalnego czasu oczekiwanego na wykonanie do uzupełnienia. Aby uzyskać więcej informacji, zobacz Jakość usług .

Posprzątać

Gdy aplikacja zakończy pracę z przygotowanym modelem, framework udostępnia odwołanie do obiektu @1.3::IPreparedModel . Kiedy nie ma już odniesienia do obiektu IPreparedModel , jest on automatycznie niszczony w usłudze sterownika, która go utworzyła. W tym momencie można odzyskać zasoby specyficzne dla modelu w ramach implementacji destruktora w sterowniku. Jeśli usługa sterownika chce, aby obiekt IPreparedModel został automatycznie zniszczony, gdy nie będzie już potrzebny klientowi, nie może zawierać żadnych odniesień do obiektu IPreparedModel po zwróceniu 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ść frameworka do prawidłowego przydzielania pracy. Sterownik powinien zgłosić części, których nie może obsłużyć, do frameworka i pozwolić frameworkowi 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 (poziom API 29) mają jedynie referencyjną implementację procesora w celu sprawdzenia poprawności testów CTS i VTS. Zoptymalizowane implementacje zawarte w platformach mobilnego uczenia maszynowego są preferowane w stosunku do implementacji procesora NNAPI.

Funkcje użytkowe

Baza kodu NNAPI zawiera funkcje narzędziowe, z których mogą korzystać usługi sterowników.

Plik frameworks/ml/nn/common/include/Utils.h zawiera różnorodne funkcje narzędziowe, takie jak te używane do rejestrowania i konwersji pomiędzy różnymi wersjami NN HAL.

  • VLogging: VLOG to makro otaczające LOG systemu Android, które rejestruje wiadomość tylko wtedy, gdy we właściwości debug.nn.vlog ustawiono odpowiedni znacznik. initVLogMask() musi zostać wywołana przed jakimkolwiek wywołaniem VLOG . Makra VLOG_IS_ON można użyć do sprawdzenia, czy VLOG jest aktualnie włączony, umożliwiając pominięcie skomplikowanego kodu logowania, jeśli nie jest on potrzebny. Wartość nieruchomości musi należeć do jednej z następujących wartości:

    • Pusty ciąg znaków wskazujący, że nie należy przeprowadzać rejestrowania.
    • Token 1 lub all wskazujący, że należy przeprowadzić całe rejestrowanie.
    • Lista znaczników rozdzielonych spacjami, przecinkami lub dwukropkami, wskazująca, które rejestrowanie ma zostać wykonane. Tagi to compilation , cpuexe , driver , execution , manager i model .
  • 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łanie compliantWithV1_0 w V1_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 i update mogą pomóc w tworzeniu pola Capabilities::operandPerformance .

  • Wykonywanie zapytań o właściwości typów: isExtensionOperandType , isExtensionOperationType , nonExtensionSizeOfData , nonExtensionOperandSizeOfData , nonExtensionOperandTypeIsScalar , tensorHasUnspecifiedDimensions .

Plik frameworks/ml/nn/common/include/ValidateHal.h zawiera funkcje narzędziowe służące do sprawdzania, czy obiekt NN HAL jest prawidłowy zgodnie ze specyfikacją jego wersji HAL.

  • validate* : Zwraca wartość true , jeśli obiekt NN HAL jest prawidłowy zgodnie ze specyfikacją jego wersji HAL. Typy OEM i typy rozszerzeń nie są sprawdzane. Na przykład validateModel zwraca false jeśli model zawiera operację odwołującą się do indeksu operandu, który nie istnieje, lub operację, która nie jest obsługiwana w tej wersji HAL.

Plik frameworks/ml/nn/common/include/Tracing.h zawiera makra upraszczające dodawanie informacji systracingu do kodu sieci neuronowych. Na przykład zobacz wywołania makr NNTRACE_* w przykładowym sterowniku .

Plik frameworks/ml/nn/common/include/GraphDump.h zawiera funkcję narzędziową umożliwiającą zrzut zawartości Model w formie graficznej na potrzeby debugowania.

  • graphDump : Zapisuje reprezentację modelu w formacie Graphviz ( .dot ) do określonego strumienia (jeśli jest dostępny) lub do logcat (jeśli nie podano strumienia).

Walidacja

Aby przetestować implementację NNAPI, użyj testów VTS i CTS zawartych w frameworku Android. VTS ćwiczy sterowniki bezpośrednio (bez użycia frameworka), natomiast CTS ćwiczy je pośrednio poprzez framework. Testują one każdą metodę API i sprawdzają, czy wszystkie operacje obsługiwane przez sterowniki działają poprawnie i zapewniają wyniki spełniające wymagania dotyczące precyzji.

Wymagania dotyczące dokładności w CTS i VTS dla NNAPI są następujące:

  • Liczba zmiennoprzecinkowa: abs(oczekiwana - rzeczywista) <= atol + rtol * abs(oczekiwana); Gdzie:

    • Dla fp32, atol = 1e-5f, rtol = 5,0f * 1,1920928955078125e-7
    • Dla fp16 atol = rtol = 5,0f * 0,0009765625f
  • Kwantyzowane: przesunięcie o jeden (z wyjątkiem mobilenet_quantized , które ma przesunięcie o trzy)

  • Wartość logiczna: dokładne dopasowanie

Jednym ze sposobów, w jakie CTS testuje NNAPI, jest generowanie stałych wykresów pseudolosowych używanych do testowania i porównywania wyników wykonania każdego sterownika z referencyjną implementacją NNAPI. W przypadku sterowników z NN HAL 1.2 lub nowszą wersją, jeśli wyniki nie spełniają kryteriów precyzji, CTS zgłasza błąd i zrzuca plik specyfikacji uszkodzonego modelu do /data/local/tmp w celu debugowania. Aby uzyskać więcej informacji na temat kryteriów precyzji, zobacz TestRandomGraph.cpp i TestHarness.h .

Testowanie fuzza

Celem testów rozmytych jest wykrycie awarii, stwierdzeń, naruszeń pamięci lub ogólnego niezdefiniowanego zachowania testowanego kodu z powodu takich czynników, jak nieoczekiwane dane wejściowe. Do testów rozmytych NNAPI system Android używa testów opartych na bibliotece libFuzzer , które są skuteczne w rozmywaniu, ponieważ wykorzystują pokrycie linii z poprzednich przypadków testowych do generowania nowych losowych danych wejściowych. Na przykład libFuzzer preferuje przypadki testowe, które działają na nowych wierszach kodu. To znacznie skraca czas potrzebny testom na znalezienie problematycznego kodu.

Aby przeprowadzić testy fuzz w celu sprawdzenia 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 sterownika, kierowcy muszą zweryfikować argumenty otrzymywanych wywołań. Walidacja ta 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ą zakłócać innych aplikacji podczas korzystania z tego samego urządzenia.

Zestaw testowy uczenia maszynowego systemu Android

Pakiet testowy Android Machine Learning Test Suite (MLTS) to test porównawczy NNAPI zawarty w CTS i VTS służący do sprawdzania dokładności rzeczywistych modeli na urządzeniach dostawców. Test porównawczy ocenia opóźnienia i dokładność oraz porównuje wyniki sterowników z wynikami uzyskanymi przy użyciu TF Lite działającego na procesorze, dla tego samego modelu i zestawów danych. Dzięki temu dokładność sterownika nie jest gorsza niż implementacja referencyjna procesora.

Twórcy platform Android używają również MLTS do oceny opóźnień i dokładności sterowników.

Benchmark NNAPI można znaleźć w dwóch projektach w AOSP:

Modele i zbiory danych

Test porównawczy NNAPI wykorzystuje następujące modele i zbiory danych.

  • MobileNetV1 float i u8 skwantowane w różnych rozmiarach, działają na małym podzbiorze (1500 obrazów) Open Images Dataset v4.
  • MobileNetV2 float i u8 skwantowane w różnych rozmiarach, działają na małym podzbiorze (1500 obrazów) Open Images Dataset v4.
  • Model akustyczny oparty na długiej pamięci krótkotrwałej (LSTM) do zamiany tekstu na mowę, prowadzony w oparciu o niewielki podzbiór zbioru CMU Arctic.
  • Model akustyczny oparty na LSTM do automatycznego rozpoznawania mowy, prowadzony na małym podzbiorze zbioru danych LibriSpeech.

Aby uzyskać więcej informacji, zobacz platform/test/mlts/models .

Test naprężeń

Pakiet testowy Android Machine Learning obejmuje serię testów zderzeniowych mających na celu sprawdzenie odporności sterowników w trudnych warunkach użytkowania lub w trudnych przypadkach związanych z zachowaniem klientów.

Wszystkie testy zderzeniowe zapewniają następujące funkcje:

  • Wykrywanie zawieszeń: Jeśli klient NNAPI zawiesza się podczas testu, test kończy się niepowodzeniem z powodu niepowodzenia HANG i zestaw testów przechodzi do następnego testu.
  • Wykrywanie awarii klienta NNAPI: testy przetrwają awarie klienta i 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 sterowników, które nie powodują awarii NNAPI i nie powodują niepowodzenia testu. Aby zaradzić tego rodzaju awariom, zaleca się uruchomienie polecenia tail w dzienniku systemowym w celu wykrycia błędów lub awarii związanych ze sterownikiem.
  • Targetowanie na wszystkie dostępne akceleratory: Testy przeprowadzane są na wszystkich dostępnych sterownikach.

Wszystkie testy zderzeniowe dają następujące cztery możliwe wyniki:

  • SUCCESS : Wykonanie zakończone bez błędu.
  • FAILURE : Wykonanie nie powiodło się. Zwykle jest to spowodowane niepowodzeniem podczas testowania modelu, wskazującym, że sterownik nie skompilował lub nie wykonał modelu.
  • HANG : Proces testowy przestał odpowiadać.
  • CRASH : Proces testowy uległ awarii.

Więcej informacji na temat testów warunków skrajnych i pełną listę testów zderzeniowych można znaleźć w platform/test/mlts/benchmark/README.txt .

Użyj MLTS

Aby skorzystać z MLTS:

  1. Podłącz urządzenie docelowe do stacji roboczej i upewnij się, że jest ono osiągalne przez adb . Wyeksportuj zmienną środowiskową ANDROID_SERIAL urządzenia docelowego, jeśli podłączonych jest więcej niż jedno urządzenie.
  2. 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 w postaci strony 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 HAL dla systemu Android i sieci neuronowych.

Androida 11

W Androidzie 11 wprowadzono NN HAL 1.3, który zawiera następujące istotne zmiany.

  • Obsługa 8-bitowej kwantyzacji ze znakiem 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 większości skwantowanych operacji ze znakiem i bez znaku sterowniki muszą dawać takie same wyniki aż do przesunięcia wynoszącego 128. Istnieje pięć wyjątków od tego wymagania: CAST , HASHTABLE_LOOKUP , LSH_PROJECTION , PAD_V2 i QUANTIZED_16BIT_LSTM . Operacja QUANTIZED_16BIT_LSTM nie obsługuje argumentów ze znakiem, a pozostałe cztery operacje obsługują kwantyzację ze znakiem, ale nie wymagają, aby wyniki były takie same.
  • Obsługa chronionych wykonań, w których struktura wywołuje metodę IPreparedModel::executeFenced w celu uruchomienia chronionego, asynchronicznego wykonania na przygotowanym modelu z wektorem ogrodzeń synchronizacji, na które należy czekać. Aby uzyskać więcej informacji, zobacz temat Wykonanie chronione .
  • Wsparcie przepływu sterowania. Dodaje operacje IF i WHILE , 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 czas oczekiwany na przygotowanie modelu oraz maksymalny oczekiwany czas wykonania. Aby uzyskać więcej informacji, zobacz Jakość usług .
  • Obsługa domen pamięci zapewniających interfejsy alokatora dla buforów zarządzanych przez sterowniki. Pozwala to na przekazywanie natywnych pamięci urządzenia pomiędzy wykonaniami, eliminując niepotrzebne kopiowanie i transformację danych pomiędzy kolejnymi wykonaniami na tym samym sterowniku. Aby uzyskać więcej informacji, zobacz Domeny pamięci .

Androida 10

W Androidzie 10 wprowadzono NN HAL 1.2, który zawiera następujące istotne zmiany.

  • Struktura Capabilities obejmuje wszystkie typy danych, w tym skalarne typy danych, i reprezentuje niezrelaksowaną wydajność przy użyciu wektora, a nie nazwanych pól.
  • Metody getVersionString i getType 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 wykonania synchronicznego. Metoda execute_1_2 informuje platformę, aby wykonała wykonanie asynchronicznie. Zobacz Wykonanie .
  • Parametr MeasureTiming do executeSynchronously , execute_1_2 i wykonywania serii określa, czy sterownik ma mierzyć czas trwania wykonania. Wyniki są raportowane w strukturze Timing . Zobacz Czas .
  • 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ń dostawców, które są zbiorami operacji i typów danych zdefiniowanych przez dostawcę. Sterownik raportuje obsługiwane rozszerzenia za pomocą metody IDevice::getSupportedExtensions . Zobacz Rozszerzenia dostawców .
  • Zdolność obiektu serii do kontrolowania zestawu wykonań serii przy użyciu szybkich kolejek komunikatów (FMQ) do komunikacji między procesami aplikacji i sterowników, zmniejszając opóźnienia. Zobacz Wykonywanie seryjne i szybkie kolejki wiadomości .
  • Obsługa AHardwareBuffer umożliwiająca sterownikowi wykonywanie operacji bez kopiowania danych. Zobacz AHardwareBuffer .
  • Ulepszona obsługa buforowania artefaktów kompilacji, aby skrócić czas kompilacji podczas uruchamiania aplikacji. Zobacz Buforowanie kompilacji .

W systemie Android 10 wprowadzono następujące typy operandów i operacje.

  • Typy operandów

    • 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
  • Operacje

    • 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 wielu dotychczasowych operacji. Aktualizacje dotyczą głównie następujących kwestii:

  • Obsługa układu pamięci NCHW
  • Obsługa tensorów o randze innej niż 4 w operacjach softmax i normalizacyjnych
  • Wsparcie dla rozszerzonych skrętó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 na temat zmian, 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 istotne zmiany.

  • IDevice::prepareModel_1_1 zawiera parametr ExecutionPreference . Kierowca może to wykorzystać do dostosowania przygotowania, wiedząc, że aplikacja woli oszczędzać baterię lub będzie wykonywała model w szybkich kolejnych 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 typu float mogą być uruchamiane przy użyciu 16-bitowego zakresu i/lub precyzji, ustawiając Model.relaxComputationFloat32toFloat16 na true . Struktura Capabilities zawiera dodatkowe pole relaxedFloat32toFloat16Performance , dzięki czemu sterownik może raportować do struktury swoje zrelaksowane działanie.

Androida 8.1

Początkowa wersja HAL sieci neuronowych (1.0) została wydana w systemie Android 8.1. Aby uzyskać więcej informacji, zobacz /neuralnetworks/1.0/ .