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_v2hf_mobilevit_smallqai_hub_midasqai_hub_real_esrgan_x4plustorchvision_mobilenet_v2torchvision_resnet18torchvision_squeezenet1_1u2net_litewhisper_tiny_decoderwhisper_tiny_encoderyamnetyolo11n
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:
- O teste JIT no dispositivo padrão (para execução e validação).
- 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
Defina uma função
BackendSpec:crie uma função que retorne um dicionário contendo a especificação do novo acelerador.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.
Especificar nomes de biblioteca (
plugin,dispatch): forneça os nomes de arquivo do plug-in e das bibliotecas de envio.Registre a especificação:mescle a nova função de especificação à função principal
_Specspara 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:
- Crie o binário
example_binem C++. - Envie o binário,
libLiteRtDispatch_Example.so,libLiteRtCompilerPlugin_Example.soe o arquivo.tflitepara o dispositivo. - 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.