Geben Sie Notizen zu Python-Skripten ein, um das PyTorch-Modell in C ++ mit libtorch auszuführen

Hintergrund

Ich möchte ein Pytorch-Modell (insbesondere ein Sprachverarbeitungssystem) verfolgen (eingefrorenes Modell, Tflite-Modell in TensorFlow).

Pytorch selbst macht eine Art Inferenz, aber es hat seine Grenzen. Insbesondere im Sprachverarbeitungssystem gibt es verschiedene Codes außer dem neuronalen Teil. Da es dynamische Arrays und Wiederholungen gibt, ist es auch erforderlich, entsprechend zu tippen.

Umgebung

Angenommen, Pytorch v1.4.0 (letzter Stand vom 04.04.2020).

JIT-Modell

https://pytorch.org/docs/stable/jit.html

Ist das verfolgte Modell ideal und das zweitplatzierte TorchScript?

Es scheint, dass Sie beide kombinieren können.

Umgebung

Untersuchen Sie den Typ

Sie können die Typen Ihres aktuellen Python-Skripts durchgehen, um dies herauszufinden.

Soll ich einen Python-Debugger oder Ipython verwenden ... Wird es im Jupyter-Labor angezeigt?

Ich kenne nur die grundlegende Ausführung von vim + Befehlszeilen, daher überprüfe ich durch Einfügen von print (Typ (x)) usw., wo ich jeden Typ haben möchte ...

Art

https://pytorch.org/docs/stable/jit.html

Für Python2 usw. und 3.5 können Sie "torch.jit.annotate" verwenden oder den Typ in den Kommentar schreiben. Es wird jedoch empfohlen, das "Typing" -Modul und die Typanmerkung in der Python-Syntax zu verwenden.

Stichprobe


def forward(self, x: List[torch.Tensor]) -> Tuple[torch.Tensor]:
  my_list: List[Tuple[int, float]] = []

Das kannst du fühlen.

Optional

Wie std :: optional in C ++ kann None oder mit einem Typ "Optional [T]" sein.

Optional[int]

@torch.jit.export

Normalerweise werden nur die Methode "forward ()" und die von forward aufgerufene Funktion JIT-kompiliert. Sie können die Methode jedoch explizit exportieren (JIT kompilieren), indem Sie den Dekorator "@ torch.jit.export" verwenden. (Forward ist implizit mit @ torch.jit.export dekoriert)

nn.ModuleList

nn.ModuleList (Array)

...
self.mods = nn.Modulelist([...])

for i in range(10):
  self.mods[i](x)

[jit] Can't index nn.ModuleList in script function #16123 https://github.com/pytorch/pytorch/issues/16123

[JIT] Add modulelist indexing for integer literal #29236 https://github.com/pytorch/pytorch/pull/29236

Derzeit scheint es, dass es durch Iteration in Form von "constants" und "for mod in modules" behandelt werden kann. Wenn Sie jedoch mehrere nn.ModuleList verwenden, müssen Sie eine dedizierte Klasse neu definieren. In diesem Fall muss jedoch die Definition von Netzwerkoperationsänderungen (der Name von state_dict ändert sich) und das Gewicht des vorab trainierten Modells gut behandelt werden. Auch in Version 1.5.0 (Version 1.6.0?) Wird self. Array-Indizes mit Konstanten wie mods [0] werden allmählich unterstützt, aber bei der Auswertung (libtorch-Seite) von TorchScript ist ein Fehler aufgetreten. (Der Ausdruck ist wiegetattr (xxx, 10). Ich muss etwas länger warten (was zur Laufzeit nicht analysiert werden kann).

Darüber hinaus wird die umgekehrte Iteration mit "umgekehrt" beim Iterieren von nn.ModuleList nicht unterstützt.

print, assert

In TorchScript funktionieren print und assert auch in TorchScript (möglicherweise nicht in der Spur). Es kann verwendet werden, um eine Nachricht zum Debuggen zu senden.

Läuft das Skript in JIT?

Wenn es per Skript ausgeführt wird, möchten Sie einige Verarbeitungen weglassen. Wenn Keine, aber keine angenommen wird, ist der Typ beliebig, sodass Sie nicht mit "Optional [T]" tippen können, sodass die Verarbeitung aufgeteilt wird. Ich habe einen Fall, den ich will.

torch.jit.is_scripting () bestimmt, ob das Skript zur Laufzeit ausgeführt (von libtorch ausgeführt) wird, sodass nicht bestimmt werden kann, ob es verfolgt (kompiliert) wird.

Es wäre schön, wenn es einige Dekorateure gäbe, aber es scheint keine aktuelle Situation zu geben.

Daher scheint es nicht möglich zu sein, funktionsweise zwischen Python und TorchScript zu wechseln. Wie Sie in der Torchscript-Dokumentation sehen können,

@torch.jit.ignore
def forward_pytorch():
  ...

def forward_for_torchscript():
  ...

def forward():
  if torch.jit.is_scripting():
    forward_for_torchscript()
  else
    foward_pytorch()

Da der Ausdruck (Anweisung) selbst das Ziel der Ablaufverfolgung ist, kann er bei Verwendung von Code mit numpy () usw. nicht kompiliert werden, und es tritt ein Fehler auf. Sie müssen wie oben beschrieben funktionieren und den mit pytorch (+ numpy) ausgeführten Code nach @ torch.jit.ignore migrieren (da @ torch.jit.unused kompiliert werden muss).

_Flatten_parameters () in nn.RNN

Das intern verwendete GeneratorExp unterstützt TorchScript nicht. Hiermit können Sie das Speicherlayout für die GPU anpassen, damit Sie es ignorieren können (löschen Sie den Code).

Andere

Für nicht verwendet und ignoriert wird "Weiterleiten" definiert, dies dient jedoch zu Lernzwecken und kann verwendet werden, wenn Sie es in TorchScript ignorieren möchten.

Der Unterschied zwischen unbenutzt und ignorieren besteht darin, dass unbenutzt beim Aufrufen einer Methode eine Ausnahme auslöst, beim Aufrufen einer Methode jedoch ignoriert. Grundsätzlich scheint es besser, unbenutzte zu verwenden.

F.pad(x, [0, 0, maxlen - m.size(2), 0])
         ^^^^^^^^^^^^^^^^^^^^^

Es wurde nicht als "List [int]" vom Typ abgeleitet (M ist torch.Tensor). Es wurde gelöst, indem explizit eine Variable vom Typ int erstellt wurde.

.numpy()

Es scheint, dass .numpy () nicht verwendet werden kann. ZB x.cpu (). Data.numpy (). vielleicht...? Es ist auch wünschenswert, die numpy-Funktion in dem zu verfolgenden Code nicht zu verwenden.

T.B.W.

Rückgabetyp des Eintrags "forward"

Es scheint gut, den Typ, der von "forward" des Modells zurückgegeben wird, das der Eintrag sein wird, explizit anzugeben. Dies soll es einfacher machen zu verstehen, um welchen Typ es sich bei der Ausführung auf der C ++ - Seite handelt. (Wenn die Typen nicht übereinstimmen, wird zur Laufzeit eine Zusicherung ausgegeben.)

Wenn nur ein Tensor zurückgegeben wird, kann er als "torch :: Tensor" behandelt werden.

Wenn Sie mehrere Tensoren zurückgeben möchten, ist dies Tupel,

model.forward(inputs).toTuple()

Wird besorgt.

TODO


def myfun(x, activation = None):
  if activation:
    x = activation(x)

  return x

myfun(activation=torch.relu)

Was soll ich tun, wenn ich so etwas wie eine beliebige Funktion oder Keine ausführen möchte?

class Mod:
  def forward(self, x, alpha=1.0):
    ...

class Model:
  def __init__(self):
    self.mod = Mod()

  def forward(self, x):
    self.mod.forward(x)
    ...

Es gibt ein optionales Argument in der Weiterleitung der Klasse, das intern wie in aufgerufen wird. Soll ich es löschen, wenn ich es nicht benutze?

Recommended Posts

Geben Sie Notizen zu Python-Skripten ein, um das PyTorch-Modell in C ++ mit libtorch auszuführen
So verpacken Sie C in Python
Konvertieren Sie in PyTorch geschriebenes Python-Skript mit PyInstaller in exe
Versuchen Sie, sich mit Python bei qiita anzumelden
WEB-Scraping mit Python (für persönliche Notizen)
Memo, um nach KPI mit Python zu fragen
Anmerkung von nfc.ContactlessFrontend () von nfcpy von Python
Tipps zum Umgang mit Binärdateien in Python
Geben Sie Anmerkungen für Python2 in Stub-Dateien ein!
So arbeiten Sie mit BigQuery in Python
Verarbeiten Sie mehrere Listen mit for in Python
[Mit Kommentar] Löse Fizz Buzz (entspricht Paiza Rang C) mit Python
So betreiben Sie die Zeitstempelstation in Python
Eine Einführung in Python für C-Sprachprogrammierer
Hinweise für Python-Anfänger mit Erfahrung in anderen Sprachen 12 (+1) Elemente nach Funktion
Hinweise von der Installation von Homebrew bis zum Erstellen einer Anaconda-Umgebung für Python mit pyenv
Eine verwirrende Geschichte mit zwei Möglichkeiten, XGBoost in Python + zu implementieren
Auf der Suche nach einer effizienten Möglichkeit, eine Docker-Datei mit Python mit Gedichten zu schreiben
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 11 und 12 Einführung in Pandas Matplotlib
Verwendung der C-Bibliothek in Python
[REAPER] Wie man Reascript mit Python spielt
So generieren Sie eine Sequenz in Python und C ++
Konvertieren Sie PDFs mit Python in Massenbilder
Wickeln Sie C mit Cython für Python ein
Melden Sie sich mit Selenium Python bei Yahoo Business an
Boost.NumPy Tutorial zum Erweitern von Python in C ++ (Übung)
Versuchen Sie, RPN mit Python zu berechnen (für Anfänger)
Hinweise zur Implementierung einer einfachen Co-Filterung in Python
Wie man tkinter mit Python in Pyenv benutzt
Wrap C ++ mit Cython zur Verwendung von Python
Wie man mit dem Datum / Uhrzeit-Typ in Pythons SQLite3 umgeht
[Einführung für Anfänger] Umgang mit MySQL mit Python
Einstellungen für den Einstieg in MongoDB mit Python
Python C ++ Notizen
[Für Anfänger von Wettkampfprofis] Ich habe versucht, 40 AOJ "ITP I" -Fragen mit Python zu lösen
C / Python> Lesen Sie den Wert fwrite () in C in Python> v0.1: 1 Wert / v0.2: 3 Werte / v0.3: entspricht size_t / v0.4: Doppelkomplextyp lesen
[Für Anfänger] Web-Scraping mit Python "Greifen Sie auf die URL auf der Seite zu, um den Inhalt abzurufen."
Ein Tool zum Erstellen von Maskenbildern für ETC in Python
[Für Anfänger] Wie man den Befehl say mit Python benutzt!
So konvertieren / wiederherstellen Sie einen String mit [] in Python
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
So führen Sie eine Hash-Berechnung mit Salt in Python durch
Spezifischer Beispielcode für die Arbeit mit SQLite3 in Python
Erklären Sie ausführlich, wie Sie mit Python einen Sound erzeugen
C-Sprache, Java, Python-Benchmarks mit Primfaktorisierung
So führen Sie Python im virtuellen Raum aus (für MacOS)
So führen Sie Tests zusammen mit Python unittest aus
VS-Code-Einstellungen für die Entwicklung in Python mit Abschluss
Versuchen Sie, Python mit pybind11 in ein C ++ - Programm einzubetten
Konvertieren Sie das Bild in .zip mit Python in PDF
Super Primer für Python-Erste Schritte mit Python3.5 in 3 Minuten
Python - Hinweise beim Konvertieren vom Typ str in den Typ int
[Einführung in Python] Hochgeschwindigkeits-Einführung in Python für vielbeschäftigte C ++ - Programmierer
Ich war süchtig danach, 2020 mit Selen (+ Python) zu kratzen
Vom Kauf eines Computers bis zur Ausführung eines Programms auf Python
Für diejenigen, die Python mit vim schreiben möchten