次の方法で共有


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

適用対象:Python SDK azureml v1

この記事では、Azure Machine Learning SDKParallelRunStep クラスを使用してエラーが発生した場合のトラブルシューティングの方法について説明します。

パイプラインのトラブルシューティングに関する一般的なヒントについては、「機械学習パイプラインのトラブルシューティング」を参照してください。

スクリプトのローカルでのテスト

ParallelRunStep は、ML パイプラインのステップとして実行されます。 最初の手順として、スクリプトをローカルでテストすることもできます。

エントリ スクリプトの要件

ParallelRunStep のエントリ スクリプトには、run() 関数が "含まれている必要があります"。また、オプションで init() 関数が含まれています。

  • init(): この関数は、後の処理のためのコストのかかる準備、または一般的な準備を行うときに使用します。 たとえば、これを使って、モデルをグローバル オブジェクトに読み込みます。 この関数は、プロセスの開始時に 1 回だけ呼び出されます。

    Note

    init メソッドが出力ディレクトリを作成する場合は、parents=True および exist_ok=True を指定します。 init メソッドは、ジョブが実行されているすべてのノードの各ワーカー プロセスから呼び出されます。

  • run(mini_batch): この関数は、mini_batch インスタンスごとに実行されます。
    • mini_batch: ParallelRunStep は run メソッドを呼び出して、そのメソッドに、リストまたは Pandas DataFrame のいずれかを引数として渡します。 mini_batch のエントリはそれぞれ、ファイル パス (入力が FileDataset の場合) または Pandas DataFrame (入力が TabularDataset の場合) にすることができます。
    • response: run() メソッドは、Pandas DataFrame または配列を返します。 append_row output_action の場合、これらの返される要素は、共通の出力ファイルに追加されます。 summary_only の場合、要素のコンテンツは無視されます。 すべての出力アクションについて、返される出力要素はそれぞれ、入力ミニバッチ内で成功した 1 つの入力要素の実行を示します。 入力を実行出力結果にマップできるだけの十分なデータが実行結果に含まれていることを確認してください。 実行の出力は出力ファイルに書き込まれますが、順序どおりであることは保証されません。出力でいずれかのキーを使って、入力にマップする必要があります。

      Note

      1 つの入力要素に対して 1 つの出力要素が必要です。

%%writefile digit_identification.py
# Snippets from a sample script.
# Refer to the accompanying digit_identification.py
# (https://github.com/Azure/MachineLearningNotebooks/tree/master/how-to-use-azureml/machine-learning-pipelines/parallel-run)
# for the implementation script.

import os
import numpy as np
import tensorflow as tf
from PIL import Image
from azureml.core import Model


def init():
    global g_tf_sess

    # Pull down the model from the workspace
    model_path = Model.get_model_path("mnist")

    # Construct a graph to execute
    tf.reset_default_graph()
    saver = tf.train.import_meta_graph(os.path.join(model_path, 'mnist-tf.model.meta'))
    g_tf_sess = tf.Session()
    saver.restore(g_tf_sess, os.path.join(model_path, 'mnist-tf.model'))


def run(mini_batch):
    print(f'run method start: {__file__}, run({mini_batch})')
    resultList = []
    in_tensor = g_tf_sess.graph.get_tensor_by_name("network/X:0")
    output = g_tf_sess.graph.get_tensor_by_name("network/output/MatMul:0")

    for image in mini_batch:
        # Prepare each image
        data = Image.open(image)
        np_im = np.array(data).reshape((1, 784))
        # Perform inference
        inference_result = output.eval(feed_dict={in_tensor: np_im}, session=g_tf_sess)
        # Find the best probability, and add it to the result list
        best_result = np.argmax(inference_result)
        resultList.append("{}: {}".format(os.path.basename(image), best_result))

    return resultList

推論スクリプトと同じディレクトリに他のファイルまたはフォルダーがある場合、現在の作業ディレクトリを特定することでそれらを参照することができます。 パッケージをインポートする場合は、パッケージ フォルダーを sys.path に追加することもできます 。

script_dir = os.path.realpath(os.path.join(__file__, '..',))
file_path = os.path.join(script_dir, "<file_name>")

packages_dir = os.path.join(file_path, '<your_package_folder>')
if packages_dir not in sys.path:
    sys.path.append(packages_dir)
from <your_package> import <your_class>

ParallelRunConfig のパラメーター

ParallelRunConfig は、Azure Machine Learning パイプライン内にある ParallelRunStep インスタンスの主要な構成です。 これは、お使いのスクリプトをラップし、必要なパラメーターを構成するときに使用します。たとえば、次のようなエントリです。

  • entry_script: 複数のノードで並列で実行されるローカル ファイル パスとしてのユーザー スクリプト。 source_directory が存在する場合は、相対パスを使用する必要があります。 それ以外の場合は、マシンでアクセス可能な任意のパスを使用します。

  • mini_batch_size:1 つの run() 呼び出しに渡されたミニバッチのサイズ (省略可能。既定値は、FileDataset の場合は 10 ファイルで、TabularDataset の場合は 1MB です。)

    • FileDataset の場合、これはファイル数を示し、最小値は 1 です。 複数のファイルを 1 つのミニバッチに結合できます。
    • TabularDataset の場合は、データのサイズです。 サンプル値は、10241024KB10MB、および 1GB です。 推奨値は 1MB です。 TabularDataset のミニバッチは、ファイル境界を超えません。 たとえば、さまざまなサイズの複数の.csv ファイルがある場合、最も小さいものは 100 KB、最大は 10 MB です。 mini_batch_size = 1MB が設定されている場合、1 MB 未満のファイルは 1 つのミニバッチとして扱われ、1 MB を超えるファイルは複数のミニバッチに分割されます。

      Note

      SQL でサポートされる TabularDataset は、パーティション分割できません。 1 つの parquet ファイルと 1 つの行グループの TabularDataset をパーティション分割することはできません。

  • error_threshold:処理中に無視する必要のあるエラーの数。TabularDataset の場合はレコード エラー数、FileDataset の場合はファイル エラー数を示します。 入力全体に対するエラーの数がこの値を超えると、ジョブは中止されます。 エラーのしきい値は入力全体を対象としています。run() メソッドに送信された個々のミニバッチを対象にしているものではありません。 範囲は [-1, int.max] です。 -1 は、処理中にすべての失敗を無視することを示します。

  • output_action: 次のいずれかの値が、出力がどのように構成されるかを示しています:

    • summary_only: ユーザー スクリプトは出力ファイルを保存する必要があります。 run() の出力は、エラーしきい値の計算にのみ使用されます。
    • append_row: すべての入力について、ParallelRunStep によって出力フォルダーにファイルが 1 つ作成され、行で区切られたすべての出力が追加されます。
  • append_row_file_name:append_row output_action の出力ファイル名をカスタマイズします (省略可能。既定値は parallel_run_step.txt です)。

  • source_directory:コンピューティング ターゲットで実行されるすべてのファイルを含むフォルダーへのパス (省略可能)。

  • compute_target:サポートされるのは AmlCompute のみです。

  • node_count:ユーザー スクリプトの実行に使用されるコンピューティング ノードの数。

  • process_count_per_node: エントリ スクリプトを並列で実行するノードあたりのワーカー プロセスの数。 GPU マシンの場合、既定値は 1 です。 CPU マシンの場合、既定値はノードあたりのコア数です。 ワーカー プロセスは、パラメーターとして取得したミニ バッチを渡すことによって、run() を繰り返し呼び出します。 ジョブ内のワーカー プロセスの総数は process_count_per_node * node_count で、これにより並列で実行する run() の最大数が決定します。

  • environment:Python 環境定義。 既存の Python 環境が使用されるように、または一時的な環境が設定されるように構成できます。 定義で、必要なアプリケーションの依存関係を設定することもできます (省略可能)。

  • logging_level:ログの詳細。 値は詳細度が低い順に WARNINGINFODEBUG です。 (省略可能。既定値は INFO です)

  • run_invocation_timeout:run() メソッド呼び出しのタイムアウト (秒単位)。 (省略可能、既定値は 60 です)

  • run_max_try:ミニバッチに対する run() の最大試行回数。 例外がスローされた場合、run() は失敗します。run_invocation_timeout に到達した場合は何も返されません (省略可能。既定値は 3 です)。

mini_batch_sizenode_countprocess_count_per_nodelogging_levelrun_invocation_timeoutrun_max_tryPipelineParameter として指定すると、パイプラインの実行を再送信するときに、パラメーターの値を微調整できます。

CUDA デバイスの可視性

GPU を搭載したコンピューティング ターゲットの場合、ワーカー プロセスで環境変数 CUDA_VISIBLE_DEVICES が設定されます。 AmlCompute では、GPU デバイスの総数は環境変数 AZ_BATCHAI_GPU_COUNT_FOUND で確認でき、これは自動的に設定されます。 各ワーカー プロセスに専用の GPU を設定する場合は、process_count_per_node をマシン上の GPU デバイスの数と同じに設定します。 その後、各ワーカー プロセスでは、CUDA_VISIBLE_DEVICES に一意なインデックスが割り当てられます。 ワーカー プロセスが何らかの理由で停止した場合、次に開始されるワーカー プロセスが、解放された GPU インデックスを使用します。

GPU デバイスの総数が process_count_per_node 未満の場合、すべての GPU が占有されるまで、インデックスが小さいワーカー プロセスに GPU インデックスを割り当てることができます。

GPU デバイスの合計を 2 と想定して process_count_per_node = 4 を例とすると、プロセス 0 とプロセス 1 のインデックスが 0 と 1 になります。 プロセス 2 と 3 には環境変数がありません。 この環境変数を GPU の割り当てに使用するライブラリの場合、プロセス 2 と 3 には GPU がなく、GPU デバイスを取得しようとしません。 プロセス 0 では、停止すると GPU インデックス 0 が解放されます。 次のプロセス (該当する場合) であるプロセス 4 には、GPU インデックス 0 が割り当てられます。

詳細については、「CUDA Pro Tip: Control GPU Visibility with CUDA_VISIBLE_DEVICES(CUDA Pro ヒント: CUDA_VISIBLE_DEVICES を使用した GPU 可視性の制御)」を参照してください。

ParallelRunStep を作成するためのパラメーター

スクリプト、環境構成、およびパラメーターを使用して、ParallelRunStep を作成します。 お使いの推論スクリプトの実行の対象としてご自身のワークスペースに関連付けたコンピューティング ターゲットを指定します。 ParallelRunStep を使用して、バッチ推論パイプラインのステップを作成します。このステップでは、次のすべてのパラメーターが使用されます。

  • name: ステップの名前。3 文字以上 32 文字以内で、一意の名前にする必要があります。また、正規表現 ^[a-z]([-a-z0-9]*[a-z0-9])?$ を使用できます。
  • parallel_run_config:ParallelRunConfig オブジェクト (前述にて定義)。
  • inputs:並列処理のためにパーティション分割される 1 つ以上の single 型の Azure Machine Learning データセット。
  • side_inputs:パーティション分割する必要のないサイド入力として使用される 1 つ以上の参照データまたはデータセット。
  • output: 出力データが保存されるディレクトリ パスを表す OutputFileDatasetConfig オブジェクト。
  • arguments:ユーザー スクリプトに渡された引数の一覧。 それらを実際のエントリ スクリプト内で取得するには、unknown_args を使用します (省略可能)。
  • allow_reuse:同じ設定/入力で実行されたときに、ステップで前の結果を再利用するかどうか。 このパラメーターが False の場合、パイプラインの実行中、このステップに対して必ず新しい実行が生成されます (省略可能。既定値は True です)。
from azureml.pipeline.steps import ParallelRunStep

parallelrun_step = ParallelRunStep(
    name="predict-digits-mnist",
    parallel_run_config=parallel_run_config,
    inputs=[input_mnist_ds_consumption],
    output=output_dir,
    allow_reuse=True
)

リモート コンテキストからのスクリプトのデバッグ

スコアリング スクリプトのローカルでのデバッグから実際のパイプラインでのデバッグに切り替えることは、大幅な変更であり、簡単ではありません。 ポータルでのログの検索については、機械学習パイプラインのリモート コンテキストからのスクリプトのデバッグに関するセクションを参照してください。 そのセクションの情報は、ParallelRunStep にも適用されます。

ParallelRunStep ジョブには分散型の性質があるため、複数の異なるソースからのログが存在します。 ただし、概要情報を提供する、統合されたファイルが 2 つ作成されます。

  • ~/logs/job_progress_overview.txt:このファイルでは、これまでに作成されたミニバッチ (タスクとも呼ばれます) の数とこれまでに処理されたミニバッチの数に関する概要が示されます。 最後にはジョブの結果が示されます。 ジョブが失敗した場合は、エラー メッセージと、トラブルシューティングを始める場所が示されます。

  • ~/logs/job_result.txt: ジョブの結果が表示されます。 ジョブが失敗した場合は、エラー メッセージと、トラブルシューティングを始める場所が示されます。

  • ~/logs/job_error.txt: このファイルは、スクリプト内のエラーをまとめたものです。

  • ~/logs/sys/master_role.txt:このファイルでは、実行中のジョブのプリンシパル ノード (オーケストレーターとも呼ばれます) が示されます。 タスクの作成、進行状況の監視、実行結果が含まれます。

  • ~/logs/sys/job_report/processed_mini-batches.csv: 処理されたすべてのミニバッチの表。 ミニバッチの各実行の結果、その実行エージェント ノード ID、プロセス名が表示されます。 また、経過時間とエラー メッセージも含まれます。 ミニバッチの各実行のログは、ノード ID とプロセス名に従って確認できます。

EntryScript ヘルパーおよび PRINT ステートメントを使用してエントリ スクリプトから生成されたログは、次のファイルにあります。

  • ~/logs/user/entry_script_log/<node_id>/<process_name>.log.txt:これらのファイルは、EntryScript ヘルパーを使用して entry_script から書き込まれたログです。

  • ~/logs/user/stdout/<node_id>/<process_name>.stdout.txt: これらのファイルは、entry_script の stdout (PRINT ステートメントなど) のログです。

  • ~/logs/user/stderr/<node_id>/<process_name>.stderr.txt:これらのファイルは、entry_script の stderr のログです。

たとえば、このスクリーンショットは、ノード 0 process001 でミニバッチ 0 が失敗したことを示しています。 エントリ スクリプトの対応するログは、~/logs/user/entry_script_log/0/process001.log.txt~/logs/user/stdout/0/process001.log.txt~/logs/user/stderr/0/process001.log.txt にあります

サンプル processed_mini-batches.csv ファイルのスクリーンショット。

各ノードによってスコアリング スクリプトがどのように実行されたかを十分に理解する必要がある場合は、ノードごとの各プロセス ログを確認してください。 プロセス ログは、ワーカー ノード別にグループ化されて ~/logs/sys/node フォルダーにあります。

  • ~/logs/sys/node/<node_id>/<process_name>.txt: このファイルは、各ミニバッチがワーカーによって収集または完了される際に、その詳細情報を提供します。 各ミニバッチについて、次の情報が記録されます。

    • ワーカー プロセスの IP アドレスと PID。
    • 項目の合計数、正常に処理された項目数、および失敗した項目数。
    • 開始時刻、期間、処理時間、および実行メソッドの時間。

また、各ノードのリソース使用率の定期的チェックの結果を表示することもできます。 ログ ファイルとセットアップ ファイルは次のフォルダーにあります。

  • ~/logs/perf:秒単位でチェック間隔を変更するには、--resource_monitor_interval を設定します。 既定の間隔は 600 で、これは約 10 分です。 監視を停止するには、値を 0 に設定します。 各 <node_id> フォルダーには次のものが含まれます。

    • os/:ノードで実行されているすべてのプロセスに関する情報。 1 回のチェックでオペレーティング システムのコマンドが実行され、その結果がファイルに保存されます。 Linux では、コマンドは psです。 Windows では、tasklist を使用します。
      • %Y%m%d%H:サブフォルダー名は、time to hour です。
        • processes_%M:ファイルは、チェック時間の分で終了します。
    • node_disk_usage.csv:ノードの詳細なディスク使用量。
    • node_resource_usage.csv:ノードのリソース使用状況の概要。
    • processes_resource_usage.csv:各プロセスのリソース使用状況の概要。

一般的なジョブ失敗の理由

SystemExit: 42

Exit 41 と Exit 42 は、PRS 設計終了コードです。 ワーカー ノードは、独立して終了したことをコンピューティング マネージャーに通知するために、41 で終了します。 これは想定されているものです。 リーダー ノードは、ジョブの結果を示す 0 または 42 で終了できます。 Exit 42 は、ジョブが失敗したことを意味します。 失敗の理由は、~/logs/job_result.txt で確認できます。 前のセクションに従ってジョブをデバッグできます。

データのアクセス許可

ジョブのエラーは、コンピューティングが入力データにアクセスできないことを示します。 コンピューティング クラスターとストレージに ID ベースが使用されている場合は、ID ベースのデータ認証を参照できます。

プロセスが予期せず終了しました

予期しない例外またはハンドルされない例外が原因でプロセスがクラッシュする可能性があります。システムはメモリ不足例外のためにプロセスを強制終了します。 PRS システム ログ ~/logs/sys/node/<node-id>/_main.txt では、次のようなエラーが見つかります。

<process-name> exits with returncode -9.

メモリ不足

~/logs/perf はプロセスの計算リソース消費量をログに記録します。 各タスク プロセッサのメモリ使用量を確認できます。 ノードのメモリ使用量の合計を見積もることができます。

メモリ不足エラーは ~/system_logs/lifecycler/<node-id>/execution-wrapper.txt にあります。

コンピューティング リソースが制限に近づいている場合は、ノードあたりのプロセス数を減らすか、VM サイズをアップグレードすることをおすすめします。

未処理の例外

場合によっては、Python プロセスが失敗したスタックをキャッチできない場合があります。 環境変数 env["PYTHONFAULTHANDLER"]="true" を追加して、Python 組み込み障害ハンドラーを有効にすることができます。

ミニバッチ タイムアウト

ミニバッチ タスクに応じて run_invocation_timeout 引数を調整できます。 run() 関数に予想以上の時間がかかる場合は、いくつかのヒントを次に示します。

  • ミニバッチの経過時間と処理時間を確認します。 処理時間は、プロセスの CPU 時間を測定します。 処理時間が経過した時間よりも大幅に短い場合は、タスクに大量の IO 操作またはネットワーク要求があるかどうかを確認できます。 これらの操作の長い待機時間は、ミニバッチ タイムアウトの一般的な理由です。

  • 一部の特定のミニバッチは、他のミニバッチよりも時間がかかります。 構成を更新するか、入力データを操作してミニバッチ処理時間のバランスを取ることができます。

リモート コンテキストからユーザー スクリプトのログを記録する方法

ParallelRunStep は、process_count_per_node に基づいて、1 つのノードで複数のプロセスを実行できます。 ノード上の各プロセスのログを整理し、PRINT および LOG ステートメントを組み合わせるには、次に示すように ParallelRunStep ロガーをお勧めします。 EntryScript からロガーを取得して、ポータルの logs/user フォルダーにログが表示されるようにします。

ロガーを使用したサンプル エントリ スクリプト:

from azureml_user.parallel_run import EntryScript

def init():
    """Init once in a worker process."""
    entry_script = EntryScript()
    logger = entry_script.logger
    logger.info("This will show up in files under logs/user on the Azure portal.")


def run(mini_batch):
    """Call once for a mini batch. Accept and return the list back."""
    # This class is in singleton pattern. It returns the same instance as the one in init()
    entry_script = EntryScript()
    logger = entry_script.logger
    logger.info(f"{__file__}: {mini_batch}.")
    ...

    return mini_batch

Python の logging からのメッセージはどこにシンクされますか。

ParallelRunStep ではルート ロガーにハンドラーが設定され、これによってメッセージは logs/user/stdout/<node_id>/processNNN.stdout.txt にシンクされます。

logging の既定値は INFO レベルです。 既定では、DEBUG のような INFO より低いレベルは表示されません。

ポータルに表示するファイルに書き込むにはどうすればよいですか。

/logs フォルダーに書き込まれるファイルは、アップロードされてポータルに表示されます。 下のようにフォルダー logs/user/entry_script_log/<node_id> を取得し、書き込むファイル パスを作成できます。

from pathlib import Path
from azureml_user.parallel_run import EntryScript

def init():
    """Init once in a worker process."""
    entry_script = EntryScript()
    log_dir = entry_script.log_dir
    log_dir = Path(entry_script.log_dir)  # logs/user/entry_script_log/<node_id>/.
    log_dir.mkdir(parents=True, exist_ok=True) # Create the folder if not existing.

    proc_name = entry_script.agent_name  # The process name in pattern "processNNN".
    fil_path = log_dir / f"{proc_name}_<file_name>" # Avoid conflicting among worker processes with proc_name.

新しいプロセス内でログを処理する方法

subprocess モジュールを使用して、ご自身のエントリ スクリプト内で新しいプロセスを生成し、その入力/出力/エラー パイプに接続して、リターン コードを取得することができます。

推奨されるアプローチは、run() 関数を使用して capture_output=True を指定することです。 エラーは logs/user/error/<node_id>/<process_name>.txt に表示されます。

Popen() を使用する場合は、stdout/stderr を次のようなファイルにリダイレクトする必要があります。

from pathlib import Path
from subprocess import Popen

from azureml_user.parallel_run import EntryScript


def init():
    """Show how to redirect stdout/stderr to files in logs/user/entry_script_log/<node_id>/."""
    entry_script = EntryScript()
    proc_name = entry_script.agent_name  # The process name in pattern "processNNN".
    log_dir = Path(entry_script.log_dir)  # logs/user/entry_script_log/<node_id>/.
    log_dir.mkdir(parents=True, exist_ok=True) # Create the folder if not existing.
    stdout_file = str(log_dir / f"{proc_name}_demo_stdout.txt")
    stderr_file = str(log_dir / f"{proc_name}_demo_stderr.txt")
    proc = Popen(
        ["...")],
        stdout=open(stdout_file, "w"),
        stderr=open(stderr_file, "w"),
        # ...
    )

Note

ワーカー プロセスによって、"system" コードとエントリ スクリプト コードが同じプロセスで実行されます。

stdout または stderr が指定されていない場合、ワーカー プロセスの設定は、エントリ スクリプト内で Popen() を使用して作成されたサブプロセスによって継承されます。

stdout~/logs/sys/node/<node_id>/processNNN.stdout.txt に、~/logs/sys/node/<node_id>/processNNN.stderr.txtstderr に書き込まれます。

ファイルを出力ディレクトリに書き込んで、それをポータルで表示するにはどうすればよいですか。

出力ディレクトリを EntryScript クラスから取得して、そこに書き込むことができます。 書き込まれたファイルを表示するには、Azure Machine Learning ポータルの実行ビュー手順で、 [出力 + ログ] タブを選択します。 [Data outputs](データ出力) リンクを選択し、ダイアログで説明されている手順を完了します。

EntryScript をエントリ スクリプトで、次の例のように使用します。

from pathlib import Path
from azureml_user.parallel_run import EntryScript

def run(mini_batch):
    output_dir = Path(entry_script.output_dir)
    (Path(output_dir) / res1).write...
    (Path(output_dir) / res2).write...

ルックアップ テーブルを含むファイルなどのサイド入力をすべてのワーカーに渡すにはどうすればよいですか?

ユーザーは、ParalleRunStep の side_inputs パラメーターを使用して、参照データをスクリプトに渡すことができます。 side_inputs として提供されるすべてのデータセットは、各ワーカー ノードにマウントされます。 ユーザーは引数を渡すことによって、マウントの場所を取得できます。

参照データが含まれるデータセットを作成し、ローカル マウント パスを指定して、それをワークスペースに登録します。 これを ParallelRunStepside_inputs パラメーターに渡します。 また、arguments セクションにそのパスを追加して、マウントされたパスに簡単にアクセスすることもできます。

注意

FileDatasets を使用するのは side_inputs だけにしてください。

local_path = "/tmp/{}".format(str(uuid.uuid4()))
label_config = label_ds.as_named_input("labels_input").as_mount(local_path)
batch_score_step = ParallelRunStep(
    name=parallel_step_name,
    inputs=[input_images.as_named_input("input_images")],
    output=output_dir,
    arguments=["--labels_dir", label_config],
    side_inputs=[label_config],
    parallel_run_config=parallel_run_config,
)

その後、次のように、スクリプト (init() メソッドなど) でアクセスできるようになります。

parser = argparse.ArgumentParser()
parser.add_argument('--labels_dir', dest="labels_dir", required=True)
args, _ = parser.parse_known_args()

labels_path = args.labels_dir

サービス プリンシパルの認証での入力データセットの使用方法

ユーザーは、ワークスペースで使用されるサービス プリンシパルの認証で入力データセットを渡すことができます。 ParallelRunStep でこのようなデータセットを使用する場合、ParallelRunStep 構成を構築するためにデータセットが登録されている必要があります。

service_principal = ServicePrincipalAuthentication(
    tenant_id="***",
    service_principal_id="***",
    service_principal_password="***")

ws = Workspace(
    subscription_id="***",
    resource_group="***",
    workspace_name="***",
    auth=service_principal
    )

default_blob_store = ws.get_default_datastore() # or Datastore(ws, '***datastore-name***')
ds = Dataset.File.from_files(default_blob_store, '**path***')
registered_ds = ds.register(ws, '***dataset-name***', create_new_version=True)

進行状況を調べてそれを分析する方法

このセクションでは、ParallelRunStep ジョブの進行状況を調べて、予期しない動作の原因を調べる方法について説明します。

ジョブの進行状況を調べる方法

StepRun の全体的な状態を調べる以外に、スケジュールまたは処理されたミニバッチの数と出力生成の進行状況を ~/logs/job_progress_overview.<timestamp>.txt で確認できます。 ファイルは毎日ローテーションされます。 タイムスタンプが最も大きいもので最新情報を確認できます。

進展がしばらくの間ない場合、何を調べたらよいか

~/logs/sys/error に移動して例外がないか調べます。 何もない場合は、エントリ スクリプトに時間がかかっている可能性があります。コードで進行状況情報を出力して時間のかかる部分を見つけるか、"--profiling_module", "cProfile"ParallelRunSteparguments に追加して、<process_name>.profile という名前のプロファイル ファイルを ~/logs/sys/node/<node_id> フォルダーの下に生成することができます。

ジョブが停止するのはいつか

キャンセルしていない場合、ジョブは次の状態で停止する可能性があります。

  • 完了。 すべてのミニバッチが正常に処理され、append_row モードで出力が生成されます。
  • 失敗。 Parameters for ParallelRunConfigerror_threshold を超えている場合、あるいはシステム エラーがジョブ中に発生した場合。

エラーの根本原因をどこで探すか

~/logs/job_result.txt の情報をたどると、原因と詳細なエラー ログが見つかります。

ノードのエラーがジョブの結果に影響するか

指定されたコンピューティング クラスターに他の使用可能なノードがある場合は、影響しません。 ParallelRunStep は、各ノードで個別に実行できます。 単一ノードの失敗では、ジョブ全体が失敗することはありません。

エントリ スクリプトの init 関数が失敗するとどうなりますか

ParallelRunStep には、ジョブのエラーをあまり長い時間遅らせずに、一時的な問題から復旧する機会を与えるために一定の回数再試行するメカニズムがあります。 そのメカニズムを以下に示します。

  1. ノードが起動した後、init がすべてのエージェントで失敗し続ける場合は、3 * process_count_per_node 回のエラーの後に試行を停止します。
  2. ジョブの開始後、すべてのノードのすべてのエージェントで init が失敗し続ける場合、ジョブの実行時間が 2 分を超えて 2 * node_count * process_count_per_node 回のエラーが発生した場合は試行を停止します。
  3. すべてのエージェントが init3 * run_invocation_timeout + 30 秒を超えてスタックしている場合、進展がない時間が長すぎるため、ジョブは失敗します。

OutOfMemory はどうなりますか? どうしたら原因を調べることができますか?

プロセスはシステムによって終了される場合があります。 ParallelRunStep が、ミニバッチを処理する現在の試みを失敗状態に設定し、失敗したプロセスを再開しようとします。 ~logs/perf/<node_id> を調べると、メモリを消費しているプロセスがわかります。

processNNN ファイルが多数あるのはなぜですか?

ParallelRunStep は、異常終了したワーカー プロセスの代わりに新しいものを開始します。 各プロセスでは、ログとして一連の processNNN ファイルが生成されます。 ただし、ユーザー スクリプトの init 関数中の例外が理由でプロセスが失敗し、エラーが 3 * process_count_per_node 回続けて繰り返す場合、新しいワーカー プロセスは開始されません。

次のステップ