Spark-г MLflow ашиглан өргөтгөж байна

Сайн байна уу, Хабаровскийн оршин суугчид. Бид аль хэдийн бичсэнчлэн энэ сард OTUS нэг дор хоёр машин сургалтын сургалтыг эхлүүлж байна суурь и дэвшилтэт. Үүнтэй холбогдуулан бид хэрэгтэй материалаа үргэлжлүүлэн хуваалцсаар байна.

Энэ нийтлэлийн зорилго нь бидний анхны хэрэглээний талаар ярих явдал юм MLflow.

Бид шалгалтыг эхлүүлнэ MLflow хянах серверээс болон судалгааны бүх давталтыг бүртгэнэ. Дараа нь бид UDF ашиглан Spark-ийг MLflow-тай холбох туршлагаа хуваалцах болно.

Агуулга

Бид орж байна Альфа эрүүл мэнд Хүмүүсийг эрүүл мэнд, сайн сайхан байдалд нь хариуцах боломжийг олгохын тулд бид машин сургалт болон хиймэл оюун ухааныг ашигладаг. Тийм ч учраас машин сургалтын загварууд нь бидний хөгжүүлж буй өгөгдлийн шинжлэх ухааны бүтээгдэхүүний гол цөм нь байдаг тул бид машин сургалтын амьдралын мөчлөгийн бүх талыг хамарсан нээлттэй эхийн платформ болох MLflow-д татагдсан юм.

MLflow

MLflow-ийн гол зорилго нь өгөгдөл судлаачдад машин сургалтын бараг бүх номын сантай ажиллах боломжийг олгодог машин сургалтын дээд давхаргыг хангах явдал юм.h2o, керас, үсрэх, пирторч, склерн и tensorflow), түүний ажлыг дараагийн шатанд гаргах.

MLflow нь гурван бүрэлдэхүүн хэсгийг хангадаг:

  • дагах нь – туршилтын бичлэг, хүсэлт: код, өгөгдөл, тохиргоо, үр дүн. Загвар бүтээх үйл явцыг хянах нь маш чухал юм.
  • Төслүүд – Ямар ч платформ дээр ажиллах савлагааны формат (жишээ нь. SageMaker)
  • загвар – янз бүрийн байршуулах хэрэгсэлд загвар оруулах нийтлэг формат.

MLflow (бичиж байх үеийн альфа хувилбар) нь туршилт, дахин ашиглах, байршуулах зэрэг машин сургалтын амьдралын мөчлөгийг удирдах боломжийг олгодог нээлттэй эхийн платформ юм.

MLflow-г тохируулж байна

MLflow ашиглахын тулд та эхлээд Python орчныг бүхэлд нь тохируулах хэрэгтэй, үүнд бид ашиглах болно PyEnv (Mac дээр Python суулгахын тулд шалгана уу энд). Ингэснээр бид үүнийг ажиллуулахад шаардлагатай бүх сангуудыг суулгах виртуал орчинг бий болгож чадна.

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

Шаардлагатай номын сангуудыг суулгацгаая.

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

Тэмдэглэл: Бид UDF гэх мэт загваруудыг ажиллуулахын тулд PyArrow ашигладаг. Сүүлийн хувилбарууд хоорондоо зөрчилдсөн тул PyArrow болон Numpy-ийн хувилбаруудыг засах шаардлагатай болсон.

Tracking UI-г ажиллуулна уу

MLflow Tracking нь Python болон ашиглан туршилтыг бүртгэх, асуух боломжийг бидэнд олгодог REST API. Үүнээс гадна, та загвар олдворуудыг хаана хадгалахаа тодорхойлох боломжтой (localhost, Amazon S3, Azure Blob хадгалах сан, Google Cloud Storage буюу SFTP сервер). Бид Alpha Health-д AWS ашигладаг тул бидний олдворын хадгалалт S3 байх болно.

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

MLflow нь байнгын файл хадгалах санг ашиглахыг зөвлөж байна. Файл хадгалах газар нь сервер ажиллуулж, туршилтын мета өгөгдлийг хадгалах газар юм. Серверийг эхлүүлэхдээ энэ нь байнгын файлын дэлгүүр рүү чиглэж байгаа эсэхийг шалгаарай. Энд бид туршилтын хувьд зүгээр л ашиглах болно /tmp.

Хэрэв бид хуучин туршилтуудыг ажиллуулахын тулд mlflow серверийг ашиглахыг хүсвэл тэдгээр нь файлын санд байх ёстой гэдгийг санаарай. Гэсэн хэдий ч үүнгүйгээр бид тэдгээрийг UDF-д ашиглаж болно, учир нь бидэнд зөвхөн загварт хүрэх зам хэрэгтэй болно.

Тайлбар: Tracking UI болон загвар үйлчлүүлэгч нь олдворын байршилд хандах эрхтэй байх ёстой гэдгийг санаарай. Өөрөөр хэлбэл, Tracking UI нь EC2-ийн инстанцид байрлаж байгаагаас үл хамааран MLflow-ийг дотооддоо ажиллуулж байх үед машин нь олдворын загвар бичихийн тулд S3 руу шууд хандах ёстой.

Spark-г MLflow ашиглан өргөтгөж байна
Tracking UI нь олдворуудыг S3 хувин дотор хадгалдаг

Ажиллаж буй загварууд

Tracking server ажиллаж эхэлмэгц та загваруудыг сургаж эхлэх боломжтой.

Жишээ болгон бид MLflow жишээн дээрх дарсны өөрчлөлтийг ашиглах болно Склерн.

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

Бидний өмнө дурдсанчлан MLflow нь загварын параметрүүд, хэмжигдэхүүнүүд болон олдворуудыг бүртгэх боломжийг олгодог бөгөөд ингэснээр та тэдгээр нь давталтын явцад хэрхэн хувьсан өөрчлөгдөж байгааг хянах боломжтой. Энэ функц нь маш ашигтай, учир нь бид Tracking сервертэй холбоо барьж эсвэл git hash logs-ийг ашиглан ямар код шаардлагатай давталт хийсэн болохыг ойлгох замаар хамгийн сайн загварыг гаргах боломжтой.

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

Spark-г MLflow ашиглан өргөтгөж байна
Дарсны давталт

Загварт зориулсан серверийн хэсэг

"mlflow server" командыг ашиглан эхлүүлсэн MLflow хянах сервер нь гүйлтийг хянах, дотоод файлын системд өгөгдөл бичихэд зориулагдсан REST API-тай. Та "MLFLOW_TRACKING_URI" орчны хувьсагчийг ашиглан хяналтын серверийн хаягийг зааж өгөх боломжтой бөгөөд MLflow хянах API нь эхлүүлэх мэдээлэл, бүртгэлийн хэмжигдэхүүн гэх мэтийг үүсгэх/хүлээн авахын тулд энэ хаяг дээрх хяналтын сервертэй автоматаар холбогдоно.

Эх сурвалж: Docs// Хяналтын сервер ажиллуулж байна

Загварыг серверээр хангахын тулд бидэнд ажиллаж байгаа хянах сервер (эхлүүлэх интерфейсийг харна уу) болон загварын Run ID хэрэгтэй.

Spark-г MLflow ашиглан өргөтгөж байна
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

MLflow үйлчилгээний функцийг ашиглан загварт үйлчлэхийн тулд бид зүгээр л зааж өгснөөр загварын талаарх мэдээллийг хүлээн авах Tracking UI руу нэвтрэх шаардлагатай болно. --run_id.

Загвар нь Tracking сервертэй холбогдоход бид шинэ загварын төгсгөлийн цэгийг авах боломжтой.

# 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-аас ажиллаж байгаа загварууд

Tracking сервер нь загваруудад бодит цаг хугацаанд үйлчлэхэд хангалттай хүчирхэг хэдий ч тэднийг сургаж, серверийн функцийг ашиглана уу (эх сурвалж: mlflow // docs // загварууд # орон нутгийн), Spark (багц эсвэл урсгал) ашиглах нь түгээлтийн улмаас бүр илүү хүчирхэг шийдэл юм.

Та офлайнаар сургалтаа хийгээд дараа нь гаралтын загварыг бүх өгөгдөлдөө ашигласан гэж төсөөлөөд үз дээ. Энд Spark болон MLflow гэрэлтдэг.

PySpark + Jupyter + Spark суулгана уу

Эх сурвалж: Эхлээрэй PySpark - Jupyter

Spark датафрэймд MLflow загваруудыг хэрхэн ашиглаж байгааг харуулахын тулд бид Jupyter дэвтэрүүдийг PySpark-тай хамтран ажиллахаар тохируулах хэрэгтэй.

Хамгийн сүүлийн үеийн тогтвортой хувилбарыг суулгаж эхэл 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 болон Jupyter-ийг виртуал орчинд суулгана уу:

pip install pyspark jupyter

Орчны хувьсагчдыг тохируулах:

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"

Шийдвэрлэж байж notebook-dir, бид дэвтэрээ хүссэн хавтсандаа хадгалах боломжтой.

PySpark-аас Jupyter-ийг эхлүүлж байна

Бид Бархасбадь гарагийг PySpark драйвер болгон тохируулах боломжтой болсон тул одоо бид Jupyter дэвтэрийг 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

Spark-г MLflow ашиглан өргөтгөж байна

Дээр дурдсанчлан MLflow нь S3-д загвар олдворуудыг бүртгэх боломжийг олгодог. Сонгосон загвараа гартаа авмагц модулийг ашиглан 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)

Spark-г MLflow ашиглан өргөтгөж байна
PySpark - Дарсны чанарын таамаглалыг гаргаж байна

Энэ хүртэл бид PySpark-ийг MLflow-тай хэрхэн ашиглах талаар ярилцаж, дарсны чанарын таамаглалыг бүхэлд нь дарсны мэдээллийн багц дээр ажиллуулж байсан. Хэрэв та Scala Spark-аас Python MLflow модулиудыг ашиглах шаардлагатай бол яах вэ?

Бид үүнийг мөн Spark контекстийг Scala болон Python хооронд хувааж туршиж үзсэн. Өөрөөр хэлбэл, бид MLflow UDF-ийг Python дээр бүртгүүлж, үүнийг Scala-аас ашигласан (тиймээ, магадгүй хамгийн сайн шийдэл биш, гэхдээ бидэнд байгаа зүйл).

Scala Spark + MLflow

Энэ жишээнд бид нэмэх болно Тори Цөм одоо байгаа Бархасбадь руу.

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

Хавсаргасан дэвтэрээс харахад UDF нь Spark болон PySpark-ийн хооронд хуваагддаг. Энэ хэсэг нь Scala-д дуртай, машин сургалтын загваруудыг үйлдвэрлэлд нэвтрүүлэхийг хүсдэг хүмүүст хэрэг болно гэж найдаж байна.

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

Дараагийн алхамууд

MLflow нь бичиж байх үед альфа хувилбарт байгаа ч гэсэн энэ нь маш ирээдүйтэй харагдаж байна. Олон тооны машин сургалтын тогтолцоог ажиллуулж, тэдгээрийг нэг цэгээс ашиглах чадвар нь зөвлөмж өгөх системийг дараагийн түвшинд хүргэдэг.

Нэмж дурдахад MLflow нь өгөгдлийн инженерүүд болон мэдээллийн шинжлэх ухааны мэргэжилтнүүдийг хооронд нь ойртуулж, тэдгээрийн хооронд нийтлэг давхарга үүсгэдэг.

MLflow-ийн энэхүү хайгуулын дараа бид урагшилж, үүнийг Spark дамжуулах хоолой болон зөвлөмжийн системд ашиглах болно гэдэгт итгэлтэй байна.

Файлын системийн оронд файл хадгалах санг мэдээллийн сантай синхрончлох нь сайхан байх болно. Энэ нь бидэнд нэг файлын хадгалах санг ашиглах олон төгсгөлийн цэгүүдийг өгөх ёстой. Жишээлбэл, олон тохиолдлыг ашигла Presto и Athena ижил Glue метастортой.

Дүгнэж хэлэхэд, бидний өгөгдөлтэй ажиллах ажлыг илүү сонирхолтой болгосон MLFlow нийгэмлэгт баярлалаа гэж хэлмээр байна.

Хэрэв та MLflow-тай тоглож байгаа бол эргэлзэх хэрэггүй, бидэн рүү бичиж, үүнийг хэрхэн ашиглаж байгаагаа, хэрэв та үүнийг үйлдвэрлэлд ашиглаж байгаа бол бүү хэл.

Курсуудын талаар илүү ихийг олж мэдэх:
Машины сургалт. Үндсэн курс
Машины сургалт. Ахисан түвшний сургалт

Цааш унших:

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх