Zmniejsz rozmiar binarny TensorFlow Lite

Przegląd

Podczas wdrażania modeli dla aplikacji uczenia maszynowego (ODML) na urządzeniu należy pamiętać o ograniczonej pamięci dostępnej na urządzeniach mobilnych. Rozmiary binarne modelu są ściśle skorelowane z liczbą operacji używanych w modelu. TensorFlow Lite umożliwia zmniejszenie rozmiaru binarnego modelu za pomocą selektywnych kompilacji. Kompilacje selektywne pomijają nieużywane operacje w zestawie modeli i tworzą kompaktową bibliotekę zawierającą tylko środowisko wykonawcze i jądra operacyjne wymagane do uruchomienia modelu na urządzeniu mobilnym.

Kompilacja selektywna dotyczy następujących trzech bibliotek operacji.

  1. Wbudowana biblioteka operacyjna TensorFlow Lite
  2. Niestandardowe operacje TensorFlow Lite
  3. Wybierz bibliotekę operacyjną TensorFlow

Poniższa tabela pokazuje wpływ selektywnych kompilacji na niektóre typowe przypadki użycia:

Nazwa modelu Domena Architektura docelowa Rozmiary plików AAR
Mobilenet_1.0_224(liczba zmiennoprzecinkowa) Klasyfikacja obrazu armeabi-v7a tensorflow-lite.aar (296 635 bajtów)
arm64-v8a tensorflow-lite.aar (382 892 bajtów)
PRZYPRAWA Ekstrakcja wysokości dźwięku armeabi-v7a tensorflow-lite.aar (375 813 bajtów)
tensorflow-lite-select-tf-ops.aar (1 676 380 bajtów)
arm64-v8a tensorflow-lite.aar (421 826 bajtów)
tensorflow-lite-select-tf-ops.aar (2 298 630 bajtów)
i3d-kinetyka-400 Klasyfikacja wideo armeabi-v7a tensorflow-lite.aar (240 085 bajtów)
tensorflow-lite-select-tf-ops.aar (1 708 597 bajtów)
arm64-v8a tensorflow-lite.aar (273 713 bajtów)
tensorflow-lite-select-tf-ops.aar (2 339 697 bajtów)

Selektywnie buduj TensorFlow Lite z Bazel

W tej sekcji założono, że pobrałeś kody źródłowe TensorFlow i skonfigurowałeś lokalne środowisko programistyczne dla Bazel.

Twórz pliki AAR dla projektu Android

Możesz zbudować niestandardowe raporty AAR TensorFlow Lite, podając ścieżki do plików modelu w następujący sposób.

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

Powyższe polecenie wygeneruje plik AAR bazel-bin/tmp/tensorflow-lite.aar dla wbudowanych i niestandardowych operacji TensorFlow Lite; i opcjonalnie generuje plik bazel-bin/tmp/tensorflow-lite-select-tf-ops.aar , jeśli Twoje modele zawierają Select TensorFlow ops. Zauważ, że tworzy to „gruby” AAR z kilkoma różnymi architekturami; jeśli nie potrzebujesz ich wszystkich, użyj podzbioru odpowiedniego dla twojego środowiska wdrażania.

Twórz z niestandardowymi operacjami

Jeśli opracowałeś modele Tensorflow Lite z niestandardowymi operacjami, możesz je zbudować, dodając następujące flagi do polecenia budowania:

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

Flaga tflite_custom_ops_srcs zawiera pliki źródłowe twoich niestandardowych operacji, a flaga tflite_custom_ops_deps zawiera zależności potrzebne do zbudowania tych plików źródłowych. Pamiętaj, że te zależności muszą istnieć w repozytorium TensorFlow.

Zaawansowane zastosowania: niestandardowe reguły Bazel

Jeśli Twój projekt korzysta z Bazel i chciałbyś zdefiniować niestandardowe zależności TFLite dla danego zestawu modeli, możesz zdefiniować następujące reguły w repozytorium projektu:

Tylko dla modeli z wbudowanymi operacjami:

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

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

Zaawansowane zastosowania: Twórz niestandardowe biblioteki współdzielone C/C++

Jeśli chcesz zbudować własne niestandardowe obiekty współdzielone TFLite C/C++ w odniesieniu do danych modeli, możesz wykonać poniższe kroki:

Utwórz tymczasowy plik BUILD, uruchamiając następujące polecenie w katalogu głównym kodu źródłowego TensorFlow:

mkdir -p tmp && touch tmp/BUILD

Budowanie niestandardowych obiektów współdzielonych C

Jeśli chcesz zbudować niestandardowy obiekt udostępniony TFLite C, dodaj następujące elementy do pliku 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",
    ],
)

Nowo dodany cel można zbudować w następujący sposób:

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

i dla Androida (zamień android_arm na android_arm64 dla wersji 64-bitowej):

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

Tworzenie niestandardowych obiektów udostępnionych w języku C++

Jeśli chcesz zbudować niestandardowy obiekt udostępniony TFLite C++, dodaj następujące elementy do pliku 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",
    ],
)

Nowo dodany cel można zbudować w następujący sposób:

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

i dla Androida (zamień android_arm na android_arm64 dla wersji 64-bitowej):

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

W przypadku modeli z operacjami Select TF musisz również zbudować następującą bibliotekę współdzieloną:

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

Nowo dodany cel można zbudować w następujący sposób:

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

i dla Androida (zamień android_arm na android_arm64 dla wersji 64-bitowej):

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

Selektywnie buduj TensorFlow Lite z Dockerem

W tej sekcji założono, że zainstalowałeś Dockera na komputerze lokalnym i pobrałeś tutaj plik TensorFlow Lite Dockerfile.

Po pobraniu powyższego pliku Dockerfile możesz zbudować obraz dockera, uruchamiając:

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

Twórz pliki AAR dla projektu Android

Pobierz skrypt do budowania z Dockerem, uruchamiając:

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

Następnie możesz zbudować niestandardowy AAR TensorFlow Lite, podając ścieżki do plików modelu w następujący sposób.

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

Flaga checkpoint to zatwierdzenie, gałąź lub znacznik repozytorium TensorFlow, które chcesz pobrać przed zbudowaniem bibliotek; domyślnie jest to najnowsza gałąź wydania. Powyższe polecenie wygeneruje plik AAR tensorflow-lite.aar dla wbudowanych i niestandardowych operacji TensorFlow Lite oraz opcjonalnie plik AAR tensorflow-lite-select-tf-ops.aar dla wybranych operacji TensorFlow w bieżącym katalogu.

Opcja --cache_dir określa katalog pamięci podręcznej. Jeśli nie zostanie podany, skrypt utworzy katalog o nazwie bazel-build-cache w bieżącym katalogu roboczym do buforowania.

Dodaj pliki AAR do projektu

Dodaj pliki AAR, importując je bezpośrednio do swojego projektu lub publikując niestandardowe AAR w lokalnym repozytorium Maven . Pamiętaj, że musisz również dodać pliki AAR dla tensorflow-lite-select-tf-ops.aar , jeśli je generujesz.

Selektywna kompilacja dla iOS

Zapoznaj się z sekcją Kompilowanie lokalnie, aby skonfigurować środowisko kompilacji i obszar roboczy TensorFlow, a następnie postępuj zgodnie z instrukcjami , aby użyć skryptu kompilacji selektywnej dla systemu iOS.