Reduzir o tamanho do binário LiteRT

Visão geral

Ao implantar modelos para aplicativos de machine learning (ODML) no dispositivo, é é importante ter uma noção da memória limitada disponível nos dispositivos móveis. Os tamanhos dos binários do modelo estão estreitamente correlacionados ao número de operações usadas no um modelo de machine learning. A LiteRT permite reduzir os tamanhos binários do modelo usando versões seletivas. Os builds seletivas ignoram as operações não utilizadas no conjunto de modelos e produzir uma biblioteca compacta apenas com o ambiente de execução e os kernels de operação necessários para que o modelo seja executado no dispositivo móvel.

A compilação seletiva se aplica às três bibliotecas de operações a seguir.

  1. Biblioteca de operações integrada do LiteRT
  2. Operações personalizadas da LiteRT (em inglês)
  3. Selecionar a biblioteca de operações do TensorFlow

A tabela abaixo demonstra o impacto dos builds seletivos para alguns usos comuns casos:

Nome do modelo Domínio Arquitetura de destino Tamanhos dos arquivos AAR
Mobilenet_1.0_224(float) Classificação de imagens armeabi-v7a tensorflow-lite.aar (296.635 bytes)
arm64-v8a tensorflow-lite.aar (382.892 bytes)
ESPECIFICAÇÃO Extração do tom de som armeabi-v7a tensorflow-lite.aar (375.813 bytes)
tensorflow-lite-select-tf-ops.aar (1.676.380 bytes)
arm64-v8a tensorflow-lite.aar (421.826 bytes)
tensorflow-lite-select-tf-ops.aar (2.298.630 bytes)
i3d-kinetics-400 (link em inglês) Classificação do vídeo armeabi-v7a tensorflow-lite.aar (240.085 bytes)
tensorflow-lite-select-tf-ops.aar (1.708.597 bytes)
arm64-v8a tensorflow-lite.aar (273.713 bytes)
tensorflow-lite-select-tf-ops.aar (2.339.697 bytes)

Crie LiteRT seletivamente com o Bazel

Esta seção pressupõe que você fez o download dos códigos-fonte do TensorFlow e os definiu no desenvolvimento local de produção para o Bazel

Criar arquivos AAR para projetos Android

É possível criar AARs personalizados do LiteRT fornecendo os caminhos de arquivo do modelo da seguinte forma.

sh tensorflow/lite/tools/build_aar.sh \
  --input_models=/a/b/model_one.tflite,/c/d/model_two.tflite \
  --target_archs=x86,x86_64,arm64-v8a,armeabi-v7a

O comando acima vai gerar o arquivo AAR bazel-bin/tmp/tensorflow-lite.aar para operações personalizadas e integradas do LiteRT; e, opcionalmente, gera o aar arquivo bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar se os modelos contiverem Selecione Operações do TensorFlow. Isso gera uma "gordura" AARs com diversas arquiteturas Se você não precisar de todos eles, use o subconjunto apropriado para o ambiente de implantação.

Criar com operações personalizadas

Se você desenvolveu modelos LiteRT com operações personalizadas, é possível criá-los adicionando as seguintes sinalizações ao comando "build":

sh tensorflow/lite/tools/build_aar.sh \
  --input_models=/a/b/model_one.tflite,/c/d/model_two.tflite \
  --target_archs=x86,x86_64,arm64-v8a,armeabi-v7a \
  --tflite_custom_ops_srcs=/e/f/file1.cc,/g/h/file2.h \
  --tflite_custom_ops_deps=dep1,dep2

A flag tflite_custom_ops_srcs contém arquivos de origem das operações personalizadas e a flag tflite_custom_ops_deps contém dependências para criar essas origens. . Observe que essas dependências precisam existir no repositório do TensorFlow.

Usos avançados: regras personalizadas do Bazel

Caso seu projeto use o Bazel e você queira definir um TFLite personalizado dependências para um determinado conjunto de modelos, é possível definir as seguintes regras em seu repositório do projeto:

Apenas para os modelos com as operações integradas:

load(
    "@org_tensorflow//tensorflow/lite:build_def.bzl",
    "tflite_custom_android_library",
    "tflite_custom_c_library",
    "tflite_custom_cc_library",
)

# A selectively built TFLite Android library.
tflite_custom_android_library(
    name = "selectively_built_android_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

# A selectively built TFLite C library.
tflite_custom_c_library(
    name = "selectively_built_c_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

# A selectively built TFLite C++ library.
tflite_custom_cc_library(
    name = "selectively_built_cc_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

Para os modelos com Select TF ops:

load(
    "@org_tensorflow//tensorflow/lite/delegates/flex:build_def.bzl",
    "tflite_flex_android_library",
    "tflite_flex_cc_library",
)

# A Select TF ops enabled selectively built TFLite Android library.
tflite_flex_android_library(
    name = "selective_built_tflite_flex_android_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

# A Select TF ops enabled selectively built TFLite C++ library.
tflite_flex_cc_library(
    name = "selective_built_tflite_flex_cc_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

Usos avançados: criar bibliotecas compartilhadas C/C++ personalizadas

Se você quiser criar seus próprios objetos compartilhados TFLite C/C++ personalizados para os modelos fornecidos, siga as etapas abaixo:

Crie um arquivo BUILD temporário executando o seguinte comando na raiz. do código-fonte do TensorFlow:

mkdir -p tmp && touch tmp/BUILD

Como criar objetos compartilhados C personalizados

Se você quiser criar um objeto compartilhado TFLite C personalizado, adicione o seguinte a Arquivo tmp/BUILD:

load(
    "//tensorflow/lite:build_def.bzl",
    "tflite_custom_c_library",
    "tflite_cc_shared_object",
)

tflite_custom_c_library(
    name = "selectively_built_c_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

# Generates a platform-specific shared library containing the LiteRT C
# API implementation as define in `c_api.h`. The exact output library name
# is platform dependent:
#   - Linux/Android: `libtensorflowlite_c.so`
#   - Mac: `libtensorflowlite_c.dylib`
#   - Windows: `tensorflowlite_c.dll`
tflite_cc_shared_object(
    name = "tensorflowlite_c",
    linkopts = select({
        "//tensorflow:ios": [
            "-Wl,-exported_symbols_list,$(location //tensorflow/lite/c:exported_symbols.lds)",
        ],
        "//tensorflow:macos": [
            "-Wl,-exported_symbols_list,$(location //tensorflow/lite/c:exported_symbols.lds)",
        ],
        "//tensorflow:windows": [],
        "//conditions:default": [
            "-z defs",
            "-Wl,--version-script,$(location //tensorflow/lite/c:version_script.lds)",
        ],
    }),
    per_os_targets = True,
    deps = [
        ":selectively_built_c_lib",
        "//tensorflow/lite/c:exported_symbols.lds",
        "//tensorflow/lite/c:version_script.lds",
    ],
)

O destino recém-adicionado pode ser criado da seguinte maneira:

bazel build -c opt --cxxopt=--std=c++17 \
  //tmp:tensorflowlite_c

e para Android (substitua android_arm por android_arm64 para 64 bits):

bazel build -c opt --cxxopt=--std=c++17 --config=android_arm \
  //tmp:tensorflowlite_c

Como criar objetos compartilhados C++ personalizados

Se você quiser criar um objeto compartilhado TFLite C++ personalizado, adicione o seguinte para o arquivo tmp/BUILD:

load(
    "//tensorflow/lite:build_def.bzl",
    "tflite_custom_cc_library",
    "tflite_cc_shared_object",
)

tflite_custom_cc_library(
    name = "selectively_built_cc_lib",
    models = [
        ":model_one.tflite",
        ":model_two.tflite",
    ],
)

# Shared lib target for convenience, pulls in the core runtime and builtin ops.
# Note: This target is not yet finalized, and the exact set of exported (C/C++)
# APIs is subject to change. The output library name is platform dependent:
#   - Linux/Android: `libtensorflowlite.so`
#   - Mac: `libtensorflowlite.dylib`
#   - Windows: `tensorflowlite.dll`
tflite_cc_shared_object(
    name = "tensorflowlite",
    # Until we have more granular symbol export for the C++ API on Windows,
    # export all symbols.
    features = ["windows_export_all_symbols"],
    linkopts = select({
        "//tensorflow:macos": [
            "-Wl,-exported_symbols_list,$(location //tensorflow/lite:tflite_exported_symbols.lds)",
        ],
        "//tensorflow:windows": [],
        "//conditions:default": [
            "-Wl,-z,defs",
            "-Wl,--version-script,$(location //tensorflow/lite:tflite_version_script.lds)",
        ],
    }),
    per_os_targets = True,
    deps = [
        ":selectively_built_cc_lib",
        "//tensorflow/lite:tflite_exported_symbols.lds",
        "//tensorflow/lite:tflite_version_script.lds",
    ],
)

O destino recém-adicionado pode ser criado da seguinte maneira:

bazel build -c opt  --cxxopt=--std=c++17 \
  //tmp:tensorflowlite

e para Android (substitua android_arm por android_arm64 para 64 bits):

bazel build -c opt --cxxopt=--std=c++17 --config=android_arm \
  //tmp:tensorflowlite

Para os modelos com as operações "Select TF", você também precisa criar o seguinte biblioteca compartilhada também:

load(
    "@org_tensorflow//tensorflow/lite/delegates/flex:build_def.bzl",
    "tflite_flex_shared_library"
)

# Shared lib target for convenience, pulls in the standard set of TensorFlow
# ops and kernels. The output library name is platform dependent:
#   - Linux/Android: `libtensorflowlite_flex.so`
#   - Mac: `libtensorflowlite_flex.dylib`
#   - Windows: `libtensorflowlite_flex.dll`
tflite_flex_shared_library(
  name = "tensorflowlite_flex",
  models = [
      ":model_one.tflite",
      ":model_two.tflite",
  ],
)

O destino recém-adicionado pode ser criado da seguinte maneira:

bazel build -c opt --cxxopt='--std=c++17' \
      --config=monolithic \
      --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
      //tmp:tensorflowlite_flex

e para Android (substitua android_arm por android_arm64 para 64 bits):

bazel build -c opt --cxxopt='--std=c++17' \
      --config=android_arm \
      --config=monolithic \
      --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
      //tmp:tensorflowlite_flex

Criar LiteRT seletivamente com o Docker

Esta seção pressupõe que você já instalou Docker na máquina local e fez o download do Dockerfile LiteRT aqui.

Depois de fazer o download do Dockerfile acima, você pode criar a imagem Docker em execução:

docker build . -t tflite-builder -f tflite-android.Dockerfile

Criar arquivos AAR para projetos Android

Faça o download do script para criar com o Docker executando:

curl -o build_aar_with_docker.sh \
  https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/lite/tools/build_aar_with_docker.sh &&
chmod +x build_aar_with_docker.sh

Em seguida, é possível criar o AAR LiteRT personalizado fornecendo seu arquivo de modelo da maneira a seguir.

sh build_aar_with_docker.sh \
  --input_models=/a/b/model_one.tflite,/c/d/model_two.tflite \
  --target_archs=x86,x86_64,arm64-v8a,armeabi-v7a \
  --checkpoint=master \
  [--cache_dir=<path to cache directory>]

A flag checkpoint é uma confirmação, uma ramificação ou uma tag do repositório do TensorFlow que você deseja fazer check-out antes de criar as bibliotecas, por padrão, é a versão mais recente de lançamento. O comando acima gera o arquivo AAR tensorflow-lite.aar para operações integradas e personalizadas do LiteRT e, opcionalmente, o arquivo AAR tensorflow-lite-select-tf-ops.aar para Selecionar operações do TensorFlow em diretório atual.

--cache_dir especifica o diretório do cache. Se não for fornecido, o script crie um diretório chamado bazel-build-cache no diretório de trabalho atual para armazenamento em cache.

Adicionar arquivos AAR ao projeto

Adicione arquivos AAR importando-os diretamente para sua conta projeto ou publicando o AAR personalizado para o Maven local repositório. Observação que você tem que adicionar os arquivos AAR para tensorflow-lite-select-tf-ops.aar como se você gerá-la.

Build seletiva para iOS

Consulte a seção Como construir localmente para configurar o ambiente de build, configurar o espaço de trabalho do TensorFlow e seguir as guia para usar a seleção script de build para iOS.