Ahogrammer

Deep Dive Into NLP, ML and Cloud

入門 AWS Step Functions

最近は仕事の一つとして、機械学習用のワークフローを作成しています。ワークフローを作成するサービスやソフトウェアはいくつかありますが、それら中でもAWS Step Functionsを使おうと考えています。今回の記事は、AWS Step Functionsについて調べたことを簡単にまとめた内容となっています。

Step Functionsとは?

AWS Step Functionsとは、ワークフローを定義して、実行・管理できるマネージドサービスです。AWS上の各サービスをコンポーネントとしてワークフローを定義することができます。また、定義したワークフローは、以下のようなグラフィカルなコンソールで確認できます。

f:id:Hironsan:20190515084114p:plain

Step Functionsで何ができるか?

Step Functionsを使うことで、さまざまなタスクで構成される複雑なワークフローを簡単に定義できます。たとえば、画像を複数のフォーマットに変換し、拡大縮小してAmazon Rekognitionで分析するプロセスは、各タスクをLambda関数で記述し、ワークフローとして定義することで、簡単に実行できます。

f:id:Hironsan:20190515085319p:plain
Ref: https://cloudacademy.com/lab/introduction-aws-step-functions/

Step Functionsがなぜ必要か?

Step Functionsを使うことで、各コンポーネントを再利用可能な形で書くことができます。Lambdaだけでワークフローを書こうとすると、一つのLambda関数内にすべての処理を書くか、Lambda関数内から別のLambda関数を呼ぶ必要があります。一つのLambda関数で書くとメンテナンスが難しくなるという欠点があり、Lambda関数内から別の関数を呼び出すと、関数間が密結合になり、再利用しにくい関数になるという欠点があります。

Step Functionsの料金

Step Functionsは状態遷移ごとに課金されます。最初の4000回の状態遷移については一月の無料枠の範囲内なので課金されません。それ以降は状態遷移あたりに課金されます。リージョンによって金額は異なるのですが、バージニア北部の場合、1000回の状態遷移で0.025 USDが課金されます。金額の詳細は以下を参照すると良いでしょう。

aws.amazon.com

Step Functionsの使い方

ワークフローの定義は、Amazon States Languageを使って行います。Amazon States Languageを使うことで、ステートマシンをJSON形式で宣言的に記述することができます。たとえば、以下のように記述します。

{
  "Comment": "A Hello World example of the Amazon States Language using a Pass state",
  "StartAt": "HelloWorld",
  "States": {
    "HelloWorld": {
      "Type": "Pass",
      "Result": "Hello World!",
      "End": true
    }
  }
}

JSONで書くと一見複雑に見えるのですが、図にすると以下のようにシンプルです。

f:id:Hironsan:20190516083706p:plain

このJSONで記述したステートマシンには、状態とその間の関係を記述していきます。状態はStatesの中に書いていきます。上のJSONの場合は状態としてHelloWorldだけが存在しています。StartAtにはステートマシンの開始状態を指定します。今回の場合はHelloWorldステートから始まるということを示しています。End: trueがある場合は実行を停止します。

Typeは状態のタイプを指定するフィールドです。上の場合はタイプとしてPassが指定されていますが、これは入力に何もせずに出力するという意味があります。ResultはPass状態からの出力を書くフィールドで、今回の場合は「Hello World!」が出力されます。

もう少し複雑な例について見てみましょう。以下の例では状態が複数含まれています。

{
  "Comment": "An example of the Amazon States Language using a choice state.",
  "StartAt": "FirstState",
  "States": {
    "FirstState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FUNCTION_NAME",
      "Next": "ChoiceState"
    },
    "ChoiceState": {
      "Type" : "Choice",
      "Choices": [
        {
          "Variable": "$.foo",
          "NumericEquals": 1,
          "Next": "FirstMatchState"
        },
        {
          "Variable": "$.foo",
          "NumericEquals": 2,
          "Next": "SecondMatchState"
        }
      ],
      "Default": "DefaultState"
    },

    "FirstMatchState": {
      "Type" : "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:OnFirstMatch",
      "Next": "NextState"
    },

    "SecondMatchState": {
      "Type" : "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:OnSecondMatch",
      "Next": "NextState"
    },

    "DefaultState": {
      "Type": "Fail",
      "Error": "DefaultStateError",
      "Cause": "No Matches!"
    },

    "NextState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FUNCTION_NAME",
      "End": true
    }
  }
}

図にすると以下のようになります。図を見ると条件分岐が入っていることがわかります。

f:id:Hironsan:20190516083414p:plain

このステートマシンはStartAtFirstStateが指定されていることから、FirstStateステートから開始されることがわかります。そのFirstStateステートはTypeResourceNextフィールドを持ちます。TypeTaskが指定されていると、このステートで一つの作業が実行されることを表しています。どんな作業が実行されるのかはResourceに指定します。今回の場合はLambda関数が指定されていることがわかります。Nextには次に遷移する状態を指定します。

次の状態であるChoiceStateはそのタイプがChoiceになっていることが確認できます。タイプをChoiceにすることで、ステートマシンに条件分岐を実装できます。Choicesフィールドの中に条件分岐のルールを書き、どれにもマッチしない場合はDefaultで指定した状態に遷移します。

Choicesフィールドの中身を見てみましょう。

{
   "Variable": "$.foo",
   "NumericEquals": 1,
   "Next": "FirstMatchState"
}

Variableフィールドには条件分岐の対象となるデータを指定します。今回の場合は$.fooを指定しているので、ステートマシンの入力からfooフィールドの値を取り出して使うことを示しています。

{
    "foo": 1
}

その次には比較するタイプを指定します。上の例の場合、NumericEqualsを指定しているので、Variableの値が比較条件に指定した値と数値的に等しいかを検証します。比較結果が真であればNextフィールドに指定したステートに遷移します。

残りの部分は、これまでに説明した内容を繰り返し適用しているだけです。

おわりに

今回はAWS Step Functionsの概要について紹介しました。次回の記事ではStep Functionsを使った機械学習/自然言語処理向けのワークフローを構築してみます。

参考資料