Größe des TensorFlow Lite-Binärprogramms reduzieren

Überblick

Wenn Sie Modelle für On-Device-Anwendungen für maschinelles Lernen (ODML) bereitstellen, sollten Sie sich des begrenzten Arbeitsspeichers auf Mobilgeräten bewusst sein. Die binären Größen des Modells stehen in engem Zusammenhang mit der Anzahl der im Modell verwendeten Vorgänge. Mit TensorFlow Lite können Sie die binären Größen des Modells mithilfe selektiver Builds reduzieren. Selektive Builds überspringen nicht verwendete Vorgänge in Ihrem Modellsatz und erstellen eine kompakte Bibliothek mit nur der Laufzeit und den Op-Kernels, die für die Ausführung des Modells auf Ihrem Mobilgerät erforderlich sind.

Selektive Builds werden auf die folgenden drei Vorgangsbibliotheken angewendet.

  1. Integrierte TensorFlow Lite-Vorgangsbibliothek
  2. Benutzerdefinierte TensorFlow Lite-Vorgänge
  3. TensorFlow-Vorgangsbibliothek auswählen

Die folgende Tabelle zeigt die Auswirkungen selektiver Builds für einige gängige Anwendungsfälle:

Modellname Domain Zielarchitektur AAR-Dateigröße(n)
Mobilenet_1.0_224(float) Bildklassifizierung Armeabi-V7a tensorflow-lite.aar (296.635 Byte)
arm64-v8a tensorflow-lite.aar (382.892 Byte)
GEWÜRZ Extraktion von Tonhöhen Armeabi-V7a tensorflow-lite.aar (375.813 Byte)
tensorflow-lite-select-tf-ops.aar (1.676.380 Byte)
arm64-v8a tensorflow-lite.aar (421.826 Byte)
tensorflow-lite-select-tf-ops.aar (2.298.630 Byte)
i3d-kinetics-400 Videoklassifizierung Armeabi-V7a tensorflow-lite.aar (240.085 Byte)
tensorflow-lite-select-tf-ops.aar (1.708.597 Byte)
arm64-v8a tensorflow-lite.aar (273.713 Byte)
tensorflow-lite-select-tf-ops.aar (2.339.697 Byte)

TensorFlow Lite selektiv mit Bazel erstellen

In diesem Abschnitt wird davon ausgegangen, dass Sie TensorFlow-Quellcodes heruntergeladen und die lokale Entwicklungsumgebung in Baizel eingerichtet haben.

AAR-Dateien für Android-Projekt erstellen

Sie können die benutzerdefinierten TensorFlow Lite-ARs erstellen, indem Sie die Pfade der Modelldateien so angeben.

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

Der obige Befehl generiert die AAR-Datei bazel-bin/tmp/tensorflow-lite.aar für integrierte und benutzerdefinierte TensorFlow Lite-Vorgänge. Außerdem wird optional die AAR-Datei bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar generiert, wenn Ihre Modelle die Option „TensorFlow-Vorgänge auswählen“ enthalten. Beachten Sie, dass dadurch ein "fetter" AAR mit mehreren verschiedenen Architekturen erstellt wird. Wenn Sie nicht alle benötigen, verwenden Sie die für Ihre Bereitstellungsumgebung geeignete Teilmenge.

Build mit benutzerdefinierten Operationen

Wenn Sie Tensorflow Lite-Modelle mit benutzerdefinierten Operationen entwickelt haben, können Sie diese erstellen, indem Sie dem Build-Befehl die folgenden Flags hinzufügen:

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

Das Flag tflite_custom_ops_srcs enthält Quelldateien Ihrer benutzerdefinierten Vorgänge und das Flag tflite_custom_ops_deps enthält Abhängigkeiten zum Erstellen dieser Quelldateien. Diese Abhängigkeiten müssen im TensorFlow-Repository vorhanden sein.

Erweiterte Verwendung: Benutzerdefinierte Bazel-Regeln

Wenn Ihr Projekt Bazel verwendet und Sie benutzerdefinierte TFLite-Abhängigkeiten für einen bestimmten Satz von Modellen definieren möchten, können Sie die folgende(n) Regel(n) in Ihrem Projekt-Repository definieren:

Nur für Modelle mit integrierten Operationen:

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

Für Modelle mit TF-Operationen auswählen:

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

Fortgeschrittene Nutzung: Benutzerdefinierte gemeinsam genutzte C/C++ Bibliotheken erstellen

Wenn Sie eigene benutzerdefinierte, gemeinsam genutzte TFLite C/C++-Objekte für die jeweiligen Modelle erstellen möchten, können Sie die folgenden Schritte ausführen:

Erstellen Sie eine temporäre Build-Datei. Führen Sie dazu den folgenden Befehl im Stammverzeichnis des TensorFlow-Quellcodes aus:

mkdir -p tmp && touch tmp/BUILD

Benutzerdefinierte gemeinsam genutzte C-Objekte erstellen

Wenn Sie ein benutzerdefiniertes gemeinsam genutztes TFLite C-Objekt erstellen möchten, fügen Sie der Datei tmp/BUILD Folgendes hinzu:

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

Das neu hinzugefügte Ziel kann so erstellt werden:

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

und für Android (ersetzen Sie android_arm durch android_arm64 für 64-Bit):

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

Benutzerdefinierte gemeinsam genutzte C++ Objekte erstellen

Wenn Sie ein benutzerdefiniertes gemeinsam genutztes TFLite C++-Objekt erstellen möchten, fügen Sie der Datei tmp/BUILD Folgendes hinzu:

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

Das neu hinzugefügte Ziel kann so erstellt werden:

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

und für Android (ersetzen Sie android_arm durch android_arm64 für 64-Bit):

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

Für die Modelle mit den Vorgängen zum Auswählen von TFs müssen Sie außerdem die folgende gemeinsam genutzte Bibliothek erstellen:

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

Das neu hinzugefügte Ziel kann so erstellt werden:

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

und für Android (ersetzen Sie android_arm durch android_arm64 für 64-Bit):

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

TensorFlow Lite mit Docker selektiv erstellen

In diesem Abschnitt wird davon ausgegangen, dass Sie Docker auf Ihrem lokalen Computer installiert und hier das TensorFlow Lite-Dockerfile heruntergeladen haben.

Nachdem Sie das obige Dockerfile heruntergeladen haben, können Sie das Docker-Image mit folgendem Befehl erstellen:

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

AAR-Dateien für Android-Projekt erstellen

Laden Sie das Skript zum Erstellen mit Docker herunter, indem Sie folgenden Befehl ausführen:

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

Anschließend können Sie das benutzerdefinierte TensorFlow Lite-AAR erstellen, indem Sie die Modelldateipfade wie folgt angeben.

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

Das Flag checkpoint ist ein Commit, Branch oder Tag des TensorFlow-Repositorys, das Sie vor dem Erstellen der Bibliotheken auschecken möchten. Standardmäßig ist es der neueste Release-Branch. Der obige Befehl generiert die AAR-Datei tensorflow-lite.aar für die integrierten und benutzerdefinierten Operationen von TensorFlow Lite und optional die AAR-Datei tensorflow-lite-select-tf-ops.aar für „Select TensorFlow Operationen“ in Ihrem aktuellen Verzeichnis.

Mit „--cache_dir“ wird das Cache-Verzeichnis angegeben. Falls nicht angegeben, erstellt das Skript zum Speichern im Cache ein Verzeichnis mit dem Namen bazel-build-cache unter dem aktuellen Arbeitsverzeichnis.

AAR-Dateien zum Projekt hinzufügen

Zum Hinzufügen von AAR-Dateien importieren Sie den AAR direkt in Ihr Projekt oder veröffentlichen den benutzerdefinierten AAR in Ihrem lokalen Maven-Repository. Sie müssen die AAR-Dateien auch für tensorflow-lite-select-tf-ops.aar hinzufügen, wenn Sie sie generieren.

Selektiver Build für iOS

Lesen Sie im Abschnitt „Lokal erstellen“ nach, wie Sie die Build-Umgebung einrichten und den TensorFlow-Arbeitsbereich konfigurieren. Folgen Sie dann der Anleitung zur Verwendung des selektiven Build-Skripts für iOS.