Réduire la taille binaire de TensorFlow Lite

Aperçu

Lors du déploiement de modèles pour des applications d'apprentissage automatique sur appareil (ODML), il est important d'être conscient de la mémoire limitée disponible sur les appareils mobiles. Les tailles binaires du modèle sont étroitement corrélées au nombre d'opérations utilisées dans le modèle. TensorFlow Lite vous permet de réduire les tailles binaires des modèles en utilisant des versions sélectives. Les builds sélectifs ignorent les opérations inutilisées dans votre ensemble de modèles et produisent une bibliothèque compacte avec uniquement le runtime et les noyaux opérationnels nécessaires pour que le modèle s'exécute sur votre appareil mobile.

La construction sélective s'applique aux trois bibliothèques d'opérations suivantes.

  1. Bibliothèque d'opérations intégrée TensorFlow Lite
  2. Opérations personnalisées TensorFlow Lite
  3. Sélectionnez la bibliothèque d'opérations TensorFlow

Le tableau ci-dessous illustre l'impact des compilations sélectives pour certains cas d'utilisation courants :

Nom du modèle Domaine Architecture cible Taille(s) de fichier AAR
Mobilenet_1.0_224(flottant) Classement des images armeabi-v7a tensorflow-lite.aar (296 635 octets)
arm64-v8a tensorflow-lite.aar (382 892 octets)
PIMENTER Extraction de la hauteur du son armeabi-v7a tensorflow-lite.aar (375 813 octets)
tensorflow-lite-select-tf-ops.aar (1 676 380 octets)
arm64-v8a tensorflow-lite.aar (421 826 octets)
tensorflow-lite-select-tf-ops.aar (2 298 630 octets)
i3d-kinetics-400 Classement vidéo armeabi-v7a tensorflow-lite.aar (240 085 octets)
tensorflow-lite-select-tf-ops.aar (1 708 597 octets)
arm64-v8a tensorflow-lite.aar (273 713 octets)
tensorflow-lite-select-tf-ops.aar (2 339 697 octets)

Créez sélectivement TensorFlow Lite avec Bazel

Cette section suppose que vous avez téléchargé les codes sources de TensorFlow et configuré l'environnement de développement local sur Bazel.

Construire des fichiers AAR pour le projet Android

Vous pouvez créer les AAR TensorFlow Lite personnalisés en fournissant les chemins d'accès aux fichiers de modèle comme suit.

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

La commande ci-dessus générera le fichier AAR bazel-bin/tmp/tensorflow-lite.aar pour les opérations intégrées et personnalisées de TensorFlow Lite ; et éventuellement, génère le fichier aar bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar si vos modèles contiennent des opérations Select TensorFlow. Notez que cela construit un AAR "gras" avec plusieurs architectures différentes ; si vous n'en avez pas tous besoin, utilisez le sous-ensemble approprié à votre environnement de déploiement.

Construire avec des opérations personnalisées

Si vous avez développé des modèles Tensorflow Lite avec des opérations personnalisées, vous pouvez les créer en ajoutant les options suivantes à la commande de génération :

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

L'indicateur tflite_custom_ops_srcs contient les fichiers source de vos opérations personnalisées et l'indicateur tflite_custom_ops_deps contient des dépendances pour créer ces fichiers source. Notez que ces dépendances doivent exister dans le référentiel TensorFlow.

Utilisations avancées : règles Bazel personnalisées

Si votre projet utilise Bazel et que vous souhaitez définir des dépendances TFLite personnalisées pour un ensemble de modèles donné, vous pouvez définir les règles suivantes dans votre référentiel de projet :

Pour les modèles avec les opérations intégrées uniquement :

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

Pour les modèles avec les ops Select 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",
    ],
)

Utilisations avancées : créer des bibliothèques partagées C/C++ personnalisées

Si vous souhaitez créer vos propres objets partagés TFLite C/C++ personnalisés vers les modèles donnés, vous pouvez suivre les étapes ci-dessous :

Créez un fichier BUILD temporaire en exécutant la commande suivante dans le répertoire racine du code source TensorFlow :

mkdir -p tmp && touch tmp/BUILD

Construire des objets partagés C personnalisés

Si vous souhaitez créer un objet partagé TFLite C personnalisé, ajoutez ce qui suit au fichier 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",
    ],
)

La cible nouvellement ajoutée peut être construite comme suit :

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

et pour Android (remplacez android_arm par android_arm64 pour 64 bits) :

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

Création d'objets partagés C++ personnalisés

Si vous souhaitez créer un objet partagé TFLite C++ personnalisé, ajoutez ce qui suit au fichier 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",
    ],
)

La cible nouvellement ajoutée peut être construite comme suit :

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

et pour Android (remplacez android_arm par android_arm64 pour 64 bits) :

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

Pour les modèles avec les opérations Select TF, vous devez également créer la bibliothèque partagée suivante :

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

La cible nouvellement ajoutée peut être construite comme suit :

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

et pour Android (remplacez android_arm par android_arm64 pour 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

Créer sélectivement TensorFlow Lite avec Docker

Cette section suppose que vous avez installé Docker sur votre ordinateur local et téléchargé le fichier Docker de TensorFlow Lite ici .

Après avoir téléchargé le Dockerfile ci-dessus, vous pouvez créer l'image Docker en exécutant :

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

Construire des fichiers AAR pour le projet Android

Téléchargez le script de compilation avec Docker en exécutant :

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

Ensuite, vous pouvez créer l'AAR TensorFlow Lite personnalisé en fournissant les chemins d'accès aux fichiers de modèle comme suit.

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

L'indicateur de point de checkpoint est un commit, une branche ou une balise du référentiel TensorFlow que vous souhaitez extraire avant de créer les bibliothèques ; par défaut, il s'agit de la branche de la dernière version. La commande ci-dessus générera le fichier AAR tensorflow-lite.aar pour les opérations intégrées et personnalisées TensorFlow Lite et éventuellement le fichier AAR tensorflow-lite-select-tf-ops.aar pour les opérations Select TensorFlow dans votre répertoire actuel.

Le --cache_dir spécifie le répertoire de cache. S'il n'est pas fourni, le script créera un répertoire nommé bazel-build-cache sous le répertoire de travail actuel pour la mise en cache.

Ajouter des fichiers AAR au projet

Ajoutez des fichiers AAR en important directement l'AAR dans votre projet ou en publiant l'AAR personnalisé dans votre référentiel Maven local . Notez que vous devez également ajouter les fichiers AAR pour tensorflow-lite-select-tf-ops.aar si vous le générez.

Construction sélective pour iOS

Veuillez consulter la section Générer localement pour configurer l'environnement de génération et configurer l'espace de travail TensorFlow, puis suivez le guide pour utiliser le script de génération sélective pour iOS.