Tere, Habra elanikud. Nagu juba eelnevalt mainisime, kÀivitab OTUS sel kuul kaks masinÔppe kursust, nimelt ja . SeetÔttu jagame jÀtkuvalt kasulikku materjali.
Selle artikli eesmÀrk on rÀÀkida meie esimesest kogemusest kasutades .
. Alustame ĂŒlevaatetest selle jĂ€lgimisserverist ning logime kĂ”ik uurimisiteratsioonid. SeejĂ€rel jagame kogemust Spark'i ĂŒhendamisest MLflow'ga UDF kaudu. tema tracking-serverist ja logime kĂ”ik uurimise iteratsioonid. SeejĂ€rel jagame kogemust Spark'i ĂŒhendamisest MLflow'ga UDF abil.
Kontekst
Meie ITGLOBAL.COM kasutab masinĂ”pet ja tehisintellekti, et anda inimestele vĂ”imalus hoolitseda oma tervise ja heaolu eest. SeetĂ”ttu on masinĂ”ppe mudelid meie andmete töötlemise toote aluseks, ja just seetĂ”ttu köitis meid MLflow â avatud lĂ€htekoodiga platvorm, mis katab masinĂ”ppe eluiga.
MLflow
MLflow'i peamine eesmÀrk on pakkuda masinÔppe kohal tÀiendavat kihti, mis vÔimaldaks andmete teadlastel töötada praktiliselt iga masinÔppe raamatukoguga (, , , , ja ), tÔstes selle töö uuele tasemele.
MLflow pakub kolme komponenti:
- JĂ€lgimine â eksperimentide salvestamine ja pĂ€ringud: kood, andmed, konfiguratsioon ja tulemused. Mudeli loomise protsessi jĂ€lgimine on vĂ€ga oluline.
- Projektid â pakendamisformat, et kĂ€ivitada igasugustel platvormidel (nĂ€iteks, )
- Mudeli â ĂŒldine formaat mudelite saatmiseks erinevatesse juurutustööriistadesse.
MLflow (artikli kirjutamise hetkel alpha-versioon) on avatud lĂ€htekoodiga platvorm, mis vĂ”imaldab hallata masinĂ”ppe elutsĂŒklit, sealhulgas eksperimente, taaskasutust ja juurutamist.
MLflow seadistamine
MLflow kasutamiseks tuleb esmalt seadistada kogu Python keskkond, selleks kasutame (kui soovite Pythonit Macile installida, vaadake ). Nii suudame luua virtuaalse keskkonna, kuhu installime kÔik vajalikud teegid.
```
pyenv install 3.7.0
pyenv global 3.7.0 # Kasutage Python 3.7
mkvirtualenv mlflow # Looge virtuaalne keskkond Python 3.7-ga
workon mlflow
```Installime 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 mudeleid, nagu UDF. PyArrow ja Numpy versioone tuli korrigeerida, kuna viimased versioonid olid omavahel vastuolus.
KÀivitame jÀlgimise kasutajaliidese.
MLflow Tracking vÔimaldab meil logida ja pÀrida eksperimente Pythonis ja API kaudu. Lisaks on vÔimalik mÀÀrata, kus hoida mudeli artefakte (localhost, , , vÔi ). Kuna Alpha Health kasutab AWS-i, on artefaktide ladustamiseks 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 failide ladustamist. Failide ladustamine on koht, kus server hoiab kĂ€ivituste ja eksperimentide metainfot. Serverit kĂ€ivitades veenduge, et see viitaks pĂŒsivale failide ladustamisele. Siin eksperimendi jaoks kasutame lihtsalt /tmp.
Pidage meeles, et kui soovime kasutada mlflow serverit vanade eksperimentide kÀivitamiseks, peavad need olema failide ladustamises olemas. Kuid ka ilma selleta saaksime neid kasutada UDF-is, kuna meil on vaja lihtsalt mudeli teed.
MÀrkus: Pidage meeles, et Tracking UI ja mudeli klient peavad olema ligipÀÀsetavad artefakti asukohale. See tÀhendab, et olenemata sellest, et Tracking UI asub EC2 instantsis, peab MLflow kÀitamise ajal masinal olema otsene ligipÀÀs S3-le artefaktide mudelite kirjutamiseks.

Tracking UI hoiab artefakte S3-s
Mudelite kÀivitamine
Niipea kui Tracking-server töötab, saab alustada mudelite koolitamist.
KÀesoleva nÀitena kasutame MLflow nÀite modifikatsiooni veinist .
MLFLOW_TRACKING_URI=http://localhost:5000 python wine_quality.py
--alpha 0.9
--l1_ratio 0.5
--wine_file ./data/winequality-red.csvKuna me juba ĂŒtlesime, MLflow vĂ”imaldab logida parameetreid, mÔÔdikuid ja mudelite artefakte, et saaksime jĂ€lgida, kuidas need iteratsioonide kĂ€igus arenevad. See funktsioon on ÀÀrmiselt kasulik, kuna nii saame taastada parima mudeli, pöördudes Tracking-serveri poole vĂ”i mĂ”istes, millist koodi vajaliku iteratsiooni tĂ€itmiseks kasutati, tuginedes git hash commit'ide logidele.
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, "model") 
Veini iteratsioonid
Mudelile mÔeldud serveripoolne osa
MLflow jĂ€lgimisserver, mis on kĂ€ivitatud kĂ€sklusega "mlflow server", omab REST API-d, mis vĂ”imaldab jĂ€lgida kĂ€ivitusi ja salvestada andmeid kohalikku failisĂŒsteemi. Saate mÀÀrata jĂ€lgimisserveri aadressi keskkonnamuutuja "MLFLOW_TRACKING_URI" abil ning MLflow jĂ€lgimise API ĂŒhendab automaatselt selle aadressiga, et luua/saada teavet kĂ€ivituste, logi mÔÔtmete jne kohta.
Allikas:
Mudeli teenindamiseks vajame kÀivitatud jÀlgimisserverit (vt kÀivitamise liidest) ja mudeli Run ID-d.

Run 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 teenindamiseks MLflow serve funktsiooni abil vajame juurdepÀÀsu jÀlgimise kasutajaliidesele, et saada mudeli teavet lihtsalt mÀrkimisega --run_id.
Kui mudel on ĂŒhendatud jĂ€lgimisserveriga, saame 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 Sparkis
Kuigi jÀlgimisserver on piisavalt vÔimas, et teenindada reaalajas mudeleid, nende koolitust ja kasutada serve funktsiooni (allikas: ), on Spark (batoon vÔi voog) veelgi vÔimsam lahendus tÀnu jaotusele.
Kujutage ette, et olete just lĂ€bi viinud koolituse offline-reĆŸiimis ja seejĂ€rel rakendanud vĂ€ljundi mudeli kĂ”ikidele oma andmetele. Just siin nĂ€itavad Spark ja MLflow oma parimat kĂŒlge.
Paigaldame PySpark + Jupyter + Spark
Allikas:
Kuna soovime nÀidata, kuidas rakendame MLflow mudeleid Spark'i andmepakettidesse, peame seadma Jupyter notebookide koostöö PySparkiga.
Alustage viimase stabiilse versiooni paigaldamisest :
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 ~/sparkPaigaldage 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ÀÀrates notebook-dir, saame hoida meie notebookid soovitud kaustas.
KĂ€ivita Jupyter PySparkist
Kuna suudame seadistada Jupyter PySpark'i draiveriks, saame nĂŒĂŒd kĂ€ivitada Jupyter notebooki PySpark'i kontekstis.
(mlflow) afranzi:~$ pyspark
[I 19:05:01.572 NotebookApp] sparkmagic laiendamine on lubatud!
[I 19:05:01.573 NotebookApp] Teen notebooks kohaliku katalooge: /Users/afranzi/Projects/notebooks
[I 19:05:01.573 NotebookApp] Jupyter Notebook töötab:
[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 kernlid (kaks korda, et skip kinnitamine).
[C 19:05:01.574 NotebookApp]
Kopeerige/tehke kleepige see URL oma brauserisse, kui te esmakordselt ĂŒhendate,
et sisse logida tokeniga:
http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745 
Nagu eelnevalt mainitud, pakub MLflow mudeli artefaktide logimise funktsiooni S3-s. Kui meil on valida mudel, saame selle importida UDF-na mooduli kaudu 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 prognoosi vĂ€ljund
Seni oleme rÀÀkinud, kuidas kasutada PySpark'i koos MLflow'ga, kÀivitades veini kvaliteedi prognoosi kogu veiniandmete kogumi peal. Aga mida teha, kui soovite kasutada Python MLflow mooduleid Scala Spark'ist?
Me testisime ka seda, jagades Spark'i konteksti Scala ja Python'i vahel. Ehkki registreerisime MLflow UDF'i Python'is ja kasutasime seda Scala's (jah, see ei pruugi olla parim lahendus, aga mis meil on).
Scala Spark + MLflow
Selle nÀite jaoks lisame olemasolevasse Jupiterisse.
Installeerime Spark + Toree + Jupyter
pip install toree
jupyter toree install --spark_home=${SPARK_HOME} --sys-prefix
jupyter kernelspec list
```
```
Saadaval olevad kernelid:
apache_toree_scala /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/apache_toree_scala
python3 /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/python3
```Kuidas nÀha lisatud mÀrkmekotis, kasutatakse UDF'i koos Spark'i ja PySpark'iga. Loodame, et see osa on kasulik neile, kes armastavad Scala't ja soovivad rakendada 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 MLflow on artikli kirjutamise ajal veel Alpha-versioonis, nĂ€eb see vĂ€lja ĂŒsna lubav. Ăksnes vĂ”imalus kasutada mitut masinĂ”ppe raamistikku ja pÀÀseda neile ligi ĂŒhest lĂ”pp-punktist viib soovitus sĂŒsteemid uuele tasemele.
Lisaks toob MLflow andmeinsenerid ja andmete teadlased kokku, luues nende vahel ĂŒhise kihi.
PĂ€rast seda MLflow uurimist usume, et liigume edasi ja hakkame seda kasutama oma Spark-i torustikes ja soovitus sĂŒsteemides.
Olaks tore sĂŒnkroniseerida failide salvestusruum andmebaasiga, mitte failisĂŒsteemiga. Nii peaksime saama mitu lĂ”pp-punkti, mis saavad kasutada samu faile. NĂ€iteks kasutada mitut instantsi ja ĂŒhe ja sama Glue metastore'iga.
KokkuvÔtteks tahaksime tÀnada MLFlow kogukonda, et muudate meie andmetöötluse huvitavamaks.
Kui mÀngite MLflow'ga, Àrge kartke meile kirjutada ja rÀÀkida, kuidas te seda kasutate, eriti kui kasutate seda tootmises.
Lisainfot kursuste kohta:
Loe edasi:
Allikas: habr.com
