Rozšírenie Spark s MLflow

Dobrý deň, obyvatelia Khabrovska. Ako sme už písali, tento mesiac OTUS spúšťa dva kurzy strojového učenia naraz, a to základňu и pokročilé. V tejto súvislosti pokračujeme v zdieľaní užitočných materiálov.

Účelom tohto článku je hovoriť o našich prvých skúsenostiach s používaním MLflow.

Začneme recenziu MLflow zo svojho sledovacieho servera a zaznamenajte všetky iterácie štúdie. Potom sa podelíme o naše skúsenosti s prepojením Spark s MLflow pomocou UDF.

kontext

Sme v tom Alpha Health Používame strojové učenie a umelú inteligenciu, aby sme ľuďom umožnili prevziať zodpovednosť za svoje zdravie a pohodu. Preto sú modely strojového učenia jadrom produktov pre vedu o údajoch, ktoré vyvíjame, a preto nás zaujal MLflow, platforma s otvoreným zdrojom, ktorá pokrýva všetky aspekty životného cyklu strojového učenia.

MLflow

Hlavným cieľom MLflow je poskytnúť ďalšiu vrstvu nad strojovým učením, ktorá by umožnila vedcom údajov pracovať s takmer akoukoľvek knižnicou strojového učenia (h2o, KERAS, mleap, pytorch, sklearn и tensorflow), posúvajúc jej prácu na ďalšiu úroveň.

MLflow poskytuje tri komponenty:

  • Sledovanie – zaznamenávanie a požiadavky na experimenty: kód, údaje, konfigurácia a výsledky. Sledovanie procesu tvorby modelu je veľmi dôležité.
  • projekty – Formát balenia na spustenie na akejkoľvek platforme (napr. SageMaker)
  • Modely – spoločný formát na predkladanie modelov rôznym nástrojom nasadenia.

MLflow (v čase písania vo verzii alfa) je platforma s otvoreným zdrojom, ktorá vám umožňuje spravovať životný cyklus strojového učenia vrátane experimentovania, opätovného použitia a nasadenia.

Nastavenie MLflow

Ak chcete používať MLflow, musíte najprv nastaviť celé prostredie Pythonu, na čo použijeme PyEnv (ak chcete nainštalovať Python na Mac, pozrite sa tu). Takto si vytvoríme virtuálne prostredie, kde nainštalujeme všetky knižnice potrebné na jeho spustenie.

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

Nainštalujeme potrebné knižnice.

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

Poznámka: PyArrow používame na spustenie modelov, ako je UDF. Verzie PyArrow a Numpy bolo potrebné opraviť, pretože posledné verzie boli vo vzájomnom konflikte.

Spustite používateľské rozhranie sledovania

MLflow Tracking nám umožňuje zaznamenávať a dotazovať experimenty pomocou Pythonu a REST API. Okrem toho môžete určiť, kam sa majú ukladať artefakty modelu (localhost, amazon S3, Azure Blob Storage, Google Cloud Storage alebo SFTP server). Keďže v Alpha Health používame AWS, naše úložisko artefaktov bude S3.

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

MLflow odporúča používať trvalé ukladanie súborov. Úložisko súborov je miesto, kde bude server ukladať metadáta spustenia a experimentu. Pri spúšťaní servera sa uistite, že ukazuje na trvalé úložisko súborov. Tu na experiment jednoducho použijeme /tmp.

Pamätajte, že ak chceme použiť server mlflow na spustenie starých experimentov, musia byť prítomné v úložisku súborov. Avšak aj bez toho by sme ich mohli použiť v UDF, keďže potrebujeme iba cestu k modelu.

Poznámka: Majte na pamäti, že používateľské rozhranie sledovania a klient modelu musia mať prístup k umiestneniu artefaktu. To znamená, že bez ohľadu na to, že používateľské rozhranie sledovania sa nachádza v inštancii EC2, pri lokálnom spustení MLflow musí mať počítač priamy prístup k S3, aby mohol zapisovať modely artefaktov.

Rozšírenie Spark s MLflow
Sledovacie používateľské rozhranie ukladá artefakty do vedra S3

Bežecké modely

Hneď ako je spustený sledovací server, môžete začať trénovať modely.

Ako príklad použijeme úpravu vína z príkladu MLflow v Sklearn.

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

Ako sme už diskutovali, MLflow vám umožňuje zaznamenávať parametre modelu, metriky a artefakty, aby ste mohli sledovať, ako sa počas iterácií vyvíjajú. Táto funkcia je mimoriadne užitočná, pretože týmto spôsobom môžeme reprodukovať najlepší model kontaktovaním sledovacieho servera alebo porozumením, ktorý kód dokončil požadovanú iteráciu pomocou git hash logov odovzdaní.

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

Rozšírenie Spark s MLflow
Iterácie vína

Serverová časť pre model

Sledovací server MLflow, spustený pomocou príkazu „mlflow server“, má rozhranie REST API na sledovanie chodov a zapisovanie údajov do lokálneho systému súborov. Adresu servera sledovania môžete zadať pomocou premennej prostredia „MLFLOW_TRACKING_URI“ a rozhranie API na sledovanie MLflow automaticky kontaktuje server sledovania na tejto adrese, aby vytvoril/prijal informácie o spustení, metriky denníka atď.

Zdroj: Dokumenty// Spustenie sledovacieho servera

Aby sme mohli modelu poskytnúť server, potrebujeme server na sledovanie spustenia (pozri rozhranie spustenia) a Run ID modelu.

Rozšírenie Spark s MLflow
Spustiť 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

Na poskytovanie modelov pomocou funkcie poskytovania MLflow budeme potrebovať prístup do používateľského rozhrania sledovania, aby sme mohli získať informácie o modeli jednoduchým zadaním --run_id.

Keď sa model spojí so serverom sledovania, môžeme získať nový koncový bod modelu.

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

Bežecké modely od Spark

Napriek tomu, že Tracking server je dostatočne výkonný na to, aby obsluhoval modely v reálnom čase, trénoval ich a využíval funkcionalitu servera (zdroj: mlflow // docs // modely # local), je použitie Spark (dávkové alebo streamovanie) ešte výkonnejšie riešenie vďaka distribúcii.

Predstavte si, že ste jednoducho urobili školenie offline a potom ste použili výstupný model na všetky svoje údaje. To je miesto, kde Spark a MLflow žiaria.

Nainštalujte PySpark + Jupyter + Spark

Zdroj: Začnite PySpark - Jupyter

Aby sme ukázali, ako aplikujeme modely MLflow na dátové rámce Spark, musíme nastaviť notebooky Jupyter, aby spolupracovali s PySpark.

Začnite inštaláciou najnovšej stabilnej verzie 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̀

Nainštalujte PySpark a Jupyter vo virtuálnom prostredí:

pip install pyspark jupyter

Nastavte premenné prostredia:

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"

Po určení notebook-dir, môžeme si zošity uložiť do požadovaného priečinka.

Spustenie Jupyter z PySpark

Keďže sme boli schopní nakonfigurovať Jupiter ako ovládač PySpark, teraz môžeme spustiť notebook Jupyter v kontexte 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

Rozšírenie Spark s MLflow

Ako je uvedené vyššie, MLflow poskytuje funkciu na zaznamenávanie artefaktov modelu v S3. Hneď ako máme vybraný model v rukách, máme možnosť ho pomocou modulu importovať ako UDF 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)

Rozšírenie Spark s MLflow
PySpark - Výstupné predpovede kvality vína

Až do tohto bodu sme hovorili o tom, ako používať PySpark s MLflow a spúšťať predpovede kvality vína v celom súbore údajov o víne. Čo ak však potrebujete použiť moduly Python MLflow od Scala Spark?

Testovali sme to aj rozdelením kontextu Spark medzi Scala a Python. To znamená, že sme zaregistrovali MLflow UDF v Pythone a použili ho zo Scaly (áno, možno to nie je najlepšie riešenie, ale čo máme).

Scala Spark + MLflow

Pre tento príklad doplníme Toree Kernel do existujúceho Jupitera.

Nainštalujte 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
```

Ako môžete vidieť z priloženého poznámkového bloku, UDF je zdieľaný medzi Spark a PySpark. Dúfame, že táto časť bude užitočná pre tých, ktorí milujú Scala a chcú nasadiť modely strojového učenia vo výrobe.

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

Ďalšie kroky

Aj keď je MLflow v čase písania vo verzii Alpha, vyzerá celkom sľubne. Už len schopnosť spúšťať viacero rámcov strojového učenia a využívať ich z jedného koncového bodu posúva systémy odporúčaní na ďalšiu úroveň.

Okrem toho MLflow zbližuje Data Engineers a Data Science špecialistov a vytvára medzi nimi spoločnú vrstvu.

Po tomto prieskume MLflow sme si istí, že sa pohneme vpred a použijeme ho pre naše potrubia Spark a systémy odporúčaní.

Bolo by pekné synchronizovať úložisko súborov s databázou namiesto systému súborov. To by nám malo poskytnúť viacero koncových bodov, ktoré môžu používať rovnaké úložisko súborov. Napríklad použite viacero inštancií Presto и Athena s rovnakým Glue metastore.

Aby som to zhrnul, rád by som sa poďakoval komunite MLFlow za to, že naša práca s dátami bola zaujímavejšia.

Ak sa s MLflow pohrávate, neváhajte nám napísať a povedzte nám, ako ho používate, a ešte viac, ak ho používate vo výrobe.

Zistite viac o kurzoch:
Strojové učenie. Základný kurz
Strojové učenie. Kurz pre pokročilých

Čítaj viac:

Zdroj: hab.com

Pridať komentár