概要

Cloud Functionsを利用してCloud ML Engineのジョブ登録をしてみました。

前提

Cloud FunctionsはPython 3.7(Beta)を利用

Cloud FunctionsでPython?という方は下記をご参考ください。

Google Cloud FunctionsでPythonを利用してみた(Beta利用)
https://cloudpack.media/42488

Cloud ML Engineのジョブ登録

下記記事の手順で、gcloud ml-engine jobs submit trainingが実行できる環境がある前提です。

MacでCloud Machine Learning Engineを利用してみる
https://cloudpack.media/42306

手順

下準備

変数を設定します。上記記事の手順を済ませている場合、すでに設定済みだと思います。
設定済みの場合、ジョブ名は重複するとCloud MLでジョブ登録できないので、変更しましょう。

fish

> set -x REGION us-central1
> set -x BUCKET_NAME 任意のバケット名

> set -x TRAIN_DATA gs://$BUCKET_NAME/data/adult.data.csv
> set -x EVAL_DATA gs://$BUCKET_NAME/data/adult.test.csv
> set -x TEST_JSON gs://$BUCKET_NAME/data/test.json
> set -x JOB_NAME functions_ml_test_01

bach

> export REGION=us-central1
> export BUCKET_NAME=任意のバケット名

> export TRAIN_DATA=gs://$BUCKET_NAME/data/adult.data.csv
> export EVAL_DATA=gs://$BUCKET_NAME/data/adult.test.csv
> export TEST_JSON=gs://$BUCKET_NAME/data/test.json
> export JOB_NAME=functions_ml_test_01

データをCloud Storageにコピーします。
上記記事の手順を済ませている場合、すでにファイルはコピーされていると思います。

> cd 任意のディレクトリ/cloudml-samples/census/estimator/

> gsutil cp -r data/ gs://$BUCKET_NAME/data/

> gsutil ls gs://$BUCKET_NAME/data/
gs://任意のバケット名/data/adult.data.csv
gs://任意のバケット名/data/test.json

Cloud ML Engineにジョブ登録するのに利用するPythonパッケージを作成します。

> touch setup.py
> touch requirements.txt

setup.py

#!/usr/bin/env python

from setuptools import setup, Command, find_packages


with open('requirements.txt') as f:
    required = f.read().splitlines()

setup(name='functions_ml_test',
      version='0.0.1',
      description='hoge',
      license='Apache License 2.0',
      author='hoge',
      author_email='hoge@example.com',
      url='',
      packages=find_packages(),
      install_requires = required
     )

requirements.txt

tensorflow==1.7.1

パッケージ作成に必要なファイルを用意したら、パッケージングします。

> python setup.py sdist
(略)
Writing functions_ml_test-0.0.1/setup.cfg
Creating tar archive
removing 'functions_ml_test-0.0.1' (and everything under it)

> ls dist/
functions_ml_test-0.0.1.tar.gz

パッケージングできたらCloud Storageへコピーします。

> gsutil cp dist/functions_ml_test-0.0.1.tar.gz gs://$BUCKET_NAME/sources

> gsutil ls gs://$BUCKET_NAME/sources
gs://任意のバケット名/sources/functions_ml_test-0.0.1.tar.gz

ローカルでMLジョブ登録できるか確認

ローカルからCloud MLにジョブ登録できるか確認しておきます。

> gcloud ml-engine jobs submit training $JOB_NAME \
    --job-dir gs://$BUCKET_NAME/$JOB_NAME \
    --runtime-version 1.8 \
    --python-version=3.5 \
    --module-name trainer.task \
    --packages gs://$BUCKET_NAME/sources/functions_ml_test-0.0.1.tar.gz \
    --region $REGION \
    -- \
    --train-files $TRAIN_DATA \
    --eval-files $EVAL_DATA \
    --train-steps 1000 \
    --eval-steps 100 \
    --verbosity DEBUG

Job [functions_ml_test_01] submitted successfully.
Your job is still active. You may view the status of your job with the command

  $ gcloud ml-engine jobs describe functions_ml_test_01

or continue streaming the logs with the command

  $ gcloud ml-engine jobs stream-logs functions_ml_test_01
jobId: functions_ml_test_01
state: QUEUED

ジョブ登録後、学習が完了したか確認します。

> gcloud ml-engine jobs describe $JOB_NAME

createTime: '2018-08-07T08:14:01Z'
endTime: '2018-08-07T08:21:05Z'
etag: SPDifLtZPoY=
jobId: functions_ml_test_01
startTime: '2018-08-07T08:14:26Z'
state: SUCCEEDED
(略)

はい。

Cloud Functionsで関数登録

ここからが本題です。
Cloud Functionsで関数を作成します。ここではローカルからデプロイしてみます。
ランタイムはPython 3.7なので、Cloud FunctionsでPython?という方は下記をご参考ください(再掲

Google Cloud FunctionsでPythonを利用してみた(Beta利用)
https://cloudpack.media/42488

ソースの準備

先程のディレクトリとは別ディレクトリで作業します。

> mkdir 任意のディレクトリ/function_ml_test
> cd 任意のディレクトリ/function_ml_test
> touch main.py
> touch requirements.txt

とりあえずジョブ登録したいだけなので、パラメータはべた書きにしてます。(雑
実際に使うときには環境変数や実行時にパラメータ指定できるようにしましょう。

任意のバケット名GCPのプロジェクトID の置き換え忘れにご注意(1敗
ジョブID(ここではfunctions_ml_test_02)は先程ローカルからジョブ登録した際のものと変えておきます。

main.py

from googleapiclient import discovery

def create_ml_job(request):
    # パラメータ設定
    training_inputs = {
        'packageUris': ['gs://任意のバケット名/sources/functions_ml_test-0.0.1.tar.gz'],
        'pythonModule': 'trainer.task',
        'args': [
            '--job-dir', 'gs://任意のバケット名/functions_ml_test_02',
            '--train-files', 'gs://任意のバケット名/data/adult.data.csv',
            '--eval-files', 'gs://任意のバケット名/data/adult.test.csv',
            '--train-steps', 1000,
            '--eval-steps', 100,
            '--verbosity', 'DEBUG',
        ],
        'region': 'us-central1',
        'runtimeVersion': '1.8',
        'pythonVersion': '3.5'
    }
    job_spec = {'jobId': 'functions_ml_test_02', 'trainingInput': training_inputs}

    # Cloud MLにジョブ登録
    project_id = 'projects/{}'.format('GCPのプロジェクトID')
    cloudml = cloudml = discovery.build('ml', 'v1')
    request = cloudml.projects().jobs().create(body=job_spec,
                parent=project_id)
    response = request.execute()

Cloud MLにジョブ登録するのに、Python用のライブラリを利用するので、requirements.txtに指定しておきます。

requirements.txt

google-api-python-client

Cloud Functionsへデプロイ

ローカルで用意したソースをデプロイします。

--trigger-xxxは必須となるので、ここでは--trigger-http としておきます。
--runtime=python37の指定がないとNode.jsと扱いされるのでご注意ください。
あとは、gcloud functionsではなくて、gcloud beta functions です。

> gcloud beta functions deploy create_ml_job --trigger-http --runtime=python37

Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
entryPoint: create_ml_job
(略)
name: projects/xxx/locations/us-central1/functions/create_ml_job
runtime: python37
(略)
status: ACTIVE
timeout: 60s
updateTime: '2018-08-07T08:55:01Z'
versionId: '1'

はい。

デプロイできたら実行してみます。

> gcloud beta functions call create_ml_job

executionId: r8br62c1rk9g
result: OK

Cloud MLにジョブ登録できたので、学習完了を見守りましょう。

> gcloud ml-engine jobs describe functions_ml_test_02

createTime: '2018-08-07T09:34:20Z'
endTime: '2018-08-07T09:40:53Z'
etag: OJrb-vhEags=
jobId: functions_ml_test_02
startTime: '2018-08-07T09:34:46Z'
state: SUCCEEDED
(略)

はい。

無事に登録&実行できました。
とりあえず連携できるよね。って実装なので、各パラメータは環境変数に入れるか実行時に指定できるようにしましょう。(2回目)

参考

Google Cloud FunctionsでPythonを利用してみた(Beta利用)
https://cloudpack.media/42488

MacでCloud Machine Learning Engineを利用してみる
https://cloudpack.media/42306

元記事はこちら

Cloud FunctionsとCloud ML Engineを連携させてみた