Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

概要

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

kai_kou
2004年からWeb系のシステムエンジニアとして開発、運用、マネジメントを経験。現在はアイレット(クラウドパック)に所属。 べ、別にいいね貰えたからってモチベーションが上がって記事とコードの品質があがるわけじゃないんだからね///
https://twitter.com/k_aik_ou
cloudpack
Amazon Web Services (AWS) の導入設計、環境構築、運用・保守をサポートするマネジドホスティングサービス
https://cloudpack.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away