A Spark képességeinek bővítése az MLflow-val

Helló, Habrovčanok. Ahogy már írtuk, ebben a hónapban az OTUS két gépi tanulás tanfolyamot indít, nevezetesen alapfokú és haladó. Ennek kapcsán továbbra is megosztjuk a hasznos anyagokat.

Ennek a cikknek a célja, hogy bemutassa az első tapasztalatainkat a MLflow.

témában. Kezdjük a nyomkövető szerverével, és feljegyezzük a kutatás minden iterációját. Ezután megosztjuk a Spark és az MLflow UDF-vel való összekapcsolásának tapasztalatait. MLflow Alpha Health

Környezet

1cloud gépi tanulást és mesterséges intelligenciát alkalmaz, hogy lehetőséget adjon az embereknek az egészségük és jólétük kezelésére. Ezért a gépi tanulási modellek képezik az adatfeldolgozó termékeink alapját, és ezért vonzott minket az MLflow – egy nyílt forráskódú platform, amely a gépi tanulás életciklusának minden aspektusát lefedi. Az MLflow fő célja, hogy egy további réteget biztosítson a gépi tanulás fölött, amely lehetővé teszi az adat tudósok számára, hogy szinte bármely gépi tanulási könyvtárral dolgozzanak (

MLflow

h2okeras, mleap, pytorch, sklearn, tensorflow és ), új szintre emelve a munkájukat.Az MLflow három komponenst biztosít:

Nyomkövetés

  • – kísérletek rögzítése és lekérdezése: kód, adatok, konfiguráció és eredmények. Nagyon fontos nyomon követni a modell létrehozásának folyamatát. – Csomagolási forma bármely platformon való futtatáshoz (például,
  • Projects SageMaker Modellek)
  • – közös formátum a modellek különböző telepítési eszközökbe való küldésére. Az MLflow (a cikk írásakor alpha verzióban) egy nyílt forráskódú platform, amely lehetővé teszi a gépi tanulás életciklusának kezelését, beleértve a kísérleteket, újrahasználást és telepítést.

Az MLflow beállítása

Az MLflow használatához először be kell állítani az egész Python környezetet, ehhez a

PyEnv használjuk. (A Python telepítéséhez Mac-en nézz be ). Így létrehozhatunk egy virtuális környezetet, ahová telepítjük az összes szükséges könyvtárat. ide``` pyenv install 3.7.0 pyenv global 3.7.0 # Használja a Python 3.7-et mkvirtualenv mlflow # Hozzon létre egy virtuális környezetet Python 3.7-tel workon mlflow ```

Telepítjük a szükséges könyvtárakat.

``` pip install mlflow==0.7.0 Cython==0.29 numpy==1.14.5 pandas==0.23.4 pyarrow==0.11.0 ```

Megjegyzés: a PyArrow-t használjuk olyan modellek futtatására, mint az UDF. A PyArrow és a Numpy verzióját meg kellett javítani, mivel az utolsó verziók konfliktusba kerültek egymással.

Megjegyzés: PyArrow-t használunk olyan modellek, mint az UDF futtatására. A PyArrow és a Numpy verziókat ki kellett javítani, mivel a legújabb verziók konfliktusban voltak egymással.

Indítjuk a Tracking UI-t

Az MLflow Tracking lehetővé teszi számunkra, hogy naplózni és lekérdezni tudjuk a kísérleteket Python segítségével, és REST API. Ezen kívül meghatározhatjuk, hol tároljuk a modell artefaktumokat (localhost, Amazon S3, Azure Blob Storage, Google Cloud Storage vagy SFTP-szerver). Mivel az Alpha Health-nél AWS-t használunk, az artefaktumok tárolására az S3-at választjuk.

# Running a Tracking Server
mlflow server 
    --file-store /tmp/mlflow/fileStore 
    --default-artifact-root s3://<bucket>/mlflow/artifacts/ 
    --host localhost
    --port 5000

Az MLflow javasolja a tartós fájltároló használatát. A fájltároló az a hely, ahol a szerver tárolni fogja a futások és kísérletek metaadatait. A szerver indításakor győződjön meg róla, hogy egy tartós fájltárolóra mutat. Itt a kísérlethez egyszerűen használni fogjuk /tmp.

Ne feledje, hogy ha az mlflow szervert szeretnénk használni régi kísérletek futtatásához, akkor azoknak jelen kell lenniük a fájltárolóban. Azonban enélkül is használhatjuk őket az UDF-ben, mivel csak a modellhez szükséges útvonalra van szükségünk.

Megjegyzés: Vegye figyelembe, hogy a Tracking UI-nak és a modell kliensnek hozzáféréssel kell rendelkeznie az artefaktum helyéhez. Tehát függetlenül attól, hogy a Tracking UI egy EC2 példányban található, a MLflow helyi indításakor a gépnek közvetlen hozzáféréssel kell rendelkeznie az S3-hoz, hogy az artefaktum modellek írását elvégezhesse.

A Spark képességeinek bővítése az MLflow-val
A Tracking UI az artefaktumokat egy S3 vödörben tárolja

Modellek indítása

Amint a Tracking-szerver működik, elkezdhetjük a modellek tanítását.

Példaként a bor MLflow példájának módosítását fogjuk alkalmazni Sklearn.

MLFLOW_TRACKING_URI=http://localhost:5000 python wine_quality.py 
  --alpha 0.9
  --l1_ration 0.5
  --wine_file ./data/winequality-red.csv

Ahogy már említettük, az MLflow lehetővé teszi a paraméterek, metrikák és modell artefaktumok naplózását, hogy nyomon követhessük, hogyan fejlődnek iterációk során. Ez a funkció rendkívül hasznos, mivel így képesek vagyunk reprodukálni a legjobb modellt, akár a Tracking-szerverhez fordulva, akár a git commitok logját felhasználva megérteni, hogy melyik kód hajtotta végre a szükséges iterációt.

with mlflow.start_run():

    ... model ...

    mlflow.log_param("source", wine_path)
    mlflow.log_param("alpha", alpha)
    mlflow.log_param("l1_ratio", l1_ratio)

    mlflow.log_metric("rmse", rmse)
    mlflow.log_metric("r2", r2)
    mlflow.log_metric("mae", mae)

    mlflow.set_tag('domain', 'wine')
    mlflow.set_tag('predict', 'quality')
    mlflow.sklearn.log_model(lr, "model")

A Spark képességeinek bővítése az MLflow-val
Bor iterációk

A modell szerveroldala

A tracking server MLflow, launched using the command "mlflow server", has a REST API for tracking runs and recording data in the local file system. You can specify the address of the tracking server using the environment variable "MLFLOW_TRACKING_URI" and the MLflow tracking API will automatically connect to the tracking server at this address to create/retrieve run information, log metrics, etc.

Forrás: Docs// Running a tracking server

To provide the model with a server, we will need a running tracking server (see the launch interface) and the model's Run ID.

A Spark képességeinek bővítése az MLflow-val
Run ID

# Serve a sklearn model through 127.0.0.0:5005
MLFLOW_TRACKING_URI=http://0.0.0.0:5000 mlflow sklearn serve 
  --port 5005  
  --run_id 0f8691808e914d1087cf097a08730f17 
  --model-path model

To serve models using the MLflow serve functionality, we need access to the Tracking UI to obtain information about the model simply by specifying --run_id.

Once the model is connected to the Tracking server, we can obtain a new endpoint for the model.

# Query Tracking Server Endpoint
curl -X POST 
  http://127.0.0.1:5005/invocations 
  -H 'Content-Type: application/json' 
  -d '[
	{
		"fixed acidity": 3.42, 
		"volatile acidity": 1.66, 
		"citric acid": 0.48, 
		"residual sugar": 4.2, 
		"chloridessssss": 0.229, 
		"free sulfur dsioxide": 19, 
		"total sulfur dioxide": 25, 
		"density": 1.98, 
		"pH": 5.33, 
		"sulphates": 4.39, 
		"alcohol": 10.8
	}
]'

> {"predictions": [5.825055635303461]}

Running models from Spark

Although the Tracking server is powerful enough to serve models in real-time, training, and using the serve functionality (source: mlflow // docs // models # local), applying Spark (batch or streaming) is an even more powerful solution due to its distributed nature.

Imagine that you just performed training offline and then applied the resulting model to all your data. This is where Spark and MLflow can shine.

Installing PySpark + Jupyter + Spark

Forrás: Get started PySpark — Jupyter

To show how we apply MLflow models to Spark dataframes, we need to set up collaboration between Jupyter notebooks and PySpark.

Start by installing the latest stable version Apache Spark:

cd ~/Downloads/
tar -xzf spark-2.4.3-bin-hadoop2.7.tgz
mv ~/Downloads/spark-2.4.3-bin-hadoop2.7 ~/\nln -s ~/spark-2.4.3-bin-hadoop2.7 ~/spark`

Install PySpark and Jupyter in a virtual environment:

pip install pyspark jupyter

Set environment variables:

export SPARK_HOME=~/spark
export PATH=$SPARK_HOME/bin:$PATH
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS="notebook --notebook-dir=${HOME}/Projects/notebooks"

Defining notebook-dir, we will be able to store our notebooks in the desired folder.

Launching Jupyter from PySpark

Since we managed to set up Jupyter as the PySpark driver, we can now launch Jupyter notebook in the context of PySpark.

(mlflow) afranzi:~$ pyspark
[I 19:05:01.572 NotebookApp] sparkmagic kiterjesztés engedélyezve!
[I 19:05:01.573 NotebookApp] Jegyzetfüzetek kiszolgálása a helyi könyvtárból: /Users/afranzi/Projects/notebooks
[I 19:05:01.573 NotebookApp] A Jupyter Jegyzetfüzet a következő címen fut:
[I 19:05:01.573 NotebookApp] http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745
[I 19:05:01.573 NotebookApp] Használja a Control-C billentyűkombinációt a szerver leállításához és az összes kernel leállításához (két alkalommal a megerősítés kihagyásához).
[C 19:05:01.574 NotebookApp]

    Másolja/beilleszti ezt az URL-t a böngészőjébe, amikor először csatlakozik,
    hogy bejelentkezzen egy tokennel:
        http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745

A Spark képességeinek bővítése az MLflow-val

Ahogy azt már említettük, az MLflow lehetőséget biztosít a modell artefaktumainak S3-ba való naplózására. Amint megvan a kiválasztott modell, lehetőségünk nyílik arra, hogy importáljuk azt UDF-ként a következő modul segítségével: mlflow.pyfunc.

import mlflow.pyfunc

model_path = 's3:///mlflow/artifacts/1/0f8691808e914d1087cf097a08730f17/artifacts/model'
wine_path = '/Users/afranzi/Projects/data/winequality-red.csv'
wine_udf = mlflow.pyfunc.spark_udf(spark, model_path)

df = spark.read.format("csv").option("header", "true").option('delimiter', ';').load(wine_path)
columns = [ "fixed acidity", "volatile acidity", "citric acid",
            "residual sugar", "chlorides", "free sulfur dioxide",
            "total sulfur dioxide", "density", "pH",
            "sulphates", "alcohol"
          ]
          
df.withColumn('prediction', wine_udf(*columns)).show(100, False)

A Spark képességeinek bővítése az MLflow-val
PySpark – Bor-minőség előrejelzések kimenete

Eddig arról beszéltünk, hogyan tudjuk használni a PySparkot az MLflow-val, míg az összes boradat készletén a minőség előrejelzése zajlik. De mi a teendő, ha a Python MLflow modulokat Scala Spark-ból szeretnénk használni?

Teszteltük ezt, megosztva a Spark kontextust Scala és Python között. Tehát regisztráltuk az MLflow UDF-et Pythonban, és használtuk Scala-ból (igen, nem a legjobb megoldás, de ez van).

Scala Spark + MLflow

Ehhez a példához hozzáadjuk a Toree Kernel-t a meglévő Jupiterhez.

Spark + Toree + Jupyter telepítése

pip install toree
jupyter toree install --spark_home=${SPARK_HOME} --sys-prefix
jupyter kernelspec list
```
```
Elérhető kernellel:
  apache_toree_scala    /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/apache_toree_scala
  python3               /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/python3
```

Ahogy az a csatolt notebookból látszik, az UDF-et együtt használják Spark és PySpark. Reméljük, hogy ez a rész hasznos lesz azok számára, akik szeretik a Scalát és szeretnék telepíteni a gépi tanulási modelleket a gyakorlatban.

import org.apache.spark.sql.functions.col
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.{Column, DataFrame}
import scala.util.matching.Regex

val FirstAtRe: Regex = "^_".r
val AliasRe: Regex = "[\s_.:@]+".r

def getFieldAlias(field_name: String): String = {
    FirstAtRe.replaceAllIn(AliasRe.replaceAllIn(field_name, "_"), "")
}

def selectFieldsNormalized(columns: List[String])(df: DataFrame): DataFrame = {
    val fieldsToSelect: List[Column] = columns.map(field =>
        col(field).as(getFieldAlias(field))
    )
    df.select(fieldsToSelect: _*)
}

def normalizeSchema(df: DataFrame): DataFrame = {
    val schema = df.columns.toList
    df.transform(selectFieldsNormalized(schema))
}

FirstAtRe = ^_
AliasRe = [s_.:@]+

getFieldAlias: (field_name: String)String
selectFieldsNormalized: (columns: List[String])(df: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
normalizeSchema: (df: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
Out[1]:
[s_.:@]+
In [2]:
val winePath = "~\/Research\/mlflow-workshop\/examples\/wine_quality\/data\/winequality-red.csv"
val modelPath = "\/tmp\/mlflow\/artifactStore\/0\/96cba14c6e4b452e937eb5072467bf79\/artifacts\/model"

winePath = ~\/Research\/mlflow-workshop\/examples\/wine_quality\/data\/winequality-red.csv
modelPath = \/tmp\/mlflow\/artifactStore\/0\/96cba14c6e4b452e937eb5072467bf79\/artifacts\/model
Out[2]:
\/tmp\/mlflow\/artifactStore\/0\/96cba14c6e4b452e937eb5072467bf79\/artifacts\/model
In [3]:
val df = spark.read
              .format("csv")
              .option("header", "true")
              .option("delimiter", ";")
              .load(winePath)
              .transform(normalizeSchema)

df = [fixed_acidity: string, volatile_acidity: string ... 10 more fields]
Out[3]:
[fixed_acidity: string, volatile_acidity: string ... 10 more fields]
In [4]:
%%PySpark
import mlflow
from mlflow import pyfunc

model_path = "\/tmp\/mlflow\/artifactStore\/0\/96cba14c6e4b452e937eb5072467bf79\/artifacts\/model"
wine_quality_udf = mlflow.pyfunc.spark_udf(spark, model_path)

spark.udf.register("wineQuality", wine_quality_udf)
Out[4]:
<function spark_udf..predict at 0x1116a98c8>
In [6]:
df.createOrReplaceTempView("wines")
In [10]:
%%SQL
SELECT 
    quality,
    wineQuality(
        fixed_acidity,
        volatile_acidity,
        citric_acid,
        residual_sugar,
        chlorides,
        free_sulfur_dioxide,
        total_sulfur_dioxide,
        density,
        pH,
        sulphates,
        alcohol
    ) AS prediction
FROM wines
LIMIT 10
Out[10]:
+-------+------------------+
|quality|        prediction|
+-------+------------------+
|      5| 5.576883967129615|
|      5|  5.50664776916154|
|      5| 5.525504822954496|
|      6| 5.504311247097457|
|      5| 5.576883967129615|
|      5|5.5556903912725755|
|      5| 5.467882654744997|
|      7| 5.710602976324739|
|      7| 5.657319539336507|
|      5| 5.345098606538708|
+-------+------------------+

In [17]:
spark.catalog.listFunctions.filter('name like "%wineQuality%").show(20, false)

+-----------+--------+-----------+---------+-----------+
|name       |database|description|className|isTemporary|
+-----------+--------+-----------+---------+-----------+
|wineQuality|null    |null       |null     |true       |
+-----------+--------+-----------+---------+-----------+

Következő lépések

Bár a cikk írásának idején az MLflow alfa verzióban van, ígéretesnek tűnik. Az egyetlen lehetőség, hogy több gépi tanulási keretrendszert futtathatunk és használhatunk egyetlen végpontból, új szintre emeli az ajánlási rendszereket.

Továbbá, az MLflow közel hozza a Data mérnököket és az adatelemző szakembereket, létrehozva köztük egy közös réteget.

Az MLflow ezen kutatása után biztosak vagyunk benne, hogy tovább fogunk lépni és használni fogjuk azt a Spark pipelinjeinkben és ajánlórendszerekben.

Jó lenne, ha az adattárhelyzést az adatbázissal szinkronizálnánk a fájlrendszer helyett. Így több végpontot kellene kapnunk, amelyek ugyanazt az adattárhelyzést használják. Például több példány használata. Presto és Athena ugyanazzal a Glue metastore-val.

Összefoglalva, szeretnénk köszönetet mondani az MLFlow közösségnek, hogy érdekesebbé teszik a munkánkat az adatokkal.

Ha játszol az MLflow-val, ne habozz írni nekünk és mesélni, hogyan használod, és különösen, ha éles környezetben is használod.

Tudd meg többet a kurzusokról:
Gépi tanulás. Alapkurzus
Gépi tanulás. Haladó kurzus

Tovább olvasva:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster