Sparki laiendamine MLflow abil

Tere, Khabrovites. Nagu juba kirjutasime, käivitab OTUS sel kuul korraga kaks masinõppe kursust, nimelt alus и arenenud. Sellega seoses jätkame kasuliku materjali jagamist.

Selle artikli eesmärk on rääkida meie esimesest kogemusest MLflow.

Alustame ülevaatamist MLflow oma jälgimisserverist ja prologige kõik uuringu iteratsioonid. Seejärel jagame kogemust Sparki ühendamisest MLflow-ga UDF-i abil.

Kontekst

Me oleme sees Alfa tervis kasutame masinõpet ja tehisintellekti, et anda inimestele võimalus oma tervise ja heaolu eest hoolitseda. Seetõttu on masinõppemudelid meie arendatavate andmetoodete keskmes ja seetõttu jõudis meie tähelepanu alla MLflow, avatud lähtekoodiga platvorm, mis hõlmab masinõppe elutsükli kõiki aspekte.

MLflow

MLflow peamine eesmärk on pakkuda masinõppele lisakihti, mis võimaldaks andmeteadlastel töötada peaaegu iga masinõppe raamatukoguga (h2o, keras, mleap, pütorch, sklearn и tensorivool), viies tema töö järgmisele tasemele.

MLflow sisaldab kolme komponenti:

  • Jälgimine – katsete salvestamine ja taotlused: kood, andmed, konfiguratsioon ja tulemused. Väga oluline on jälgida mudeli loomise protsessi.
  • Projektid - Pakendivorming mis tahes platvormil kasutamiseks (näiteks SageMaker)
  • Mudelid on levinud vorming mudelite esitamiseks erinevatele juurutustööriistadele.

MLflow (kirjutamise ajal alfa) on avatud lähtekoodiga platvorm, mis võimaldab hallata masinõppe elutsüklit, sealhulgas katsetamist, taaskasutamist ja juurutamist.

MLflow seadistamine

MLflow kasutamiseks tuleb esmalt seadistada kogu Pythoni keskkond, selleks me kasutame PyEnv (Pythoni installimiseks Maci vaadake kliki siia). Nii saame luua virtuaalse keskkonna, kuhu installime kõik tööks vajalikud teegid.

```
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
```

Installige vajalikud raamatukogud.

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

Märkus. Kasutame PyArrowt selliste mudelite käitamiseks nagu UDF-id. PyArrow ja Numpy versioonid vajasid parandamist, kuna uusimad versioonid olid omavahel vastuolus.

Jälgimisliidese käivitamine

MLflow Tracking võimaldab meil logida ja teha päringuid Pythoni ja Pythoni eksperimentide kohta REST API. Lisaks saate määrata, kuhu mudeliartefakte salvestada (localhost, Amazon S3, Azure Blobi salvestusruum, Google Cloud Storage või SFTP server). Kuna kasutame Alpha Healthis AWS-i, on S3 artefaktide salvestusruum.

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

MLflow soovitab kasutada püsivat failisalvestust. Failide salvestusruum on koht, kus server salvestab käitamise ja katsetamise metaandmeid. Serveri käivitamisel veenduge, et see osutaks püsivale failisalvestusele. Siin kasutame katse huvides lihtsalt /tmp.

Pidage meeles, et kui tahame kasutada mlflow serverit vanade katsete käitamiseks, peavad need failihoidlas olemas olema. Kuid isegi ilma selleta saaksime neid UDF-is kasutada, kuna vajame ainult teed mudelini.

Märkus. Pidage meeles, et jälgimisliidesel ja mudelikliendil peab olema juurdepääs artefakti asukohale. See tähendab, et olenemata asjaolust, et jälgimisliides asub EC2 eksemplaris, peab MLflow kohapeal käitamisel masinal olema artefaktimudelite kirjutamiseks otsejuurdepääs S3-le.

Sparki laiendamine MLflow abil
Jälgimisliides salvestab artefakte S3 ämbrisse

Jooksvad mudelid

Niipea, kui jälgimisserver töötab, saate alustada mudelite treenimist.

Näitena kasutame MLflow näite veini modifikatsiooni Sklearn.

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

Nagu me ütlesime, võimaldab MLflow logida parameetreid, mõõdikuid ja mudeli artefakte, et saaksite jälgida nende arengut iteratsioonidena. See funktsioon on äärmiselt kasulik, kuna võimaldab meil reprodutseerida parimat mudelit, võttes ühendust jälgimisserveriga või mõista, milline kood sooritas nõutava iteratsiooni, kasutades committide git hash logisid.

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

Sparki laiendamine MLflow abil
veini iteratsioonid

Tagumine ots mudeli jaoks

Käsuga “mlflow server” käivitatud MLflow jälgimisserveril on REST API käikude jälgimiseks ja andmete kirjutamiseks kohalikku failisüsteemi. Saate määrata jälgimisserveri aadressi keskkonnamuutuja "MLFLOW_TRACKING_URI" abil ja MLflow jälgimise API võtab sellel aadressil automaatselt ühendust jälgimisserveriga, et luua/ hankida käitamisteavet, logimõõdikuid jne.

Allikas: Dokumendid// Jälgimisserveri käitamine

Mudeli serveriga varustamiseks vajame töötavat jälgimisserverit (vt käivitusliidest) ja mudeli Run ID-d.

Sparki laiendamine MLflow abil
Käivita 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

MLflow serveerimisfunktsiooni kasutavate mudelite teenindamiseks vajame juurdepääsu jälgimisliidesele, et mudeli kohta teavet hankida, lihtsalt täpsustades --run_id.

Kui mudel võtab jälgimisserveriga ühendust, saame hankida uue mudeli lõpp-punkti.

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

Sparki jooksvad mudelid

Vaatamata asjaolule, et jälgimisserver on piisavalt võimas, et mudeleid reaalajas teenindada, neid koolitada ja serveri funktsioone kasutada (allikas: mlflow // docs // mudelid #local), on Sparki kasutamine (partii- või voogedastus) selle levitamise tõttu veelgi võimsam lahendus.

Kujutage ette, et tegite just võrguühenduseta koolitust ja rakendasite seejärel väljundmudeli kõigile oma andmetele. Siin tulevadki Spark ja MLflow omaette.

Installige PySpark + Jupyter + Spark

Allikas: Alustage PySpark – Jupyter

Et näidata, kuidas rakendame MLflow mudeleid Sparki andmeraamidele, peame seadistama Jupyteri märkmikud PySparkiga töötama.

Alustage uusima stabiilse versiooni installimisega 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̀

Installige PySpark ja Jupyter virtuaalsesse keskkonda:

pip install pyspark jupyter

Seadistage keskkonnamuutujad:

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"

Olles määratlenud notebook-dir, saame salvestada oma märkmikud soovitud kausta.

Jupyteri käivitamine PySparkist

Kuna saime Jupiteri seadistada PySparki draiverina, saame nüüd Jupyteri sülearvutit PySparki kontekstis käivitada.

(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

Sparki laiendamine MLflow abil

Nagu eespool mainitud, pakub MLflow S3-s mudeli artefaktide logimise funktsiooni. Niipea kui valitud mudel on meie käes, on meil võimalus see mooduli abil UDF-ina importida 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)

Sparki laiendamine MLflow abil
PySpark – veinikvaliteedi ennustamine

Siiani oleme rääkinud sellest, kuidas kasutada PySparki MLflow-ga, käivitades kogu veiniandmestiku veinikvaliteedi prognoosi. Aga mis siis, kui peate kasutama Scala Sparki Pythoni MLflow mooduleid?

Testisime ka seda, jagades Sparki konteksti Scala ja Pythoni vahel. See tähendab, et registreerisime Pythonis MLflow UDF-i ja kasutasime seda Scalast (jah, võib-olla mitte parim lahendus, aga see, mis meil on).

Scala Spark + MLflow

Selle näite puhul lisame Toree Kernel olemasolevasse Jupiterisse.

Installige 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
```

Nagu lisatud märkmikust näha, jagatakse UDF-i Sparki ja PySparki vahel. Loodame, et see osa on kasulik neile, kes armastavad Scalat ja soovivad masinõppemudeleid tootmises juurutada.

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

Järgmised sammud

Kuigi MLflow on kirjutamise ajal Alpha, tundub see üsna paljutõotav. Juba ainuüksi võimalus käitada mitut masinõpperaamistikku ja kasutada neid ühest lõpp-punktist viib soovitussüsteemid järgmisele tasemele.

Lisaks lähendab MLflow andmeinsenerid ja andmeteadlased üksteisele, pannes nende vahele ühise kihi.

Pärast seda MLflow uurimist jätkame kindlasti ja kasutame seda oma Sparki torustike ja soovitussüsteemide jaoks.

Tore oleks failisüsteemi asemel sünkroonida failihoidla andmebaasiga. See peaks andma meile mitu lõpp-punkti, mis saavad kasutada sama failijagamist. Näiteks kasutage mitut eksemplari Presto и Athena sama Glue metastore'iga.

Kokkuvõtteks tahaksin tänada MLFlow kogukonda meie andmetega töötamise huvitavamaks muutmise eest.

Kui mängite MLflow-ga, siis kirjutage meile ja rääkige meile, kuidas seda kasutate, ja veelgi enam, kui kasutate seda tootmises.

Lisateavet kursuste kohta:
masinõpe. Põhikursus
masinõpe. edasijõudnute kursus

Loe rohkem:

Allikas: www.habr.com

Lisa kommentaar