Pacote de testes do acelerador LiteRT (ATS)

O LiteRT Accelerator Test Suite (ATS) é uma ferramenta abrangente usada para validar a correção funcional e medir o desempenho de implementações de aceleradores personalizados integrados ao framework LiteRT.

Visão geral e funcionalidade principal

A principal função do ATS é executar modelos de machine learning predefinidos em um acelerador de destino e comparar os resultados com o backend padrão da CPU do LiteRT.

  • Validação:o pacote executa a validação numérica comparando os tensores de saída (ativações) produzidos pelo acelerador com aqueles produzidos pelo back-end de CPU conhecido. Isso garante que a implementação do acelerador mantenha a precisão e a correção necessárias.
  • Métricas de performance:captura e registra automaticamente detalhes críticos de performance, incluindo latência e outras métricas relevantes, que são disponibilizadas ao usuário.
  • Execução:os testes geralmente são executados em um dispositivo de destino (por exemplo, um smartphone Android) e gerenciados por um wrapper de script de shell que processa transferências de arquivos e configuração usando a ferramenta adb (Android Debug Bridge).

Dados de teste (modelos)

O conjunto ATS usa uma coleção de modelos .tflite amplamente usados como dados de teste. Os dados de entrada são gerados aleatoriamente com base no tipo de dados e podem ser propagados conforme necessário.

Modelos incluídos

Os modelos a seguir são incluídos e baixados automaticamente para teste (sujeito a alterações):

  • 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

Recuperação manual de modelos

Embora os modelos sejam baixados automaticamente durante um bazel run, é possível recuperar manualmente todo o conjunto de modelos usando wget:

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

Como definir um pacote do ATS com o Bazel

Use a macro litert_define_ats do Bazel para configurar e definir um destino de teste do ATS específico para o acelerador.

A macro cria automaticamente duas metas executáveis:

  1. O teste JIT no dispositivo padrão (para execução e validação).
  2. Um teste de modo "somente compilação" de AOT dedicado (para compilação de host).

Exemplo de uso do litert_define_ats

O exemplo define um conjunto do ATS chamado example_ats para um acelerador com o nome de back-end 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 = "",
)

Execução

Para executar o teste padrão direcionado ao Android (que processa todas as operações 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

Para executar o teste de compilação 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

Execução do Linux (host)

Para execução no Linux, em que o ATS é executado na mesma máquina que faz o build, os usuários precisam usar o binário :ats diretamente:

bazel run -c opt :ats

Execução de IoT

Para a execução de IoT, os usuários precisam criar o binário no host e enviá-lo manualmente para o dispositivo.

Sinalizações de linha de comando

O executável ats aceita várias flags para controle granular sobre testes e relatórios.

Sinalização Tipo Descrição
--backend std::string Obrigatório. Qual back-end do LiteRT usar como acelerador em teste (o "real"). As opções são cpu, npu ou gpu.
--compile_mode bool Se for "true", vai executar a etapa de compilação AOT na estação de trabalho em vez da execução no dispositivo. OBSERVAÇÃO: essa opção é vinculada automaticamente ao destino de build "aot" e não precisa ser definida explicitamente.
--models_out std::string O caminho do diretório em que os modelos serializados (compilados) de efeito colateral são salvos. Relevante apenas para compilação AOT ou JIT.
--dispatch_dir std::string Caminho para o diretório que contém a biblioteca de envio do acelerador (relevante para a NPU).
--plugin_dir std::string Caminho para o diretório que contém a biblioteca de plug-in do compilador do acelerador (relevante para NPU).
--soc_manufacturer std::string O fabricante do SoC para segmentar a compilação AOT (relevante para a compilação de NPU).
--soc_model std::string O modelo de SOC a ser segmentado para compilação AOT (relevante para compilação de NPU).
--iters_per_test size_t Número de iterações a serem executadas por teste, cada uma com dados de tensor aleatórios diferentes.
--max_ms_per_test int64_t Tempo máximo em milissegundos para executar cada teste antes de um tempo limite.
--fail_on_timeout bool Indica se o teste deve falhar se a execução atingir o tempo limite.
--csv std::string Caminho do arquivo para salvar o relatório detalhado no formato CSV.
--dump_report bool Se os detalhes completos do relatório devem ser despejados diretamente na saída do console do usuário.
--data_seed std::optional<int> Uma única semente para geração de dados globais.
--do_register std::vector<std::string> Expressões regulares para incluir explicitamente testes específicos (por exemplo, *mobilenet*).
--dont_register std::vector<std::string> Expressões regulares para excluir testes específicos.
--extra_models std::vector<std::string> Lista opcional de diretórios ou arquivos de modelo a serem adicionados ao conjunto de testes.
--limit int32_t Limite o número total de testes registrados e executados.
--quiet bool Minimizar a saída de geração de registros durante a execução do teste.

Como usar os utilitários de build litert_device_script para ATS

Os usuários de destino do ATS executam automaticamente um ponto de entrada de shell que processa toda a configuração do ambiente e o envio de bibliotecas necessárias quando o dispositivo de destino é diferente do host em que o build foi concluído (por exemplo, adb push).

Essa funcionalidade é fornecida de forma genérica pelas utilidades litert_device_script que os builds do ATS usam em segundo plano. Há um processo de registro que os aceleradores precisam fazer para acessar essa funcionalidade de build. Além de oferecer suporte a ats, esses utilitários podem ser usados de forma independente para simular cc_binary e cc_test, que devem ser executados em um dispositivo diferente do host de build que exige dependências push.

Registro de back-end

Para ativar um novo acelerador para uso com litert_device_script (e, portanto, ATS), as bibliotecas necessárias precisam ser registradas no arquivo litert_device_common.bzl do Bazel. O registro é baseado em um nome de"back-end" exclusivo, que é mapeado para um conjunto de bibliotecas compiláveis ou pré-compiladas necessárias para que o LiteRT opere com esse acelerador.

Etapas de inscrição

  1. Defina uma função BackendSpec:crie uma função que retorne um dicionário contendo a especificação do novo acelerador.

  2. Especificar bibliotecas (libs): é uma lista de tuplas que detalham o caminho de destino do Bazel para a biblioteca compartilhada e a variável de ambiente (LD_LIBRARY_PATH) necessária para que o vinculador de dispositivos a encontre.

    • Biblioteca de envio:necessária para a execução no tempo de execução.
    • Biblioteca de plug-in do compilador:necessária para o modo de compilação AOT.
  3. Especificar nomes de biblioteca (plugin, dispatch): forneça os nomes de arquivo do plug-in e das bibliotecas de envio.

  4. Registre a especificação:mescle a nova função de especificação à função principal _Specs para disponibilizá-la pelo ID exclusivo do back-end.

Exemplo de registro (_ExampleSpec)

O código a seguir de litert_device_common.bzl ilustra como o acelerador "example" é registrado:

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]

Como usar o registro com litert_device_exec

Depois de registrado, use o litert_device_exec e macros relacionadas com o novo backend_id. Essa macro agrupa automaticamente as bibliotecas necessárias e os arquivos de dados especificados com o binário de destino.

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

Executar esse destino (bazel run ... :example_bin_device) vai:

  1. Crie o binário example_bin em C++.
  2. Envie o binário, libLiteRtDispatch_Example.so, libLiteRtCompilerPlugin_Example.so e o arquivo .tflite para o dispositivo.
  3. Execute o binário usando adb shell.

Observação sobre caminhos de dispositivos:o local canônico dos arquivos no dispositivo espelha a árvore de runfiles do Bazel, especificamente /data/local/tmp/runfiles/runfiles_relative_path. O script do dispositivo processa automaticamente a definição dos caminhos adequados para o vinculador dinâmico.

Modo de compilação (AOT)

Para aceleradores que oferecem suporte a uma etapa de compilação antecipada (AOT), o ATS pode ser executado em um "modo de compilação" dedicado.

  • Finalidade:esse modo foi projetado para ser executado em uma estação de trabalho (máquina host), não no dispositivo de destino. Ele compila os modelos para o hardware de destino especificado sem executá-los.
  • Saída:todos os modelos compilados são enviados para um diretório designado na estação de trabalho.
  • Ativação:as macros de build do ATS vão emitir um destino específico para aot em que as bibliotecas são criadas para a plataforma host. Esse fluxo pode ser ativado em qualquer binário com a flag --compile_mode, mas é vinculado automaticamente aos argumentos do build AOT.

Próxima ampliação

O pacote será expandido para incluir testes dedicados para operações únicas (ops), além de modelos completos.