Ymestyn Spark gyda MLflow

Helo, Khabrovites. Fel y gwnaethom ysgrifennu eisoes, y mis hwn mae OTUS yn lansio dau gwrs ar ddysgu peirianyddol ar unwaith, sef sylfaen ΠΈ uwch. Yn hyn o beth, rydym yn parhau i rannu deunydd defnyddiol.

Pwrpas yr erthygl hon yw siarad am ein profiad cyntaf gyda llif ML.

Byddwn yn dechrau'r adolygiad llif ML o'i weinydd olrhain a phrologiwch bob iteriad o'r astudiaeth. Yna byddwn yn rhannu'r profiad o gysylltu Spark ag MLflow gan ddefnyddio UDF.

Cyd-destun

Rydyn ni i mewn Iechyd Alffa rydym yn defnyddio dysgu peirianyddol a deallusrwydd artiffisial i rymuso pobl i ofalu am eu hiechyd a'u lles. Dyna pam mae modelau dysgu peiriant wrth wraidd y cynhyrchion data rydyn ni'n eu datblygu, a dyna pam y daeth MLflow, llwyfan ffynhonnell agored sy'n rhychwantu pob agwedd ar gylch bywyd dysgu peiriannau, i'n sylw.

llif ML

Prif nod MLflow yw darparu haen ychwanegol ar ben dysgu peiriant a fyddai'n caniatΓ‘u i wyddonwyr data weithio gyda bron unrhyw lyfrgell dysgu peiriannau (h2o, keras, mleap, pytorch, sglearn ΠΈ tensorflow), mynd Ò’i gwaith i’r lefel nesaf.

Mae MLflow yn darparu tair cydran:

  • Olrhain – cofnodi a cheisiadau am arbrofion: cod, data, ffurfweddiad a chanlyniadau. Mae'n bwysig iawn dilyn y broses o greu model.
  • prosiectau - Fformat pecynnu i'w redeg ar unrhyw blatfform (er enghraifft, SageMaker)
  • Modelau yn fformat cyffredin ar gyfer cyflwyno modelau i wahanol offer defnyddio.

Mae MLflow (alffa ar adeg ysgrifennu) yn blatfform ffynhonnell agored sy'n eich galluogi i reoli'r cylch bywyd dysgu peiriannau, gan gynnwys arbrofi, ailddefnyddio a defnyddio.

Sefydlu MLflow

I ddefnyddio MLflow, yn gyntaf rhaid i chi sefydlu'r amgylchedd Python cyfan, ar gyfer hyn byddwn yn defnyddio PyEnv (i osod Python ar Mac, edrychwch yma). Felly gallwn greu amgylchedd rhithwir lle byddwn yn gosod yr holl lyfrgelloedd angenrheidiol i redeg.

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

Gosod y llyfrgelloedd gofynnol.

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

Nodyn: Rydym yn defnyddio PyArrow i redeg modelau fel UDFs. Roedd angen gosod y fersiynau o PyArrow a Numpy oherwydd bod y fersiynau diweddaraf yn gwrthdaro Γ’'i gilydd.

Lansio UI Olrhain

Mae Olrhain MLflow yn ein galluogi i logio ac ymholi arbrofion gyda Python a REST API. Yn ogystal, gallwch ddiffinio ble i storio arteffactau model (localhost, amazon S3, Storio Azure Blob, Google Cloud Storio neu gweinydd SFTP). Gan ein bod yn defnyddio AWS yn Alpha Health, S3 fydd y storfa ar gyfer yr arteffactau.

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

Mae MLflow yn argymell defnyddio storfa ffeiliau barhaus. Y storfa ffeiliau yw lle bydd y gweinydd yn storio metadata rhedeg ac arbrofi. Wrth gychwyn y gweinydd, gwnewch yn siΕ΅r ei fod yn pwyntio at storio ffeiliau'n barhaus. Yma, er mwyn arbrawf, byddwn yn syml yn defnyddio /tmp.

Cofiwch, os ydym am ddefnyddio'r gweinydd mlflow i redeg hen arbrofion, rhaid iddynt fod yn bresennol yn y storfa ffeiliau. Fodd bynnag, hyd yn oed heb hyn, byddem yn gallu eu defnyddio yn yr UDF, gan mai dim ond y llwybr i'r model sydd ei angen arnom.

Nodyn: Cofiwch fod yn rhaid i'r UI Olrhain a'r cleient model gael mynediad i leoliad yr arteffact. Hynny yw, waeth beth fo'r ffaith bod yr UI Olrhain wedi'i leoli mewn enghraifft EC2, wrth redeg MLflow yn lleol, rhaid i'r peiriant gael mynediad uniongyrchol i S3 i ysgrifennu modelau arteffactau.

Ymestyn Spark gyda MLflow
Mae olrhain UI yn storio arteffactau mewn bwced S3

Modelau Rhedeg

Cyn gynted ag y bydd y gweinydd Olrhain yn rhedeg, gallwch chi ddechrau hyfforddi'r modelau.

Fel enghraifft, byddwn yn defnyddio'r addasiad gwin o'r enghraifft MLflow yn Sklearn.

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

Fel y dywedasom, mae MLflow yn caniatΓ‘u ichi logio'r paramedrau, metrigau, ac arteffactau model fel y gallwch olrhain sut maent yn datblygu fel iteriadau. Mae'r nodwedd hon yn hynod ddefnyddiol, oherwydd mae'n ein galluogi i atgynhyrchu'r model gorau trwy gysylltu Γ’'r gweinydd Olrhain neu ddeall pa god a gyflawnodd yr iteriad gofynnol gan ddefnyddio logiau hash git yr ymrwymiadau.

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

Ymestyn Spark gyda MLflow
iteriadau gwin

Pen Γ΄l ar gyfer y model

Mae gan y gweinydd olrhain MLflow a lansiwyd gyda'r gorchymyn β€œgweinydd mlflow” API REST ar gyfer olrhain rhediadau ac ysgrifennu data i'r system ffeiliau leol. Gallwch nodi cyfeiriad y gweinydd olrhain gan ddefnyddio'r newidyn amgylchedd "MLFLOW_TRACKING_URI" a bydd yr API olrhain MLflow yn cysylltu'n awtomatig Γ’'r gweinydd olrhain yn y cyfeiriad hwn i greu / cael gwybodaeth lansio, logio metrigau, ac ati.

Ffynhonnell: Dogfennau // Rhedeg gweinydd olrhain

Er mwyn darparu gweinyddwr i'r model, mae angen gweinydd olrhain rhedeg arnom (gweler y rhyngwyneb lansio) ac ID Rhedeg y model.

Ymestyn Spark gyda MLflow
Rhedeg 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

Er mwyn gwasanaethu modelau gan ddefnyddio swyddogaeth gwasanaeth MLflow, mae angen mynediad i'r UI Olrhain i gael gwybodaeth am y model trwy nodi'n syml --run_id.

Unwaith y bydd y model yn cysylltu Γ’'r Gweinydd Olrhain, gallwn gael pwynt terfyn model newydd.

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

Modelau rhedeg o Spark

Er gwaethaf y ffaith bod y gweinydd Olrhain yn ddigon pwerus i wasanaethu modelau mewn amser real, eu hyfforddi a defnyddio ymarferoldeb y gweinydd (ffynhonnell: mlflow // docs // modelau #lleol), mae defnyddio Spark (swp neu ffrydio) yn ateb hyd yn oed yn fwy pwerus oherwydd ei ddosbarthiad.

Dychmygwch eich bod newydd wneud hyfforddiant all-lein ac yna cymhwyso'r model allbwn i'ch holl ddata. Dyma lle mae Spark ac MLflow yn dod i'w rhan eu hunain.

Gosod PySpark + Jupyter + Spark

Ffynhonnell: Cychwyn arni PySpark - Jupyter

I ddangos sut rydym yn cymhwyso modelau MLflow i fframiau data Spark, mae angen i ni sefydlu llyfrau nodiadau Jupyter i weithio gyda PySpark.

Dechreuwch trwy osod y fersiwn sefydlog ddiweddaraf 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Μ€

Gosod PySpark a Jupyter mewn amgylchedd rhithwir:

pip install pyspark jupyter

Gosod newidynnau amgylchedd:

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"

Wedi diffinio notebook-dir, byddwn yn gallu storio ein llyfrau nodiadau yn y ffolder a ddymunir.

Rhedeg Jupyter o PySpark

Gan ein bod wedi gallu sefydlu Jupiter fel gyrrwr PySpark, gallwn nawr redeg y llyfr nodiadau Jupyter mewn cyd-destun 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

Ymestyn Spark gyda MLflow

Fel y soniwyd uchod, mae MLflow yn darparu swyddogaeth logio arteffactau model yn S3. Cyn gynted ag y bydd gennym y model a ddewiswyd yn ein dwylo, mae gennym gyfle i'w fewnforio fel UDF gan ddefnyddio'r modiwl 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)

Ymestyn Spark gyda MLflow
PySpark - Rhagfynegi ansawdd gwin

Hyd at y pwynt hwn, rydym wedi siarad am sut i ddefnyddio PySpark gyda MLflow trwy redeg rhagfynegiad ansawdd gwin ar y set ddata gwin gyfan. Ond beth os oes angen i chi ddefnyddio'r modiwlau Python MLflow o Scala Spark?

Fe wnaethon ni brofi hyn hefyd trwy rannu cyd-destun Spark rhwng Scala a Python. Hynny yw, fe wnaethom gofrestru MLflow UDF yn Python, a'i ddefnyddio o Scala (ie, efallai nad yr ateb gorau, ond yr hyn sydd gennym).

Scala Spark + MLflow

Ar gyfer yr enghraifft hon, byddwn yn ychwanegu Cnewyllyn Toree i mewn i Iau presennol.

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

Fel y gwelwch o'r llyfr nodiadau atodedig, rhennir UDF rhwng Spark a PySpark. Gobeithiwn y bydd y rhan hon yn ddefnyddiol i'r rhai sy'n caru Scala ac sydd am ddefnyddio modelau dysgu peirianyddol i gynhyrchu.

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

Camau nesaf

Er bod MLflow yn Alpha ar adeg ysgrifennu, mae'n edrych yn eithaf addawol. Mae gallu rhedeg sawl fframwaith dysgu peiriant a'u defnyddio o un pwynt terfyn yn mynd Γ’ systemau argymell i'r lefel nesaf.

Yn ogystal, mae MLflow yn dod Γ’ pheirianwyr Data a Gwyddonwyr Data yn agosach at ei gilydd, gan osod haen gyffredin rhyngddynt.

Ar Γ΄l yr archwiliad hwn o MLflow, rydym yn sicr o fynd ymlaen a'i ddefnyddio ar gyfer ein piblinellau Spark a'n systemau argymell.

Byddai'n braf cydamseru'r storfa ffeiliau gyda'r gronfa ddata yn lle'r system ffeiliau. Dylai hyn roi diweddbwyntiau lluosog i ni a all ddefnyddio'r un gyfran ffeil. Er enghraifft, defnyddiwch sawl achos Presto ΠΈ Athena gyda'r un metastore Glud.

I grynhoi, hoffwn ddiolch i gymuned MLFlow am wneud ein gwaith gyda data yn fwy diddorol.

Os ydych chi'n chwarae gyda MLflow, mae croeso i chi ysgrifennu atom a dweud wrthym sut rydych chi'n ei ddefnyddio, a hyd yn oed yn fwy felly os ydych chi'n ei ddefnyddio wrth gynhyrchu.

Dysgwch fwy am gyrsiau:
dysgu peirianyddol. Cwrs sylfaenol
dysgu peirianyddol. cwrs uwch

Darllen mwy:

Ffynhonnell: hab.com

Ychwanegu sylw