الغرض من هذه المقالة هو مشاركة تجربتنا الأولى مع MLflow .
سنبدأ مراجعتنا لـ MLflow من خادم التتبع الخاص به ونستمر في جميع تكرارات الدراسة. ثم سنشارك تجربتنا في ربط Spark بـ MLflow باستخدام UDFs.
سياق الكلام
في Alpha Health ، نستخدم التعلم الآلي والذكاء الاصطناعي لتمكين الأشخاص من الاهتمام بصحتهم ورفاهيتهم. هذا هو السبب في أن نماذج التعلم الآلي هي في صميم منتجات البيانات التي نطورها ، ولهذا السبب تم لفت انتباهنا إلى MLflow ، وهو نظام أساسي مفتوح المصدر يغطي جميع جوانب دورة حياة التعلم الآلي.
MLflow
والهدف الرئيسي من MLflow هو توفير طبقة إضافية على رأس تعلم الآلة التي من شأنها أن تسمح للعلماء البيانات إلى العمل مع مكتبة تقريبا أي تعلم آلة ( H2O ، keras ، mleap ، pytorch ، sklearn و tensorflow )، نقله إلى المستوى التالي.
يوفر MLflow ثلاثة مكونات:
- التتبع - تجارب التسجيل والاستعلام: التعليمات البرمجية والبيانات والتكوين والنتائج. من المهم جدًا متابعة عملية إنشاء النموذج.
- المشاريع - تنسيق التعبئة والتغليف للتشغيل على أي منصة (مثل SageMaker )
- النماذج هي تنسيق شائع لإرسال النماذج إلى أدوات النشر المختلفة.
MLflow (ألفا في وقت كتابة هذا التقرير) هو نظام أساسي مفتوح المصدر يسمح لك بإدارة دورة حياة التعلم الآلي ، بما في ذلك التجريب وإعادة الاستخدام والنشر.
تكوين MLflow
لاستخدام MLflow ، تحتاج أولاً إلى إعداد بيئة Python بأكملها ، لذلك سنستخدم PyEnv (لتثبيت Python على Mac ، ألق نظرة هنا ). حتى نتمكن من إنشاء بيئة افتراضية حيث سنقوم بتثبيت جميع المكتبات اللازمة للتشغيل.
```
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
```
ملاحظة: نحن نستخدم PyArrow لتشغيل نماذج مثل UDFs. يجب إصلاح إصدارات PyArrow و Numpy لأن أحدث الإصدارات كانت متضاربة.
إطلاق واجهة المستخدم للتتبع
يتيح لنا MLflow Tracking تسجيل التجارب وتقديم طلبات لها باستخدام Python و REST API. بالإضافة إلى ذلك ، يمكنك تحديد مكان تخزين عناصر النموذج (المضيف المحلي أو Amazon S3 أو Azure Blob Storage أو Google Cloud Storage أو خادم SFTP ). نظرًا لأننا نستخدم AWS في Alpha Health ، فسيتم استخدام 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 ، لأننا نحتاج فقط إلى المسار إلى النموذج.
ملاحظة: ضع في اعتبارك أن واجهة مستخدم التتبع والعميل النموذجي يجب أن يكون لهما حق الوصول إلى موقع القطعة الأثرية. أي ، بغض النظر عن حقيقة أن واجهة المستخدم للتتبع موجودة في مثيل EC2 ، عندما يتم تشغيل MLflow محليًا ، يجب أن يكون للجهاز وصول مباشر إلى S3 لكتابة النماذج الأثرية.
تقوم واجهة مستخدم التتبع بتخزين العناصر الأثرية في حاوية S3
نماذج التشغيل
بمجرد تشغيل خادم التتبع ، يمكنك البدء في تدريب النماذج.
كمثال ، سنستخدم تعديل النبيذ من مثال MLflow في Sklearn .
MLFLOW_TRACKING_URI=http://localhost:5000 python wine_quality.py \
--alpha 0.9
--l1_ration 0.5
--wine_file ./data/winequality-red.csv
كما قلنا سابقًا ، يتيح لك MLflow تسجيل المعلمات والمقاييس والقطع الأثرية للنماذج بحيث يمكنك تتبع كيفية تطورها أثناء تكرارها. هذه الميزة مفيدة للغاية ، لأنه بهذه الطريقة يمكننا إعادة إنتاج أفضل نموذج عن طريق الاتصال بخادم التتبع أو من خلال فهم الرمز الذي قام بإجراء التكرار المطلوب باستخدام سجلات تنفيذ تجزئة git.
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 ، الذي تم إطلاقه باستخدام الأمر "mlflow server" ، على واجهة برمجة تطبيقات REST لتتبع عمليات الإطلاق وكتابة البيانات إلى نظام الملفات المحلي. يمكنك تحديد عنوان خادم التتبع باستخدام متغير البيئة "MLFLOW_TRACKING_URI" وستتصل واجهة برمجة تطبيقات MLflow للتتبع تلقائيًا بخادم التتبع على هذا العنوان لإنشاء / الحصول على معلومات الإطلاق ومقاييس السجل ، إلخلتزويد النموذج بخادم ، نحتاج إلى خادم تتبع قيد التشغيل (راجع واجهة التشغيل) ومعرف تشغيل النموذج.
المصدر: Docs // تشغيل خادم تتبع
معرف التشغيل
# 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 ، نحتاج إلى الوصول إلى واجهة مستخدم التتبع للحصول على معلومات حول النموذج ببساطة عن طريق التحديد
--run_id.
بمجرد أن يتواصل النموذج مع خادم التتبع ، يمكننا الحصول على نقطة نهاية النموذج الجديد.
# 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
على الرغم من حقيقة أن خادم التتبع قوي بما يكفي لخدمة النماذج في الوقت الفعلي ، قم بتدريبهم واستخدام وظيفة الخدمة (المصدر: mlflow // docs // Models # local ) ، فإن استخدام Spark (الدفعة أو البث) يعد حلاً أكثر قوة لـ حساب التوزيع.
تخيل أنك قمت للتو بالتدريب دون اتصال بالإنترنت ثم قمت بتطبيق نموذج الإخراج على جميع بياناتك. هذا هو المكان الذي ستظهر فيه Spark و MLflow أفضل ما لديهم.
قم بتثبيت PySpark + Jupyter + Spark
المصدر: ابدأ PySpark - Jupyter
لإظهار كيفية تطبيقنا لنماذج MLflow على إطارات بيانات Spark ، نحتاج إلى إعداد دفاتر 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، يمكننا تخزين دفاتر الملاحظات الخاصة بنا في المجلد المطلوب.
إطلاق Jupyter من PySpark
نظرًا لأننا تمكنا من إعداد Jupiter باعتباره برنامج تشغيل 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
كما ذكر أعلاه ، يوفر 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)
PySpark - إخراج توقعات جودة النبيذ
حتى هذه النقطة ، تحدثنا عن كيفية استخدام PySpark مع MLflow من خلال تشغيل تنبؤات جودة النبيذ على مجموعة بيانات النبيذ بأكملها. ولكن ماذا لو كنت بحاجة إلى استخدام وحدات Python MLflow من Scala Spark؟
اختبرنا ذلك أيضًا عن طريق تقسيم سياق Spark بين Scala و Python. أي أننا سجلنا MLflow UDF في Python ، واستخدمناه من Scala (نعم ، ربما ليس الحل الأفضل ، ولكن ما لدينا).
سكالا سبارك + MLflow
في هذا المثال ، سنضيف Toree Kernel إلى كوكب المشتري الحالي.
قم بتثبيت 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. نأمل أن يكون هذا الجزء مفيدًا لأولئك الذين يحبون سكالا ويريدون نشر نماذج التعلم الآلي في الإنتاج.
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 في Alpha وقت كتابة هذا التقرير ، إلا أنه يبدو واعدًا جدًا. إن مجرد القدرة على تشغيل أطر عمل متعددة للتعلم الآلي واستخدامها من نقطة نهاية واحدة يأخذ أنظمة التوصية إلى المستوى التالي.
بالإضافة إلى ذلك ، يعمل MLflow على التقريب بين مهندسي البيانات وعلماء البيانات من خلال إنشاء طبقة مشتركة بينهم.
بعد إجراء هذا البحث على MLflow ، نحن على ثقة من أننا سنمضي قدمًا ونستخدمه لخطوط أنابيب Spark وأنظمة التوصية.
سيكون من الجيد مزامنة تخزين الملفات مع قاعدة البيانات بدلاً من نظام الملفات. بهذه الطريقة نحتاج إلى الحصول على نقاط نهاية متعددة يمكنها استخدام نفس تخزين الملفات. على سبيل المثال ، استخدم مثيلات متعددة من Prestoو أثينا مع نفسه metastore الغراء.
للتلخيص ، أود أن أشكر مجتمع MLFlow لجعل عملنا مع البيانات أكثر إثارة للاهتمام.
إذا كنت تلعب مع MLflow ، فلا تتردد في مراسلتنا وإخبارنا بكيفية استخدامك لها ، وأكثر من ذلك إذا كنت تستخدمها في الإنتاج.
تعرف على المزيد حول الدورات:
التعلم الآلي. دورة تعلم الآلة الأساسية
. دورة متقدمة
اقرأ أكثر: