Suite di test dell'acceleratore LiteRT (ATS)

La LiteRT Accelerator Test Suite (ATS) è uno strumento completo utilizzato per convalidare la correttezza funzionale e misurare le prestazioni delle implementazioni personalizzate dell'acceleratore integrate con il framework LiteRT.

Panoramica e funzionalità di base

La funzione principale di ATS è eseguire modelli di machine learning predefiniti su un acceleratore di destinazione e confrontare i risultati con il backend della CPU standard LiteRT.

  • Convalida:la suite esegue la convalida numerica confrontando i tensori di output (attivazioni) prodotti dall'acceleratore con quelli prodotti dal backend della CPU noto. In questo modo, l'implementazione dell'acceleratore mantiene la precisione e la correttezza richieste.
  • Metriche sul rendimento:acquisisce e registra automaticamente i dettagli critici sul rendimento, inclusa la latenza e altre metriche pertinenti, che vengono rese disponibili all'utente.
  • Esecuzione:i test vengono in genere eseguiti su un dispositivo di destinazione (ad es. uno smartphone Android) e sono gestiti da un wrapper script shell che gestisce i trasferimenti di file e la configurazione utilizzando lo strumento adb (Android Debug Bridge).

Dati di test (modelli)

La suite ATS utilizza una raccolta di .tflite modelli ampiamente utilizzati come dati di test. I dati di input vengono generati in modo casuale in base al tipo di dati e possono essere inizializzati in base alle esigenze.

Modelli inclusi

I seguenti modelli vengono inclusi e scaricati automaticamente per i test (soggetti a modifiche):

  • 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

Recupero manuale del modello

Anche se i modelli vengono scaricati automaticamente durante un bazel run, puoi recuperare manualmente l'intero set di modelli utilizzando wget:

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

Definizione di una suite ATS con Bazel

Utilizza la macro litert_define_ats Bazel per configurare e definire una destinazione di test ATS specifica per l'acceleratore.

La macro crea automaticamente due target eseguibili:

  1. Il test JIT sul dispositivo standard (per l'esecuzione e la convalida).
  2. Un test della modalità "solo compilazione" AOT dedicato (per la compilazione host).

Esempio di utilizzo di litert_define_ats

L'esempio definisce una suite ATS denominata example_ats per un acceleratore con il nome di backend 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 = "",
)

Esecuzione

Per eseguire il test standard mirato per Android (che gestisce tutte le operazioni 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

Per eseguire il test di compilazione 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

Esecuzione Linux (host)

Per l'esecuzione di Linux, in cui ATS viene eseguito sulla stessa macchina che esegue la build, gli utenti dovranno utilizzare direttamente il binario :ats:

bazel run -c opt :ats

Esecuzione IoT

Per l'esecuzione dell'IoT, gli utenti dovranno creare il binario sull'host e inviarlo manualmente al proprio dispositivo.

Flag della riga di comando

L'eseguibile ats accetta diversi flag per un controllo granulare su test e report.

Flag Tipo Descrizione
--backend std::string Obbligatorio. Quale backend LiteRT utilizzare come acceleratore in fase di test (il "reale"). Le opzioni sono cpu, npu o gpu.
--compile_mode bool Se è true, esegue il passaggio di compilazione AOT sulla workstation anziché l'esecuzione sul dispositivo. NOTA: questa opzione è associata automaticamente al target di build "aot" e non deve essere impostata in modo esplicito.
--models_out std::string Il percorso della directory in cui vengono salvati i modelli serializzati (compilati) con effetti collaterali. Pertinente solo per la compilazione AOT o JIT.
--dispatch_dir std::string Percorso della directory contenente la libreria di distribuzione dell'acceleratore (pertinente per la NPU).
--plugin_dir std::string Percorso della directory contenente la libreria del plug-in del compilatore dell'acceleratore (pertinente per la NPU).
--soc_manufacturer std::string Il produttore del SoC da scegliere come target per la compilazione AOT (pertinente per la compilazione della NPU).
--soc_model std::string Il modello SOC da scegliere come target per la compilazione AOT (pertinente per la compilazione NPU).
--iters_per_test size_t Numero di iterazioni da eseguire per test, ognuna con dati tensoriali randomizzati diversi.
--max_ms_per_test int64_t Tempo massimo in millisecondi per eseguire ogni test prima di un timeout.
--fail_on_timeout bool Indica se il test deve non riuscire se l'esecuzione scade.
--csv std::string Il percorso del file in cui salvare il report dettagliato in formato CSV.
--dump_report bool Indica se scaricare tutti i dettagli del report direttamente nell'output della console dell'utente.
--data_seed std::optional<int> Un unico seme per la generazione di dati globali.
--do_register std::vector<std::string> Espressioni regolari per includere esplicitamente test specifici (ad es. *mobilenet*).
--dont_register std::vector<std::string> Espressioni regolari per escludere test specifici.
--extra_models std::vector<std::string> Elenco facoltativo di directory o file modello da aggiungere alla suite di test.
--limit int32_t Limitare il numero totale di test registrati ed eseguiti.
--quiet bool Ridurre al minimo l'output di logging durante l'esecuzione del test.

Utilizzare le utilità di compilazione litert_device_script per ATS

Gli utenti di destinazione ATS vengono eseguiti automaticamente e includono un punto di ingresso della shell che gestisce tutta la configurazione dell'ambiente e il push di tutte le librerie richieste quando il dispositivo di destinazione è diverso dall'host su cui è stata completata la build (ad es. adb push).

Questa funzionalità viene fornita in modo generico tramite le utilità litert_device_script che le build ATS utilizzano internamente. Gli acceleratori devono seguire una procedura di registrazione per accedere a questa funzionalità di build. Oltre a supportare ats, queste utilità possono essere utilizzate in modo autonomo per simulare cc_binary e cc_test destinati all'esecuzione su un dispositivo diverso dall'host di build che richiede dipendenze push.

Registrazione del backend

Per abilitare un nuovo acceleratore per l'utilizzo con litert_device_script (e quindi ATS), le relative librerie richieste devono essere registrate nel file litert_device_common.bzl Bazel. La registrazione si basa su un nome "backend" univoco che viene mappato a un insieme di librerie compilabili o precompilate necessarie per il funzionamento di LiteRT con l'acceleratore.

Passaggi per la registrazione

  1. Definisci una funzione BackendSpec: crea una funzione che restituisce un dizionario contenente la specifica del nuovo acceleratore.

  2. Specifica librerie (libs): questo è un elenco di tuple che descrivono il percorso di destinazione Bazel per la libreria condivisa e la variabile di ambiente (LD_LIBRARY_PATH) richiesta per consentire al linker del dispositivo di trovarla.

    • Dispatch Library:obbligatoria per l'esecuzione in fase di runtime.
    • Libreria del plug-in del compilatore: obbligatoria per la modalità di compilazione AOT.
  3. Specifica i nomi delle librerie (plugin, dispatch): fornisci i nomi dei file delle librerie di plug-in e di distribuzione.

  4. Registra la specifica:unisci la nuova funzione di specifica alla funzione _Specs principale per renderla disponibile tramite il suo ID backend univoco.

Registrazione di esempio (_ExampleSpec)

Il seguente codice di litert_device_common.bzl mostra come viene registrato l'acceleratore "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]

Sfruttare la registrazione con litert_device_exec

Una volta registrato, utilizza litert_device_exec e le macro correlate con il nuovo backend_id. Questa macro raggruppa automaticamente le librerie richieste e tutti i file di dati specificati con il binario di destinazione.

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",
)

L'esecuzione di questo target (bazel run ... :example_bin_device):

  1. Crea il file binario C++ example_bin.
  2. Trasferisci il binario, libLiteRtDispatch_Example.so, libLiteRtCompilerPlugin_Example.so e il file .tflite sul dispositivo.
  3. Esegui il file binario utilizzando adb shell.

Nota sui percorsi dei dispositivi: la posizione canonica dei file sul dispositivo riflette l'albero dei runfile di Bazel, in particolare /data/local/tmp/runfiles/runfiles_relative_path. Lo script del dispositivo gestisce automaticamente l'impostazione dei percorsi appropriati per il linker dinamico.

Modalità di compilazione (AOT)

Per gli acceleratori che supportano un passaggio di compilazione Ahead-of-Time (AOT), ATS può essere eseguito in una "modalità di compilazione" dedicata.

  • Scopo: questa modalità è progettata per essere eseguita su una workstation (macchina host), non sul dispositivo di destinazione. Compila i modelli per l'hardware di destinazione specificato senza eseguirli.
  • Output:tutti i modelli compilati vengono inviati a una directory designata sulla workstation.
  • Attivazione:le macro di compilazione ATS genereranno un target specifico per aot in cui le librerie vengono create per la piattaforma host. Questo flusso può essere attivato su qualsiasi binario con il flag --compile_mode, ma è associato automaticamente agli argomenti della build AOT.

Espansione futura

È previsto che la suite venga ampliata per includere test dedicati per le singole operazioni (ops), oltre ai modelli completi.