トラブルシューティング

クラウドでモデルのトレーニングや予測の取得を行うときに発生するエラーの原因を突き止めるのが難しいことがあります。このページでは、問題を見つけてデバッグする方法について説明します。

コマンドライン ツール

エラー:(gcloud)無効な選択肢: 'ml-engine'。

このエラーは、gcloud を更新する必要があることを示しています。gcloud を更新するには、次のコマンドを実行します。

gcloud components update

ジョブログの使用

トラブルシューティングを行うには、最初に Stackdriver Logging によって記録されたジョブログを調べることをおすすめします。

さまざまなタイプのオペレーションのロギング

ログの内容は、次の各セクションで示すようにオペレーションのタイプによって異なります。

トレーニングのログ

すべてのトレーニング ジョブがログに記録されます。このログに記録されるイベントは、トレーニング サービスからのものも、トレーニング アプリケーションからのものもあります。Cloud ML Engine は、トレーナーからのすべてのロギング メッセージ(たとえば logging.Logger オブジェクトを使用)を記録します。

バッチ予測のログ

すべてのバッチ予測ジョブがログに記録されます。

オンライン予測のログ

オンライン予測リクエストを行ったときに、デフォルトではログは生成されません。モデルリソースを作成するときに、次の方法で Stackdriver Logging を有効にすることができます。

gcloud

gcloud ml-engine models create を実行するときに --enable-logging フラグを指定します。

Python

projects.models.create の呼び出しに使用する Model リソースの中で onlinePredictionLoggingTrue に設定します。

ログを見つける

ジョブのログには、オペレーションのすべてのイベントが記録されています。分散トレーニングを使用しているときは、クラスタ内のすべてのプロセスからのイベントがログに記録されます。分散型トレーニング ジョブを実行する場合は、ジョブレベルのログはマスター ワーカー プロセスのものとして報告されます。エラーのトラブルシューティングの最初のステップは一般的に、そのプロセスのログを調べて、記録されたイベントのうちクラスタ内の他のプロセスのものを除外することです。このセクションの例では、このフィルタリングを示しています。

ログのフィルタリングは、コマンドラインからでも、Google Cloud Platform Console の [Stackdriver Logging] セクションからでも行うことができます。どちらの場合も、次に示すメタデータ値を必要に応じてフィルタの中で使用します。

メタデータ項目 条件を満たすものを表示するフィルタ
resource.type "cloud_ml_job" に等しい。
resource.labels.job_id ジョブ名に等しい。
resource.labels.task_name "master-replica-0" に等しい(マスター ワーカーのログエントリのみを読み取る場合)。
severity ERROR 以上(エラー状態に対応するログエントリのみを読み取る場合)。

コマンドライン

gcloud beta logging read を使用して必要なクエリを作成します。たとえば次のようなものがあります。

各例は、次に示す環境変数に依存しています。

PROJECT="my-project-name"
JOB="my_job_name"

好みに応じて、文字列リテラルを代わりに入力することができます。

マスター ワーカーのログを画面に出力するには:
gcloud beta logging read --project=${PROJECT} "resource.type=\"ml_job\" and resource.labels.job_id=${JOB} and resource.labels.task_name=\"master-replica-0\""
ログに記録されたエラーのうち、マスター ワーカーのものだけを画面に出力するには:
gcloud beta logging read --project=${PROJECT} "resource.type=\"ml_job\" and resource.labels.job_id=${JOB} and resource.labels.task_name=\"master-replica-0\" and severity>=ERROR"

上記の例は、Cloud ML Engine のトレーニング ジョブのログをフィルタリングする最も一般的なケースを示しています。Stackdriver Logging には、フィルタリングのための便利なオプションが多数あり、検索を絞り込む必要がある場合に使用できます。高度なフィルタリングのドキュメントに、これらのオプションの詳細な説明があります。

Console

  1. Google Cloud Platform Console で機械学習の [ジョブ] ページを開きます。 Cloud Platform Console でジョブを開く

  2. 失敗したジョブを [ジョブ] ページの一覧から選択して詳細情報を表示します。

Cloud ML Engine ジョブリストに、失敗したジョブが表示されています。

  1. [ログを表示] をクリックして Stackdriver Logging を開きます。

失敗したジョブのジョブ詳細ページ。

Stackdriver Logging に直接移動することもできますが、ジョブを見つけるというステップが必要になります。

  1. リソース セレクタを展開します。
  2. リソースリストの中の [Cloud ML Engine ジョブ] を展開します。
  3. job_id リストの中でジョブ名を見つけます(ジョブ名の最初の数文字を検索ボックスに入力して、表示されるジョブを絞り込むことができます)。
  4. ジョブのエントリを展開し、タスクリストから master-replica-0 を選択します。

ログ フィルタ セレクタがすべて展開されています。

ログからの情報の取得

ジョブの正しいログが見つかり、フィルタリングして master-replica-0 だけが表示される状態になったら、ログに記録されたイベントを調べて問題の発生源を見つけます。これには標準的な Python のデバッグ手順が含まれますが、次のことに注意してください。

  • イベントの重大度はいくつかのレベルに分かれています。イベントをフィルタリングして、特定のレベル(エラーだけ、またはエラーと警告など)のイベントだけを表示することができます。
  • 問題が発生したためトレーナーが回復不能なエラー状態(戻りコード > 0)で終了した場合は、例外としてログに記録され、その前にスタック トレースが記録されます。

どのセクションも展開されていないログエントリ

  • さらに情報を入手するには、記録された JSON メッセージの中のオブジェクトを展開します(右向き矢印付きで、内容は {...} と表示されています)。たとえば、jsonPayload を展開すると、スタック トレースはメインのエラーの説明よりも読みやすい形式で表示されます。

JSON ペイロード セクションが展開されているログエントリ

  • エラーの中には、再試行可能なエラーもあります。このようなエラーには一般的に、スタック トレースが含まれていないため、診断が難しくなることがあります。

ロギングを最大限に活用

Cloud ML Engine トレーニング サービスは、自動的に次のイベントを記録します。

  • サービス内部のステータス情報。
  • トレーナー アプリケーションから stderr に送信されるメッセージ。
  • トレーナー アプリケーションから stdout に送信される出力テキスト。

トレーナー アプリケーションのエラーのトラブルシューティングを容易にするために、次のようにプログラミングすることをおすすめします。

  • 意味のあるメッセージを stderr に送信します(たとえば logging を使用します)。
  • なんらかの問題が生じたときは、最も論理的で記述的な例外を発生させます。
  • 説明の文字列を例外オブジェクトに追加します。

Python のドキュメントに、例外に関する詳しい情報が記載されています。

トレーニングのトラブルシューティング

このセクションでは、トレーニング ジョブに適用されるコンセプトとエラー条件について説明します。

トレーニング アプリケーションの戻りコードの理解

クラウドでのトレーニング ジョブを制御するのは、トレーニング クラスタのマスター ワーカー プロセスで実行されるメイン プログラムです。

  • トレーニングを単一のプロセスで行う場合は(非分散型)、ワーカーは 1 つだけであり、これがマスターです。
  • メイン プログラムは、TensorFlow トレーニング アプリケーションの __main__ 関数です。
  • Cloud ML Engine のトレーニング サービスによるトレーナー アプリケーションの実行は、アプリケーションが正常に完了するか回復不能なエラーが発生するまで続きます。つまり、再試行可能なエラーが発生した場合はプロセスが再起動される可能性があります。

トレーニング サービスは、プロセスを管理します。プログラムの終了は、マスター ワーカー プロセスの戻りコードに従って処理されます。

戻りコード 意味 Cloud ML Engine のレスポンス
0 正常に完了 シャットダウンしてジョブのリソースを解放します。
1~128 回復不能エラー ジョブを終了してエラーをログに記録します。

__main__ 関数の戻りコードに関して、特に何もする必要はありません。正常に完了したときは Python が自動的に 0 を返し、処理できない例外が発生したときは正のコードを返します。例外オブジェクトに特定の戻りコードを設定するようにプログラミングされていても(間違いではありませんが、あまり一般的な方法ではありません)、上記の表のパターンに従っている限り、Cloud ML Engine のジョブに影響が及ぶことはありません。その場合も、クライアント コードは一般的に、再試行可能なエラーを直接示すことはありません。このようなエラーは、運用環境からのものです。

特定のエラー条件の処理

このセクションでは、一部のユーザーに影響を及ぼすことが知られているエラー状態に関するガイダンスを示します。

何も進行することなくトレーナーが永遠に実行を続ける

状況によっては、トレーナー アプリケーションが実行を続けているにもかかわらずトレーニング タスクが何も進行しないことがあります。この原因としては、決して利用可能になることのないリソースを待っているブロック呼び出しが考えられます。この問題を軽減するには、トレーナーの中でタイムアウト時間を設定してください。

トレーナーのタイムアウト時間を設定する

タイムアウト(ミリ秒単位)は、セッションを作成するときに設定することも、グラフのステップを実行するときに設定することもできます。

  • Session オブジェクトを作成するときに、タイムアウト時間を次のように config パラメータで設定します。

    sess = tf.Session(config=tf.ConfigProto(operation_timeout_in_ms=500))
    
  • Session.run の 1 回の呼び出しに適用するタイムアウトを設定するには、次のように options パラメータを使用します。

    v = session.run(fetches, options=tf.RunOptions(timeout_in_ms=500))
    

詳細については、TensorFlow の Session のドキュメントをご覧ください。

プログラムがコード -9 で終了する

終了コード -9 が続く場合は、トレーナー アプリケーションが、そのプロセス用に割り当てられているよりも多くのメモリを使用している可能性があります。このエラーを解決するには、メモリ使用量を減らすか、メモリ容量の大きいマシンタイプを使用してください。

  • グラフとトレーナー アプリケーションに、予想以上に多くのメモリを使用しているオペレーションがあるかどうかを調べます。メモリ使用量に影響を与えるものとしては、データの複雑さと、計算グラフのオペレーションの複雑さがあります。
  • ジョブに割り当てられるメモリを増やすには、次のような方法が必要になることがあります。
    • 定義済みのスケール階層を使用する場合は、マシンを追加せずにマシンあたりのメモリ割り当てを増やすことはできません。カスタム階層に切り替えて、クラスタ内のマシンタイプを自分で定義する必要があります。
    • 定義済みの各マシンタイプの正確な設定は変更される可能性がありますが、大まかな比較は可能です。マシンタイプの比較表がトレーニングのコンセプトのページにあります。
    • 適切なメモリ割り当てを見つけるためにさまざまなマシンタイプをテストするときは、請求される料金を最小限に抑えるために、マシンを 1 つだけ、または小さいサイズのクラスタを使用することをおすすめします。

プログラムがコード -15 で終了する

一般的に、終了コード -15 はシステムによる保守を示します。これは再試行可能なエラーであるため、プロセスは自動的に再起動されます。

ジョブが長時間キューに入っている

トレーニング ジョブの StateQUEUED の状態が長時間に及ぶ場合は、ジョブ リクエストの割り当てを超過している可能性があります。

Cloud ML Engine によるトレーニング ジョブの開始はジョブ作成時間に基づいており、先入れ先出し規則が使用されます。ジョブがキューに入っている場合は、プロジェクト割り当てがすべて、そのジョブよりも前に送信されたジョブに使用されているか、キューの先頭のジョブが要求している ML ユニット / GPU が残りの割り当てを超えていることを示しています。

ジョブがキューに入れられた理由は、トレーニング ログに記録されます。ログの中で次のようなメッセージを探してください。

This job is number 2 in the queue and requires
4.000000 ML units and 0 GPUs. The project is using 4.000000 ML units out of 4
allowed and 0 GPUs out of 10 allowed.

このメッセージは、キュー内のジョブの現在位置と、プロジェクトの現在の使用量と割り当てを表しています。

なお、理由がログに記録されるのは、キューに入っているジョブのうち、ジョブ作成時間順で最初の 10 個だけです。

割り当てられた数以上のリクエストが必要になることが多い場合は、割り当ての増加をリクエストできます。プレミアム サポート パッケージをお持ちの場合は、サポートにご連絡ください。それ以外の場合は、リクエストをメールで Cloud ML Engine フィードバックにお送りください。

割り当てを超過した

「project_number への割当てが失敗しました...」のようなエラーが返された場合は、リソース割り当てを超過している可能性があります。リソース消費量のモニタリングと増加のリクエストは、コンソールの API Manager の Cloud ML Engine 割り当てページで行うことができます。

保存パスが無効

ジョブの終了時に返されるエラー メッセージに「無効な保存パス gs://... で復元が呼び出されました」が含まれている場合は、使用している Google Cloud Storage バケットが正しく設定されていない可能性があります。

  1. Google Cloud Platform Console の Google Cloud Storage の [ブラウザ] ページを開きます。 Cloud Platform Console のブラウザを開く

  2. 使用しているバケットの [デフォルトのストレージ クラス] を調べます。

Google Cloud Platform バケットが 2 つあり、一方はサポート対象外のマルチリージョンに割り当てられ、他方はリージョンに割り当てられています

  • これは [Regional] のはずです。このとおりの場合は、他に問題があります。ジョブをもう一度実行してみてください。
  • [Multi-Regional] の場合は、[Regional] に変更するか、トレーニングのデータを別のバケットに移動する必要があります。前者については、Cloud Storage のドキュメントにあるバケットのストレージ クラスの変更手順をご覧ください。

トレーナーが AbortedError で終了する

実行するトレーナーで TensorFlow Supervisor を使用して分散ジョブを管理している場合は、ジョブ全体を停止させるべきでない状況のときに TensorFlow が AbortedError 例外をスローすることがあります。トレーナーでその例外をキャッチして適切に対処することができます。ただし、Cloud ML Engine で実行されるトレーナーでは、Supervisor はサポートされなくなりました。バージョン 1.0 でのトレーナーのサポートに関する変更点については、移行ガイドをご覧ください。

予測のトラブルシューティング

このセクションでは、予測を取得するときに発生する一般的な問題をまとめています。

オンライン予測の特定の条件の処理

このセクションでは、一部のユーザーに影響を及ぼすことが知られているオンライン予測エラー条件に関するガイダンスを示します。

予測の完了までに時間がかかりすぎる(30~180 秒)

オンライン予測の遅さの原因として最も一般的なものは、処理ノードが 0 からスケールアップされることです。モデルに対する予測リクエストが絶えず行われる場合は、予測を処理できる状態のノードが 1 つ以上維持されます。モデルが予測を処理しない時間が長期に及んだ場合は、サービスが自動的に「スケールダウン」し、使用可能なノードは 0 になります。このようなスケールダウンの後に行われた予測リクエストは、結果が返されるまで通常よりも長い時間がかかりますが、これは処理するためのノードのプロビジョニングが必要になるためです。

HTTP ステータス コード

オンライン予測リクエストでエラーが発生すると、通常は HTTP ステータス コードがサービスから返されます。よく発生するコードと、オンライン予測におけるその意味を次に示します。

429 - メモリ不足

処理ノードでのモデルの実行中に、メモリの空きがなくなりました。予測ノードに割り当てられたメモリを増やす方法は、この時点ではありません。モデルを実行できるようにするには、次のことを試してみてください。

  • 次の方法でモデルを小さくします。
    • 精度の低い変数を使用する。
    • 連続データを量子化する。
    • 他の入力特徴のサイズを小さくする(たとえば、ボキャブラリのサイズを小さくする)。
  • バッチのインスタンス数を減らしてリクエストをもう一度送信します。
429 - 保留中のリクエストが多すぎます

モデルが処理できる以上のリクエストが発生しています。自動スケーリングを使用している場合は、システムがスケールアップできる速さを超えてリクエストが発生しています。

自動スケーリングを使用しているときは、指数バックオフを指定してリクエストを再送信してみてください。このようにすると、システムに調整する時間を与えることができます。

429 - 割り当て

Google Cloud Platform プロジェクトのリクエスト数は、100 秒あたり 10,000 件(1 秒あたり約 100 件)に制限されています。一時的なスパイクでこのエラーが発生した場合は、指数バックオフを使用して再試行するとすべてのリクエストを時間どおりに処理できることがあります。このコードが返されることが続く場合は、割り当ての増加をリクエストしてください。詳細については、割り当てのページをご覧ください。

503 - ご利用のコンピュータ ネットワークから通常以上のトラフィックが検出されました

単一の IP からモデルが受け取るリクエストの頻度が高すぎるため、サービス妨害攻撃が疑われています。リクエストの送信を 1 分間停止してから、頻度を下げて送信を再開してください。

500 - モデルを読み込めませんでした

システムがモデルを読み込むことができませんでした。次のステップを試してください。

  • トレーナーがエクスポートしているモデルが正しいことを確認します。
  • テスト予測を gcloud ml-engine local predict コマンドで試します。
  • モデルを再度エクスポートして、再試行します。

リクエストの内容に関するエラー メッセージ

次に示すメッセージはすべて、予測入力に関係しています。

「リクエスト本文が空白であるか、不適切または無効な JSON があります」
リクエスト内の JSON を解析できなかったか、リクエストが空です。JSON を無効にするエラーや省略がメッセージにないかどうかを確認してください。
「リクエスト本文に「インスタンス」フィールドが見つかりません」
リクエスト本文の形式が正しくありません。リクエスト本文は、JSON オブジェクトであり、キーは 1 つだけで名前が "instances" であり、この中にすべての入力インスタンスのリストが格納されている必要があります。
リクエストの作成時に、JSON のエンコーディング エラーが発生しました

リクエストの中に base64 でエンコードされたデータがありますが、適切な JSON 形式ではありません。base64 でエンコードされた文字列はそれぞれ、"b64" という名前の単一のキーを持つオブジェクトで表す必要があります。次に例を示します。

{"b64": "an_encoded_string"}

base64 エラーは、base64 でエンコードされていないバイナリデータがある場合にも発生します。データをエンコードして、上記の例に示した形式で指定してください。

クラウドの予測に要する時間がデスクトップよりも長い

オンライン予測は、大量の予測リクエストを短時間で処理するスケーラブルなサービスとして設計されています。このサービスは、処理リクエストすべての全体的なパフォーマンスを高めるように最適化されています。スケーラビリティに重点を置いていることから、パフォーマンス特性はローカルマシンで少数の予測を生成する場合とは異なるものとなります。

次のステップ

フィードバックを送信...

Cloud Machine Learning Engine(Cloud ML Engine)