MLflow เชธเชพเชฅเซ‡ เชธเซเชชเชพเชฐเซเช• เชตเชฟเชธเซเชคเชฐเซ‡ เช›เซ‡

เชนเซ‡เชฒเซ‹, เช–เชพเชฌเซเชฐเซ‹เชตเชธเซเช• เชฐเชนเซ‡เชตเชพเชธเซ€เช“. เช…เชฎเซ‡ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชฒเช–เซเชฏเซเช‚ เช›เซ‡ เชคเซ‡เชฎ, เช† เชฎเชนเชฟเชจเซ‡ OTUS เชเช• เชธเชพเชฅเซ‡ เชฌเซ‡ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เช•เซ‹เชฐเซเชธ เชถเชฐเซ‚ เช•เชฐเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡, เชเชŸเชฒเซ‡ เช•เซ‡ เชชเชพเชฏเซ‹ ะธ เช…เชฆเซเชฏเชคเชจ. เช† เชธเช‚เชฆเชฐเซเชญเซ‡, เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชถเซ‡เชฐ เช•เชฐเชตเชพเชจเซเช‚ เชšเชพเชฒเซ เชฐเชพเช–เซ€เช เช›เซ€เช.

เช† เชฒเซ‡เช–เชจเซ‹ เชนเซ‡เชคเซ เช…เชฎเชพเชฐเชพ เช‰เชชเชฏเซ‹เช—เชจเชพ เชชเซเชฐเชฅเชฎ เช…เชจเซเชญเชต เชตเชฟเชถเซ‡ เชตเชพเชค เช•เชฐเชตเชพเชจเซ‹ เช›เซ‡ MLflow.

เช…เชฎเซ‡ เชธเชฎเซ€เช•เซเชทเชพ เชถเชฐเซ‚ เช•เชฐเซ€เชถเซเช‚ MLflow เชคเซ‡เชจเชพ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐเชฎเชพเช‚เชฅเซ€ เช…เชจเซ‡ เช…เชญเซเชฏเชพเชธเชจเชพ เชคเชฎเชพเชฎ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจเซ‹เชจเซ‡ เชฒเซ‹เช— เช•เชฐเซ‹. เชชเช›เซ€ เช…เชฎเซ‡ UDF เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ MLflow เชธเชพเชฅเซ‡ Spark เชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชจเซ‹ เช…เชฎเชพเชฐเซ‹ เช…เชจเซเชญเชต เชถเซ‡เชฐ เช•เชฐเซ€เชถเซเช‚.

เชธเช‚เชฆเชฐเซเชญ

เช…เชฎเซ‡ เช…เช‚เชฆเชฐ เช›เซ€เช เช†เชฒเซเชซเชพ เช†เชฐเซ‹เช—เซเชฏ เช…เชฎเซ‡ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เช…เชจเซ‡ เช†เชฐเซเชŸเชฟเชซเชฟเชถเชฟเชฏเชฒ เช‡เชจเซเชŸเซ‡เชฒเชฟเชœเชจเซเชธเชจเซ‹ เช‰เชชเชฏเซ‹เช— เชฒเซ‹เช•เซ‹เชจเซ‡ เชคเซ‡เชฎเชจเชพ เชธเซเชตเชพเชธเซเชฅเซเชฏ เช…เชจเซ‡ เชธเซเช–เชพเช•เชพเชฐเซ€เชจเซ€ เชœเชตเชพเชฌเชฆเชพเชฐเซ€ เชฒเซ‡เชตเชพ เชฎเชพเชŸเซ‡ เชธเชถเช•เซเชค เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช•เชฐเซ€เช เช›เซ€เช. เชเชŸเชฒเชพ เชฎเชพเชŸเซ‡ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เชฎเซ‰เชกเชฒเซเชธ เช…เชฎเซ‡ เชตเชฟเช•เชธเชฟเชค เช•เชฐเซ€เช เช›เซ€เช เชคเซ‡ เชกเซ‡เชŸเชพ เชธเชพเชฏเชจเซเชธ เชชเซเชฐเซ‹เชกเช•เซเชŸเซเชธเชจเชพ เชนเชพเชฐเซเชฆเชฎเชพเช‚ เช›เซ‡, เช…เชจเซ‡ เชคเซ‡เชฅเซ€ เชœ เช…เชฎเซ‡ MLflow, เชเช• เช“เชชเชจ เชธเซ‹เชฐเซเชธ เชชเซเชฒเซ‡เชŸเชซเซ‹เชฐเซเชฎ เช•เซ‡ เชœเซ‡ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เชฒเชพเช‡เชซเชธเชพเช‡เช•เชฒเชจเชพ เชคเชฎเชพเชฎ เชชเชพเชธเชพเช“เชจเซ‡ เช†เชตเชฐเซ€ เชฒเซ‡ เช›เซ‡, เชคเชฐเชซ เช†เช•เชฐเซเชทเชพเชฏเชพ เชนเชคเชพ.

MLflow

MLflowเชจเซเช‚ เชฎเซเช–เซเชฏ เชงเซเชฏเซ‡เชฏ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช—เชจเซ€ เชŸเซ‹เชš เชชเชฐ เชเช• เชตเชงเชพเชฐเชพเชจเซเช‚ เชธเซเชคเชฐ เชชเซ‚เชฐเซเช‚ เชชเชพเชกเชตเชพเชจเซเช‚ เช›เซ‡ เชœเซ‡ เชกเซ‡เชŸเชพ เชตเซˆเชœเซเชžเชพเชจเชฟเช•เซ‹เชจเซ‡ เชฒเช—เชญเช— เช•เซ‹เชˆเชชเชฃ เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡ (h2O, เช•เซ‡เชฐเชพ, mleap, เชชเซ€เชŸเซ‹เชฐเซเชš, sklearn ะธ เชŸเซ‡เชจเซเชธเชซเซ‹เชฐเซเชฒเซ‹), เชคเซ‡เชฃเซ€เชจเชพ เช•เชพเชฐเซเชฏเชจเซ‡ เช†เช—เชฒเชพ เชธเซเชคเชฐ เชชเชฐ เชฒเชˆ เชœเชˆ เชฐเชนเซเชฏเชพ เช›เซ‡.

MLflow เชคเซเชฐเชฃ เช˜เชŸเช•เซ‹ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡:

  • เชŸเซเชฐเซ‡เช•เชฟเช‚เช— - เชฐเซ‡เช•เซ‹เชฐเซเชกเชฟเช‚เช— เช…เชจเซ‡ เชชเซเชฐเชฏเซ‹เช—เซ‹ เชฎเชพเชŸเซ‡เชจเซ€ เชตเชฟเชจเช‚เชคเซ€เช“: เช•เซ‹เชก, เชกเซ‡เชŸเชพ, เช—เซ‹เช เชตเชฃเซ€ เช…เชจเซ‡ เชชเชฐเชฟเชฃเชพเชฎเซ‹. เชฎเซ‹เชกเซ‡เชฒ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซเช‚ เชจเชฟเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเซเช‚ เช–เซ‚เชฌ เชœ เชฎเชนเชคเซเชตเชชเซ‚เชฐเซเชฃ เช›เซ‡.
  • เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ - เช•เซ‹เชˆเชชเชฃ เชชเซเชฒเซ‡เชŸเชซเซ‹เชฐเซเชฎ เชชเชฐ เชšเชฒเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‡เช•เซ‡เชœเชฟเช‚เช— เชซเซ‹เชฐเซเชฎเซ‡เชŸ (เชฆเชพ.เชค. เชธเซ‡เชœเชฎเซ‡เช•เชฐ)
  • เชฎเซ‹เชกเชฒเซเชธ - เชตเชฟเชตเชฟเชง เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เชŸเซ‚เชฒเซเชธ เชชเชฐ เชฎเซ‹เชกเชฒเซเชธ เชธเชฌเชฎเชฟเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซเช‚ เชธเชพเชฎเชพเชจเซเชฏ เชซเซ‹เชฐเซเชฎเซ‡เชŸ.

MLflow (เชฒเซ‡เช–เชตเชพเชจเชพ เชธเชฎเชฏเซ‡ เช†เชฒเซเชซเชพเชฎเชพเช‚) เชเช• เช“เชชเชจ เชธเซ‹เชฐเซเชธ เชชเซเชฒเซ‡เชŸเชซเซ‹เชฐเซเชฎ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชชเซเชฐเชฏเซ‹เช—, เชชเซเชจเชƒเช‰เชชเชฏเซ‹เช— เช…เชจเซ‡ เชœเชฎเชพเชตเชŸ เชธเชนเชฟเชค เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช— เชฒเชพเช‡เชซเชธเชพเช‡เช•เชฒเชจเซเช‚ เชธเช‚เชšเชพเชฒเชจ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡.

MLflow เชธเซ‡เชŸ เช•เชฐเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡

MLflow เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเซ‡ เชชเชนเซ‡เชฒเชพ เชคเชฎเชพเชฐเชพ เชธเชฎเช—เซเชฐ เชชเชพเชฏเชฅเซ‹เชจ เชชเชฐเซเชฏเชพเชตเชฐเชฃเชจเซ‡ เชธเซ‡เชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡, เช† เชฎเชพเชŸเซ‡ เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚ PyEnv (เชฎเซ‡เช• เชชเชฐ เชชเชพเชฏเชฅเซ‹เชจ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชคเชชเชพเชธเซ‹ เช…เชนเซ€เช‚). เช† เชฐเซ€เชคเซ‡ เช†เชชเชฃเซ‡ เชตเชฐเซเชšเซเชฏเซเช…เชฒ เชตเชพเชคเชพเชตเชฐเชฃ เชฌเชจเชพเชตเซ€ เชถเช•เซ€เช เช›เซ€เช เชœเซเชฏเชพเช‚ เช†เชชเชฃเซ‡ เชคเซ‡เชจเซ‡ เชšเชฒเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ เชฌเชงเซ€ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เช“ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ€เชถเซเช‚.

```
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 เชจเซ€ เช†เชตเซƒเชคเซเชคเชฟเช“เชจเซ‡ เช เซ€เช• เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เชชเช›เซ€เชจเซ€ เช†เชตเซƒเชคเซเชคเชฟเช“ เชเช•เชฌเซ€เชœเชพ เชธเชพเชฅเซ‡ เชตเชฟเชฐเซ‹เชงเชพเชญเชพเชธเซ€ เชนเชคเซ€.

เชŸเซเชฐเซ‡เช•เชฟเช‚เช— UI เชฒเซ‹เชจเซเชš เช•เชฐเซ‹

MLflow เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เช…เชฎเชจเซ‡ Python เช…เชจเซ‡ เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชชเซเชฐเชฏเซ‹เช—เซ‹เชจเซ‡ เชฒเซ‹เช— เช…เชจเซ‡ เช•เซเชตเซ‡เชฐเซ€ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡ REST API. เชตเชงเซเชฎเชพเช‚, เชคเชฎเซ‡ เชจเช•เซเช•เซ€ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช•เซ‡ เชฎเซ‹เชกเซ‡เชฒ เช†เชฐเซเชŸเชฟเชซเซ‡เช•เซเชŸเซเชธ เช•เซเชฏเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเซ€ (เชฒเซ‹เช•เชฒเชนเซ‹เชธเซเชŸ, เชเชฎเซ‡เชเซ‹เชจ S3, เชเชเซเชฏเซเชฐ เชฌเซเชฒเซ‹เชฌ เชธเซเชŸเซ‹เชฐเซ‡เชœ, เช—เซ‚เช—เชฒ เชฎเซ‡เช˜ เชธเซเชŸเซ‹เชฐเซ‡เชœ เช…เชฅเชตเชพ 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 เชฎเชพเช‚ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช, เช•เชพเชฐเชฃ เช•เซ‡ เช…เชฎเชจเซ‡ เชซเช•เซเชค เชฎเซ‹เชกเซ‡เชฒเชจเชพ เชฎเชพเชฐเซเช—เชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เชจเซ‹เช‚เชง: เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฐเชพเช–เซ‹ เช•เซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— UI เช…เชจเซ‡ เชฎเซ‹เชกเซ‡เชฒ เช•เซเชฒเชพเชฏเช‚เชŸ เชชเชพเชธเซ‡ เช†เชฐเซเชŸเชฟเชซเซ‡เช•เซเชŸ เชธเซเชฅเชพเชจเชจเซ€ เชเช•เซเชธเซ‡เชธ เชนเซ‹เชตเซ€ เช†เชตเชถเซเชฏเช• เช›เซ‡. เชเชŸเชฒเซ‡ เช•เซ‡, เชŸเซเชฐเซ…เช•เชฟเช‚เช— UI เช EC2 เช‰เชฆเชพเชนเชฐเชฃเชฎเชพเช‚ เชฐเชนเซ‡เชฒเซเช‚ เช›เซ‡ เชคเซ‡ เชนเช•เซ€เช•เชคเชจเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ€เชงเชพ เชตเชฟเชจเชพ, เชœเซเชฏเชพเชฐเซ‡ เชธเซเชฅเชพเชจเชฟเช• เชฐเซ€เชคเซ‡ MLflow เชšเชฒเชพเชตเซ€ เชฐเชนเซเชฏเชพ เชนเซ‹เชฏ, เชคเซเชฏเชพเชฐเซ‡ เชฎเชถเซ€เชจเชจเซ‡ เช†เชฐเซเชŸเชฟเชซเซ‡เช•เซเชŸ เชฎเซ‰เชกเชฒเซเชธ เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡ S3 เชชเชฐ เชธเซ€เชงเซ‹ เชเช•เซเชธเซ‡เชธ เชนเซ‹เชตเซ‹ เช†เชตเชถเซเชฏเช• เช›เซ‡.

MLflow เชธเชพเชฅเซ‡ เชธเซเชชเชพเชฐเซเช• เชตเชฟเชธเซเชคเชฐเซ‡ เช›เซ‡
เชŸเซเชฐเซ‡เช•เชฟเช‚เช— UI เช S3 เชฌเช•เซ‡เชŸเชฎเชพเช‚ เช•เชฒเชพเช•เซƒเชคเชฟเช“เชจเซ‡ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเซ‡ เช›เซ‡

เชšเชพเชฒเซ€ เชฐเชนเซ‡เชฒ เชฎเซ‹เชกเซ‡เชฒเซ‹

เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ เชšเชพเชฒเซ เชฅเชคเชพเชจเซ€ เชธเชพเชฅเซ‡ เชœ เชคเชฎเซ‡ เชฎเซ‹เชกเชฒเซเชธเชจเซ‡ เชคเชพเชฒเซ€เชฎ เช†เชชเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช…เชฎเซ‡ เชฎเชพเช‚ 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 เชคเชฎเชจเซ‡ เชฎเซ‹เชกเชฒ เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐเซเชธ, เชฎเซ‡เชŸเซเชฐเชฟเช•เซเชธ เช…เชจเซ‡ เช†เชฐเซเชŸเชฟเชซเซ‡เช•เซเชŸเซเชธเชจเซ‡ เชฒเซ‰เช— เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡ เชœเซ‡เชฅเซ€ เช•เชฐเซ€เชจเซ‡ เชคเชฎเซ‡ เชŸเซเชฐเซ…เช• เช•เชฐเซ€ เชถเช•เซ‹ เช•เซ‡ เชคเซ‡เช“ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจเซ‹ เชชเชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชตเชฟเช•เชธเชฟเชค เชฅเชพเชฏ เช›เซ‡. เช† เชธเซเชตเชฟเชงเชพ เช…เชคเซเชฏเช‚เชค เช‰เชชเชฏเซ‹เช—เซ€ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เช† เชฐเซ€เชคเซ‡ เช…เชฎเซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐเชจเซ‹ เชธเช‚เชชเชฐเซเช• เช•เชฐเซ€เชจเซ‡ เช…เชฅเชตเชพ เช•เชฎเชฟเชŸเซเชธเชจเชพ เช—เชฟเชŸ เชนเซ‡เชถ เชฒเซ‹เช—เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เชฏเชพ เช•เซ‹เชกเซ‡ เชœเชฐเซ‚เชฐเซ€ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เชคเซ‡ เชธเชฎเชœเซ€เชจเซ‡ เชถเซเชฐเซ‡เชทเซเช  เชฎเซ‹เชกเชฒเชจเซเช‚ เชชเซเชจเชƒเช‰เชคเซเชชเชพเชฆเชจ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช.

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 เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ, "mlflow server" เช†เชฆเซ‡เชถเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชถเชฐเซ‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡, เชคเซ‡เชฎเชพเช‚ เชฐเชจ เชŸเซเชฐเซ‡เช• เช•เชฐเชตเชพ เช…เชจเซ‡ เชธเซเชฅเชพเชจเชฟเช• เชซเชพเช‡เชฒ เชธเชฟเชธเซเชŸเชฎเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡ REST API เช›เซ‡. เชคเชฎเซ‡ เชเชจเซเชตเชพเชฏเชฐเซเชจเชฎเซ‡เชจเซเชŸ เชตเซ‡เชฐเซ€เชเชฌเชฒ โ€œMLFLOW_TRACKING_URIโ€ เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ เชธเชฐเชจเชพเชฎเซเช‚ เชจเชฟเชฐเซเชฆเชฟเชทเซเชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ MLflow เชŸเซเชฐเซ‡เช•เชฟเช‚เช— API เชฒเซ‹เชจเซเชš เชฎเชพเชนเชฟเชคเซ€, เชฒเซ‹เช— เชฎเซ‡เชŸเซเชฐเชฟเช•เซเชธ เชตเช—เซ‡เชฐเซ‡ เชฌเชจเชพเชตเชตเชพ/เชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช† เชธเชฐเชจเชพเชฎเชพเช‚ เชชเชฐ เช†เชชเชฎเซ‡เชณเซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐเชจเซ‹ เชธเช‚เชชเชฐเซเช• เช•เชฐเชถเซ‡.

เชธเซ‹เชฐเซเชธ: เชกเซ‰เช•เซเชธ// เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ เชšเชฒเชพเชตเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡

เชธเชฐเซเชตเชฐ เชธเชพเชฅเซ‡ เชฎเซ‹เชกเซ‡เชฒ เชชเซเชฐเชฆเชพเชจ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเชจเซ‡ เชšเชพเชฒเชคเซเช‚ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ (เชฒเซ‹เชจเซเชš เชˆเชจเซเชŸเชฐเชซเซ‡เชธ เชœเซเช“) เช…เชจเซ‡ เชฎเซ‹เชกเซ‡เชฒเชจเชพ เชฐเชจ IDเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

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 เชธเชฐเซเชต เชตเชฟเชงเซ‡เชฏเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชฎเซ‹เชกเชฒเซเชธเชจเซ‡ เชธเซ‡เชตเชพ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเชจเซ‡ เชซเช•เซเชค เชธเซเชชเชทเซเชŸ เช•เชฐเซ€เชจเซ‡ เชฎเซ‹เชกเซ‡เชฒ เชตเชฟเชถเซ‡ เชฎเชพเชนเชฟเชคเซ€ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเชŸเซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— UI เชจเซ€ เชเช•เซเชธเซ‡เชธเชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเชถเซ‡ --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]}

เชธเซเชชเชพเชฐเซเช•เชจเชพ เชฎเซ‹เชกเซ‡เชฒเซ‹ เชšเชพเชฒเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡

เชนเช•เซ€เช•เชค เช เช›เซ‡ เช•เซ‡ เชŸเซเชฐเซ‡เช•เชฟเช‚เช— เชธเชฐเซเชตเชฐ เชตเชพเชธเซเชคเชตเชฟเช• เชธเชฎเชฏเชฎเชพเช‚ เชฎเซ‹เชกเชฒเซเชธเชจเซ‡ เชธเซ‡เชตเชพ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡, เชคเซ‡เชฎเชจเซ‡ เชคเชพเชฒเซ€เชฎ เช†เชชเชตเชพ เช…เชจเซ‡ เชธเชฐเซเชตเชฐ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‚เชฐเชคเซเช‚ เชถเช•เซเชคเชฟเชถเชพเชณเซ€ เช›เซ‡ (เชธเซเชฐเซ‹เชค: mlflow // docs // models # local), เชตเชฟเชคเชฐเชฃเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เชธเซเชชเชพเชฐเซเช• (เชฌเซ‡เชš เช…เชฅเชตเชพ เชธเซเชŸเซเชฐเซ€เชฎเชฟเช‚เช—) เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชตเชงเซ เชถเช•เซเชคเชฟเชถเชพเชณเซ€ เช‰เช•เซ‡เชฒ เช›เซ‡.

เช•เชฒเซเชชเชจเชพ เช•เชฐเซ‹ เช•เซ‡ เชคเชฎเซ‡ เชซเช•เซเชค เช‘เชซเชฒเชพเช‡เชจ เชคเชพเชฒเซ€เชฎ เช•เชฐเซ€ เช…เชจเซ‡ เชชเช›เซ€ เชคเชฎเชพเชฐเชพ เชฌเชงเชพ เชกเซ‡เชŸเชพ เชชเชฐ เช†เช‰เชŸเชชเซเชŸ เชฎเซ‹เชกเซ‡เชฒ เชฒเชพเช—เซ เช•เชฐเซเชฏเซเช‚. เช† เชคเซ‡ เช›เซ‡ เชœเซเชฏเชพเช‚ เชธเซเชชเชพเชฐเซเช• เช…เชจเซ‡ MLflow เชšเชฎเช•เซ‡ เช›เซ‡.

PySpark + Jupyter + Spark เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ‹

เชธเซ‹เชฐเซเชธ: เชชเซเชฐเชพเชฐเช‚เชญ เช•เชฐเซ‹ PySpark - Jupyter

เช…เชฎเซ‡ Spark เชกเซ‡เชŸเชพเชซเซเชฐเซ‡เชฎ เชชเชฐ MLflow เชฎเซ‹เชกเชฒเซเชธ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฒเชพเช—เซ เช•เชฐเซ€เช เช›เซ€เช เชคเซ‡ เชฌเชคเชพเชตเชตเชพ เชฎเชพเชŸเซ‡, PySpark เชธเชพเชฅเซ‡ เชฎเชณเซ€เชจเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช…เชฎเชพเชฐเซ‡ Jupyter เชจเซ‹เชŸเชฌเซเช•เซเชธ เชธเซ‡เชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เชจเชตเซ€เชจเชคเชฎ เชธเซเชฅเชฟเชฐ เชธเช‚เชธเซเช•เชฐเชฃ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ€เชจเซ‡ เชชเซเชฐเชพเชฐเช‚เชญ เช•เชฐเซ‹ เช…เชชเชพเชšเซ‡ เชธเซเชชเชพเชฐเซเช•:

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 เชกเซเชฐเชพเช‡เชตเชฐ เชคเชฐเซ€เช•เซ‡ เชœเซเชฏเซเชชเซ€เชŸเชฐเชจเซ‡ เช—เซ‹เช เชตเซ€ เชถเช•เซเชฏเชพ เชนเซ‹เชตเชพเชฅเซ€, เชนเชตเซ‡ เช…เชฎเซ‡ PySpark เชจเชพ เชธเช‚เชฆเชฐเซเชญเชฎเชพเช‚ Jupyter เชจเซ‹เชŸเชฌเซเช• เชšเชฒเชพเชตเซ€ เชถเช•เซ€เช เช›เซ€เช.

(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 เชธเชพเชฅเซ‡ เชธเซเชชเชพเชฐเซเช• เชตเชฟเชธเซเชคเชฐเซ‡ เช›เซ‡

เช‰เชชเชฐ เชธเซ‚เชšเชตเซเชฏเชพ เชฎเซเชœเชฌ, 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)

MLflow เชธเชพเชฅเซ‡ เชธเซเชชเชพเชฐเซเช• เชตเชฟเชธเซเชคเชฐเซ‡ เช›เซ‡
PySpark - เช†เช‰เชŸเชชเซเชŸเชฟเช‚เช— เชตเชพเช‡เชจเชจเซ€ เช—เซเชฃเชตเชคเซเชคเชพเชจเซ€ เช†เช—เชพเชนเซ€เช“

เช† เชฌเชฟเช‚เชฆเซ เชธเซเชงเซ€, เช…เชฎเซ‡ MLflow เชธเชพเชฅเซ‡ PySpark เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ‹ เชคเซ‡ เชตเชฟเชถเซ‡ เชตเชพเชค เช•เชฐเซ€ เช›เซ‡, เชธเชฎเช—เซเชฐ เชตเชพเช‡เชจ เชกเซ‡เชŸเชพเชธเซ‡เชŸ เชชเชฐ เชตเชพเช‡เชจเชจเซ€ เช—เซเชฃเชตเชคเซเชคเชพเชจเซ€ เช†เช—เชพเชนเซ€เช“ เชšเชพเชฒเซ€ เชฐเชนเซ€ เช›เซ‡. เชชเชฐเช‚เชคเซ เชœเซ‹ เชคเชฎเชพเชฐเซ‡ เชธเซเช•เซ‡เชฒเชพ เชธเซเชชเชพเชฐเซเช•เชฎเชพเช‚เชฅเซ€ เชชเชพเชฏเชฅเซ‹เชจ เชเชฎเชเชฒเชซเซเชฒเซ‹ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ เชคเซ‹ เชถเซเช‚?

เช…เชฎเซ‡ เชธเซเช•เซ‡เชฒเชพ เช…เชจเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชตเชšเซเชšเซ‡ เชธเซเชชเชพเชฐเซเช• เชธเช‚เชฆเชฐเซเชญเชจเซ‡ เชตเชฟเชญเชพเชœเชฟเชค เช•เชฐเซ€เชจเซ‡ เชชเชฃ เช†เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเซเชฏเซเช‚ เช›เซ‡. เชเชŸเชฒเซ‡ เช•เซ‡, เช…เชฎเซ‡ Python เชฎเชพเช‚ MLflow UDF เชฐเชœเซ€เชธเซเชŸเชฐ เช•เชฐเซเชฏเซเช‚ เช›เซ‡, เช…เชจเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— Scala (เชนเชพ, เช•เชฆเชพเชš เชถเซเชฐเซ‡เชทเซเช  เช‰เช•เซ‡เชฒ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชถเซเช‚ เช›เซ‡) เชฅเซ€ เช•เชฐเซเชฏเซ‹ เช›เซ‡.

เชธเซเช•เซ‡เชฒเชพ เชธเซเชชเชพเชฐเซเช• + 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 เชชเชพเช‡เชชเชฒเชพเช‡เชจเซเชธ เช…เชจเซ‡ เชญเชฒเชพเชฎเชฃเช•เชฐเซเชคเชพ เชธเชฟเชธเซเชŸเชฎเซ‹ เชฎเชพเชŸเซ‡ เช•เชฐเซ€เชถเซเช‚.

เชซเชพเช‡เชฒ เชธเชฟเชธเซเชŸเชฎเชจเซ‡ เชฌเชฆเชฒเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เช เชธเชพเชฅเซ‡ เชซเชพเช‡เชฒ เชธเซเชŸเซ‹เชฐเซ‡เชœเชจเซ‡ เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เช เช•เชฐเชตเซเช‚ เชธเชฐเชธ เชฐเชนเซ‡เชถเซ‡. เช†เชจเชพเชฅเซ€ เช…เชฎเชจเซ‡ เชฌเชนเซเชตเชฟเชง เช…เช‚เชคเชฟเชฎ เชฌเชฟเช‚เชฆเซเช“ เชฎเชณเชตเชพ เชœเซ‹เชˆเช เชœเซ‡ เชธเชฎเชพเชจ เชซเชพเช‡เชฒ เชธเซเชŸเซ‹เชฐเซ‡เชœเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เซ‡. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฌเชนเซเชตเชฟเชง เช‰เชฆเชพเชนเชฐเชฃเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹ เชชเซเชฐเซ‡เชธเซเชŸเซ‹ ะธ เชเชฅเซ‡เชจเชพ เชธเชฎเชพเชจ เช—เซเช‚เชฆเชฐ เชฎเซ‡เชŸเชพเชธเซเชŸเซ‹เชฐ เชธเชพเชฅเซ‡.

เชธเชพเชฐเชพเช‚เชถ เชฎเชพเชŸเซ‡, เชนเซเช‚ เชกเซ‡เชŸเชพ เชธเชพเชฅเซ‡เชจเชพ เช…เชฎเชพเชฐเชพ เช•เชพเชฐเซเชฏเชจเซ‡ เชตเชงเซ เชฐเชธเชชเซเชฐเชฆ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ MLFlow เชธเชฎเซเชฆเชพเชฏเชจเซ‹ เช†เชญเชพเชฐ เช•เชนเซ‡เชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚.

เชœเซ‹ เชคเชฎเซ‡ MLflow เชธเชพเชฅเซ‡ เชฐเชฎเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ‹, เชคเซ‹ เช…เชฎเชจเซ‡ เชฒเช–เชตเชพเชฎเชพเช‚ เช…เชšเช•เชพเชถเซ‹ เชจเชนเซ€เช‚ เช…เชจเซ‡ เช…เชฎเชจเซ‡ เชœเชฃเชพเชตเซ‹ เช•เซ‡ เชคเชฎเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเซ‹ เช›เซ‹, เช…เชจเซ‡ เชคเซ‡เชฅเซ€ เชชเชฃ เชตเชงเซ เชœเซ‹ เชคเชฎเซ‡ เช‰เชคเซเชชเชพเชฆเชจเชฎเชพเช‚ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹ เช›เซ‹.

เช…เชญเซเชฏเชพเชธเช•เซเชฐเชฎเซ‹ เชตเชฟเชถเซ‡ เชตเชงเซ เชœเชพเชฃเซ‹:
เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช—. เชฎเซ‚เชณเชญเซ‚เชค เช…เชญเซเชฏเชพเชธเช•เซเชฐเชฎ
เชฎเชถเซ€เชจ เชฒเชฐเซเชจเชฟเช‚เช—. เชเชกเชตเชพเชจเซเชธ เช•เซ‹เชฐเซเชธ

เชตเชงเซ เชตเชพเช‚เชšเซ‹:

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹