Framlengir Spark með MLflow

Halló, Khabrovsk íbúar. Eins og við skrifuðum þegar, í þessum mánuði setur OTUS af stað tvö vélanámskeið í einu, þ.e grunnur и háþróaður. Í þessu sambandi höldum við áfram að deila gagnlegu efni.

Tilgangur þessarar greinar er að tala um fyrstu reynslu okkar af notkun MLflow.

Við byrjum á endurskoðuninni MLflow frá rakningarþjóni sínum og skráðu allar endurtekningar rannsóknarinnar. Síðan munum við deila reynslu okkar af því að tengja Spark við MLflow með UDF.

Samhengi

Við erum í AlphaHealth Við notum vélanám og gervigreind til að gera fólki kleift að taka ábyrgð á heilsu sinni og vellíðan. Þess vegna eru vélanámslíkön kjarninn í gagnavísindavörum sem við þróum, og þess vegna laðuðumst við að MLflow, opnum vettvangi sem nær yfir alla þætti lífsferils vélnáms.

MLflow

Meginmarkmið MLflow er að útvega viðbótarlag ofan á vélanám sem gerir gagnafræðingum kleift að vinna með nánast hvaða vélanámssafn sem er (h2o, erfitt, mleap, pytorch, læra и tensorflow), taka verk hennar á næsta stig.

MLflow býður upp á þrjá þætti:

  • Rekja spor einhvers - Upptaka og beiðnir um tilraunir: kóða, gögn, stillingar og niðurstöður. Það er mjög mikilvægt að fylgjast með ferlinu við að búa til líkan.
  • verkefni - Pökkunarsnið til að keyra á hvaða vettvang sem er (t.d. SageMaker)
  • Models – algengt snið til að senda líkön í ýmis dreifingartæki.

MLflow (í alfa þegar þetta er skrifað) er opinn uppspretta vettvangur sem gerir þér kleift að stjórna lífsferli vélnáms, þar með talið tilraunir, endurnotkun og uppsetningu.

Setja upp MLflow

Til að nota MLflow þarftu fyrst að setja upp allt Python umhverfið þitt, til þess munum við nota PyEnv (til að setja upp Python á Mac skaltu skoða hér). Þannig getum við búið til sýndarumhverfi þar sem við munum setja upp öll nauðsynleg bókasöfn til að keyra það.

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

Við skulum setja upp nauðsynleg bókasöfn.

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

Athugið: Við notum PyArrow til að keyra líkön eins og UDF. Laga þurfti útgáfurnar af PyArrow og Numpy vegna þess að síðarnefndu útgáfurnar stanguðust á.

Ræstu mælingarviðmót

MLflow Tracking gerir okkur kleift að skrá og spyrjast fyrir um tilraunir með Python og REST API. Að auki geturðu ákveðið hvar á að geyma líkangripi (localhost, Amazon S3, Azure Blob Geymsla, Skýgeymsla Google eða SFTP þjónn). Þar sem við notum AWS hjá Alpha Health verður gripageymslan okkar S3.

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

MLflow mælir með því að nota viðvarandi skráageymslu. Skráageymsla er þar sem þjónninn mun geyma lýsigögn keyrslu og tilrauna. Þegar þjónninn er ræstur skaltu ganga úr skugga um að hann vísi á viðvarandi skráageymsluna. Hér fyrir tilraunina munum við einfaldlega nota /tmp.

Mundu að ef við viljum nota mlflow þjóninn til að keyra gamlar tilraunir verða þær að vera til staðar í skráageymslunni. Hins vegar, jafnvel án þessa, gætum við notað þau í UDF, þar sem við þurfum aðeins leiðina að líkaninu.

Athugið: Hafðu í huga að notendaviðmót rakningar og líkanbiðlari verða að hafa aðgang að staðsetningu gripsins. Það er, burtséð frá því að mælingarviðmótið er í EC2 tilviki, þegar MLflow er keyrt á staðnum, verður vélin að hafa beinan aðgang að S3 til að skrifa artifact módel.

Framlengir Spark með MLflow
Rekja notendaviðmót geymir gripi í S3 fötu

Módel í gangi

Um leið og mælingarþjónninn er í gangi geturðu byrjað að þjálfa líkönin.

Sem dæmi munum við nota vínbreytinguna úr MLflow dæminu í Sklearn.

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

Eins og við höfum þegar rætt, gerir MLflow þér kleift að skrá líkanbreytur, mælikvarða og gripi svo þú getir fylgst með hvernig þeir þróast í gegnum endurtekningar. Þessi eiginleiki er afar gagnlegur vegna þess að þannig getum við endurskapað besta líkanið með því að hafa samband við rakningarþjóninn eða skilja hvaða kóða framkvæmdi nauðsynlega endurtekningu með því að nota git hash logs yfir skuldbindingar.

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

Framlengir Spark með MLflow
Vínendurtekningar

Server hluti fyrir líkanið

MLflow rakningarþjónninn, ræstur með „mlflow server“ skipuninni, er með REST API til að rekja keyrslur og skrifa gögn í staðbundið skráarkerfi. Þú getur tilgreint heimilisfang rakningarþjónsins með því að nota umhverfisbreytuna „MLFLOW_TRACKING_URI“ og MLflow rakningarforritaskilið mun sjálfkrafa hafa samband við rakningarþjóninn á þessu heimilisfangi til að búa til/taka á móti ræsiupplýsingum, annálamælingum osfrv.

Heimild: Skjöl// Að keyra rakningarþjón

Til að útvega líkaninu netþjón, þurfum við hlaupandi rakningarþjón (sjá ræsingarviðmót) og Run ID líkansins.

Framlengir Spark með MLflow
Keyra auðkenni

# 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

Til að þjóna líkönum sem nota MLflow þjóna virknina þurfum við aðgang að rakningarviðmótinu til að fá upplýsingar um líkanið einfaldlega með því að tilgreina --run_id.

Þegar líkanið hefur samband við rakningarþjóninn getum við fengið nýjan endapunkt líkansins.

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

Hlaupandi módel frá Spark

Þrátt fyrir þá staðreynd að mælingarþjónninn sé nógu öflugur til að þjóna líkönum í rauntíma, þjálfaðu þau og notaðu virkni netþjónsins (heimild: mlflow // skjöl // módel # staðbundið), notkun Spark (lotu eða streymi) er enn öflugri lausn vegna dreifingar.

Ímyndaðu þér að þú hafir einfaldlega stundað þjálfunina án nettengingar og síðan notað úttakslíkanið á öll gögnin þín. Þetta er þar sem Spark og MLflow skína.

Settu upp PySpark + Jupyter + Spark

Heimild: Byrjaðu PySpark - Jupyter

Til að sýna hvernig við notum MLflow líkön á Spark gagnaramma þurfum við að setja upp Jupyter fartölvur til að vinna saman með PySpark.

Byrjaðu á því að setja upp nýjustu stöðugu útgáfuna 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̀

Settu upp PySpark og Jupyter í sýndarumhverfinu:

pip install pyspark jupyter

Settu upp umhverfisbreytur:

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"

Búinn að ákveða notebook-dir, við getum geymt fartölvurnar okkar í viðkomandi möppu.

Ræsir Jupyter frá PySpark

Þar sem við gátum stillt Jupiter sem PySpark ökumann, getum við nú keyrt Jupyter minnisbók í samhengi við 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

Framlengir Spark með MLflow

Eins og getið er hér að ofan, býður MLflow upp á eiginleika til að skrá líkangripi í S3. Um leið og við höfum valið líkan í okkar höndum höfum við tækifæri til að flytja það inn sem UDF með því að nota eininguna 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)

Framlengir Spark með MLflow
PySpark - Gefur spár um víngæði

Hingað til höfum við talað um hvernig á að nota PySpark með MLflow, og keyra spár um víngæði á öllu víngagnasettinu. En hvað ef þú þarft að nota Python MLflow einingar frá Scala Spark?

Við prófuðum þetta líka með því að skipta Spark samhenginu á milli Scala og Python. Það er, við skráðum MLflow UDF í Python og notuðum það frá Scala (já, kannski ekki besta lausnin, en það sem við höfum).

Scala Spark + MLflow

Fyrir þetta dæmi munum við bæta við Toree kjarna inn í núverandi Júpíter.

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

Eins og þú sérð á meðfylgjandi minnisbók er UDF deilt á milli Spark og PySpark. Við vonum að þessi hluti muni nýtast þeim sem elska Scala og vilja setja vélanámslíkön í framleiðslu.

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

Næstu skref

Jafnvel þó að MLflow sé í Alpha útgáfu þegar þetta er skrifað, lítur það nokkuð efnilegt út. Bara hæfileikinn til að keyra marga vélanámsramma og neyta þeirra frá einum endapunkti tekur ráðgjafakerfi á næsta stig.

Að auki færir MLflow gagnaverkfræðinga og gagnavísindasérfræðinga nær saman og leggur sameiginlegt lag á milli þeirra.

Eftir þessa könnun á MLflow erum við fullviss um að við munum halda áfram og nota það fyrir Spark leiðslur okkar og meðmælakerfi.

Það væri gaman að samstilla skráageymsluna við gagnagrunninn í stað skráarkerfisins. Þetta ætti að gefa okkur marga endapunkta sem geta notað sömu skráargeymsluna. Notaðu til dæmis mörg tilvik Presto и Athena með sama Glue metastore.

Til að draga saman vil ég þakka MLFlow samfélaginu fyrir að gera starf okkar með gögn áhugaverðara.

Ef þú ert að leika þér með MLflow skaltu ekki hika við að skrifa okkur og segja okkur hvernig þú notar það, og jafnvel meira ef þú notar það í framleiðslu.

Sjá nánar um námskeiðin:
Vélnám. Grunnnámskeið
Vélnám. Framhaldsnámskeið

Lestu meira:

Heimild: www.habr.com

Bæta við athugasemd