Razširitev Spark z MLflow

Pozdravljeni, Khabrovci. Kot smo že pisali, ta mesec OTUS lansira dva tečaja o strojnem učenju naenkrat, in sicer bazo и napredno. V zvezi s tem še naprej delimo uporabno gradivo.

Namen tega članka je govoriti o naši prvi izkušnji z MLflow.

Začeli bomo s pregledom MLflow iz svojega strežnika za sledenje in podaljša vse ponovitve študije. Nato bomo delili izkušnjo povezovanja Spark z MLflow z uporabo UDF.

Kontekst

Smo notri Alfa zdravje uporabljamo strojno učenje in umetno inteligenco, da bi ljudem omogočili skrb za svoje zdravje in dobro počutje. Zato so modeli strojnega učenja jedro podatkovnih izdelkov, ki jih razvijamo, in zakaj je MLflow, odprtokodna platforma, ki pokriva vse vidike življenjskega cikla strojnega učenja, pritegnila našo pozornost.

MLflow

Glavni cilj MLflow je zagotoviti dodatno plast poleg strojnega učenja, ki bi podatkovnim znanstvenikom omogočila delo s skoraj vsako knjižnico strojnega učenja (h2o, keras, mleap, pitorha, sklearn и tensorflo), svoje delo dvigne na višjo raven.

MLflow ponuja tri komponente:

  • Sledenje – snemanje in zahteve za poskuse: koda, podatki, konfiguracija in rezultati. Zelo pomembno je slediti procesu ustvarjanja modela.
  • projekti – Oblika pakiranja za izvajanje na kateri koli platformi (npr. SageMaker)
  • Modeli je običajna oblika za predložitev modelov različnim orodjem za uvajanje.

MLflow (alfa v času pisanja) je odprtokodna platforma, ki vam omogoča upravljanje življenjskega cikla strojnega učenja, vključno s preizkušanjem, ponovno uporabo in uvajanjem.

Nastavitev MLflow

Če želite uporabljati MLflow, morate najprej nastaviti celotno okolje Python, za to bomo uporabili PyEnv (za namestitev Pythona na Mac si oglejte tukaj). Tako lahko ustvarimo virtualno okolje, kjer bomo namestili vse knjižnice, potrebne za delovanje.

```
pyenv install 3.7.0
pyenv global 3.7.0 # Use Python 3.7
mkvirtualenv mlflow # Create a Virtual Env with Python 3.7
workon mlflow
```

Namestite zahtevane knjižnice.

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

Opomba: PyArrow uporabljamo za izvajanje modelov, kot so UDF. Različici PyArrow in Numpy je bilo treba popraviti, ker sta bili najnovejši različici med seboj v nasprotju.

Zagon uporabniškega vmesnika za sledenje

MLflow Tracking nam omogoča beleženje in poizvedovanje poskusov s Pythonom in REST API. Poleg tega lahko določite, kje želite shraniti artefakte modela (localhost, Amazon S3, Azure Blob Storage, Google Cloud Storage ali strežnik SFTP). Ker pri Alpha Health uporabljamo AWS, bo S3 shramba za artefakte.

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

MLflow priporoča uporabo obstojnega pomnilnika datotek. Shranjevanje datotek je mesto, kjer bo strežnik shranjeval metapodatke o izvajanju in poskusu. Ko zaženete strežnik, se prepričajte, da kaže na trajno shrambo datotek. Tukaj bomo zaradi eksperimenta preprosto uporabili /tmp.

Upoštevajte, da če želimo uporabiti strežnik mlflow za izvajanje starih poskusov, morajo biti prisotni v shrambi datotek. Vendar bi jih tudi brez tega lahko uporabili v UDF, saj potrebujemo samo pot do modela.

Opomba: Upoštevajte, da morata imeti uporabniški vmesnik za sledenje in odjemalec modela dostop do lokacije artefakta. To pomeni, ne glede na dejstvo, da se uporabniški vmesnik za sledenje nahaja v instanci EC2, mora imeti stroj pri lokalnem izvajanju MLflow neposreden dostop do S3 za pisanje modelov artefaktov.

Razširitev Spark z MLflow
Uporabniški vmesnik za sledenje shranjuje artefakte v vedro S3

Tekaški modeli

Takoj ko se strežnik za sledenje zažene, lahko začnete usposabljati modele.

Kot primer bomo uporabili modifikacijo vina iz primera MLflow v Sklearn.

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

Kot smo rekli, vam MLflow omogoča beleženje parametrov, meritev in artefaktov modela, tako da lahko spremljate, kako se razvijajo kot iteracije. Ta funkcija je izjemno uporabna, saj nam omogoča reprodukcijo najboljšega modela tako, da stopimo v stik s strežnikom za sledenje ali razumemo, katera koda je izvedla zahtevano ponovitev z uporabo git hash dnevnikov potrditev.

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")

Razširitev Spark z MLflow
vinske ponovitve

Zadnji konec za model

Strežnik za sledenje MLflow, ki se zažene z ukazom »mlflow server«, ima API REST za sledenje izvajanj in zapisovanje podatkov v lokalni datotečni sistem. Naslov strežnika za sledenje lahko določite s spremenljivko okolja "MLFLOW_TRACKING_URI" in API za sledenje MLflow bo samodejno vzpostavil stik s strežnikom za sledenje na tem naslovu, da ustvari/dobi informacije o zagonu, meritve beleženja itd.

Vir: Dokumenti// Izvajanje strežnika za sledenje

Da bi modelu zagotovili strežnik, potrebujemo delujoč strežnik za sledenje (glejte vmesnik za zagon) in Run ID modela.

Razširitev Spark z MLflow
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

Za strežbo modelov s funkcijo serviranja MLflow potrebujemo dostop do uporabniškega vmesnika za sledenje, da dobimo informacije o modelu tako, da preprosto določimo --run_id.

Ko model vzpostavi stik s strežnikom za sledenje, lahko dobimo novo končno točko modela.

# 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]}

Tekaški modeli iz Spark

Kljub temu, da je strežnik za sledenje dovolj zmogljiv, da modele streže v realnem času, jih usposobi in uporablja funkcionalnosti strežnika (vir: mlflow // dokumenti // modeli #local), uporaba Spark (paketno ali pretočno) je zaradi distribucije še zmogljivejša rešitev.

Predstavljajte si, da ste pravkar opravili usposabljanje brez povezave in nato uporabili izhodni model za vse svoje podatke. Tukaj prideta do izraza Spark in MLflow.

Namestite PySpark + Jupyter + Spark

Vir: Začnite PySpark - Jupyter

Da pokažemo, kako uporabljamo modele MLflow za podatkovne okvire Spark, moramo nastaviti prenosne računalnike Jupyter za delo s PySpark.

Začnite z namestitvijo najnovejše stabilne različice Apache Spark:

cd ~/Downloads/
tar -xzf spark-2.4.3-bin-hadoop2.7.tgz
mv ~/Downloads/spark-2.4.3-bin-hadoop2.7 ~/
ln -s ~/spark-2.4.3-bin-hadoop2.7 ~/spark̀

Namestite PySpark in Jupyter v virtualnem okolju:

pip install pyspark jupyter

Nastavite spremenljivke okolja:

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"

Ob opredelitvi notebook-dir, bomo svoje zvezke lahko shranili v želeno mapo.

Zagon Jupytra iz PySpark

Ker smo Jupiter lahko nastavili kot gonilnik PySpark, lahko zdaj izvajamo prenosni računalnik Jupyter v kontekstu PySpark.

(mlflow) afranzi:~$ pyspark
[I 19:05:01.572 NotebookApp] sparkmagic extension enabled!
[I 19:05:01.573 NotebookApp] Serving notebooks from local directory: /Users/afranzi/Projects/notebooks
[I 19:05:01.573 NotebookApp] The Jupyter Notebook is running at:
[I 19:05:01.573 NotebookApp] http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745
[I 19:05:01.573 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 19:05:01.574 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745

Razširitev Spark z MLflow

Kot je navedeno zgoraj, MLflow zagotavlja funkcijo beleženja artefaktov modela v S3. Takoj, ko imamo izbrani model v rokah, ga imamo možnost uvoziti kot UDF s pomočjo modula mlflow.pyfunc.

import mlflow.pyfunc

model_path = 's3://<bucket>/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)

Razširitev Spark z MLflow
PySpark - Napovedovanje kakovosti vina

Do te točke smo govorili o tem, kako uporabiti PySpark z MLflow z izvajanjem napovedi kakovosti vina na celotnem naboru podatkov o vinu. Kaj pa, če morate uporabiti module Python MLflow iz Scala Spark?

To smo tudi preizkusili tako, da smo kontekst Spark razdelili med Scalo in Python. To pomeni, da smo MLflow UDF registrirali v Pythonu in ga uporabili iz Scale (ja, morda ni najboljša rešitev, ampak kar imamo).

Scala Spark + MLflow

Za ta primer bomo dodali Jedro Toree v obstoječi Jupiter.

Namestite Spark + Toree + Jupyter

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

Kot lahko vidite iz priloženega zvezka, si UDF delita Spark in PySpark. Upamo, da bo ta del koristen za tiste, ki obožujejo Scalo in želijo uvesti modele strojnega učenja v proizvodnjo.

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.<locals>.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       |
+-----------+--------+-----------+---------+-----------+

Naslednji koraki

Čeprav je MLflow v času pisanja v različici Alpha, je videti precej obetavno. Samo zmožnost izvajanja več ogrodij strojnega učenja in njihove uporabe iz ene same končne točke popelje sisteme priporočil na višjo raven.

Poleg tega MLflow zbliža podatkovne inženirje in podatkovne znanstvenike ter med njimi postavi skupno plast.

Po tem raziskovanju MLflow bomo prepričani, da ga bomo uporabili za naše cevovode Spark in sisteme priporočil.

Lepo bi bilo sinhronizirati shranjevanje datotek z bazo podatkov namesto z datotečnim sistemom. To bi nam moralo dati več končnih točk, ki lahko uporabljajo isto skupno rabo datotek. Na primer, uporabite več primerkov Presto и Athena z istim metastorem Glue.

Če povzamem, bi se rad zahvalil skupnosti MLFlow, ker je naredila naše delo s podatki bolj zanimivo.

Če se igrate z MLflow, nam lahko pišete in poveste, kako ga uporabljate, še več, če ga uporabljate v proizvodnji.

Več o tečajih:
strojno učenje. Osnovni tečaj
strojno učenje. nadaljevalni tečaj

Preberi več:

Vir: www.habr.com

Dodaj komentar