LiteRT-Binärgröße reduzieren

Übersicht

Beim Bereitstellen von Modellen für On-Device Machine Learning-Anwendungen (ODML) ist es wichtig, den begrenzten Speicherplatz auf Mobilgeräten zu berücksichtigen. Die Größe von Modellbinärdateien hängt eng mit der Anzahl der im Modell verwendeten Operationen zusammen. Mit LiteRT können Sie die Größe von Modellbinärdateien durch selektive Builds reduzieren. Bei selektiven Builds werden nicht verwendete Vorgänge in Ihrem Modellset übersprungen und es wird eine kompakte Bibliothek mit nur der Laufzeit und den Op-Kernels erstellt, die für die Ausführung des Modells auf Ihrem Mobilgerät erforderlich sind.

Der selektive Build gilt für die folgenden drei Operations-Bibliotheken.

  1. Integrierte LiteRT-Ops-Bibliothek
  2. Benutzerdefinierte LiteRT-Vorgänge
  3. TensorFlow-Vorgangsbibliothek auswählen

In der Tabelle unten sehen Sie die Auswirkungen von selektiven Builds für einige gängige Anwendungsfälle:

Modellname Domain Zielarchitektur Größe der AAR-Datei(en)
Mobilenet_1.0_224(float) Bildklassifizierung armeabi-v7a tensorflow-lite.aar (296.635 Byte)
arm64-v8a tensorflow-lite.aar (382.892 Byte)
SPICE Extraktion der Tonhöhe 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)

LiteRT mit Bazel selektiv erstellen

In diesem Abschnitt wird davon ausgegangen, dass Sie die TensorFlow-Quellcodes heruntergeladen und die lokale Entwicklungsumgebung für Bazel eingerichtet haben.

AAR-Dateien für Android-Projekt erstellen

Sie können die benutzerdefinierten LiteRT-AARs erstellen, indem Sie die Pfade zu Ihren Modelldateien wie unten angegeben 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

Mit dem obigen Befehl wird die AAR-Datei bazel-bin/tmp/tensorflow-lite.aar für integrierte und benutzerdefinierte LiteRT-Vorgänge generiert. Optional wird die AAR-Datei bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar generiert, wenn Ihre Modelle TensorFlow-Vorgänge vom Typ „Select“ enthalten. Dadurch wird eine „Fat“-AAR mit mehreren verschiedenen Architekturen erstellt. Wenn Sie nicht alle benötigen, verwenden Sie die für Ihre Bereitstellungsumgebung geeignete Teilmenge.

Benutzerdefinierte Vorgänge verwenden

Wenn Sie LiteRT-Modelle mit benutzerdefinierten Vorgängen entwickelt haben, können Sie sie 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 die Quelldateien Ihrer benutzerdefinierten Vorgänge und das Flag tflite_custom_ops_deps enthält die Abhängigkeiten zum Erstellen dieser Quelldateien. Diese Abhängigkeiten müssen im TensorFlow-Repository vorhanden sein.

Erweiterte Anwendungsfälle: Benutzerdefinierte Bazel-Regeln

Wenn in Ihrem Projekt Bazel verwendet wird und Sie benutzerdefinierte TFLite-Abhängigkeiten für eine bestimmte Gruppe von Modellen definieren möchten, können Sie die folgenden Regeln in Ihrem Projekt-Repository definieren:

Für die Modelle mit den integrierten Operationen gilt:

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 die Modelle mit TF-Vorgänge 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",
    ],
)

Erweiterte Verwendung: Benutzerdefinierte gemeinsam genutzte C/C++-Bibliotheken erstellen

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

Erstellen Sie eine temporäre BUILD-Datei, indem Sie den folgenden Befehl im Stammverzeichnis des TensorFlow-Quellcodes ausführen:

mkdir -p tmp && touch tmp/BUILD

Benutzerdefinierte C-Shared-Objekte erstellen

Wenn Sie ein benutzerdefiniertes gemeinsames 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 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",
    ],
)

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 gemeinsame C++-Objekte erstellen

Wenn Sie ein benutzerdefiniertes gemeinsames 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 der Option „TF-Vorgänge auswählen“ müssen Sie auch 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

LiteRT selektiv mit Docker erstellen

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

Nachdem Sie das oben genannte 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 für das Erstellen mit Docker herunter, indem Sie Folgendes 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 die benutzerdefinierte LiteRT-AAR erstellen, indem Sie die Pfade zu Ihren Modelldateien wie unten angegeben 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, ein Zweig oder ein Tag des TensorFlow-Repositorys, das Sie vor dem Erstellen der Bibliotheken auschecken möchten. Standardmäßig ist es der aktuelle Release-Zweig. Mit dem obigen Befehl wird die AAR-Datei tensorflow-lite.aar für integrierte und benutzerdefinierte LiteRT-Vorgänge und optional die AAR-Datei tensorflow-lite-select-tf-ops.aar für ausgewählte TensorFlow-Vorgänge in Ihrem aktuellen Verzeichnis generiert.

Mit --cache_dir wird das Cache-Verzeichnis angegeben. Wenn nicht angegeben, wird vom Skript ein Verzeichnis namens bazel-build-cache im aktuellen Arbeitsverzeichnis für das Caching erstellt.

AAR-Dateien zum Projekt hinzufügen

Fügen Sie AAR-Dateien hinzu, indem Sie die AAR-Datei direkt in Ihr Projekt importieren oder die benutzerdefinierte AAR-Datei in Ihrem lokalen Maven-Repository veröffentlichen. Beachten Sie, dass Sie die AAR-Dateien für tensorflow-lite-select-tf-ops.aar ebenfalls hinzufügen müssen, wenn Sie sie generieren.

Selektiver Build für iOS

Informationen zum Einrichten der Build-Umgebung und zum Konfigurieren des TensorFlow-Arbeitsbereichs finden Sie im Abschnitt zum lokalen Erstellen. Folgen Sie dann der Anleitung, um das selektive Build-Skript für iOS zu verwenden.