Schlangenbeschwörer:
Externe Skripte in .net-Anwendungen

Wie lassen sich externe Skripte in eine .net-Anwendung integrieren?

Nicht immer ist es möglich oder sinnvoll Anwendungen „aus einem Guss“ bzw. in einer Programmiersprache zu entwickeln oder zu betreiben. Unabhängig vom Konzept der Modularisierung, sollte, meiner Meinung nach, auch immer der Ansatz der „Best Available Technology (BAT)“ (im Deutschen wohl am besten zu übersetzen mit „Stand der Technik“) berücksichtigt werden. Viel zu häufig wird – gerade bei Konzeptionierung neuer Anwendungen – die Wahl der verwendeten Sprachen, Frameworks und Techniken darauf basierend getroffen, welche Kenntnisse der jeweilige Dienstleister anbieten kann und nicht welche Auswahl für die Lösung einer bestimmten Fragestellung am sinnvollsten wäre. Auch kann die Kombination relativ junger Technologien mit bereits etablierten Frameworks eine Herausforderung darstellen. Dazu ein konkretes Beispiel:

Eine bereits existierende, auf .net basierende Anwendung soll um Features aus dem Bereich Deep Learning erweitert werden. Neben den .net-Entwicklern, arbeiten an diesem Projekt natürlich auch Data Scientists mit, die u.a. für die Entwicklung der künstlichen neuronalen Netzwerke zuständig sind – dies aber natürlich in Python tun. Die Aufgabe besteht nun darin diese beiden Technologien zu kombinieren. Was also tun?

Option 1: Warum (überhaupt) Python?

Mit ML.Net steht ein Framework aus dem Hause Microsoft zur Verfügung, mit dessen Hilfe sich verhältnismäßig einfach machine learning-Lösungen in C# erstellen lassen. Die Daten-Wissenschaftler würden also (versuchen) ihre Konzepte in einer Sprache zu realisieren, die eine Integration unnötig macht und ggf. im Rahmen eines kompilierten Assemblies recht einfach in die bestehende Anwendung integriert werden kann.

Unabhängig davon ob sich die betroffene Fachgruppe darüber freuen würde bei der Wahl der zu verwendenden Tools eingeschränkt zu werden, gibt es einige Gründe warum sich Python und damit verbundene Frameworks im Bereich machine learning durchgesetzt haben. Mit dieser Lösung würde man sich ggf. einen Sonderfall ins Haus holen, bei dem man nur mit deutlich erhöhtem Aufwand auf dem aktuellen Stand der Technik bleiben und somit gegen den BAT-Grundsatz verstoßen.

Option 2: Python in .net interpretieren

Es gibt eine Reihe recht guter Projekte, wie z.B. Python.net oder IronPython, die Bibliotheken bereitstellen um Python-Skripe in .net-Anwendungen auszuführen und zu interpretieren. Mithilfe verschiedener Injection-Szenarien ist es sogar möglich Variablen und Funktionen bereitzustellen, die üblicherweise nicht Bestandteil der (Core-)Python-Umgebung sind.

Leider kommen diese Interpreter gerade bei wissenschaftlichen Bibliotheken an ihre Grenzen. Um z.B. aufwändige mathematische Operationen oder (wissenschaftliche) Berechnungen durchführen zu können, stellen Frameworks wie Anaconda zusätzliche Funktionen und Bibliotheken bereit, die bei den genannten Interpretern nicht zur Verfügung stehen. Somit stellt dies nur eine engschränkt nutzbare Lösung dar.

Option 3: Die Python-Skripte als externe Prozesse ausführen

In einem Artikel in der dotnetpro vom März 2019 wird – neben einem Beispiel für die Verwendung von IronPython – genau dieses Szenario beschrieben, mit dem Lösungsansatz das Python-Skript mithilfe der .net-eigenen Process-Klasse aufzurufen, die Ausgabe zu überwachen und in der Core-Anwendung abzuwarten bis das Skript vollständig durchlaufen wurde bis die entstandenen Daten weiterverarbeitet werden.

Natürlich funktioniert dies nicht nur für Python-Skripte, sondern für alle Arten externer Skripte und Anwendungen – und das ganz ohne z.B. tiefgreifende Anpassungen an der Original-Anwendung durchführen zu müssen. Möchte man jedoch nicht jedes mal aufs Neue

  • die Process-Parameter, inkl. ggf. notwendiger für das externe Skript oder die Anwendung notwendige Kommandozeilenparameter, konfigurieren
  • den Ablauf überwachen und auf auftretende Output- oder Fehler-Events reagieren

empfiehlt sich die Kapselung in eine dafür optimierte Klasse.

Mit der ManagedProcess-Klasse stellt das aktuelle Release (1.4.1) des BYTES.NET-Frameworks genau eine derartige Kapselung bereit.

Private Async Sub RunScript()

    'create the process class instance
    Dim process As ManagedProcess = New ManagedProcess

    With process
        .Executable = "C:\Windows\System32\cmd.exe"
        .Arguments = {"/c " & """" & "%InstallationDir%..\..\..\..\samples\Scripts\LongRunningSampleScript.cmd" & """" & " TestValue"}
        .ShowUI = Me.ShowUI
    End With

    'handle the events
    AddHandler _process.OutputReceived, Sub(data As LogEntry)
                                            _log.Add(data)
                                        End Sub

    AddHandler _process.Exited, Sub(code As Integer)
                                    MsgBox("Process finished with: " & code)
                                End Sub

    Await _process.RunAsync()

End Function

Mithilfe weniger Zeilen Code ist es z.B. möglich ein Skript (mithilfe eines beliebigen externen Interpreters) auszuführen und sowohl auf Rückgaben zu reagieren als auch auf den Abschluss des Runs zu warten. Zudem bietet die Klasse die Vorteile, dass

  • mit RunAsync bereits eine Methode bereitgestellt wird, die die Nutzeroberfläche während (eines beliebig langen) Durchlaufs nicht blockiert
  • ein einheitliches Event (OutputReceived) zur Verfügung steht, dass die Verarbeitung der Rückgaben ermöglicht; Fehler können mithilfe des InformationLevel des zurückgegebenen LogEntry-Objekts identifiziert werden
  • relative Pfade – z.B. mithilfe der generischen %InstallationDir%-Variable – für den Interpreter-Pfad unterstützt werden, so dass auch Interpreter wie z.B. Anaconda in einer portable-Version (z.B. als Bestandteil eines Installationspakets) genutzt werden können

Ein detailliertes Beispiel für den Einsatz mit Windows-Batch (*.cmd) und Python (*.py) ist im zugehörigen Repository auf Github verfügbar.

Der Geist in der Grafikkarte:
NVIDIAs GPC2020

Im Rahmen der GPC 2020 kommen Spezialisten aus allen Fachbereichen zusammen – in diesem Jahr online

Aufgrund der durch das COVID-19 hervorgerufenen, geänderten Rahmenbedingungen, findet NVIDIAs diesjährige GPU Technology Conference als digitales Online-Event statt, anstatt wie ursprünlich geplant in San Jose. Da die Anmeldung kostenfrei ist, kommt man auf diese Weise in den Genuss teils hochspezialisierter Fachvorträge, ganz ohne Ausgaben für Reise oder Hotel.

Neben einer Vielzahl von Kursen, Workshops und Postern zu den verschiedensten Anwendungsfällen und Teilaspekten von High Performance Computing (HPC) und Artifical Intelligence (AI), werden auf der GTC Tools und Lösungen präsentiert, die die Entwicklung und Integration von Deep Learning (DL)-Ansätzen weiter vereinfachen und somit noch massentauglicher machen sollen. Um dieses Ziel zu erreichen, findet man im Session-Katalog auch immer wieder Vorträge, wie der von Will Ramey, in dem Grundlagen zum Thema künstliche Intelligenz erklärt werden

Doch weshalb betreibt eine Firma, die die meisten Endanwender lediglich als Hersteller von Grafikkarten kennen, einen derartigen Aufwand?

Die Antwort ist recht einfach: Um Grafikkarten zu verkaufen.

Zugegeben, diese Darstellung ist sehr stark vereinfacht, jedoch verdiente NVIDIA, nach Zahlen vom März 2020, etwa 9,5 Milliarden US-Dollar mit dem Verkauf von Graphics Processing Units (GPUs) und lag damit im Q4 2019 deutlich vor dem Mitbewerber AMD.

Warum aber profitiert gerade ein Hersteller von Grafikkarten vom Trendthema AI – und nicht Firmen wie Intel oder AMD, deren Prozessor-Chips (CPU) in praktisch jedem Heimcomputer und Server verbaut sind?

Technisch gesehen ist auch diese Antwort recht einfach: Grundsätzlich basieren die meisten DL-Modelle auf der gewichteten, stufenweisen Verarbeitung von Parametern. Tim Dettmers hat das Grundkonzept hinter Deep Learning in einem Artikel im NVIDIA Developer Blog zusammengefasst.

Mathematisch wird dies über sogenannte Matrix-Multiplikationen abgebildet – und genau da kommt der Vorteil der GPU gegenüber der CPU zum Tragen: Grafikkarten wurden ursprünglich genau dazu entwickelt diese mathematischen Operationen möglichst performant durchzuführen. Im direkten Vergleich kann bereits eine GPU deutlich mehr Bilder pro Sekunde verarbeiten als ein Verbund aus 5 CPUs – und die Leistungsfähigkeit der GPUs hat sich in den letzten Jahren immer weiter erhöht.

Auch wenn die prominentesten Beispiele für Deep Learning oder AI aus den Bereichen der Bildverarbeitung oder autonomen Fahren kommen, sorgt die Zunahme sogenannter Edge Devices als Bestandteil des IoT dafür, dass immer größere Datenmengen zu verarbeiten, (vor) zu klassifizieren und für (de-)zentrale Erfassungs- und Verarbeitungssysteme aufzubereiten sind. Um dies zu realisieren, genügen traditionelle, regelbasierte Systeme of nicht mehr. Ein Ansatz zur Lösung dieser Herausforderungen is Deep Learning oder AI – dazu bedarf es jedoch neben der passenden Hard- und Software auch Wissenschaftler und Spezialisten die in der Lage sind mit diesen Systemen zu arbeiten.