Tere, Habrikum. Nagu me juba oleme kirjutanud, kÀivitab otus sel kuul kaks kursust masinÔppe kohta, nimelt ja . SeetÔttu jÀtkame kasuliku materjali jagamist.
Selle artikli eesmÀrk on jagada meie esimest kogemust MLflow kasutamisest. .
Alustame ĂŒlevaate tema jĂ€lgimise serverist ja logime kĂ”ik katsetamise iteratsioonid. SeejĂ€rel jagame oma kogemust Spark'i ĂŒhendamisest MLflow'ga UDF abil.
Kontekst
Meie kasutame masinĂ”pet ja tehisintellekti, et anda inimestele vĂ”imalus hoolitseda oma tervise ja heaolu eest. SeetĂ”ttu on masinĂ”ppe mudelid meie arendatavate andmetöötlustoodete aluseks ning meie tĂ€helepanu köitis MLflow â avatud lĂ€htekoodiga platvorm, mis katab kogu masinĂ”ppe elutsĂŒkli.
MLflow
MLflow pÔhiline eesmÀrk on luua tÀiendav kiht masinÔppe kohal, mis vÔimaldaks andmete teadlastel töötada praktiliselt iga masinÔppe teegiga (, , , , ja ), tÔstes oma töö jÀrgmisele tasemele.
MLflow pakub kolme komponenti:
- JĂ€lgimine â katsete salvestamine ja pĂ€ringud: kood, andmed, konfiguratsioon ja tulemused. Mudeli loomise protsessi jĂ€lgimine on vĂ€ga oluline.
- Projects â Pakendamisformaat, et kĂ€ivitada igal platvormil (nĂ€iteks, )
- Mudels â ĂŒhine formaat mudelite saatmiseks erinevatesse juurutustööriistadesse.
MLflow (artikli kirjutamise ajal alpha-versioonis) on avatud lĂ€htekoodiga platvorm, mis vĂ”imaldab hallata masinĂ”ppe elutsĂŒklit, sealhulgas katseid, taaskasutust ja juurutamist.
MLflow seadistamine
MLflow'i kasutamiseks tuleb kÔigepealt seadistada kogu Python keskkond, selleks kasutame (Python installimiseks Mac'ile vaadake sisestust), et saaksime luua virtuaalse keskkonna, kuhu paigaldame kÔik kÀivitamiseks vajalikud teegid. ). Nii saame luua virtuaalse keskkonna, kuhu paigaldame kÔik vajalikud teegid.
```
pyenv install 3.7.0
pyenv global 3.7.0 # Kasuta Python 3.7
mkvirtualenv mlflow # Loo virtuaalne keskkond Python 3.7-ga
workon mlflow
```Paigaldame vajalikud teegid.
```
pip install mlflow==0.7.0
Cython==0.29
numpy==1.14.5
pandas==0.23.4
pyarrow==0.11.0
```MÀrkus: kasutame PyArrow't selliste mudelite nagu UDF kÀivitamiseks. PyArrow ja Numpy versioone tuli parandada, kuna viimased versioonid olid omavahel vastuolus.
KÀivitame jÀlgimise kasutajaliidese
MLflow Tracking vÔimaldab meil logida ja teha pÀringuid eksperimentide kohta Pythoniga ja API. Lisaks sellele saab mÀÀrata, kus hoida mudeli artefakte (localhost, , , vÔi ). Kuna Alpha Health kasutab AWS-i, on artefaktide hoidmiseks S3.
# 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 failihoidlat. Failihoidla all mĂ”istetakse kohta, kus server hoiab kĂ€ivituste ja eksperimentide metainformatsiooni. Serveri kĂ€ivitamisel veenduge, et see osutab pĂŒsivale failihoidlale. Siin eksperimentimiseks kasutame lihtsalt /tmp.
Pidage meeles, et kui soovime kasutada mlflow serverit vanade eksperimentide kÀivitamiseks, peavad need olema failihoidlas. Kuid isegi ilma selleta saaksime neid kasutada UDF-nagu, kuna vajame vaid teed mudelini.
MÀrkus: Pidage meeles, et Tracking UI ja mudeli klient peaksid saama juurdepÀÀsu artefakti asukohale. See tÀhendab, et sÔltumata sellest, kus Tracking UI asub EC2 instances, peab MLflow kohaliku kÀivitamise ajal masinal olema otsene juurdepÀÀs S3-le artefakti mudelite kirjutamiseks.

Tracking UI hoiab artefakte S3 Àmbris
Mudelite kÀivitamine
Kui Tracking-server on töökorras, saab alustada mudelite Ôpetamist.
NÀiteks kasutame MLflow nÀite wine modifikatsiooni .
MLFLOW_TRACKING_URI=http://localhost:5000 python wine_quality.py
--alpha 0.9
--l1_ration 0.5
--wine_file ./data/winequality-red.csvNagu varem mainitud, vÔimaldab MLflow logida parameetreid, meetrikat ja mudeli artefakte, et jÀlgida nende arengut iteratsioonide kÀigus. See funktsioon on ÀÀrmiselt kasulik, kuna nii saame taasesitada parima mudeli, pöördudes Tracking-serveri poole vÔi mÔistmaks, millist koodi vajamineva iteratsiooni tÀitmiseks kasutati git hash commitide logide abil.
with mlflow.start_run():
... mudel ...
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, "mudel") 
Wine iteratsioonid
Mudeli serveripoolne osa
MLflow jĂ€lgimisserver, mis on kĂ€ivitatud kĂ€suga âmlflow serverâ, sisaldab REST API-d jooksude jĂ€lgimiseks ning andmete salvestamiseks kohalikku failisĂŒsteemi. Saate mÀÀrata jĂ€lgimisserveri aadressi keskkonnamuutuja âMLFLOW_TRACKING_URIâ abil ning MLflow jĂ€lgimis-API vahetab selle aadressiga ĂŒhendust, et luua / saada teavet jooksu, logimist mÔÔdikute jne kohta.
Allikas:
Mudeli serveriga varustamiseks vajame kÀivitatud jÀlgimisserverit (vt kÀivitamise liides) ja mudeli jooksu ID-d.

Jooksu 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 Mudelite haldamiseks MLflow serve funktsiooni kaudu vajame juurdepÀÀsu JÀlgimise UI-le, et saada mudeli teavet, lihtsalt nÀidates --run_id.
Kui mudel saab ĂŒhendust jĂ€lgimisserveriga, saame luua 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]}Mudelite kÀitamine Sparkist
Kuigi jÀlgimisserver on piisavalt vÔimas mudelite haldamiseks reaalajas, nende Ôpetamiseks ja funktsiooni serve kasutamiseks (allikas: ), on Spark (partii vÔi voog) veelgi vÔimsam lahendus, tÀnu jaotusele.
Kujutage ette, et olete just kohtunud Ôppimisega offline, ja seejÀrel rakendanud vÀljundmudelit kÔigile oma andmetele. Just siin nÀitavad Spark ja MLflow end parimal vÔimalikul viisil.
Paigaldame PySpark + Jupyter + Spark
Allikas:
NÀidates, kuidas rakendame MLflow mudeleid Spark DataFrame'idele, peate seadistama Jupyteri ja PySpark koostöö.
Alustage viimase stabiilse versiooni installimisega :
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 ~/sparkInstallige PySpark ja Jupyter virtuaalsesse keskkonda:
pip install pyspark jupyterSeadistage 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" MÀÀratledes notebook-dir, saame hoida meie notebooke soovitud kaustas.
KĂ€ivitage Jupyter PySparkist
Kuna suutsime seadistada Jupiteri PySpark juhtimiseks, saame nĂŒĂŒd kĂ€ivitada Jupyteri mĂ€rkmiku PySpark kontekstis.
(mlflow) afranzi:~$ pyspark
[I 19:05:01.572 NotebookApp] sparkmagic laiendus on aktiveeritud!
[I 19:05:01.573 NotebookApp] Teen notebooke kohalikus kataloogis: /Users/afranzi/Projects/notebooks
[I 19:05:01.573 NotebookApp] Jupyter Notebook töötab aadressil:
[I 19:05:01.573 NotebookApp] http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745
[I 19:05:01.573 NotebookApp] Kasutage Control-C, et peatada see server ja sulgeda kÔik tuumad (kaks korda, et kinnitamisest mööda minna).
[C 19:05:01.574 NotebookApp]
Kopeerige/kleepige see URL oma brauserisse, kui ĂŒhendate esmakordselt,
et sisse logida toega:
http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745 
Nagu eespool öeldud, pakub MLflow mudeli artefaktide logimise funktsiooni S3-s. Kui meil on valitud mudel, saame selle importida UDF-ina, kasutades moodulit mlflow.pyfunc.
import mlflow.pyfunc
model_path = 's3:///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) 
PySpark â Veini kvaliteedi ennustuse vĂ€ljund
Me oleme seni rÀÀkinud, kuidas kasutada PySpark'i koos MLflow'ga, kÀivitades veini kvaliteedi ennustamise kogu veini andmehulgaga. Kuid mida teha, kui peate kasutama MLflow Python mooduleid Scala Sparkist?
Me oleme seda katsetanud, jagades Spark'i konteksti Scala ja Python vahel. St registreerisime MLflow UDF-i Pythonis ja kasutasime seda Scalas (jah, see ei pruugi olla parim lahendus, aga mis meil on).
Scala Spark + MLflow
Selle nÀite jaoks lisame olemasolevasse Jupyterisse.
Installeerime Spark + Toree + Jupyter
pip install toree
jupyter toree install --spark_home=${SPARK_HOME} --sys-prefix
jupyter kernelspec list
```
```
Saadaval kernelid:
apache_toree_scala /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/apache_toree_scala
python3 /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/python3
```Nagu nÀha on lisatud notebook'ist, kasutatakse UDF-i koos Spark'i ja PySpark'iga. Loodame, et see osa on kasulik neile, kes armastavad Scala't ja soovivad juurutada masinÔppe mudeleid tootmises.
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..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 artikli kirjutamise ajal on MLflow Alpha-versioonis, nĂ€eb see ĂŒsna paljutĂ”otav vĂ€lja. Ainult vĂ”imalus kasutada erinevaid masinĂ”ppe raamistikke ja kasutada neid ĂŒhest lĂ”pp-punktist viib soovitusgeneratsioonisĂŒsteemid uuele tasemele.
Lisaks sellele toob MLflow andmeinsenerid ja andeteadlasi lĂ€hemale, luues nende vahele ĂŒhise kihi.
PĂ€rast seda MLflow uuringut oleme kindlad, et liigume edasi ja kasutame seda oma Spark'i torudes ja soovitussĂŒsteemides.
Oleks hea sĂŒnkroniseerida failide salvestamine andmebaasiga, mitte failisĂŒsteemiga. Nii peaksime saama mitmeid lĂ”pp-punkte, mis saavad kasutada sama failide salvestust. NĂ€iteks kasutada mitut instantsi. ja sama Glue metastore'iga.
KokkuvÔtteks tahaks tÀnada MLFlow kogukonda, et teete meie andmetööd huvitavamaks.
Kui katsetate MLflow'ga, siis Àrge kartke meile kirjutada ja rÀÀkida, kuidas te seda kasutate, eriti kui kasutate seda tootmises.
Tutvuge kursustega:
Loe edasi:
Allikas: habr.com
