MLflow ilə Spark genişləndirilir

Salam, Xabrovitlər. Artıq yazdığımız kimi, bu ay OTUS maşın öyrənməsi üzrə bir anda iki kursa başlayır, yəni baza и qabaqcıl. Bu baxımdan faydalı material paylaşmağa davam edirik.

Bu məqalənin məqsədi ilk təcrübəmiz haqqında danışmaqdır MLflow.

Baxışa başlayacağıq MLflow onun izləmə serverindən və tədqiqatın bütün iterasiyalarını proloqdan çıxarın. Sonra UDF istifadə edərək Spark-ı MLflow ilə birləşdirmək təcrübəsini paylaşacağıq.

Kontekst

İçindəyik Alfa Sağlamlığı biz maşın öyrənməsi və süni intellektdən istifadə edərək insanlara öz sağlamlıqlarının və rifahının qayğısına qalmağa imkan veririk. Buna görə də maşın öyrənməsi modelləri hazırladığımız məlumat məhsullarının mərkəzində dayanır və buna görə də maşın öyrənməsinin həyat dövrünün bütün aspektlərini əhatə edən açıq mənbə platforması olan MLflow diqqətimizi çəkdi.

MLflow

MLflow-un əsas məqsədi, məlumat alimlərinə demək olar ki, hər hansı bir maşın öyrənmə kitabxanası ilə işləməyə imkan verən maşın öyrənməsinin üstünə əlavə bir təbəqə təmin etməkdir (h2o, keras, sıçrayış, pitorch, sklearn и tensorflow), işini növbəti səviyyəyə qaldırır.

MLflow üç komponenti təmin edir:

  • İzləmə – təcrübələr üçün qeyd və sorğular: kod, verilənlər, konfiqurasiya və nəticələr. Modelin yaradılması prosesini izləmək çox vacibdir.
  • Layihələr – İstənilən platformada işləmək üçün qablaşdırma formatı (məsələn, SageMaker)
  • Models müxtəlif yerləşdirmə alətlərinə modellər təqdim etmək üçün ümumi formatdır.

MLflow (yazı zamanı alfa) təcrübə, təkrar istifadə və yerləşdirmə daxil olmaqla, maşın öyrənməsinin həyat dövrünü idarə etməyə imkan verən açıq mənbə platformasıdır.

MLflow quraşdırılması

MLflow-dan istifadə etmək üçün əvvəlcə bütün Python mühitini qurmalısınız, bunun üçün istifadə edəcəyik PyEnv (Mac-də Python quraşdırmaq üçün nəzər salın burada). Beləliklə, işləmək üçün lazım olan bütün kitabxanaları quraşdıracağımız virtual mühit yarada bilərik.

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

Lazımi kitabxanaları quraşdırın.

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

Qeyd: UDF kimi modelləri işə salmaq üçün PyArrow istifadə edirik. PyArrow və Numpy versiyaları düzəldilməli idi, çünki son versiyalar bir-biri ilə ziddiyyət təşkil edirdi.

İzləmə UI işə salınır

MLflow İzləmə bizə Python və ilə təcrübələri daxil etməyə və sorğulamağa imkan verir REST API. Bundan əlavə, siz model artefaktlarının harada saxlanacağını müəyyən edə bilərsiniz (localhost, Amazon S3, Azure Blob Yaddaşı, Google Bulud Yaddaşı və ya SFTP server). Alpha Health-də AWS istifadə etdiyimiz üçün S3 artefaktların saxlanması olacaq.

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

MLflow davamlı fayl yaddaşından istifadə etməyi tövsiyə edir. Fayl yaddaşı serverin işlək və sınaq metadata saxlayacağı yerdir. Serveri işə salarkən, onun davamlı fayl yaddaşına işarə etdiyinə əmin olun. Burada təcrübə xatirinə sadəcə istifadə edəcəyik /tmp.

Nəzərə alın ki, köhnə təcrübələri yerinə yetirmək üçün mlflow serverindən istifadə etmək istəyiriksə, onlar fayl anbarında olmalıdır. Bununla belə, bu olmasa belə, biz onları UDF-də istifadə edə bilərik, çünki bizə yalnız modelə gedən yol lazımdır.

Qeyd: Nəzərə alın ki, İzləmə UI və model müştərinin artefaktın yerinə girişi olmalıdır. Yəni, İzləmə UI-nin EC2 instansiyasında yerləşməsindən asılı olmayaraq, MLflow-u yerli olaraq işlədərkən, artefakt modellərini yazmaq üçün maşının S3-ə birbaşa çıxışı olmalıdır.

MLflow ilə Spark genişləndirilir
İzləmə UI artefaktları S3 qutusunda saxlayır

Çalışan Modellər

İzləmə serveri işə düşən kimi siz modelləri öyrətməyə başlaya bilərsiniz.

Nümunə olaraq, MLflow nümunəsindəki şərab modifikasiyasından istifadə edəcəyik Sklearn.

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

Dediyimiz kimi, MLflow sizə parametrləri, ölçüləri və model artefaktlarını qeyd etməyə imkan verir ki, onların təkrarlanma kimi necə inkişaf etdiyini izləyə biləsiniz. Bu funksiya son dərəcə faydalıdır, çünki o, bizə İzləmə serveri ilə əlaqə saxlamaqla və ya mitinqlərin git hash qeydlərindən istifadə edərək tələb olunan iterasiyanı hansı kodun yerinə yetirdiyini başa düşməklə ən yaxşı modeli təkrar istehsal etməyə imkan verir.

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

MLflow ilə Spark genişləndirilir
şərab iterasiyaları

Model üçün arxa tərəf

“mlflow server” əmri ilə işə salınan MLflow izləmə serverində əməliyyatları izləmək və məlumatların yerli fayl sisteminə yazılması üçün REST API var. Siz "MLFLOW_TRACKING_URI" mühit dəyişənindən istifadə edərək izləmə serverinin ünvanını təyin edə bilərsiniz və MLflow izləmə API-si işə salma məlumatı, giriş göstəriciləri və s. yaratmaq/almaq üçün avtomatik olaraq bu ünvandakı izləmə serveri ilə əlaqə saxlayacaq.

Mənbə: Sənədlər// İzləmə serverinin işə salınması

Modeli serverlə təmin etmək üçün bizə işləyən izləmə serveri (başlatma interfeysinə baxın) və modelin Run ID-si lazımdır.

MLflow ilə Spark genişləndirilir
ID-ni işə salın

# 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

MLflow xidmət funksiyasından istifadə edən modellərə xidmət göstərmək üçün sadəcə olaraq qeyd etməklə model haqqında məlumat əldə etmək üçün İzləmə UI-yə daxil olmalıyıq. --run_id.

Model İzləmə Serveri ilə əlaqə saxladıqdan sonra yeni model son nöqtəsini əldə edə bilərik.

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

Spark-dan işləyən modellər

İzləmə serverinin real vaxt rejimində modellərə xidmət göstərmək, onları öyrətmək və server funksionallığından istifadə etmək üçün kifayət qədər güclü olmasına baxmayaraq (mənbə: mlflow // sənədlər // modellər #yerli), Spark-dan istifadə (toplu və ya axın) paylanmasına görə daha güclü həlldir.

Təsəvvür edin ki, siz indicə oflayn məşq etdiniz və sonra çıxış modelini bütün məlumatlarınıza tətbiq etdiniz. Spark və MLflow-un özünə gəldiyi yer budur.

PySpark + Jupyter + Spark quraşdırın

Mənbə: Başlayın PySpark - Jupyter

MLflow modellərini Spark dataframelərinə necə tətbiq etdiyimizi göstərmək üçün PySpark ilə işləmək üçün Jupyter noutbuklarını qurmalıyıq.

Ən son stabil versiyanı quraşdırmaqla başlayın 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 və Jupyter-i virtual mühitdə quraşdırın:

pip install pyspark jupyter

Ətraf mühit dəyişənlərini qurun:

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üəyyən edərək notebook-dir, notebooklarımızı istədiyiniz qovluqda saxlaya biləcəyik.

PySpark-dan Jupyter işlədir

Yupiteri PySpark sürücüsü kimi qura bildiyimiz üçün indi Jupyter noutbukunu PySpark kontekstində işlədə bilərik.

(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

MLflow ilə Spark genişləndirilir

Yuxarıda qeyd edildiyi kimi, MLflow S3-də model artefaktlarını qeyd etmək funksiyasını təmin edir. Seçilmiş modeli əlimizdə olan kimi moduldan istifadə edərək onu UDF kimi idxal etmək imkanımız var 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)

MLflow ilə Spark genişləndirilir
PySpark - Şərab keyfiyyətinin proqnozlaşdırılması

Bu nöqtəyə qədər biz bütün şərab məlumat dəstində şərab keyfiyyətinin proqnozlaşdırılmasını işlətməklə PySpark-ı MLflow ilə necə istifadə etmək barədə danışdıq. Bəs Scala Spark-dan Python MLflow modullarından istifadə etməlisinizsə?

Spark kontekstini Scala və Python arasında bölməklə bunu da sınaqdan keçirdik. Yəni, biz Python-da MLflow UDF-ni qeydiyyatdan keçirdik və onu Scala-dan istifadə etdik (bəli, bəlkə də ən yaxşı həll deyil, amma bizdə olanlar).

Scala Spark + MLflow

Bu nümunə üçün əlavə edəcəyik Toree Kernel mövcud Yupiterə çevrilir.

Spark + Toree + Jupyter quraşdırın

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

Əlavə edilmiş notebookdan göründüyü kimi, UDF Spark və PySpark arasında paylaşılır. Ümid edirik ki, bu hissə Scala-nı sevənlər və maşın öyrənmə modellərini istehsala tətbiq etmək istəyənlər üçün faydalı olacaq.

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

Sonrakı addımlar

Yazı zamanı MLflow Alpha-da olsa da, olduqca perspektivli görünür. Sadəcə birdən çox maşın öyrənmə çərçivələrini işə salmaq və onlardan bir son nöqtədən istifadə etmək tövsiyə sistemlərini növbəti səviyyəyə aparır.

Bundan əlavə, MLflow Data mühəndisləri və Data Scientists-i bir-birinə yaxınlaşdıraraq, onların arasında ümumi təbəqə yaradır.

MLflow-un bu kəşfindən sonra biz əminik ki, davam edəcəyik və ondan Spark boru kəmərlərimiz və tövsiyə sistemlərimiz üçün istifadə edəcəyik.

Fayl sistemi əvəzinə fayl yaddaşını verilənlər bazası ilə sinxronlaşdırmaq yaxşı olardı. Bu, bizə eyni fayl paylaşımından istifadə edə biləcək çoxlu son nöqtələr verməlidir. Məsələn, bir neçə nümunədən istifadə edin Presto и Athena eyni Glue metastore ilə.

Yekun olaraq, məlumatlarla işimizi daha maraqlı etdiyinə görə MLFlow icmasına təşəkkür etmək istərdim.

Əgər MLflow ilə oynayırsınızsa, bizə yazın və ondan necə istifadə etdiyinizi və hətta istehsalda istifadə etdiyiniz təqdirdə daha çox məlumat verin.

Kurslar haqqında ətraflı məlumat əldə edin:
maşın öyrənməsi. Əsas kurs
maşın öyrənməsi. təkmil kurs

Daha çox oxu:

Mənbə: www.habr.com

Добавить комментарий