MLflow เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตเดชเดพเตผเด•เตเด•เต เดจเต€เดŸเตเดŸเตเดจเตเดจเต

เดนเดฒเต‹, เด–เดฌเตเดฐเต‹เดตเตเดธเตเด•เต เดจเดฟเดตเดพเดธเดฟเด•เตพ. เดžเด™เตเด™เตพ เด‡เดคเดฟเดจเด•เด‚ เดŽเดดเตเดคเดฟเดฏเดคเตเดชเต‹เดฒเต†, เดˆ เดฎเดพเดธเด‚ OTUS เด’เดฐเต‡เดธเดฎเดฏเด‚ เดฐเดฃเตเดŸเต เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เด•เต‹เดดเตเดธเตเด•เตพ เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเดพเดฏเดคเต เด…เดŸเดฟเดธเตเดฅเดพเดจเด‚ ะธ เดชเตเดฐเต‹เด—เดฎเดฟเดšเตเดšเดคเต. เด‡เด•เตเด•เดพเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดžเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเดฏ เดฎเต†เดฑเตเดฑเต€เดฐเดฟเดฏเตฝ เดชเด™เตเด•เดฟเดŸเตเดจเตเดจเดคเต เดคเตเดŸเดฐเตเดจเตเดจเต.

เดˆ เดฒเต‡เด–เดจเดคเตเดคเดฟเดจเตเดฑเต† เด‰เดฆเตเดฆเต‡เดถเตเดฏเด‚ เดžเด™เตเด™เดณเตเดŸเต† เด†เดฆเตเดฏ เด…เดจเตเดญเดตเดคเตเดคเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดธเด‚เดธเดพเดฐเดฟเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต เดŽเด‚เดŽเตฝเดซเตเดฒเต‹.

เดžเด™เตเด™เตพ เด…เดตเดฒเต‹เด•เดจเด‚ เด†เดฐเด‚เดญเดฟเด•เตเด•เตเด‚ เดŽเด‚เดŽเตฝเดซเตเดฒเต‹ เด…เดคเดฟเดจเตเดฑเต† เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดชเด เดจเดคเตเดคเดฟเดจเตเดฑเต† เดŽเดฒเตเดฒเดพ เด†เดตเตผเดคเตเดคเดจเด™เตเด™เดณเตเด‚ เดฒเต‹เด—เต เดšเต†เดฏเตเดฏเตเด•. เดคเตเดŸเตผเดจเตเดจเต เดฏเต เดกเดฟ เดŽเดซเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตเดชเดพเตผเด•เตเด•เดฟเดจเต† เดŽเด‚ เดŽเตฝเดซเตเดฒเต‹เดฏเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดšเตเดš เด…เดจเตเดญเดตเด‚ เดžเด™เตเด™เตพ เดชเด™เตเด•เดฟเดŸเตเด‚.

เดธเดจเตเดฆเตผเดญเด‚

เดžเด™เตเด™เตพ เด…เด•เดคเตเดคเดพเดฃเต เด†เตฝเดซ เดนเต†เตฝเดคเตเดคเต เด†เดณเตเด•เดณเต† เด…เดตเดฐเตเดŸเต† เด†เดฐเต‹เด—เตเดฏเดคเตเดคเดฟเดจเตเดฑเต†เดฏเตเด‚ เด•เตเดทเต‡เดฎเดคเตเดคเดฟเดจเตเดฑเต†เดฏเตเด‚ เดšเตเดฎเดคเดฒ เดเดฑเตเดฑเต†เดŸเตเด•เตเด•เดพเตป เดชเตเดฐเดพเดชเตเดคเดฐเดพเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เตเด‚ เด†เตผเดŸเตเดŸเดฟเดซเดฟเดทเตเดฏเตฝ เด‡เดจเตเดฑเดฒเดฟเดœเตปเดธเตเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต. เด…เดคเตเด•เตŠเดฃเตเดŸเดพเดฃเต เดžเด™เตเด™เตพ เดตเดฟเด•เดธเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจ เดกเดพเดฑเตเดฑเดพ เดธเดฏเตปเดธเต เด‰เตฝเดชเตเดชเดจเตเดจเด™เตเด™เดณเตเดŸเต† เดนเตƒเดฆเดฏเดญเดพเด—เดคเตเดคเต เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เดฎเต‹เดกเดฒเตเด•เตพ เด‰เดณเตเดณเดคเต, เด…เดคเตเด•เตŠเดฃเตเดŸเดพเดฃเต เดžเด™เตเด™เตพ เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เดฒเตˆเดซเต เดธเตˆเด•เตเด•เดฟเดณเดฟเดจเตเดฑเต† เดŽเดฒเตเดฒเดพ เดตเดถเด™เตเด™เดณเตเด‚ เด‰เตพเด•เตเด•เตŠเดณเตเดณเตเดจเตเดจ เด’เดฐเต เด“เดชเตเดชเตบ เดธเต‹เดดเตโ€Œเดธเต เดชเตเดฒเดพเดฑเตเดฑเตโ€Œเดซเต‹เดฎเดพเดฏ MLflow-เดฒเต‡เด•เตเด•เต เด†เด•เตผเดทเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดŸเดคเต.

เดŽเด‚เดŽเตฝเดซเตเดฒเต‹

MLflow เดจเตเดฑเต† เดชเตเดฐเดงเดพเดจ เดฒเด•เตเดทเตเดฏเด‚, เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เดฟเดจเต เดฎเตเด•เดณเดฟเตฝ เด’เดฐเต เด…เดงเดฟเด• เดฒเต†เดฏเตผ เดจเตฝเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต, เด…เดคเต เดฎเดฟเด•เตเด•เดตเดพเดฑเตเด‚ เดŽเดฒเตเดฒเดพ เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เดฒเตˆเดฌเตเดฐเดฑเดฟเดฏเดฟเดฒเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเตป เดกเดพเดฑเตเดฑ เดถเดพเดธเตเดคเตเดฐเดœเตเดžเดฐเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเด‚ (เดนเตเด•เตเดธเดจเตเดฎเตเด•เตเดธเตŠ, keras, เดšเดพเดŸเดฟเดตเต€เดดเตเด•, เดชเตˆเดฑเตเดฑเต‹เตผเดšเตเดšเต, sclearn ะธ เดŸเต†เตปเดธเตผเดซเตเดฒเต‹), เด…เดตเดณเตเดŸเต† เดœเต‹เดฒเดฟ เด…เดŸเตเดคเตเดค เด˜เดŸเตเดŸเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เด•เตŠเดฃเตเดŸเตเดชเต‹เด•เตเดจเตเดจเต.

MLflow เดฎเต‚เดจเตเดจเต เด˜เดŸเด•เด™เตเด™เตพ เดจเตฝเด•เตเดจเตเดจเต:

  • เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต - เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเด‚เด—เตเด‚ เดชเดฐเต€เด•เตเดทเดฃเด™เตเด™เตพเด•เตเด•เดพเดฏเตเดณเตเดณ เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เดณเตเด‚: เด•เต‹เดกเต, เดกเดพเดฑเตเดฑ, เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเตป, เดซเดฒเด™เตเด™เตพ. เด’เดฐเต เดฎเดพเดคเตƒเด• เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจ เดชเตเดฐเด•เตเดฐเดฟเดฏ เดจเดฟเดฐเต€เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเดคเต เดตเดณเดฐเต† เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต.
  • เดชเตเดฐเต‡เดพเดœเด•เตเดŸเตเด•เตพ - เดเดคเต เดชเตเดฒเดพเดฑเตเดฑเตโ€Œเดซเต‹เดฎเดฟเดฒเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเดจเตเดณเตเดณ เดชเดพเด•เตเด•เต‡เดœเดฟเด‚เด—เต เดซเต‹เตผเดฎเดพเดฑเตเดฑเต (เด‰เดฆเดพ. เดธเต‡เดœเต เดฎเต‡เด•เตเด•เตผ)
  • เดฎเต‡เดพเดกเดฒเตเด•เตพ - เดตเดฟเดตเดฟเดง เดตเดฟเดจเตเดฏเดพเดธ เด‰เดชเด•เดฐเดฃเด™เตเด™เดณเดฟเดฒเต‡เด•เตเด•เต เดฎเต‹เดกเดฒเตเด•เตพ เดธเดฎเตผเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เดชเตŠเดคเต เดซเต‹เตผเดฎเดพเดฑเตเดฑเต.

เดชเดฐเต€เด•เตเดทเดฃเด‚, เดชเตเดจเดฐเตเดชเดฏเต‹เด—เด‚, เดตเดฟเดจเตเดฏเดพเดธเด‚ เดŽเดจเตเดจเดฟเดต เด‰เตพเดชเตเดชเต†เดŸเต†เดฏเตเดณเตเดณ เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เดœเต€เดตเดฟเดคเดšเด•เตเดฐเด‚ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจ เด’เดฐเต เด“เดชเตเดชเตบ เดธเต‹เดดเตโ€Œเดธเต เดชเตเดฒเดพเดฑเตเดฑเตโ€Œเดซเต‹เดฎเดพเดฃเต MLflow (เดŽเดดเตเดคเตเดจเตเดจ เดธเดฎเดฏเดคเตเดคเต เด†เตฝเดซเดฏเดฟเตฝ).

MLflow เดธเดœเตเดœเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต

MLflow เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดจเดฟเด™เตเด™เตพ เด†เดฆเตเดฏเด‚ เดจเดฟเด™เตเด™เดณเตเดŸเต† เดฎเตเดดเตเดตเตป เดชเตˆเดคเตเดคเตบ เดŽเตปเดตเดฏเต‹เตบเดฎเต†เดจเตเดฑเต เดธเดœเตเดœเต€เด•เดฐเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต, เด‡เดคเดฟเดจเดพเดฏเดฟ เดžเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด‚ PyEnv (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
```

เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเด•: UDF เดชเต‹เดฒเตเดณเตเดณ เดฎเต‹เดกเดฒเตเด•เตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ PyArrow เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต. PyArrow, Numpy เดŽเดจเตเดจเดฟเดตเดฏเตเดŸเต† เดชเดคเดฟเดชเตเดชเตเด•เตพ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต, เด•เดพเดฐเดฃเด‚ เดชเดฟเดจเตเดจเต€เดŸเตเดณเตเดณ เดชเดคเดฟเดชเตเดชเตเด•เตพ เดชเดฐเดธเตเดชเดฐเด‚ เดตเตˆเดฐเตเดฆเตเดงเตเดฏเดฎเตเดณเตเดณเดตเดฏเดพเดฃเต.

เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดฏเตเด เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเด•

MLflow เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดชเตˆเดคเตเดคเตบ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเดฐเต€เด•เตเดทเดฃเด™เตเด™เตพ เดฒเต‹เด—เต เดšเต†เดฏเตเดฏเดพเดจเตเด‚ เด…เดจเตเดตเต‡เดทเดฟเด•เตเด•เดพเดจเตเด‚ เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต REST API. เด•เต‚เดŸเดพเดคเต†, เดฎเต‹เดกเตฝ เด†เตผเดŸเตเดŸเดฟเดซเดพเด•เตเดฑเตเดฑเตเด•เตพ เดŽเดตเดฟเดŸเต† เดธเต‚เด•เตเดทเดฟเด•เตเด•เดฃเดฎเต†เดจเตเดจเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดจเดฟเตผเดฃเตเดฃเดฏเดฟเด•เตเด•เดพเดจเดพเด•เตเด‚ (เดฒเต‹เด•เตเด•เตฝเดนเต‹เดธเตเดฑเตเดฑเต, เด†เดฎเดธเต‡เดพเตบ S3, เด…เดธเต‚เตผ เดฌเตเดฒเต‹เดฌเต เดธเด‚เดญเดฐเดฃเด‚, Google เด•เตเดฒเต—เดกเต เดธเด‚เดญเดฐเดฃเด‚ เด…เดฅเดตเดพ SFTP เดธเต†เตผเดตเตผ). เดžเด™เตเด™เตพ เด†เตฝเดซ เดนเต†เตฝเดคเตเดคเดฟเตฝ 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 เดธเต†เตผเดตเตผ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดฃเดฎเต†เด™เตเด•เดฟเตฝ, เด…เดต เดซเดฏเตฝ เดธเตเดฑเตเดฑเต‹เดฑเต‡เดœเดฟเตฝ เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเดฟเด•เตเด•เดฃเดฎเต†เดจเตเดจเต เด“เตผเดฎเตเดฎเดฟเด•เตเด•เตเด•. เดŽเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด‚, เด‡เดคเต เด•เต‚เดŸเดพเดคเต† เดคเดจเตเดจเต† เดžเด™เตเด™เตพเด•เตเด•เต เด…เดตเดฐเต† เดฏเต.เดกเดฟ.เดŽเดซเดฟเตฝ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเด‚, เด•เดพเดฐเดฃเด‚ เดžเด™เตเด™เตพเด•เตเด•เต เดฎเดพเดคเตƒเด•เดฏเดฟเดฒเต‡เด•เตเด•เตเดณเตเดณ เดชเดพเดค เดฎเดพเดคเตเดฐเดฎเต‡ เด†เดตเดถเตเดฏเดฎเตเดณเตเดณเต‚.

เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเด•: เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดฏเตเดเด•เตเด•เตเด‚ เดฎเต‹เดกเตฝ เด•เตเดฒเดฏเดจเตเดฑเดฟเดจเตเด‚ เด†เตผเดŸเตเดŸเดฟเดซเดพเด•เตโ€Œเดฑเตเดฑเต เดฒเตŠเด•เตเด•เต‡เดทเดจเดฟเดฒเต‡เด•เตเด•เต เด†เด•เตโ€Œเดธเดธเต เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเดฟเด•เตเด•เดฃเดฎเต†เดจเตเดจเต เด“เตผเดฎเตเดฎเดฟเด•เตเด•เตเด•. เด…เดคเดพเดฏเดคเต, เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดฏเตเด เด’เดฐเต EC2 เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เดตเดธเดฟเด•เตเด•เตเดจเตเดจเต เดŽเดจเตเดจเดคเต เดชเดฐเดฟเด—เดฃเดฟเด•เตเด•เดพเดคเต† เดคเดจเตเดจเต†, เดชเตเดฐเดพเดฆเต‡เดถเดฟเด•เดฎเดพเดฏเดฟ MLflow เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด†เตผเดŸเตเดŸเดฟเดซเดพเด•เตเดฑเตเดฑเต เดฎเต‹เดกเดฒเตเด•เตพ เดŽเดดเตเดคเตเดจเตเดจเดคเดฟเดจเต เดฎเต†เดทเต€เดจเต S3-เดฒเต‡เด•เตเด•เต เดจเต‡เดฐเดฟเดŸเตเดŸเต เด†เด•เตเดธเดธเต เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเดฟเด•เตเด•เดฃเด‚.

MLflow เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตเดชเดพเตผเด•เตเด•เต เดจเต€เดŸเตเดŸเตเดจเตเดจเต
เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต UI เด’เดฐเต 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 เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเตเดตเดดเดฟ เด†เดตเตผเดคเตเดคเดจเด™เตเด™เดณเดฟเตฝ เด…เดต เดŽเด™เตเด™เดจเต† เดตเดฟเด•เดธเดฟเด•เตเด•เตเดจเตเดจเต เดŽเดจเตเดจเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดŸเตเดฐเดพเด•เตเด•เต เดšเต†เดฏเตเดฏเดพเด‚. เดˆ เดธเดตเดฟเดถเต‡เดทเดค เดตเดณเดฐเต† เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเดฃเต, เด•เดพเดฐเดฃเด‚ เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเต†เดŸเตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต†เดฏเต‹ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด•เดฎเตเดฎเดฟเดฑเตเดฑเตเด•เดณเตเดŸเต† เดœเดฟเดฑเตเดฑเต เดนเดพเดทเต เดฒเต‹เด—เตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดเดคเต เด•เต‹เดกเดพเดฃเต เด†เดตเดถเตเดฏเดฎเดพเดฏ เด†เดตเตผเดคเตเดคเดจเด‚ เดจเดŸเดคเตเดคเดฟเดฏเดคเต เดŽเดจเตเดจเต เดฎเดจเดธเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต†เดฏเต‹ เดจเดฎเตเด•เตเด•เต เดฎเดฟเด•เดšเตเดš เดฎเต‹เดกเตฝ เดชเตเดจเตผเดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚.

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 เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเดฑเดฟเดจเต เดฑเดฃเตเดฃเตเด•เตพ เดŸเตเดฐเดพเด•เตเด•เตเดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด‚ เดชเตเดฐเดพเดฆเต‡เดถเดฟเด• เดซเดฏเตฝ เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เดกเดพเดฑเตเดฑ เดŽเดดเตเดคเตเดจเตเดจเดคเดฟเดจเตเดฎเตเดณเตเดณ เด’เดฐเต REST API เด‰เดฃเตเดŸเต. "MLFLOW_TRACKING_URI" เดŽเดจเตเดจ เดŽเตปเดตเดฏเต‹เตบเดฎเต†เดจเตเดฑเต เดตเต‡เดฐเดฟเดฏเดฌเดฟเตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเตผ เดตเดฟเดฒเดพเดธเด‚ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚, เด•เต‚เดŸเดพเดคเต† เดฒเต‹เดžเตเดšเต เดตเดฟเดตเดฐเด™เตเด™เตพ, เดฒเต‹เด—เต เดฎเต†เดŸเตเดฐเดฟเด•เตโ€Œเดธเต เดฎเตเดคเดฒเดพเดฏเดต เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเด‚ เดธเตเดตเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเด‚ MLflow เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต API เดˆ เดตเดฟเดฒเดพเดธเดคเตเดคเดฟเดฒเต† เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเดฑเตเดฎเดพเดฏเดฟ เดธเตเดตเดฏเดฎเต‡เดต เดฌเดจเตเดงเดชเตเดชเต†เดŸเตเด‚.

เด…เดตเดฒเด‚เดฌเด‚: เดกเต‹เด•เตเดธเต// เด’เดฐเต เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเตผ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเต

เด’เดฐเต เดธเต†เตผเดตเดฑเดฟเดจเตŠเดชเตเดชเด‚ เดฎเต‹เดกเตฝ เดจเตฝเด•เตเดจเตเดจเดคเดฟเดจเต, เดžเด™เตเด™เตพเด•เตเด•เต เด’เดฐเต เดฑเดฃเตเดฃเดฟเด‚เด—เต เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเดฑเตเด‚ (เดฒเต‹เดžเตเดšเต เด‡เดจเตเดฑเตผเดซเต‡เดธเต เด•เดพเดฃเตเด•) เดฎเต‹เดกเดฒเดฟเดจเตเดฑเต† เดฑเตบ เดเดกเดฟเดฏเตเด‚ เด†เดตเดถเตเดฏเดฎเดพเดฃเต.

MLflow เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตเดชเดพเตผเด•เตเด•เต เดจเต€เดŸเตเดŸเตเดจเตเดจเต
เดเดกเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด•

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

เดธเตเดชเดพเตผเด•เตเด•เดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดฎเต‹เดกเดฒเตเด•เตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเต

เดŸเตเดฐเดพเด•เตเด•เดฟเด‚เด—เต เดธเต†เตผเดตเตผ เดคเดคเตเดธเดฎเดฏเด‚ เดฎเต‹เดกเดฒเตเด•เตพ เดจเตฝเด•เดพเดจเตเด‚ เด…เดตเดฐเต† เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเด•เตเด•เดพเดจเตเด‚ เดธเต†เตผเดตเตผ เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดจเตเด‚ เดถเด•เตเดคเดฎเดพเดฃเต เดŽเดจเตเดจ เดตเดธเตเดคเตเดค เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเตเดจเตเดจเดฟเดŸเตเดŸเตเด‚ (เด‰เดฑเดตเดฟเดŸเด‚: 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 เดกเตเดฐเตˆเดตเดฑเดพเดฏเดฟ เด•เต‹เตบเดซเดฟเด—เตผ เดšเต†เดฏเตเดฏเดพเตป เดžเด™เตเด™เตพเด•เตเด•เต เด•เดดเดฟเดžเตเดžเดคเดฟเดจเดพเตฝ, 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-เตฝ เดฎเต‹เดกเตฝ เด†เตผเดŸเตเดŸเดฟเดซเดพเด•เตโ€Œเดฑเตเดฑเตเด•เตพ เดฒเต‹เด—เต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เดซเต€เดšเตเดšเตผ MLflow เดจเตฝเด•เตเดจเตเดจเต. เดคเดฟเดฐเดžเตเดžเต†เดŸเตเดคเตเดค เดฎเต‹เดกเตฝ เดจเดฎเตเดฎเตเดŸเต† เด•เตˆเดฏเดฟเตฝ เด•เดฟเดŸเตเดŸเดฟเดฏเดพเดฒเตเดŸเตป เด…เดคเต เดฎเตŠเดกเตเดฏเต‚เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดฏเต เดกเดฟ เดŽเดซเต เด†เดฏเดฟ เด‡เดฑเด•เตเด•เตเดฎเดคเดฟ เดšเต†เดฏเตเดฏเดพเตป เด…เดตเดธเดฐเดฎเตเดฃเตเดŸเต. 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 เดŽเด™เตเด™เดจเต† เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดฎเต†เดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดžเด™เตเด™เตพ เดธเด‚เดธเดพเดฐเดฟเดšเตเดšเต, เดฎเตเดดเตเดตเตป เดตเตˆเตป เดกเดพเดฑเตเดฑเดพเดธเต†เดฑเตเดฑเดฟเดฒเตเด‚ เดตเตˆเตป เด—เตเดฃเดจเดฟเดฒเดตเดพเดฐ เดชเตเดฐเดตเดšเดจเด™เตเด™เตพ เดจเดŸเดคเตเดคเตเดจเตเดจเต. เดŽเดจเตเดจเดพเตฝ เดจเดฟเด™เตเด™เตพเด•เตเด•เต Scala Spark-เตฝ เดจเดฟเดจเตเดจเต Python MLflow เดฎเตŠเดกเตเดฏเต‚เดณเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เต‡เดฃเตเดŸเดฟ เดตเดจเตเดจเดพเดฒเต‹?

เดธเตเด•เดพเดฒเดฏเตเด•เตเด•เตเด‚ เดชเตˆเดคเตเดคเดฃเดฟเดจเตเดฎเดฟเดŸเดฏเดฟเตฝ เดธเตเดชเดพเตผเด•เตเด•เต เดธเดจเตเดฆเตผเดญเด‚ เดตเดฟเดญเดœเดฟเดšเตเดšเต เดžเด™เตเด™เตพ เด‡เดคเตเด‚ เดชเดฐเต€เด•เตเดทเดฟเดšเตเดšเต. เด…เดคเดพเดฏเดคเต, เดžเด™เตเด™เตพ เดชเตˆเดคเตเดคเดฃเดฟเตฝ MLflow UDF เดฐเดœเดฟเดธเตเดฑเตเดฑเตผ เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เดธเตเด•เดพเดฒเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เด…เดคเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดคเต (เด…เดคเต†, เด’เดฐเตเดชเด•เตเดทเต‡ เดเดฑเตเดฑเดตเตเด‚ เดฎเดฟเด•เดšเตเดš เดชเดฐเดฟเดนเดพเดฐเดฎเดฒเตเดฒ, เดชเด•เตเดทเต‡ เดžเด™เตเด™เดณเตเดŸเต† เดชเด•เตเด•เดฒเตเดณเตเดณเดคเต).

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

เด…เดฑเตเดฑเดพเดšเตเดšเต เดšเต†เดฏเตเดค เดจเต‹เดŸเตเดŸเตเดฌเตเด•เตเด•เดฟเตฝ เดจเดฟเดจเตเดจเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เดพเดฃเดพเดจเดพเด•เตเดจเตเดจเดคเตเดชเต‹เดฒเต†, เดฏเต.เดกเดฟ.เดŽเดซเต เดธเตเดชเดพเตผเด•เตเด•เตเด‚ เดชเตˆเดธเตเดชเดพเตผเด•เตเด•เตเด‚ เดคเดฎเตเดฎเดฟเตฝ เดชเด™เตเด•เดฟเดŸเตเดจเตเดจเต. เดธเตเด•เดพเดฒเดฏเต† เด‡เดทเตเดŸเดชเตเดชเต†เดŸเตเดจเตเดจเดตเตผเด•เตเด•เตเด‚ เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเตฝ เดฎเต†เดทเต€เตป เดฒเต‡เดฃเดฟเด‚เด—เต เดฎเต‹เดกเดฒเตเด•เตพ เดตเดฟเดจเตเดฏเดธเดฟเด•เตเด•เดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเดตเตผเด•เตเด•เตเด‚ เดˆ เดญเดพเด—เด‚ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเด•เตเดฎเต†เดจเตเดจเต เดžเด™เตเด™เตพ เดชเตเดฐเดคเต€เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเต.

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-เดฏเตเดŸเต† เดˆ เดชเดฐเตเดฏเดตเต‡เด•เตเดทเดฃเดคเตเดคเดฟเดจเต เดถเต‡เดทเด‚, เดžเด™เตเด™เตพ เดฎเตเดจเตเดจเต‹เดŸเตเดŸเต เดชเต‹เด•เตเดฎเต†เดจเตเดจเตเด‚ เด…เดคเต เดžเด™เตเด™เดณเตเดŸเต† เดธเตเดชเดพเตผเด•เตเด•เต เดชเตˆเดชเตเดชเต เดฒเตˆเดจเตเด•เตพเด•เตเด•เตเด‚ เดถเตเดชเดพเตผเดถ เดšเต†เดฏเตเดฏเตเดจเตเดจ เดธเดฟเดธเตเดฑเตเดฑเด™เตเด™เตพเด•เตเด•เตเดฎเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดฎเต†เดจเตเดจเตเด‚ เดžเด™เตเด™เตพเด•เตเด•เต เด‰เดฑเดชเตเดชเตเดฃเตเดŸเต.

เดซเดฏเตฝ เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเดจเต เดชเด•เดฐเด‚ เดซเดฏเตฝ เดธเตเดฑเตเดฑเต‹เดฑเต‡เดœเต เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเตเดฎเดพเดฏเดฟ เดธเดฎเดจเตเดตเดฏเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเต เดจเดจเตเดจเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเด‚. เด’เดฐเต‡ เดซเดฏเตฝ เดธเด‚เดญเดฐเดฃเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดจเดพเด•เตเดจเตเดจ เด’เดจเตเดจเดฟเดฒเดงเดฟเด•เด‚ เดŽเตปเดกเต เดชเต‹เดฏเดฟเดจเตเดฑเตเด•เตพ เด‡เดคเต เดžเด™เตเด™เตพเด•เตเด•เต เดจเตฝเด•เตเด‚. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เด’เดจเตเดจเดฟเดฒเดงเดฟเด•เด‚ เดธเดจเตเดฆเตผเดญเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด• เดชเตเดฐเดธเตเดฑเตเดฑเต‡เดพ ะธ เด…เดฅเต€เดจ เด’เดฐเต‡ เด—เตเดฒเต‚ เดฎเต†เดฑเตเดฑเดพเดธเตเดฑเตเดฑเต‹เตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต.

เดšเตเดฐเตเด•เตเด•เดคเตเดคเดฟเตฝ, เดกเดพเดฑเตเดฑ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเตเดณเตเดณ เดžเด™เตเด™เดณเตเดŸเต† เดœเต‹เดฒเดฟ เด•เต‚เดŸเตเดคเตฝ เดฐเดธเด•เดฐเดฎเดพเด•เตเด•เดฟเดฏเดคเดฟเดจเต MLFlow เด•เดฎเตเดฎเตเดฏเต‚เดฃเดฟเดฑเตเดฑเดฟเด•เตเด•เต เดจเดจเตเดฆเดฟ เดชเดฑเดฏเดพเตป เดžเดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเต.

เดจเดฟเด™เตเด™เตพ MLflow เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เดณเดฟเด•เตเด•เตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ, เดžเด™เตเด™เตพเด•เตเด•เต เดŽเดดเตเดคเดพเดจเตเด‚ เดจเดฟเด™เตเด™เตพ เด…เดคเต เดŽเด™เตเด™เดจเต† เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เดžเด™เตเด™เดณเต‹เดŸเต เดชเดฑเดฏเดพเดจเตเด‚ เดฎเดŸเดฟเด•เตเด•เดฐเตเดคเต, เด…เดคเดฟเดฒเตเดชเดฐเดฟเดฏเดพเดฏเดฟ เดจเดฟเด™เตเด™เตพ เด‡เดคเต เดจเดฟเตผเดฎเตเดฎเดพเดฃเดคเตเดคเดฟเตฝ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด•เดฏเดพเดฃเต†เด™เตเด•เดฟเตฝ.

เด•เต‹เดดเตเดธเตเด•เดณเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เด•เต‚เดŸเตเดคเดฒเดฑเดฟเดฏเตเด•:
เดฏเดจเตเดคเตเดฐ เดชเด เดจเด‚. เด…เดŸเดฟเดธเตเดฅเดพเดจ เด•เต‹เดดเตเดธเต
เดฏเดจเตเดคเตเดฐ เดชเด เดจเด‚. เดตเดฟเดชเตเดฒเดฎเดพเดฏ เด•เต‹เดดเตเดธเต

เด•เต‚เดŸเตเดคเตฝ เดตเดพเดฏเดฟเด•เตเด•เตเด•:

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•