Das Trainieren von ML-Modellen und ihre Verwendung für Online-Vorhersagen in der Produktion ist keine leichte Aufgabe. Glücklicherweise gibt es immer mehr Tools und Bibliotheken, die uns bei dieser Herausforderung helfen können.
Bei der Online-Vorhersage von ML-Modellen kann man die Anforderungen an hohe Leistung und geringe Latenzzeiten erfüllen. Der Python ML-Stack ist großartig für das Training von Modellen mit einer großen Anzahl von ML-Bibliotheken, aber die Ausführungsgeschwindigkeit ist nicht die Stärke dieser Sprache. Natürlich können Sie mit verschiedenen Python-Interpretern spielen (z.B. PyPy, das JIT unterstützt - wie Java), aber ich wage zu behaupten, dass in den meisten Fällen eine Anwendung in Java schneller ist als eine Anwendung in Python. Bevor Sie irgendwelche architektonischen Entscheidungen treffen, ist es natürlich mehr als empfehlenswert, einen eigenen Benchmark durchzuführen.
Soweit ich weiß, gibt es Unternehmen, in denen Anwendungen auf Java/Scala aufgebaut sind, das Data Science Team jedoch Python verwendet. Das bringt Herausforderungen bei der Integration mit sich. Wie sollten Sie die großartigen ML-Modelle, die Ihre DSs mit Ihren Diensten erstellen, in der Produktion einsetzen? Ein beliebter Weg ist, Modelle in Container zu verpacken und sie als Microservice bereitzustellen. Aber was wäre, wenn es möglich wäre, diese Modelle direkt in Ihrer App zu verwenden?
MLeap
MLeap ist eine Bibliothek, mit der Sie Ihre ML-Pipelines serialisieren können und die eine Ausführungs-Engine für sie bereitstellt. Im Grunde können Sie also Ihre trainierten ML-Modelle in eine Datei exportieren, sie in Ihren Anwendungen wiederverwenden und brauchen keine Abhängigkeiten mehr, um Ihre Modelle zu trainieren. Wie wir in den offiziellen Dokumentationen(MLeap-Dokumentation - Gitbook) nachlesen können, werden Spark, Scikit-learn und Tensorflow unterstützt.

MLeap Serving ist ein Docker-Image, das eine gebrauchsfertige Spring Boot-App enthält: MLeap Serving - GitBook. Es bietet einen REST-Endpunkt, um Modelle hochzuladen und Vorhersagen zu treffen. Ein sehr praktisches Tool, mit dem Sie spielen oder das Sie sogar in der Produktion einsetzen können, wenn Sie keine ausgefeilten Anpassungen benötigen.
ML-Modell in Python
Lassen Sie uns ein wenig programmieren und prüfen, wie einfach es ist, MLeap zu verwenden und welche Vorteile es bringt.
Zunächst benötigen wir ein ML-Modell. Ich werde hier ein Beispiel von der Scikit-Website verwenden.
Anstatt einen einfachen Baum zu erstellen, werde ich dieses Beispiel jedoch ändern und einen Zufallswald verwenden - siehe hier
import numpy as np
import mleap.sklearn.pipeline
import mleap.sklearn.ensemble.forest
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
import time
# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))
for estimators in [1, 2, 4, 8, 16]:
# Fit regression model
regr = RandomForestRegressor(n_estimators=estimators, random_state=0)
# Definitions needed for bundle
input_features = "x"
output_vector_name = "output"
output_features = ["y"]
# Init mleap on regressor
regr.mlinit(input_features, output_vector_name, output_features)
# Create training pipeline
standard_scaler_pipeline = Pipeline([(regr.name, regr)])
# Init mleap on pipeline
standard_scaler_pipeline.mlinit()
# Fit pipeline
standard_scaler_pipeline.fit(X, y)
#Export bundle
standard_scaler_pipeline.serialize_to_bundle("/tmp", "mleap-example-" + str(estimators), True)
sum = 0
iter = 5
for j in range(iter):
start = time.perf_counter()
for i in range(100000):
standard_scaler_pipeline.predict(rng.rand(1, 1))
end = time.perf_counter()
sum += end - start
print(f"{end - start:0.4f} seconds")
print(estimators, sum / iter)
*MLeap arbeitet mit Pipelines, deshalb habe ich das Beispiel geändert und den Regressor mit der Pipeline verpackt.
Lassen Sie uns nun überprüfen, ob das Bundle existiert:
ls /tmp/mleap-example-1/
bundle.json root
Erfolg!
Die Bundle-Struktur ist recht informativ und leicht zu verstehen. Sehen Sie sich auch den folgenden Link an: mleap-docs/mleap-bundles.md unter master - combust/mleap-docs. Dort finden Sie viele Informationen über Bundles. Dokumentation ist immer Ihr bester Freund.
ML-Modell nach Scala importieren
Wir werden das Bundle aus dem Scala-Projekt wiederverwenden. Wir werden MLeap Runtime verwenden, mit dem wir Transformationen anhand von gelernten Modellen (Bundles) durchführen können. Dazu benötigen wir Abhängigkeiten:
libraryDependencies += "ml.combust.mleap" %% "mleap-runtime" % "0.17.0"
Das Laden des Pakets ist sehr einfach:
val bundle: ExtractableManagedResource\[Bundle[Transformer]] =
for (bf <- managed(BundleFile("file:/tmp/mleap-example"))) yield {
bf.loadMleapBundle().get
}
Wir müssen die Struktur der Modelleingabe erstellen:
val schema = StructType(List(StructField("x",TensorType(BasicType.Double)))).get
Als nächstes können wir die Eingabezeile vorbereiten:
val dataset = Seq(Row(DenseTensor(Array(rand.nextFloat.toDouble), List(1))))
val frame = DefaultLeapFrame(schema, dataset)
*LeapFrame ist eine Grundstruktur in MLeap.
Lassen Sie uns abschließend eine Vorhersage treffen:
println(transformer.transform(frame).get.dataset.head(1))
// output: 0.7138256817142807
Es funktioniert, brillant!
Leistungs-Benchmark
Jetzt kommt das Sahnehäubchen. Ich werde einen Leistungsvergleich durchführen, um zu prüfen, ob ich durch die Verwendung von MLeap irgendwelche Vorteile habe. Es wird ein sehr einfacher Benchmark sein, aber er sollte einen allgemeinen Überblick über die Unterschiede zwischen der Bereitstellung von Modellen mit Python und Scala geben. Wie Sie sich erinnern, habe ich dem Regressor eine Pipeline hinzugefügt, um die Ergebnisse zu verdeutlichen. Der Benchmark wird auch das Ergebnis eines Modells ohne Pipeline enthalten (damit wir sehen können, ob es einen Overhead gibt und ob dieser Overhead sinnvoll ist).
Wir haben drei Fälle:
- python regressor (ein roher Regressor, ohne Pipeline) - mit scikit
- python regressor in die pipeline gepackt - mit scikit
- scala regressor - aus dem Bundle geladen
Für jeden dieser Fälle werde ich 5 Runden durchführen, jede Runde mit 100000 Vorhersagen mit einem Regressor. Um zu prüfen, ob die Kompliziertheit des Waldes die Ergebnisse beeinflusst, werde ich das Modell mit einer unterschiedlichen Anzahl von Schätzern trainieren: {1, 2, 4, 8, 16}. Für jede Vorhersage wird eine zufällige Eingabe generiert.


Wie wir sehen, schneidet Scala besser ab als Python. Für Forest Estimator=1 benötigt Scala im Durchschnitt 100.000 Vorhersagen in etwa 0,05s, was 2 Millionen Vorhersagen pro Sekunde ergibt. Python liefert uns 4.000 Vorhersagen pro Sekunde, ist also 500 Mal langsamer als die Scala-Lösung.
Mit zunehmender Anzahl von Schätzern wird der Leistungsunterschied immer größer.
- Ich war nicht ganz präzise bei den Berechnungen und habe die Zahlen aufgerundet, da der Benchmark auf einem lokalen Rechner durchgeführt wurde. Selbst bei Verwendung gerundeter Zahlen können wir einen großen Unterschied in der Leistung der verglichenen Lösungen feststellen.
- Der Benchmark wurde mit der folgenden Hardware und dem folgenden Betriebssystem durchgeführt: Prozessor: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHzArbeitsspeicher: 40741MBetriebssystem: Ubuntu 20.04.3 LTS
MLeap und Spark ML
Das Trainieren von ML-Modellen mit Spark ist großartig, vor allem wenn Ihre Trainingssätze zu groß für den Speicher eines einzelnen Rechners sind. Auf der anderen Seite ist es viel schwieriger, ein ML-Modell zu bedienen. Natürlich können Sie dies auf eine Batch-ähnliche Weise tun, indem Sie den Spark-Job ausführen, der Vorhersagen macht und diese zur späteren Verwendung in Ihrer DB speichert. Es gibt aber ein Aber. Was ist mit der Online-Vorhersage? Das ist ein Problem, das mit Mleap gelöst werden kann. Mleap hilft Ihnen dabei, die von Spark ML trainierten Modelle in einer Datei (Bundle) zu serialisieren und später in Ihrer Anwendung zu verwenden, ohne dass Sie Spark-Abhängigkeiten haben und ohne einen Spark-Cluster.
Anwendungsfall
Kürzlich haben wir einem unserer Kunden geholfen, ein Projekt zur Klassifizierung von NSFW-Bildern mit MLeap umzusetzen. Das hat wirklich gut funktioniert, denn:
- wir haben das Open-Source ML-Modell wiederverwendet - es war nicht nötig, Zeit und Geld für das Modelltraining aufzuwenden
- Wir haben einen benutzerdefinierten Executor vorbereitet und ihn in die bestehende Infrastruktur der Client-Microservices integriert.
- Vorhersagen, die auf Bildern gemacht werden, sind extrem schnell, so dass sie online gemacht werden können.
Zusammenfassung
MLeap ist mit Sicherheit ein interessantes Tool, das Ihnen helfen kann, Ihre ML-Modelle in der Produktion einzusetzen. Vor allem, wenn Sie nach einer Möglichkeit suchen, Ihre Vorhersagen zu beschleunigen oder eine einheitliche Engine für die Erstellung von Vorhersagen mit Modellen, die mit Scikit, SparkML und TensorFlow trainiert wurden, vorbereiten möchten. Eine Sache, von der ich nicht ganz begeistert bin, ist die MLeap-Projektdokumentation, die aktueller sein und mehr Beispiele enthalten könnte.
MLeap bietet die Flexibilität, mit verschiedenen Ansätzen zu arbeiten. Sie können Container mit Ihrer Anwendung und dem ML-Modell vorbereiten und haben eine einsatzbereite Anwendung. Sie können MLeap Serving wählen und die Leistungsfähigkeit der REST-Kommunikation zum Laden/Servieren von ML-Modellen nutzen. Es ist auch möglich, einen benutzerdefinierten Server auf der Basis von MLeap Runtime vorzubereiten und Ihre Modelle mit dem folgenden Modul aus HDFS zu laden:
https://github.com/combust/mleap/blob/master/bundle-hdfs/README.md.
Es sei daran erinnert, dass MLeap eine Engine ist und keine ganze Plattform für ML-Serving. Wir werden hier also keine Unterstützung für Tools wie A/B-Tests finden.
Entdecken, Anpassen & Gewinnen!
---
Interessieren Sie sich für ML- und MLOps-Lösungen? Wie können Sie ML-Prozesse verbessern und die Lieferfähigkeit von Projekten steigern? Sehen Sie sich unsere MLOps-Demo an und melden Sie sich für eine kostenlose Beratung an.
Verfasst von
Bartosz Chodnicki
Unsere Ideen
Weitere Blogs
Contact




