Python
cloudfunctions
CloudMachineLearning

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


概要

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


前提


Cloud FunctionsはPython 3.7(Beta)を利用

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

Google Cloud FunctionsでPythonを利用してみた(Beta利用)

https://qiita.com/kai_kou/items/dca21cdfd8375a247c2f


Cloud ML Engineのジョブ登録

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

MacでCloud Machine Learning Engineを利用してみる

https://qiita.com/kai_kou/items/0952c9b28efe19f2f680


手順


下準備

変数を設定します。上記記事の手順を済ませている場合、すでに設定済みだと思います。

設定済みの場合、ジョブ名は重複すると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://qiita.com/kai_kou/items/dca21cdfd8375a247c2f


ソースの準備

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

> 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://qiita.com/kai_kou/items/dca21cdfd8375a247c2f

MacでCloud Machine Learning Engineを利用してみる

https://qiita.com/kai_kou/items/0952c9b28efe19f2f680