Zestaw testów akceleratora LiteRT (ATS)

LiteRT Accelerator Test Suite (ATS) to kompleksowe narzędzie służące do weryfikowania poprawności działania i pomiaru wydajności niestandardowych implementacji akceleratorów zintegrowanych z platformą LiteRT.

Omówienie i główne funkcje

Głównym zadaniem ATS jest wykonywanie wstępnie zdefiniowanych modeli uczenia maszynowego na akceleratorze docelowym i porównywanie wyników z standardowym backendem procesora LiteRT.

  • Weryfikacja: pakiet przeprowadza weryfikację numeryczną, porównując tensory wyjściowe (aktywacje) wygenerowane przez akcelerator z tensorami wygenerowanymi przez znane, prawidłowe zaplecze CPU. Dzięki temu wdrożenie akceleratora zachowa wymaganą precyzję i poprawność.
  • Dane o wydajności: automatycznie rejestruje i zapisuje najważniejsze szczegóły dotyczące wydajności, w tym opóźnienie i inne istotne dane, które są udostępniane użytkownikowi.
  • Wykonanie: testy są zwykle przeprowadzane na urządzeniu docelowym (np. telefonie z Androidem) i zarządzane przez skrypt powłoki, który obsługuje przesyłanie plików i konfigurację za pomocą narzędzia adb (Android Debug Bridge).

Dane testowe (modele)

Pakiet ATS wykorzystuje jako dane testowe zbiór powszechnie używanych .tflitemodeli. Dane wejściowe są generowane losowo na podstawie typu danych i w razie potrzeby mogą być inicjowane.

Uwzględnione modele

Te modele są automatycznie uwzględniane i pobierane na potrzeby testowania (mogą ulec zmianie):

  • hf_all_minilm_l6_v2
  • hf_mobilevit_small
  • qai_hub_midas
  • qai_hub_real_esrgan_x4plus
  • torchvision_mobilenet_v2
  • torchvision_resnet18
  • torchvision_squeezenet1_1
  • u2net_lite
  • whisper_tiny_decoder
  • whisper_tiny_encoder
  • yamnet
  • yolo11n

Ręczne pobieranie modelu

Modele są pobierane automatycznie podczas bazel run, ale możesz ręcznie pobrać cały zestaw modeli za pomocą wget:

wget -p -O <target_file> https://storage.googleapis.com/litert/ats_models.tar.gz

Definiowanie pakietu ATS za pomocą Bazela

Użyj makra litert_define_ats Bazel, aby skonfigurować i zdefiniować cel testowania ATS specyficzny dla akceleratora.

Makro automatycznie tworzy 2 cele, które można uruchomić:

  1. Standardowy test JIT na urządzeniu (do wykonania i weryfikacji).
  2. Specjalny test trybu „tylko kompilacja” AOT (do kompilacji hosta).

Przykład litert_define_ats użycia

W przykładzie zdefiniowano pakiet ATS o nazwie example_ats dla akceleratora o nazwie backendu example:

# Emits aot-mode and jit-mode test targets, one for running compilation test on host
# and another for running JIT and inference on device
# These targets are named with their respective suffix attribute.
litert_define_ats(
    name = "example_ats",
    backend = "example",
    compile_only_suffix = "_aot",
    do_register = [
        "*mobilenet*",
    ],
    extra_flags = ["--limit=1"],
    jit_suffix = "",
)

Wykonanie

Aby przeprowadzić standardowy test na Androidzie (który obsługuje wszystkie operacje adb):

# Handles environment setup, and build + push of library and data dependencies to the device,
# executes the suite on the target.
bazel run -c opt --config=android_arm64 :example_ats

Aby przeprowadzić test kompilacji AOT:

# Handle environment setup, and builds library dependencies for host platform.
# Executes the ats compile only flow. The "--compile_mode" flag is already
# bound to the program arguments.
bazel run :example_ats_aot

Wykonywanie w systemie Linux (host)

W przypadku wykonywania w systemie Linux, gdy ATS jest uruchamiany na tej samej maszynie, na której odbywa się kompilacja, użytkownicy muszą używać bezpośrednio pliku binarnego :ats:

bazel run -c opt :ats

Wykonanie IoT

W przypadku wykonywania kodu na urządzeniach IoT użytkownicy muszą skompilować plik binarny na hoście i ręcznie przesłać go na urządzenie.

Flagi wiersza poleceń

Plik wykonywalny ats akceptuje kilka flag, które umożliwiają szczegółową kontrolę nad testowaniem i raportowaniem.

Flaga Typ Opis
--backend std::string Wymagane. Którego backendu LiteRT użyć jako testowanego akceleratora („rzeczywistego”). Dostępne opcje to cpu, npugpu.
--compile_mode bool Jeśli ma wartość Prawda, krok kompilacji AOT jest wykonywany na stacji roboczej zamiast na urządzeniu. UWAGA: ta opcja jest automatycznie powiązana z celem kompilacji „aot” i nie trzeba jej ustawiać jawnie.
--models_out std::string Ścieżka do katalogu, w którym zapisywane są modele efektów ubocznych w formacie serializowanym (skompilowanym). Dotyczy tylko kompilacji AOT lub JIT.
--dispatch_dir std::string Ścieżka do katalogu zawierającego bibliotekę wysyłania akceleratora (dotyczy NPU).
--plugin_dir std::string Ścieżka do katalogu zawierającego bibliotekę wtyczki kompilatora akceleratora (dotyczy NPU).
--soc_manufacturer std::string Producent układu SOC, na którego ma być kierowana kompilacja AOT (dotyczy kompilacji NPU).
--soc_model std::string Model SOC, który ma być celem kompilacji AOT (dotyczy kompilacji NPU).
--iters_per_test size_t Liczba iteracji do wykonania w każdym teście, z różnymi losowymi danymi tensora.
--max_ms_per_test int64_t Maksymalny czas (w milisekundach) na wykonanie każdego testu przed upłynięciem limitu czasu.
--fail_on_timeout bool Określa, czy test powinien się nie powieść, jeśli upłynie limit czasu wykonania.
--csv std::string Ścieżka do pliku, w którym ma zostać zapisany szczegółowy raport w formacie CSV.
--dump_report bool Czy zrzucać wszystkie szczegóły raportu bezpośrednio do danych wyjściowych konsoli użytkownika.
--data_seed std::optional<int> Jeden punkt początkowy do generowania danych globalnych.
--do_register std::vector<std::string> wyrażenia regularne do jawnego uwzględniania określonych testów (np. *mobilenet*).
--dont_register std::vector<std::string> Wyrażenia regularne wykluczające określone testy.
--extra_models std::vector<std::string> Opcjonalna lista katalogów lub plików modeli do dodania do pakietu testowego.
--limit int32_t Ograniczanie łącznej liczby zarejestrowanych i przeprowadzonych testów.
--quiet bool Zminimalizuj dane wyjściowe logowania podczas uruchamiania testu.

Korzystanie z litert_device_script narzędzi do tworzenia ATS

Automatyczne testy systemowe (ATS) są wykonywane automatycznie i zawierają punkt wejścia powłoki, który obsługuje całą konfigurację środowiska i przesyłanie wymaganych bibliotek, gdy urządzenie docelowe różni się od hosta, na którym zakończono kompilację (np.adb push).

Ta funkcja jest udostępniana ogólnie za pomocą narzędzi litert_device_script, z których korzystają wewnętrznie narzędzia ATS. Aby uzyskać dostęp do tej funkcji kompilacji, akceleratory muszą przejść proces rejestracji. Oprócz obsługi ats te narzędzia mogą być używane samodzielnie do symulowania cc_binarycc_test, które mają być wykonywane na urządzeniu innym niż host kompilacji wymagający wypychania zależności.

Rejestracja backendu

Aby włączyć nowy akcelerator do użytku z litert_device_script (a tym samym z ATS), jego wymagane biblioteki muszą być zarejestrowane w pliku Bazel litert_device_common.bzl. Rejestracja jest oparta na unikalnej nazwie „backendu”, która jest powiązana z zestawem bibliotek do skompilowania lub wstępnie skompilowanych, które są potrzebne do działania LiteRT z tym akceleratorem.

Kroki rejestracji

  1. Zdefiniuj funkcję BackendSpec: utwórz funkcję, która zwraca słownik zawierający specyfikację nowego akceleratora.

  2. Określ biblioteki (libs): to lista krotek zawierających ścieżkę docelową Bazel biblioteki współdzielonej i zmienną środowiskową (LD_LIBRARY_PATH) wymaganą do znalezienia jej przez linker urządzenia.

    • Biblioteka Dispatch: wymagana do wykonania w czasie działania.
    • Biblioteka wtyczek kompilatora: wymagana w przypadku trybu kompilacji AOT.
  3. Określ nazwy bibliotek (plugin, dispatch): podaj nazwy plików wtyczki i bibliotek wysyłających.

  4. Zarejestruj specyfikację: scal nową funkcję specyfikacji z główną funkcją _Specs, aby była dostępna za pomocą unikalnego identyfikatora backendu.

Przykładowa rejestracja (_ExampleSpec)

Poniższy kod z litert_device_common.bzl pokazuje, jak rejestrowany jest akcelerator „example”:

def _ExampleSpec():
    return {
        # The unique backend ID
        "example": BackendSpec(
            id = "example",
            libs = [
                # Dispatch Library and how to find it on device
                ("//third_party/odml/litert/litert/vendors/examples:libLiteRtDispatch_Example.so", "LD_LIBRARY_PATH"),
                # Compiler Plugin Library
                ("//third_party/odml/litert/litert/vendors/examples:libLiteRtCompilerPlugin_Example.so", "LD_LIBRARY_PATH"),
            ],
            plugin = "libLiteRtCompilerPlugin_Example.so",
            dispatch = "libLiteRtDispatch_Example.so",
        ),
    }

# ... (Other specs are defined here)

def _Specs(name):
    # Your new spec function must be included here
    return (_QualcommSpec() | _GoogleTensorSpec() | _MediatekSpec() | _CpuSpec() | _GpuSpec() | _ExampleSpec())[name]

Korzystanie z rejestracji w usłudze litert_device_exec

Po zarejestrowaniu używaj litert_device_exec i powiązanych makr z nowym backend_id. To makro automatycznie łączy wymagane biblioteki i wszystkie określone pliki danych z docelowym plikiem binarnym.

cc_binary(
    name = "example_bin",
    srcs = ["example_bin.cc"],
)

litert_device_exec(
    name = "example_bin_device",
    backend_id = "example",  # Uses the libraries registered under "example"
    data = [
        "//third_party/odml/litert/litert/test:testdata/constant_output_tensor.tflite",
    ],
    target = ":example_bin",
)

Uruchomienie tego celu (bazel run ... :example_bin_device) spowoduje:

  1. Skompiluj plik binarny example_bin C++.
  2. Prześlij na urządzenie plik binarny, libLiteRtDispatch_Example.so, libLiteRtCompilerPlugin_Example.so i plik .tflite.
  3. Uruchom plik binarny za pomocą polecenia adb shell.

Uwaga dotycząca ścieżek do plików na urządzeniu: kanoniczna lokalizacja plików na urządzeniu odzwierciedla drzewo plików wykonywalnych Bazela, a konkretnie /data/local/tmp/runfiles/runfiles_relative_path. Skrypt urządzenia automatycznie obsługuje ustawianie odpowiednich ścieżek dla dynamicznego linkera.

Tryb kompilacji (AOT)

W przypadku akceleratorów, które obsługują kompilację z wyprzedzeniem (AOT), ATS można uruchomić w specjalnym „trybie kompilacji”.

  • Przeznaczenie: ten tryb jest przeznaczony do uruchamiania na stacji roboczej (maszynie hosta), a nie na urządzeniu docelowym. Kompiluje modele dla określonego sprzętu docelowego bez ich wykonywania.
  • Dane wyjściowe: wszystkie skompilowane modele są zapisywane w wyznaczonym katalogu na stacji roboczej.
  • Aktywacja: makra kompilacji ATS będą emitować konkretny cel dla aot, w którym biblioteki są tworzone dla platformy hosta. Ten proces można włączyć w przypadku dowolnego pliku binarnego za pomocą flagi --compile_mode, ale jest on automatycznie powiązany z argumentami kompilacji AOT.

Dostępność funkcji w przyszłości

Planujemy rozszerzyć ten pakiet o testy przeznaczone do pojedynczych operacji, a także pełnych modeli.