Extra Coral Dev Board Mini

Für die Arbeit mit dem Coral Dev Board Mini ist der Edge TPU Compiler (edgetpu_compiler) wichtig. Doch was macht der TPU-Compiler überhaupt? Er kann bereits trainierte Modelle in eine Form übertragen, die auf der Edge TPU des Dev Boards läuft. Diese Modelle basieren auf dem Framework TensorFlow Lite. Das Kommandozeilen-Tool erzeugt daraus Dateien mit der Endung .tflite, die auf dem Dev Board lauffähig sind. 

Hinweis: Dieser Artikel ist eine Ergänzung zu unserer Serie über das Coral Dev Board Mini. In dieser Artikelserie erfährst du, wie du mit dem Board umgehst und was du alles damit machen kannst.

Teil 1: Coral Dev Board Mini: Künstliche Intelligenz für den Hobbykeller

Teil 2: Das Coral AI Dev Board Mini im Überblick

Teil 3: Das Coral Dev Board Mini anschließen und loslegen

Teil 4: Mendel Linux: Das Betriebssystem des Coral AI Dev Board Mini

Teil 5: Kamera an das Coral AI Dev Board Mini anschließen

Teil 6: Die Erweiterungsleiste des Coral Dev Board Mini

Teil 7: Programmieren mit dem Coral AI Dev Board Mini

Teil 8: Bilderkennung mit dem Dev Board Mini und der Coral Camera

Teil 9: Spracherkennung mit dem Coral Dev Board Mini

 

Um selbst Modelle kompilieren zu können, musst du den TPU-Compiler installieren. Dazu benötigst du einen PC mit einem Debian-basierten Betriebssystem. Falls du bisher nur mit Windows gearbeitet hast: Solch ein Linux-System lässt sich sehr leicht parallel zu Windows einrichten. Eine gute Option für Einsteiger ist beispielsweise Ubuntu

Die in diesem Artikel beschriebenen Parameter ermöglichen es dir, die Kompilierung exakt an deine eigenen Bedürfnisse anzupassen. Stell zuvor sicher dass dein Modell mit der Edge TPU kompatibel ist bevor du den Compiler verwenden. Für Details zur Kompatibilität lies bitte TensorFlow models on the Edge TPU.

Sämtliche Google Coral Geräte, die du benötigst, erhältst du in unserem Shop.

Inhalt

Systemvoraussetzungen

Der Edge TPU Compiler kann auf jedem modernen Debian-basierten Linux-System ausgeführt werden. Insbesondere müssen die folgenden Voraussetzungen erfüllt sein:

  • 64-Bit-Version von Debian 6.0 oder höher, oder ein Derivat davon (etwa Ubuntu 10.0+)
  • x86-64-Systemarchitektur

Wenn dein System diese Anforderungen nicht erfüllt, probiere einmal unseren webbasierten Compiler mit Google Colab aus.

Note: Der Edge TPU Compiler ist ab Version 2.1 nicht mehr für ARM64-Systeme (wie das Coral Dev Board) verfügbar. Wir empfehlen, Ihr Modell auf einem leistungsfähigeren Desktop zu kompilieren.

Download

Du kannst den Compiler mithilfe der folgenden Kommandos auf deinem Linux-System installieren:

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list sudo apt-get update sudo apt-get install edgetpu-compiler

Verwendung

edgetpu_compiler [options] model...

Der Compiler akzeptiert den Dateipfad zu einem oder mehreren TensorFlow-Lite-Modellen (das model Argument), sowie alle Optionen. Wenn du mehrere Modelle übergibst (jedes durch ein Leerzeichen getrennt), werden sie so kompiliert, dass sie sich den RAM der Edge TPU für das Zwischenspeichern von Parameterdaten teilen können (lies hierzu über das paramter data caching).

Der Dateiname für jedes kompilierte Modell lautet input_filename_edgetpu.tflite Das Modell wird im aktuellen Verzeichnis gespeichert, sofern du mit der Option -out_dir nichts anderes angibst.

Tabelle 1. Verfügbare Compiler Optionen

Option Beschreibung
-h, --help Druckt die Kommandozeilenhilfe und beendet das Programm.
-i, --intermediate_tensors names Gibt die Tensoren an, die du als Ausgaben des benutzerdefinierten Edge TPU-Operators wünschst. Das Argument ist eine durch Komma getrennte Liste von Tensor-Namen. Alle Operatoren, die diesen Tensoren folgen, werden nicht für die Edge TPU kompiliert, befinden sich aber weiterhin in der Datei "tflite" und werden auf der CPU ausgeführt. Die endgültige Ausgabe des Modells bleibt die gleiche. Wenn du mehrere Eingabemodelle hast (für die Ko-Kompilierung), trenne die Liste der Tensoren für jedes Modell mit einem Doppelpunkt und übergib sie in der Reihenfolge, die den Eingabemodellen entspricht.
-m, --min_runtime_version num Gibt die niedrigste Edge TPU-Laufzeitversion an, mit der das Modell kompatibel sein soll. Wenn das Gerät, auf dem du dein Modell ausführen möchtest, beispielsweise über die Version 10 der Edge TPU-Laufzeit verfügt (und du die Laufzeitversion nicht aktualisieren kannst), solltest du diesen Wert auf 10 setzen, um sicherzustellen, dass dein Modell kompatibel ist. (Modelle sind immer vorwärtskompatibel mit neueren Edge TPU-Laufzeiten. Ein für Version 10 kompiliertes Modell ist mit Version 12 kompatibel). Der Standardwert hängt von der Version des Compilers ab. Sieh in der --help Ausgabe nach. Weitere Einzelheiten zu den Compiler- und Laufzeitversionen findest du weiter unten.
-n, --num_segments num Kompiliert das Modell in num Segmente. Jedes Segment kann auf einer separaten Edge TPU ausgeführt werden, wodurch sich der Gesamtdurchsatz des Modells erhöht. Einzelheiten zur Verwendung findest du unter Segmentierung eines Modells für Pipelining. Diese Funktion kann nicht verwendet werden, wenn mehrere Modelle übergeben oder mit intermediate_tensors kombiniert werden.
-o, --out_dir dir Gibt das kompilierte Modell und die Protokolldateien im Verzeichnis dir aus. Standard ist das aktuelle Verzeichnis.
-s, --show_operations Druckt das Protokoll mit den Operationen, die auf die Edge TPU abgebildet wurden. Die gleichen Informationen werden immer in eine .log Datei mit demselben Namen und Speicherort wie das kompilierte Modell geschrieben.
-d, --search_delegate Aktiviert die wiederholte Suche nach einem neuen Kompilierungs-Stopp-Punkt früher im Graphen, um seltene Compiler-Fehler zu vermeiden, wenn er auf eine nicht unterstützte Operation stößt. Diese Option kann nützlich sein, wenn der Compiler einen Edge-TPU-Delegaten nicht erstellen kann, obwohl frühe Schichten des Modells kompatibel sind. Wenn es aktiviert ist, versucht der Compiler, falls er aus irgendeinem Grund fehlschlägt, automatisch erneut zu kompilieren, bricht aber die Kompilierung ab, bevor er die fehlgeschlagene Operation erreicht. Schlägt die Kompilierung erneut fehl, wird sie wiederholt, wobei er wieder rückwärts geht und vor der fehlgeschlagenen Operation anhält, bis er die allererste Operation des Graphen erreicht. Die Schrittweite für jeden rekursiven Versuch ist standardmäßig 1 op. Du kannst die Schrittweite mit --delevate_search_step ändern. Dieses Flag kann nicht verwendet werden, wenn mehrere Modelle gemeinsam kompiliert werden. Hinzugefügt in v16.
-k, --delegate_search_step num Gibt eine Schrittgröße an (die Anzahl der rückwärts zu durchlaufenden Ops), wenn du --search_delegate verwendest, das standardmäßig eine Schrittgröße von 1 verwendet. Dies kann eine beliebige Zahl 1 oder höher sein, was dir helfen kann, einen erfolgreichen Delegaten schneller zu finden. Hinzugefügt in v16.
-t, --timeout_sec num Gibt das Compiler-Timeout in Sekunden an. Der Standardwert ist 180.
-v, --version Gibt die Compiler-Version aus und beendet sich.

Parameter Data Caching

Parameter Data Caching ist das Zwischenspeichern von Parametern.

Die Edge TPU verfügt über etwa 8 MB SRAM, in dem die Parameterdaten des Modells zwischengespeichert werden können. Ein kleiner Teil des RAM ist jedoch zunächst für die ausführbare Inferenzdatei des Modells reserviert, so dass die Parameterdaten den danach verbleibenden Platz nutzen. Die Speicherung der Parameterdaten im RAM der Edge TPU ermöglicht natürlich eine schnellere Inferenzgeschwindigkeit im Vergleich zum Abrufen der Parameterdaten aus dem externen Speicher.

Bei diesem Edge TPU-"Cache" handelt es sich nicht um einen herkömmlichen Cache, sondern um einen vom Compiler zugewiesenen Scratchpad-Speicher. Der Edge TPU Compiler fügt eine kleine ausführbare Datei in das Modell ein, die eine bestimmte Menge der Parameterdaten des Modells in den Edge TPU-RAM schreibt (falls verfügbar), bevor eine Inferenz ausgeführt wird.

Wenn du Modelle einzeln kompilierst, gibt der Compiler jedem Modell ein eindeutiges "Caching Token" (eine 64-Bit-Nummer). Wenn du dann ein Modell ausführst, vergleicht die Edge TPU-Laufzeitumgebung dieses Caching-Token mit dem Token der Daten, die derzeit zwischengespeichert sind. Wenn die Token übereinstimmen, verwendet die Laufzeitumgebung die im Cache gespeicherten Daten. Stimmen sie nicht überein, wird der Cache geleert und stattdessen die Daten des neuen Modells geschrieben. (Wenn Modelle einzeln kompiliert werden, kann jeweils nur ein Modell seine Daten zwischengespeichert haben). Dieser Prozess ist in Abbildung 1 dargestellt.

Abbildung 1. Flussdiagramm, das zeigt, wie die Edge TPU-Laufzeitumgebung den Modell-Cache im Edge TPU-RAM verwaltet


Beachte, dass das System den Cache leert und Modelldaten nur dann in den Cache schreibt, wenn dies erforderlich ist, was die Inferenz verzögert. Wenn dein Modell zum ersten Mal ausgeführt wird, ist es also immer langsamer. Spätere Inferenzen sind schneller, weil sie den bereits geschriebenen Cache nutzen. Wenn deine Anwendung jedoch ständig zwischen mehreren Modellen umschaltet, führt dieser Cache-Wechsel zu einem erheblichen Mehraufwand bei der Gesamtleistung deiner Anwendung. Hier kommt die Co-Kompilierungsfunktion ins Spiel...

 

Co-Kompilierung mehrerer Modelle

Um die Leistung zu beschleunigen, wenn du mehrere Modelle kontinuierlich auf derselben Edge TPU ausführst, unterstützt der Compiler die Co-Kompilierung. Durch die Co-Kompilierung deiner Modelle können mehrere Modelle den Edge TPU-RAM gemeinsam nutzen, um ihre Parameterdaten zwischenzuspeichern, sodass der Cache nicht jedes Mal gelöscht werden muss, wenn du ein anderes Modell ausführst.

Wenn du mehrere Modelle an den Compiler übergibst, wird jedem kompilierten Modell dasselbe Caching-Token zugewiesen. Wenn du also ein gemeinsam kompiliertes Modell zum ersten Mal ausführst, kann es seine Daten in den Cache schreiben, ohne ihn vorher zu leeren. Schau dir Abbildung 1 noch einmal an: Wenn du mehrere Modelle gemeinsam kompilierst, wird der erste Entscheidungsknoten ("Stimmt das Caching-Token des Modells mit dem Cache überein?") für jedes Modell zu "Ja", und der zweite Knoten ist nur dann "Ja", wenn jedes Modell zum ersten Mal ausgeführt wird.

Beachte jedoch, dass der jedem Modell zugewiesene Arbeitsspeicher zum Zeitpunkt der Kompilierung feststeht und nach der Reihenfolge, in der die Modelle im Compilerbefehl erscheinen, priorisiert wird. Nehmen wir zum Beispiel an, du kompilierst zwei Modelle wie hier gezeigt:

edgetpu_compiler model_A.tflite model_B.tflite

In diesem Fall wird der Cache-Speicher zunächst den Daten von Modell A zugewiesen (so viel wie möglich). Wenn danach noch Platz übrig ist, werden die Daten von Modell B in den Cache aufgenommen. Wenn einige der Modelldaten nicht in den Edge-TPU-RAM passen, müssen sie stattdessen zur Laufzeit aus dem externen Speicher geholt werden.

Wenn du mehrere Modelle gemeinsam kompilierst, ist es möglich, dass einige Modelle keinen Cache erhalten, so dass sie alle Daten aus dem externen Speicher laden müssen. Ja, das ist langsamer als die Verwendung des Cache, aber wenn du die Modelle in schneller Folge ausführst, könnte dies immer noch schneller sein als das Auslagern des Cache bei jedem anderen Modell.

Hinweis: Die Parameterdaten werden dem Cache schichtweise zugewiesen - entweder passen alle Parameterdaten einer bestimmten Schicht in den Cache und werden dorthin geschrieben, oder die Daten dieser Schicht sind zu groß, um hineinzupassen, und alle Daten für diese Schicht müssen aus dem externen Speicher geholt werden.

Überlegungen zur Leistung

Es ist wichtig, daran zu denken, dass der jedem Modell zugewiesene Cache kein herkömmlicher Cache ist, sondern ein vom Compiler zugewiesener Scratchpad-Speicher.

Der Edge TPU Compiler kennt die Größe des Edge TPU-RAM und weiß, wie viel Speicherplatz die ausführbaren und die Parameterdaten jedes Modells benötigen. Daher weist der Compiler den Parameterdaten eines jeden Modells zur Kompilierungszeit eine feste Menge an Cache-Speicherplatz zu. Der Befehl edgetpu_compiler gibt diese Informationen für jedes angegebene Modell aus. Hier ist zum Beispiel ein Ausschnitt aus der Compiler-Ausgabe für ein Modell:

On-chip memory available for caching model parameters: 6.91MiB
On-chip memory used for caching model parameters: 4.21MiB
Off-chip memory used for streaming uncached model parameters: 0.00B

In diesem Fall passen die Parameterdaten des Modells alle in den Edge TPU-RAM: Die für "Verwendeter Off-Chip-Speicher" angezeigte Menge ist Null.

Wenn du jedoch zwei Modelle gemeinsam kompilierst, verwendet das erste Modell 4,21 MiB der verfügbaren 6,91 MiB RAM, so dass nur 2,7 MiB für das zweite Modell übrig bleiben. Wenn das nicht genug Platz für alle Parameterdaten ist, dann muss der Rest aus dem externen Speicher geholt werden. In diesem Fall gibt der Compiler Informationen für das zweite Modell wie folgt aus:

On-chip memory available for caching model parameters: 2.7MiB
On-chip memory used for caching model parameters: 2.49MiB
Off-chip memory used for streaming uncached model parameters: 4.25MiB

Beachte, dass der "verwendete Off-Chip-Speicher" für dieses zweite Modell 4,25 MiB beträgt. Dieses Szenario ist in Abbildung 2 grob dargestellt.

Hinweis: Der "verfügbare Speicher auf dem Chip", der für das erste mitkompilierte Modell angezeigt wird, ist der Speicher, der nach Abzug des für die ausführbaren Dateien des Modells benötigten Speicherplatzes übrig bleibt. Wenn du mehrere Modelle gemeinsam kompilierst, wird der für die ausführbaren Dateien vorgesehene Speicherplatz von allen Modellen gemeinsam genutzt (im Gegensatz zum Speicherplatz für die Parameterdaten). Das heißt, die für die ausführbaren Dateien angegebene Menge ist nur die Menge an Speicherplatz, die von der größten ausführbaren Datei benötigt wird (nicht die Summe aller ausführbaren Dateien).

Abbildung 2. Zwei gemeinsam kompilierte Modelle, die nicht beide alle Parameterdaten im Edge TPU RAM unterbringen können

 

Selbst wenn deine Anwendung dann nur dieses zweite Modell ("Modell B") ausführt, speichert sie immer nur einen Teil ihrer Daten im Edge TPU-RAM, da dies die Menge ist, die beim Co-Kompilieren mit einem anderen Modell ("Modell A") als verfügbar ermittelt wurde. Der Hauptvorteil dieses statischen Designs besteht darin, dass die Leistung deterministisch ist, wenn deine Modelle gemeinsam kompiliert werden, und dass keine Zeit für das häufige Neuschreiben des RAM aufgewendet wird. Und wenn deine Modelle alle Parameterdaten in den Edge TPU-RAM einpassen, dann erreichst du maximale Leistungsgewinne, indem diese nie aus dem externen Speicher lesen und den Edge TPU-RAM nie neu schreiben.

Wenn du überlegst, ob du die Co-Kompilierung verwenden willst, solltest du den Compiler mit all deinen Modellen laufen lassen, um zu sehen, ob sie alle Parameterdaten in das Edge TPU-RAM einpassen können (lies dazu die Compilerausgabe). Wenn nicht alle Modelle passen, überlege, wie häufig jedes Modell verwendet wird. Übergib gegebenenfalls das am häufigsten verwendete Modell zuerst an den Compiler, damit er alle seine Parameterdaten zwischenspeichern kann. Wenn nicht alle Modelle passen und nur selten gewechselt werden, ist die Co-Kompilierung vielleicht nicht sinnvoll, da die Zeit, die für das Lesen aus dem externen Speicher aufgewendet wird, teurer ist als das regelmäßige Neuschreiben des Edge-TPU-RAM. Um zu entscheiden, was am besten funktioniert, musst du möglicherweise verschiedene Kompilierungsoptionen testen.

Tipp: Wenn die Daten für mehrere Modelle nicht alle in den Cache passen, versuche, die Modelle in einer anderen Reihenfolge an edgetpu_compiler zu übergeben. Wie bereits erwähnt, werden die Daten schichtweise zugewiesen. Du könntest also eine Reihenfolge finden, bei der mehr Gesamtdaten in den Cache passen, weil sie mehr von den kleineren Schichten zulässt.

Achtung: Du solltest vorsichtig sein, wenn du die Co-Kompilierung in Kombination mit mehreren Edge TPUs verwendest: Wenn du deine Modelle cokompilieren lässt, diese aber tatsächlich auf separaten Edge TPUs laufen, könnten deine Modelle unnötigerweise Parameterdaten im externen Speicher speichern. Du solltest also sicherstellen, dass alle gemeinsam kompilierten Modelle tatsächlich auf derselben Edge TPU ausgeführt werden.

Segmentierung eines Modells für Pipelining

Wenn dein Modell nicht in den Edge-TPU-Cache passt oder der Gesamtdurchsatz für dein Modell ein Engpass in deinem Programm ist, kannst du die Leistung wahrscheinlich verbessern, indem du dein Modell in separate Teilgraphen segmentierst, die in einer Pipeline auf separaten Edge-TPUs ausgeführt werden.

Um dein Modell zu segmentieren, gib einfach das Argument num_segments an, wenn du das Modell kompilierst. Wenn du zum Beispiel eine Pipeline mit vier Edge TPUs verwenden möchtest:

edgetpu_compiler --num_segments=4 model.tflite

Der Compiler gibt jedes Segment als separate .tflite Datei mit einem enumerierten Dateinamen aus. Du kannst dann die Inferenz mit der PipelinedModelRunner API ausführen, wie in Pipeline ein Modell mit mehreren Edge TPUs beschrieben.

Du solltest jedoch sorgfältig abwägen, mit welcher Anzahl von Segmenten du deine Leistungsziele erreichen kannst. Dies hängt von der Größe deines Modells ab und davon, ob du versuchst, ein großes Modell vollständig in den Edge-TPU-Cache einzupassen (um die Latenz zu verringern) oder ob du versuchst, den Durchsatz deines Modells zu erhöhen:

  • Wenn du dein Modell nur in den Edge-TPU-Cache einpassen musst, kannst du die Anzahl der Segmente schrittweise erhöhen, bis der Compiler für alle Segmente "Off-Chip-Speicher verwendet" mit 0,00B angibt.
  • Wenn du den Durchsatz des Modells erhöhen möchtest, ist es möglicherweise etwas schwieriger, die ideale Anzahl von Segmenten zu finden. Denn obwohl der Edge TPU Compiler dein Modell so unterteilt, dass jedes Segment ungefähr die gleiche Menge an Parameterdaten enthält, kann jedes Segment dennoch unterschiedliche Latenzen haben. Beispielsweise kann eine Schicht viel größere Eingabetensoren erhalten als andere, und diese zusätzliche Verarbeitung kann einen Engpass in deiner Pipeline verursachen. Du könntest also den Durchsatz weiter verbessern, indem du einfach ein zusätzliches Segment hinzufügst. Auf der Grundlage unserer Experimente haben wir festgestellt, dass die folgende Formel eine gut verteilte Pipeline erzeugt:
    num_segments = [Model size] MB / 6 MB
    Runde dann auf eine ganze Zahl auf. Wenn dein Modell zum Beispiel 20 MB groß ist, ist das Ergebnis 3,3, also solltest du es mit 4 Segmenten versuchen.
    Wenn die Gesamtlatenz immer noch zu hoch ist, könnte es daran liegen, dass ein Segment immer noch viel langsamer ist als die anderen und einen Engpass verursacht. Um die unterschiedlichen Segment-Latenzen zu beheben, solltest du den profilierungsbasierten Partitionierer ausprobieren, der ein Profil der Latenz für jedes Segment erstellt und dann das Modell neu segmentiert, um die Latenz über alle Segmente hinweg auszugleichen.

Hinweis: Wenn du die vollständige Kontrolle darüber haben willst, wo jedes Segment geschnitten wird, kannst du stattdessen dein Modell manuell in separate .tflite Dateien schneiden, indem du das TensorFlow `toco_convert` Werkzeug benutzt. Stelle sicher, dass du jedes .tflite Segment mit einer Nummer benennst, die der Reihenfolge entspricht, in der es in die Pipeline gehört. Beachte auch, dass toco_convert nur mit Modellen kompatibel ist, die uint8 quantisierte Parameter verwenden, also nicht mit nach dem Training quantisierten Modellen (die int8 verwenden).

Verwendung des profilierungsbasierten Partitionierers

Die Segmentierungsstrategie des Edge TPU Compilers (über die Option num_segments) verwendet eine Heuristik, die versucht, die Parameterdaten gleichmäßig zwischen den Segmenten zu verteilen - die Latenz in den einzelnen Segmenten spielt dabei keine Rolle. Daher kann es zu Engpässen in deiner Pipeline kommen, insbesondere wenn du versuchst, ein SSD-Modell oder einen anderen Modelltyp zu segmentieren, der große CPU-gebundene Ops oder Verzweigungen im Graphen aufweist. In diesen Situationen, in denen es wichtig ist, dass jedes Segment deiner Pipeline mit einigermaßen ähnlichen Latenzen arbeitet, solltest du dein Modell mit dem Werkzeug partition_with_profiling kompilieren.

Das partition_with_profiling Tool ist ein Wrapper um den Edge TPU Compiler, der jedes Segment auf einer Edge TPU profiliert und das Modell unter Verwendung verschiedener Segmentlängen iterativ neu kompiliert, bis es ein Partitionsverhältnis findet, bei dem der Unterschied zwischen dem schnellsten und dem langsamsten Segment unter einem bestimmten Schwellenwert liegt.

Um dieses Tool zu verwenden, musst du zunächst das partition_with_profiling Tool kompilieren, was du mit Docker tun kannst, wie in der Readme-Datei des Partitioners auf GitHub beschrieben. Führe dann den Profiling Partitioner aus, indem du ihm den Pfad zum Edge TPU Compiler, dein Modell und die Anzahl der zu erstellenden Segmente übergibst:

Achtung: Dein System muss Zugriff auf die gleiche Anzahl von Edge-TPUs haben, wie im Argument num_segments angegeben.

./partition_with_profiling \
  --edgetpu_compiler_binary <PATH_TO_COMPILER> \
  --model_path <PATH_TO_MODEL> \
  --output_dir <OUT_DIR> \
  --num_segments <NUM_SEGMENTS>

Dies dauert länger als eine typische Modellkompilierung, da das Modell möglicherweise mehrmals neu partitioniert werden muss und jedes Mal ein Profil erstellt werden muss, bevor eine optimale Partition gefunden wird.

Hinweis: Um ein genaues Profil deiner Pipeline-Segmente zu erstellen, sollten die vom profilierungsbasierten Partitionierer verwendeten Edge TPUs dieselbe Schnittstelle (PCIe oder USB) verwenden wie die in deinem Produktionssystem, und auch die Host-CPU sollte übereinstimmen. Wenn das nicht möglich ist, ist das in Ordnung, aber beachte, dass es einen Unterschied zwischen dem vom profilierungsbasierten Partitionierer gemessenen Durchsatz und dem Durchsatz auf deinem Produktionssystem geben kann.

 

Tabelle 2. Optionen für das Werkzeug partition_with_profiling

Option Beschreibung
--edgetpu_compiler_binary file_path Pfad zur Edge-TPU-Compiler-Binärdatei. Notwendig.
--model_path file_path Pfad zum aufzuteilenden Modell. Notwendig.
--num_segments num Anzahl der Ausgabesegmentmodelle. Notwendig.
--output_dir dir Ausgabeverzeichnis für alle kompilierten Segmente. Standard ist /tmp/models/.
--device_type type Typ des Edge TPU-Geräts, das bei der Profilerstellung für jedes Segment verwendet werden soll. Der Typ kann "pcionly", "usbonly" oder "any" sein. Standard ist "any".
--diff_threshold_ns num Die angestrebte Differenz (in ns) zwischen dem langsamsten Segment (obere Grenze) und dem schnellsten Segment (untere Grenze). Wenn der Partitionierer ein Partitionsverhältnis findet, bei dem die Differenz zwischen dem langsamsten und dem schnellsten Segment geringer ist als dieser Wert, wird er angehalten. Die Vorgabe ist 1000000 (1 ms).
--partition_search_step num Die Anzahl der Operatoren, die während jeder Iteration der Partitionssuche zu einem Segment hinzugefügt oder daraus entfernt werden. Eine Erhöhung dieser Zahl kann die Suche nach einer geeigneten Partition beschleunigen, kann aber auch zu einem Überschreiten des Minimums führen. Voreinstellung ist 1.
--delegate_search_step num Schrittweite für die Delegatensuche beim Kompilieren des Modells. Entspricht der Option delegate_search_step im Compiler. Standardwert ist 1. (Beim Werkzeug partition_with_profiling ist search_delegate immer aktiviert.)
--initial_lower_bound_ns num Anfängliche Untergrenze der Segmentlatenz. (Latenz des schnellsten Segments.) Standardmäßig wird dies vom Tool ermittelt, indem das Modell mit dem heuristischen Ansatz des Compilers segmentiert und dann die Segment-Latenzen aufgezeichnet werden.
--initial_upper_bound_ns num Anfängliche Obergrenze für die Segment-Latenz (Latenz des langsamsten Segments). Standardmäßig wird dies vom Tool ermittelt, indem das Modell mit dem heuristischen Ansatz des Compilers segmentiert und dann die Segment-Latenzen aufgezeichnet werden.

 

Weitere Einzelheiten zu diesen Tools findest du im GitHub Repository.

Um eine Inferenz mit deinen segmentierten Modell durchzuführen, lies Pipeline a model with multiple Edge TPUs.

Compiler und Laufzeitversionen

Ein für die Edge TPU kompiliertes Modell muss mit einer entsprechenden Version der Edge TPU-Laufzeit ausgeführt werden. Wenn du versuchst, ein kürzlich kompiliertes Modell mit einer älteren Laufzeitversion auszuführen, wird eine Fehlermeldung wie die folgende angezeigt:

Failed precondition: Package requires runtime version (12), which is newer than this runtime version (10).

Um dieses Problem zu lösen, aktualisiere die Edge TPU-Laufzeitumgebung auf deinem Hostsystem.

Wenn du nicht in der Lage bist, die Geräte-Laufzeit zu aktualisieren, kannst du stattdessen dein Modell neu kompilieren, um es mit der älteren Laufzeitversion kompatibel zu machen, indem du beim Ausführen von edgetpu_compiler das Flag --min_runtime_version angibst. Zum Beispiel:

edgetpu_compiler --min_runtime_version 10 your_model.tflite

Die folgende Tabelle zeigt die Edge TPU Compiler-Versionen und die entsprechende Edge TPU-Laufzeitversion, die standardmäßig erforderlich ist. Du kannst jederzeit einen neueren Compiler verwenden, um Modelle zu erstellen, die mit älteren Laufzeiten kompatibel sind (siehe oben).

Tabelle 3. Kompatibilität von Compiler und Edge TPU-Laufzeitumgebung

Compiler Version Notwendige Laufzeitumgebung
16.0 14
15.0 13
14.1 13
2.1.302470888 13
2.0.291256449 13
2.0.267685300 12
1.0 10

Hinweis: Deine Compiler- und Laufzeitversion bestimmt, welche Operationen du verwenden kannst.

Du kannst deine Compiler-Version wie folgt überprüfen:

edgetpu_compiler --version

Du kannst die Laufzeitversion auf deinem Gerät wie folgt überprüfen:

python3 -c "import pycoral.utils.edgetpu; print(pycoral.utils.edgetpu.get_runtime_version())"

Hilfe

Wenn das Protokoll für dein kompiliertes Modell viele Operationen anzeigt, die der CPU zugeordnet sind, überprüfe die Modellanforderungen sorgfältig und versuche, Änderungen vorzunehmen, um die Anzahl der Operationen zu erhöhen, die der Edge TPU zugeordnet sind.

Wenn der Compiler dein Modell nicht kompilieren kann und eine allgemeine Fehlermeldung ausgibt, kontaktiere bitte den Support von Google, um das Problem zu melden. Wenn du das tust, teile uns bitte das TensorFlow Lite Modell mit, das du zu kompilieren versuchst, damit Google das Problem debuggen kann (Google benötigt kein vollständig trainiertes Modell - eines mit zufällig initialisierten Parametern sollte ausreichen).

Hinterlasse einen Kommentar

Alle Kommentare werden vor der Veröffentlichung moderiert