Pagpapalawak ng Spark gamit ang MLflow

Kumusta, mga residente ng Khabrovsk. Tulad ng naisulat na namin, ngayong buwan ang OTUS ay naglulunsad ng dalawang kurso sa pag-aaral ng makina nang sabay-sabay, ibig sabihin base ΠΈ advanced. Kaugnay nito, patuloy kaming nagbabahagi ng kapaki-pakinabang na materyal.

Ang layunin ng artikulong ito ay pag-usapan ang tungkol sa aming unang karanasan sa paggamit MLflow.

Sisimulan natin ang pagsusuri MLflow mula sa server ng pagsubaybay nito at i-log ang lahat ng mga pag-ulit ng pag-aaral. Pagkatapos ay ibabahagi namin ang aming karanasan sa pagkonekta sa Spark sa MLflow gamit ang UDF.

Konteksto

Tayo ay nasa Alpha Health Gumagamit kami ng machine learning at artificial intelligence para bigyang kapangyarihan ang mga tao na pangasiwaan ang kanilang kalusugan at kapakanan. Iyon ang dahilan kung bakit ang mga modelo ng machine learning ay nasa puso ng mga produkto ng data science na aming binuo, at iyon ang dahilan kung bakit kami naakit sa MLflow, isang open source na platform na sumasaklaw sa lahat ng aspeto ng lifecycle ng machine learning.

MLflow

Ang pangunahing layunin ng MLflow ay magbigay ng karagdagang layer sa ibabaw ng machine learning na magpapahintulot sa mga data scientist na magtrabaho sa halos anumang library ng machine learning (h2o, matigas, mleap, pytorch, sklearn ΠΈ tensorflow), dinadala ang kanyang trabaho sa susunod na antas.

Nagbibigay ang MLflow ng tatlong bahagi:

  • Pagsubaybay – pag-record at mga kahilingan para sa mga eksperimento: code, data, configuration at mga resulta. Ang pagsubaybay sa proseso ng paglikha ng isang modelo ay napakahalaga.
  • proyekto – Format ng packaging para tumakbo sa anumang platform (hal. SageMaker)
  • Modellen – isang karaniwang format para sa pagsusumite ng mga modelo sa iba't ibang tool sa pag-deploy.

Ang MLflow (sa alpha sa oras ng pagsulat) ay isang open source na platform na nagbibigay-daan sa iyong pamahalaan ang lifecycle ng machine learning, kabilang ang pag-eeksperimento, muling paggamit, at pag-deploy.

Pagse-set up ng MLflow

Upang magamit ang MLflow kailangan mo munang i-set up ang iyong buong kapaligiran sa Python, para dito gagamitin namin PyEnv (upang i-install ang Python sa Mac, tingnan dito). Sa ganitong paraan makakagawa tayo ng isang virtual na kapaligiran kung saan ii-install natin ang lahat ng mga aklatan na kinakailangan upang patakbuhin ito.

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

I-install natin ang mga kinakailangang library.

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

Tandaan: Ginagamit namin ang PyArrow upang magpatakbo ng mga modelo tulad ng UDF. Kailangang ayusin ang mga bersyon ng PyArrow at Numpy dahil magkasalungat ang mga huling bersyon sa isa't isa.

Ilunsad ang Tracking UI

Binibigyang-daan kami ng MLflow Tracking na mag-log at mag-query ng mga eksperimento gamit ang Python at REST API. Bilang karagdagan, matutukoy mo kung saan mag-iimbak ng mga artifact ng modelo (localhost, Amazon S3, Imbakan ng Azure Blob, Google Cloud Storage o SFTP server). Dahil gumagamit kami ng AWS sa Alpha Health, ang aming imbakan ng artifact ay magiging S3.

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

Inirerekomenda ng MLflow ang paggamit ng patuloy na imbakan ng file. Ang imbakan ng file ay kung saan mag-iimbak ang server ng run at metadata ng eksperimento. Kapag sinimulan ang server, siguraduhing tumuturo ito sa patuloy na tindahan ng file. Dito para sa eksperimento ay gagamitin lang namin /tmp.

Tandaan na kung gusto naming gamitin ang mlflow server upang magpatakbo ng mga lumang eksperimento, dapat na naroroon ang mga ito sa imbakan ng file. Gayunpaman, kahit na wala ito maaari naming gamitin ang mga ito sa UDF, dahil kailangan lang namin ang landas patungo sa modelo.

Tandaan: Tandaan na ang Tracking UI at ang modelong client ay dapat may access sa lokasyon ng artifact. Ibig sabihin, anuman ang katotohanan na ang Tracking UI ay nasa isang EC2 instance, kapag lokal na pinapatakbo ang MLflow, dapat ay may direktang access ang makina sa S3 para magsulat ng mga modelo ng artifact.

Pagpapalawak ng Spark gamit ang MLflow
Ang Tracking UI ay nag-iimbak ng mga artifact sa isang S3 bucket

Mga tumatakbong modelo

Sa sandaling tumatakbo ang server ng Pagsubaybay, maaari mong simulan ang pagsasanay sa mga modelo.

Bilang halimbawa, gagamitin namin ang pagbabago ng alak mula sa halimbawa ng MLflow sa Sklearn.

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

Gaya ng napag-usapan na natin, binibigyang-daan ka ng MLflow na mag-log ng mga parameter ng modelo, sukatan, at artifact para masubaybayan mo kung paano umuunlad ang mga ito sa mga pag-ulit. Lubhang kapaki-pakinabang ang feature na ito dahil sa paraang ito ay maaari nating kopyahin ang pinakamahusay na modelo sa pamamagitan ng pakikipag-ugnayan sa server ng Pagsubaybay o pag-unawa kung aling code ang nagsagawa ng kinakailangang pag-ulit gamit ang git hash logs ng commits.

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

Pagpapalawak ng Spark gamit ang MLflow
Mga pag-ulit ng alak

Bahagi ng server para sa modelo

Ang MLflow tracking server, na inilunsad gamit ang command na "mlflow server", ay may REST API para sa pagsubaybay sa mga pagtakbo at pagsusulat ng data sa lokal na file system. Maaari mong tukuyin ang address ng tracking server gamit ang environment variable na β€œMLFLOW_TRACKING_URI” at ang MLflow tracking API ay awtomatikong makikipag-ugnayan sa tracking server sa address na ito para gumawa/makatanggap ng impormasyon sa paglulunsad, log metrics, atbp.

Pinagmulan: Docs// Pagpapatakbo ng tracking server

Upang mabigyan ang modelo ng isang server, kailangan namin ng tumatakbong server ng pagsubaybay (tingnan ang interface ng paglulunsad) at ang Run ID ng modelo.

Pagpapalawak ng Spark gamit ang MLflow
Patakbuhin ang 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

Para maghatid ng mga modelo gamit ang functionality ng MLflow serve, kakailanganin namin ng access sa Tracking UI para makatanggap ng impormasyon tungkol sa modelo sa pamamagitan lang ng pagtukoy --run_id.

Kapag nakipag-ugnayan na ang modelo sa server ng Pagsubaybay, makakakuha tayo ng bagong endpoint ng modelo.

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

Mga tumatakbong modelo mula sa Spark

Sa kabila ng katotohanan na ang server ng Pagsubaybay ay sapat na makapangyarihan upang maghatid ng mga modelo sa real time, sanayin ang mga ito at gamitin ang paggana ng server (pinagmulan: mlflow // docs // models # local), ang paggamit ng Spark (batch o streaming) ay isang mas makapangyarihang solusyon dahil sa pamamahagi.

Isipin na ginawa mo lang ang pagsasanay nang offline at pagkatapos ay inilapat ang modelo ng output sa lahat ng iyong data. Dito nagniningning ang Spark at MLflow.

I-install ang PySpark + Jupyter + Spark

Pinagmulan: Magsimula PySpark - Jupyter

Upang ipakita kung paano namin inilalapat ang mga modelo ng MLflow sa mga dataframe ng Spark, kailangan naming mag-set up ng mga Jupyter notebook upang gumana nang magkasama sa PySpark.

Magsimula sa pamamagitan ng pag-install ng pinakabagong stable na bersyon 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Μ€

I-install ang PySpark at Jupyter sa virtual na kapaligiran:

pip install pyspark jupyter

I-set up ang mga variable ng kapaligiran:

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"

Nang matukoy notebook-dir, maaari naming iimbak ang aming mga notebook sa nais na folder.

Inilunsad ang Jupyter mula sa PySpark

Dahil nagawa naming i-configure ang Jupiter bilang driver ng PySpark, maaari na naming patakbuhin ang Jupyter notebook sa konteksto ng 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

Pagpapalawak ng Spark gamit ang MLflow

Gaya ng nabanggit sa itaas, nagbibigay ang MLflow ng feature para sa mga artifact ng modelo ng pag-log sa S3. Sa sandaling nasa kamay na namin ang napiling modelo, magkakaroon kami ng pagkakataong i-import ito bilang UDF gamit ang module 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)

Pagpapalawak ng Spark gamit ang MLflow
PySpark - Naglalabas ng mga hula sa kalidad ng alak

Hanggang sa puntong ito, pinag-usapan namin kung paano gamitin ang PySpark sa MLflow, na nagpapatakbo ng mga hula sa kalidad ng alak sa buong dataset ng alak. Ngunit paano kung kailangan mong gumamit ng mga module ng Python MLflow mula sa Scala Spark?

Sinubukan din namin ito sa pamamagitan ng paghahati sa konteksto ng Spark sa pagitan ng Scala at Python. Iyon ay, inirehistro namin ang MLflow UDF sa Python, at ginamit ito mula sa Scala (oo, marahil hindi ang pinakamahusay na solusyon, ngunit kung ano ang mayroon kami).

Scala Spark + MLflow

Para sa halimbawang ito ay idaragdag namin Toree Kernel sa umiiral na Jupiter.

I-install ang 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
```

Tulad ng nakikita mo mula sa nakalakip na notebook, ang UDF ay ibinabahagi sa pagitan ng Spark at PySpark. Umaasa kaming magiging kapaki-pakinabang ang bahaging ito sa mga mahilig sa Scala at gustong mag-deploy ng mga modelo ng machine learning sa produksyon.

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

Mga susunod na hakbang

Kahit na ang MLflow ay nasa bersyon ng Alpha sa oras ng pagsulat, mukhang may pag-asa ito. Ang kakayahang magpatakbo ng maraming machine learning frameworks at gamitin ang mga ito mula sa iisang endpoint ay dadalhin ang mga nagrerekomendang system sa susunod na antas.

Bilang karagdagan, pinagsasama ng MLflow ang mga Data Engineer at mga espesyalista sa Data Science, na naglalagay ng isang karaniwang layer sa pagitan nila.

Pagkatapos ng paggalugad na ito ng MLflow, tiwala kami na susulong kami at gagamitin namin ito para sa aming mga pipeline ng Spark at recommender system.

Mas mainam na i-synchronize ang imbakan ng file sa database sa halip na ang file system. Dapat itong magbigay sa amin ng maraming endpoint na maaaring gumamit ng parehong storage ng file. Halimbawa, gumamit ng maraming pagkakataon kapagdaka ΠΈ Atenas na may parehong Glue metastore.

Upang buod, nais kong magpasalamat sa komunidad ng MLFlow para sa paggawa ng aming gawain sa data na mas kawili-wili.

Kung pinaglalaruan mo ang MLflow, huwag mag-atubiling sumulat sa amin at sabihin sa amin kung paano mo ito ginagamit, at higit pa kung ginagamit mo ito sa produksyon.

Alamin ang higit pa tungkol sa mga kurso:
Pag-aaral ng makina. Basic na kurso
Pag-aaral ng makina. Advanced na kurso

Magbasa pa:

Pinagmulan: www.habr.com

Magdagdag ng komento