Berfirehkirina Spark bi MLflow

Silav, niştecîhên Khabrovsk. Wekî ku me berê jî nivîsî, vê mehê OTUS du qursên fêrbûna makîneyê bi yekcarî dest pê dike, bi navê bingeh и pêşveçû. Di vî warî de, em berdewam dikin ku materyalên kêrhatî parve bikin.

Armanca vê gotarê ew e ku em li ser karanîna yekem ezmûna me biaxivin MLflow.

Em ê dest bi vekolînê bikin MLflow ji servera şopandina wê û hemî dubareyên lêkolînê têketin. Dûv re em ê ezmûna xwe ya girêdana Spark bi MLflow re bi karanîna UDF re parve bikin.

Context

Em tê de ne Alpha Health Em fêrbûna makîneyê û îstîxbarata çêkirî bikar tînin da ku mirovan bi hêz bikin ku berpirsiyariya tenduristî û xweşbûna xwe bigirin. Ji ber vê yekê modelên fêrbûna makîneyê di dilê hilberên zanistiya daneyê de ne ku em pêşvedixin, û ji ber vê yekê em ber bi MLflow ve hatin kişandin, platformek çavkaniyek vekirî ya ku hemî aliyên çerxa jiyana fêrbûna makîneyê vedigire.

MLflow

Armanca sereke ya MLflow peydakirina qatek pêvek li ser fêrbûna makîneyê ye ku dihêle zanyarên daneyê hema hema bi her pirtûkxaneya fêrbûna makîneyê re bixebitin (h2o, kera, mleap, pytorch, sklearn и tensorflow), karê xwe berbi astek din ve dibe.

MLflow sê beşan peyda dike:

  • kişif dike - tomarkirin û daxwazên ceribandinan: kod, dane, veavakirin û encam. Şopandina pêvajoya çêkirina modelekê pir girîng e.
  • projeyên - Forma pakkirinê ku li ser her platformê were xebitandin (mînak. SageMaker)
  • Models - Formatek hevpar ji bo şandina modelan ji amûrên cihêreng ên bicîhkirinê re.

MLflow (di dema nivîsandinê de di alpha de) platformek çavkaniyek vekirî ye ku destûrê dide te ku hûn çerxa jiyana fêrbûna makîneyê, tevî ceribandin, ji nû ve bikar anîn, û bicîhkirinê birêve bibin.

Sazkirina MLflow

Ji bo ku hûn MLflow bikar bînin hûn hewce ne ku pêşî hemî hawîrdora Python-a xwe saz bikin, ji bo vê yekê em ê bikar bînin PyEnv (ji bo sazkirina Python li Mac-ê, binihêrin vir). Bi vî rengî em dikarin jîngehek virtual biafirînin ku em ê hemî pirtûkxaneyên ku ji bo xebitandina wê hewce ne saz bikin.

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

Werin em pirtûkxaneyên pêwîst saz bikin.

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

Nîşe: Em PyArrow bikar tînin da ku modelên wekî UDF bimeşînin. Guhertoyên PyArrow û Numpy hewce bû ku bêne rast kirin ji ber ku guhertoyên paşîn bi hevûdu re nakokî bûn.

UI-ya Şopandinê dest pê bikin

Şopandina MLflow destûrê dide me ku em bi karanîna Python û ceribandinan bipirsin û bipirsin REHETÎ API. Wekî din, hûn dikarin diyar bikin ku hûn li ku derê hunerên modelê hilînin (localhost, Amazon S3, Storage Azure Blob, Google Cloud Storage an Pêşkêşkara SFTP). Ji ber ku em AWS li Alpha Health bikar tînin, hilanîna hunera me dê S3 be.

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

MLflow pêşniyar dike ku hilanîna pelê domdar bikar bînin. Hilberîna pelan ew e ku server dê metadaneyên xebitandinê û ceribandinê hilîne. Dema ku serverê dest pê dike, pê ewle bine ku ew li ser dikana pelê domdar destnîşan dike. Li vir ji bo ceribandinê em ê bi tenê bikar bînin /tmp.

Bînin bîra xwe ku heke em dixwazin servera mlflow bikar bînin da ku ceribandinên kevn bimeşînin, divê ew di hilanîna pelê de hebin. Lêbelê, bêyî vê yekê jî me dikaribû wan di UDF-ê de bikar bînin, ji ber ku em tenê riya modelê hewce ne.

Nîşe: Bînin bîra xwe ku Şopandina UI û xerîdarê modelê divê bigihîjin cîhê hunerê. Ango, bêyî ku rastiya ku UI-ya Şopandinê di mînakek EC2 de dimîne, dema ku MLflow li herêmî dimeşîne, pêdivî ye ku makîneyê rasterast xwedan S3 be da ku modelên hunerî binivîse.

Berfirehkirina Spark bi MLflow
Şopandina UI huneran di kelek S3 de hilîne

Modelên diherikin

Gava ku servera Şopandinê dimeşe, hûn dikarin dest bi perwerdekirina modelan bikin.

Wekî mînak, em ê guheztina şerabê ji mînaka MLflow tê de bikar bînin Sklearn.

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

Wekî ku me berê jî behs kir, MLflow destûrê dide we ku hûn pîvanên model, metrîk û berheman bişopînin da ku hûn bişopînin ka ew çawa li ser dubareyan pêşve diçin. Ev taybetmendî zehf bikêr e ji ber ku bi vî rengî em dikarin modela çêtirîn bi têkilî bi servera Şopandinê re an jî têgihiştina kîjan kodê bi karanîna têketinên git-hash ên commitan re dubarekirina pêwîst pêk aniye nûve bikin.

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

Berfirehkirina Spark bi MLflow
dubarekirina şerabê

Beşa serverê ji bo modelê

Pêşkêşkara şopandina MLflow, ku bi karanîna fermana "server mlflow" hatî destpêkirin, xwedan API-ya REST e ji bo şopandin û nivîsandina daneyan li pergala pelê ya herêmî. Hûn dikarin navnîşana servera şopandinê bi karanîna guhêrbara jîngehê "MLFLOW_TRACKING_URI" diyar bikin û API-ya şopandina MLflow dê bixweber bi servera şopandinê re li ser vê navnîşanê têkilî daynin da ku agahdariya destpêkirinê, pîvanên têketinê, hwd biafirînin/stînin.

Source: Belge// Pêşkêşkarek şopandinê dimeşîne

Ji bo ku model bi serverek re peyda bikin, em hewceyê serverek şopandina xebitandinê (binihêrin navbeynkariya destpêkirinê) û Nasnameya Rêvekirinê ya modelê.

Berfirehkirina Spark bi MLflow
Nasnameyê biavêje

# 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

Ji bo xizmetkirina modelên ku fonksiyona karûbarê MLflow bikar tînin, em ê hewce bikin ku bigihîjin UI-ya Şopandinê da ku agahdariya li ser modelê bi tenê bi destnîşankirinê bistînin. --run_id.

Gava ku model bi servera Şopandinê re têkilî daynin, em dikarin xalek dawiya modela nû bistînin.

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

Modelên diherikin ji Spark

Tevî vê rastiyê ku servera Şopandinê têra xwe bi hêz e ku modelan di wextê rast de xizmet bike, wan perwerde bike û fonksiyona serverê bikar bîne (çavkanî: mlflow // docs // modelên # herêmî), karanîna Spark (hevî an guheztin) ji ber belavkirinê çareseriyek hîn bihêztir e.

Bifikirin ku we tenê perwerdehiya negirêdayî kir û dûv re modela derketinê li hemî daneyên xwe bicîh kir. Li vir Spark û MLflow dibiriqe.

PySpark + Jupyter + Spark saz bikin

Source: Dest pê bikin PySpark - Jupyter

Ji bo ku nîşan bidin ka em modelên MLflow-ê li ser dataframên Spark çawa bicîh dikin, divê em notebookên Jupyter saz bikin da ku bi PySpark re bi hev re bixebitin.

Bi sazkirina guhertoya herî dawî ya stabîl dest pê bikin 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̀

PySpark û Jupyter di hawîrdora virtual de saz bikin:

pip install pyspark jupyter

Guherbarên jîngehê saz bikin:

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"

Diyar kirin notebook-dir, em dikarin defterên xwe di peldanka xwestî de hilînin.

Destpêkirina Jupyter ji PySpark

Ji ber ku me karîbû Jupiter wekî ajokerek PySpark mîheng bikin, em naha dikarin notebooka Jupyter di çarçoveya PySpark de bimeşînin.

(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

Berfirehkirina Spark bi MLflow

Wekî ku li jor hatî behs kirin, MLflow taybetmendiyek ji bo têketina hunerên modela li S3 peyda dike. Mîna ku modela hilbijartî di destên me de be, me derfet heye ku em wê wekî UDF bi karanîna modulê derxînin 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)

Berfirehkirina Spark bi MLflow
PySpark - Pêşbîniyên qalîteya şerabê derdixe

Heya vê nuqteyê, me li ser ka meriv çawa PySpark bi MLflow-ê re bikar tîne, pêşbîniyên qalîteya şerabê li ser tevahiya daneya şerabê dimeşîne. Lê heke hûn hewce ne ku modulên Python MLflow ji Scala Spark bikar bînin?

Me ev jî bi dabeşkirina çarçoweya Spark di navbera Scala û Python de ceriband. Ango, me MLflow UDF li Python tomar kir, û ew ji Scala bikar anî (erê, dibe ku ne çareseriya çêtirîn, lê ya ku me heye).

Scala Spark + MLflow

Ji bo vê nimûneyê em ê lê zêde bikin Toree Kernel nav Jupitera heyî.

Spark + Toree + Jupyter saz bikin

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

Wekî ku hûn ji notebooka pêvekirî dibînin, UDF di navbera Spark û PySpark de tê parve kirin. Em hêvî dikin ku ev beş dê ji kesên ku ji Scala hez dikin re kêrhatî be û dixwazin modelên fêrbûna makîneyê di hilberînê de bicîh bikin.

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

Gavên din

Her çend MLflow di dema nivîsandinê de di guhertoya Alpha de ye, ew pir hêvîdar xuya dike. Tenê şiyana ku meriv gelek çarçoveyên fêrbûna makîneyê bimeşîne û wan ji yek xala dawîn bikar bîne, pergalên pêşniyarker berbi astek din vedike.

Wekî din, MLflow Endezyarên Daneyê û pisporên Zanistiya Daneyê nêzikî hev dike, di navbera wan de qatek hevpar datîne.

Piştî vê lêgerîna MLflow, em pê bawer in ku em ê pêşde biçin û wê ji bo lûleyên xwe yên Spark û pergalên pêşniyarker bikar bînin.

Dê xweş be ku meriv hilanîna pelê bi databasê re li şûna pergala pelan hevdeng bike. Pêdivî ye ku ev çend xalên dawiyê bide me ku dikarin heman hilanîna pelê bikar bînin. Mînakî, gelek mînakan bikar bînin Presto и Atena bi heman metastora Glue.

Bi kurtasî, ez dixwazim spasiya civaka MLFlow bikim ku xebata me ya bi daneyan balkêştir dike.

Ger hûn bi MLflow re dilîzin, dudilî nebin ku hûn ji me re binivîsin û ji me re vebêjin ka hûn wê çawa bikar tînin, û hêj bêtir heke hûn wê di hilberînê de bikar bînin.

Di derbarê qursan de bêtir fêr bibin:
Fêrbûna makîneyê. Kursa bingehîn
Fêrbûna makîneyê. Kursa pêşketî

Zêdetir bixwînin:

Source: www.habr.com

Add a comment