Reduce el tamaño de los objetos binarios de TensorFlow Lite

Descripción general

Cuando implementas modelos para aplicaciones de aprendizaje automático en el dispositivo (ODML), es importante tener en cuenta la memoria limitada disponible en los dispositivos móviles. Los tamaños binarios del modelo están estrechamente relacionados con la cantidad de operaciones que se usan en el modelo. TensorFlow Lite te permite reducir el tamaño de los objetos binarios de los modelos mediante el uso de compilaciones selectivas. Las compilaciones selectivas omiten las operaciones sin usar en tu conjunto de modelos y producen una biblioteca compacta solo con el entorno de ejecución y los kernels de operaciones necesarios para que el modelo se ejecute en tu dispositivo móvil.

La compilación selectiva se aplica en las siguientes tres bibliotecas de operaciones.

  1. Biblioteca de operaciones integrada de TensorFlow Lite
  2. Operaciones personalizadas de TensorFlow Lite
  3. Selecciona la biblioteca de operaciones de TensorFlow

En la siguiente tabla, se muestra el impacto de las compilaciones selectivas para algunos casos de uso comunes:

Nombre del modelo Dominio Arquitectura de objetivos Tamaños de archivos AAR
Mobilenet_1.0_224(float) Clasificación de imágenes armeabi-v7a tensorflow-lite.aar (296,635 bytes)
arm64-v8a tensorflow-lite.aar (382,892 bytes)
SPICE Extracción de tono de sonido 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; Clasificación de videos 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)

Compila TensorFlow Lite de forma selectiva con Bazel

En esta sección, se supone que descargaste códigos fuente de TensorFlow y configuraste el entorno de desarrollo local en Bazel.

Cómo compilar archivos AAR para un proyecto de Android

Para compilar los AAR personalizados de TensorFlow Lite, proporciona las rutas de acceso de tus archivos del modelo de la siguiente manera.

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

El comando anterior generará el archivo AAR bazel-bin/tmp/tensorflow-lite.aar para las operaciones integradas y personalizadas de TensorFlow Lite. De forma opcional, genera el archivo aar bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar si tus modelos contienen operaciones Select de TensorFlow. Ten en cuenta que esto crea un AAR "grueso" con varias arquitecturas diferentes. Si no las necesitas todas, usa el subconjunto adecuado para tu entorno de implementación.

Compila con operaciones personalizadas

Si desarrollaste modelos de Tensorflow Lite con operaciones personalizadas, puedes compilarlos agregando las siguientes marcas al comando de compilación:

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

La marca tflite_custom_ops_srcs contiene archivos fuente de tus operaciones personalizadas y la marca tflite_custom_ops_deps contiene dependencias para compilar esos archivos de origen. Ten en cuenta que estas dependencias deben existir en el repositorio de TensorFlow.

Usos avanzados: Reglas de Bazel personalizadas

Si tu proyecto usa Bazel y deseas definir dependencias personalizadas de TFLite para un conjunto determinado de modelos, puedes definir las siguientes reglas en el repositorio de tu proyecto:

Solo para los modelos con operaciones 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 los modelos con las operaciones de selección de TF:

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 avanzados: Compila bibliotecas compartidas de C/C++ personalizadas

Si deseas compilar tus propios objetos compartidos C/C++ de TFLite personalizados con los modelos dados, puedes seguir los pasos que se indican a continuación:

Para crear un archivo de compilación temporal, ejecuta el siguiente comando en el directorio raíz del código fuente de TensorFlow:

mkdir -p tmp && touch tmp/BUILD

Cómo compilar objetos personalizados compartidos en C

Si deseas compilar un objeto compartido personalizado de TFLite C, agrega lo siguiente al archivo 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 TensorFlow Lite 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",
    ],
)

El destino agregado recientemente se puede compilar de la siguiente manera:

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

y para Android (reemplaza android_arm por android_arm64 para 64 bits):

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

Cómo compilar objetos compartidos de C++ personalizados

Si deseas compilar un objeto compartido personalizado de TFLite en C++, agrega lo siguiente al archivo 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",
    ],
)

El destino agregado recientemente se puede compilar de la siguiente manera:

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

y para Android (reemplaza android_arm por android_arm64 para 64 bits):

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

Para los modelos con las operaciones Select TF, también debes compilar la siguiente biblioteca compartida:

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

El destino agregado recientemente se puede compilar de la siguiente manera:

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

y para Android (reemplaza 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

Compila TensorFlow Lite de forma selectiva con Docker

En esta sección, se supone que instalaste Docker en tu máquina local y que descargaste el Dockerfile de TensorFlow Lite aquí.

Después de descargar el Dockerfile anterior, puedes ejecutar el siguiente comando para compilar la imagen de Docker:

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

Cómo compilar archivos AAR para un proyecto de Android

Descarga la secuencia de comandos para compilar con Docker ejecutando lo siguiente:

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

Luego, puedes compilar el AAR personalizado de TensorFlow Lite. Para ello, proporciona las rutas de acceso de tus archivos del modelo de la siguiente manera.

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>]

La marca checkpoint es una confirmación, una rama o una etiqueta del repositorio de TensorFlow que deseas confirmar antes de compilar las bibliotecas. De forma predeterminada, es la rama de la versión más reciente. El comando anterior generará el archivo AAR tensorflow-lite.aar para las operaciones integradas y personalizadas de TensorFlow Lite y, de manera opcional, el archivo AAR tensorflow-lite-select-tf-ops.aar para determinadas operaciones de TensorFlow en tu directorio actual.

--cache_dir especifica el directorio de caché. Si no se proporciona, la secuencia de comandos creará un directorio llamado bazel-build-cache en el directorio de trabajo actual para el almacenamiento en caché.

Agrega archivos AAR al proyecto

Para agregar archivos AAR, importa el AAR directamente a tu proyecto o publica el AAR personalizado en tu repositorio local de Maven. Ten en cuenta que también debes agregar los archivos AAR para tensorflow-lite-select-tf-ops.aar si lo generas.

Compilación selectiva para iOS

Consulta la sección Compila de forma local para configurar el entorno de compilación y el lugar de trabajo de TensorFlow. Luego, sigue la guía si quieres usar la secuencia de comandos de compilación selectiva para iOS.