Устранение неполадок ParallelRunStep
ОБЛАСТЬ ПРИМЕНЕНИЯ: Пакет SDK для Python версии 1
Из этой статьи вы узнаете, как выполнять отладку и устранение неполадок класса ParallelRunStep из пакета SDL решения «Машинное обучение Azure».
Общие советы по устранению неполадок конвейера см. в разделе Устранение неполадок конвейеров машинного обучения.
Локальное тестирование сценариев
ParallelRunStep выполняется в качестве одного из шагов конвейера. Вы можете протестировать сценарии локально в качестве первого шага.
Требования начального сценария
Скрипт записи для ParallelRunStep
функции должен содержать run()
функцию и при необходимости содержит init()
функцию:
init()
: эта функция применяется для всех затратных или повторяющихся операций подготовки к последующей обработке. Например, в ней можно загружать модель в глобальный объект. Эта функция будет вызываться только один раз в начале процесса.Примечание.
Если метод
init
создает выходной каталог, укажитеparents=True
иexist_ok=True
. Методinit
вызывается из каждого рабочего процесса на каждом узле, где выполняется задание.run(mini_batch)
: функция будет выполняться для каждогоmini_batch
экземпляра.mini_batch
:ParallelRunStep
вызывает метод run и передает ему в качестве аргумента список либо PandasDataFrame
. Каждая запись в mini_batch содержит одно из следующих значений: путь к файлу для входных данных в форматеFileDataset
или PandasDataFrame
для входных данных в форматеTabularDataset
.response
: метод run() должен возвращать PandasDataFrame
или массив. Для append_row output_action эти возвращаемые элементы добавляются в общий выходной файл. Для summary_only содержимое элементов игнорируется. Для всех выходных действий каждый возвращаемый элемент обозначает один успешный запуск входного элемента во входном мини-пакете. Убедитесь в том, что в результат выполнения включено достаточно данных, чтобы сопоставить входные данные с результатом вывода. Выходные данные будут записаны в выходной файл, и для них не гарантируется правильный порядок. Для сопоставления со входными данными нужно использовать какой-либо ключ.Примечание.
Для одного элемента входных данных ожидается один элемент выходных данных.
%%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
— это основная конфигурация для экземпляра ParallelRunStep
в конвейере Машинного обучения Azure. Он пригодится вам как оболочка скрипта для настройки необходимых параметров, включая перечисленные ниже записи:
entry_script
: пользовательский скрипт в виде локального пути к файлу, который будет выполняться параллельно на нескольких узлах. Если присутствуетsource_directory
, используйте относительный путь. В противном случае используйте любой путь, доступный на компьютере.mini_batch_size
: размер мини-пакета, переданного одномуrun()
вызову. (Необязательный параметр; по умолчанию заданы10
файлов дляFileDataset
и1MB
дляTabularDataset
.)- Для
FileDataset
здесь указывается количество файлов; минимальное допустимое значение —1
. Несколько файлов можно объединить в один мини-пакет. - Для
TabularDataset
здесь указывается размер данных. Примеры допустимых значений:1024
,1024KB
,10MB
и1GB
. Мы рекомендуем использовать значение1MB
. Мини-пакет изTabularDataset
никогда не пересекает границы файлов. Предположим, что у вас есть CSV-файлы с разными размерами в пределах от 100 КБ до 10 МБ. Если задатьmini_batch_size = 1MB
, все файлы с размером меньше 1 МБ будут рассматриваться как один мини-пакет. Файлы с размером, превышающим 1 МБ, будут разбиты на несколько мини-пакетов.Примечание.
Параметр TabularDatasets, поддерживаемый SQL, не может быть секционирован. Параметр TabularDatasets из одного файла Parquet и одной группы строк не может быть секционирован.
- Для
error_threshold
: количество сбоев записей иTabularDataset
сбоев файлов дляFileDataset
этого следует игнорировать во время обработки. Если общее количество ошибок для всего объема входных данных превысит это значение, задание будет прервано. Пороговое количество ошибок применяется к общему объему входных данных, а не к отдельному мини-пакету, которые передаются в методrun()
. Используется диапазон[-1, int.max]
. Часть-1
указывает на то, что следует игнорировать все сбои во время обработки.output_action
: одно из следующих значений указывает, как будут упорядочены выходные данные:summary_only
: сценарий пользователя будет хранить выходные данные.ParallelRunStep
использует выходные данные только для вычисления порога ошибок.append_row
: для всех входных данных в выходной папке будет создан только один файл, чтобы добавить все выходные данные, разделенные строкой.
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. Для компьютера с ЦП значение по умолчанию равно количеству ядер на узел. Рабочий процесс будет многократно вызыватьrun()
, передавая полученный мини-пакет. Общее число рабочих процессов в задании равноprocess_count_per_node * node_count
, что определяет максимальное числоrun()
для параллельного выполнения.environment
: определение среды Python. Вы можете настроить использование существующей среды Python или временной среды. Также это определение может задавать необходимые зависимости приложения (необязательно).logging_level
: детализация журнала. Значения уровня детализации в порядке увеличения:WARNING
,INFO
иDEBUG
. (необязательный параметр; по умолчанию используется значениеINFO
.)run_invocation_timeout
run()
: время ожидания вызова метода в секундах. (необязательный параметр, значение по умолчанию —60
)run_max_try
: максимальное количествоrun()
попыток для мини-пакета. Сбойrun()
при возникновении исключения или если при достиженииrun_invocation_timeout
ничего не возвращается (необязательно; значение по умолчанию —3
).
Можно указать mini_batch_size
, node_count
, process_count_per_node
, logging_level
, run_invocation_timeout
и run_max_try
как PipelineParameter
, чтобы при повторной отправке запуска конвейера можно было точно настроить значения параметров. В этом примере PipelineParameter
используется для mini_batch_size
и Process_count_per_node
, и эти значения будут изменены при повторной отправке.
Видимость устройств 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 равно 2, а process_count_per_node = 4
, процесс 0 и процесс 1 будут иметь индексы 0 и 1. Процессы 2 и 3 не будут иметь переменную среды. Для библиотеки, использующей эту переменную среды для назначения GPU, процессы 2 и 3 не будут иметь GPU и не будут пытаться получить устройства GPU. Если процесс 0 останавливается, он освобождает индекс GPU 0. Следующему процессу, которым является процесс 4, будет назначен индекс GPU 0.
Дополнительные сведения см. в разделе Советы по CUDA для профессионалов: управление видимостью GPU с помощью CUDA_VISIBLE_DEVICES.
Параметры для создания ParallelRunStep
Создайте ParallelRunStep, используя скрипт, конфигурацию среды и параметры. Укажите целевой объект вычислений, который уже подключен к рабочей области, в качестве целевого объекта для выполнения скрипта вывода. Используйте ParallelRunStep
, чтобы создать шаг конвейера пакетного вывода, который принимает все следующие параметры.
name
: Имя шага со следующими ограничениями на именование: уникальность, от 3 до 32 символов, соответствие регулярному выражению ^[a-z]([-a-z0-9]*[a-z0-9])?$.parallel_run_config
ParallelRunConfig
: объект, как определено ранее.inputs
: один или несколько однотипных Машинное обучение Azure наборов данных, которые следует секционировать для параллельной обработки.side_inputs
: один или несколько ссылочных данных или наборов данных, используемых в качестве побочных входных данных без необходимости секционироваться.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.
Например, файл журнала 70_driver_log.txt
содержит сведения о контроллере, который запускает код ParallelRunStep.
Из-за того, что задания ParallelRunStep имеют распределенный характер, журналы могут поступать из нескольких разных источников. Однако создается два консолидированных файла, которые предоставляют общие сведения.
~/logs/job_progress_overview.txt
: этот файл предоставляет высокоуровневую информацию о количестве мини-пакетов (также известных как задачи), созданных до сих пор и количестве мини-пакетов, обработанных до сих пор. В этом случае отображается результат задачи. Если задание завершилось с ошибкой, отобразится сообщение об ошибке, а также рекомендации по началу устранения неполадок.~/logs/sys/master_role.txt
: В этом файле доступно представление главного узла (т. н. оркестратор) выполняемого задания. Включает создание задач, мониторинг хода выполнения, результат выполнения.
Журналы, созданные на основе начального сценария с помощью вспомогательного метода EntryScript и операторов Print, находятся следующих файлах:
~/logs/user/entry_script_log/<node_id>/<process_name>.log.txt
: Это журналы, записываемые из entry_script с помощью вспомогательного метода EntryScript.~/logs/user/stdout/<node_id>/<process_name>.stdout.txt
: Эти файлы являются журналами из stdout (например, инструкции Print) в entry_script.~/logs/user/stderr/<node_id>/<process_name>.stderr.txt
: Эти файлы являются журналами из stderr в entry_script.
Следующие признаки позволяют быстро распознать ошибки в сценарии.
~/logs/user/error.txt
: этот файл попытается свести итоги ошибок в скрипте.
Дополнительные сведения об ошибках в сценарии:
~/logs/user/error/
: Содержит полные трассировки стека исключений, возникших при загрузке и выполнении скрипта записи.
Если необходимо в полной мере оценить, как сценарий оценки выполняется на каждом из узлов, просмотрите отдельные журналы процесса для каждого узла. Журналы процесса можно найти в папке sys/node
. Они сгруппированы по рабочим узлам:
~/logs/sys/node/<node_id>/<process_name>.txt
: Этот файл содержит подробные сведения о каждом мини-пакете, который выбирается или выполняется рабочей ролью. Для каждого мини-пакета этот файл содержит:- IP-адрес и идентификатор рабочего процесса.
- Общее число элементов, число успешно обработанных элементов и число элементов, обработка которых завершилась сбоем.
- Время начала, продолжительность, время обработки и время выполнения метода.
Можно также просмотреть результаты периодических проверок использования ресурсов для каждого узла. Файлы журнала и файлы установки находятся в этой папке:
~/logs/perf
: Задайте--resource_monitor_interval
для изменения интервала проверки в секундах. По умолчанию используется интервал600
, который составляет приблизительно 10 минут. Чтобы остановить наблюдение, задайте значение0
. Каждая папка<node_id>
включает:os/
: Сведения обо всех выполняющихся в узле процессах. Одна проверка запускает команду операционной системы и сохраняет результат в файл. В системе Linux используется командаps
. В системе Windows используется командаtasklist
.%Y%m%d%H
: Имя вложенной папки — это время в часах.processes_%M
: Файл завершается минутой времени проверки.
node_disk_usage.csv
: Подробные сведения об использовании диска узлом.node_resource_usage.csv
: Общие сведения об использовании ресурсов узла.processes_resource_usage.csv
: Отчет об использовании ресурсов для каждого процесса.
Ведение журнала из пользовательского сценария в удаленном контексте
ParallelRunStep может запускать несколько процессов на одном узле на основе process_count_per_node. Чтобы упорядочить журналы из каждого процесса на узле и объединить инструкции 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 and will return same instance as the one in init()
entry_script = EntryScript()
logger = entry_script.logger
logger.info(f"{__file__}: {mini_batch}.")
...
return mini_batch
Куда принимается сообщение от logging
в Python?
ParallelRunStep задает обработчик для корневого средства ведения журнала, который принимает сообщение в logs/user/stdout/<node_id>/processNNN.stdout.txt
.
По умолчанию для logging
используется уровень INFO
. По умолчанию уровни ниже INFO
, например DEBUG
, не отображаются.
Как выполнить запись в файл, отображаемый на портале?
Файлы в папке 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"),
# ...
)
Примечание.
Рабочий процесс выполняет код "system" и код начального сценария в одном и том же процессе.
Если поток stdout
или stderr
не указан, подпроцесс, созданный с помощью метода Popen()
в начальном сценарии, наследует параметр рабочего процесса.
stdout
выполнит запись в logs/sys/node/<node_id>/processNNN.stdout.txt
, а stderr
— в logs/sys/node/<node_id>/processNNN.stderr.txt
.
Как записать файл в выходной каталог, а затем просмотреть его на портале?
Вы можете получить выходной каталог из класса EntryScript
и выполнить в него запись. Чтобы просмотреть записанные файлы, в шаге запуска представления на портале Машинного обучения Azure откройте вкладку Выходные данные и журналы. Выберите ссылку 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...
Как передать всем рабочим ролям сторонние входные данные, такие как файлы, содержащие таблицу подстановки.
Пользователь может передать ссылочные данные в скрипт, используя параметр side_inputs в ParallelRunStep. Все наборы данных, предоставленные как side_inputs, будут подключены к каждому рабочему узлу. Пользователь может получить расположение подключенгия, передав аргумент.
Создайте набор данных, содержащий ссылочные данные, затем укажите локальный путь подключения и зарегистрируйте его в рабочей области. Передайте его в параметр side_inputs
вашего ParallelRunStep
. Кроме того, можно добавить путь к нему в раздел 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/errror
, чтобы узнать о наличии каких-либо исключений. Если их нет, вполне вероятно, что ваш начальный сценарий занимает много времени. Вы можете вывести сведения о ходе выполнения в коде, чтобы найти часть, на которую уходит много времени, или добавить "--profiling_module", "cProfile"
в arguments
класса ParallelRunStep
, чтобы создать файл профиля с именем <process_name>.profile
в папке ~/logs/sys/node/<node_id>
.
Когда остановится задание?
Если задание не отменено, оно остановится с состоянием:
- Завершено. Если все мини-пакеты были обработаны, а для режима
append_row
были созданы выходные данные. - сбой. Если параметр
error_threshold
вParameters for ParallelRunConfig
превышен или во время задания произошла системная ошибка.
Где найти основную причину сбоя?
Чтобы найти причину и подробный журнал ошибок, можно обратиться к ~logs/job_result.txt
.
Будет ли ошибка узла влиять на результат задания?
Нет, если в назначенном вычислительном кластере есть другие доступные узлы. Оркестратор запустит новый узел в качестве замены, а ParallelRunStep устойчив к такой операции.
Что произойдет при сбое функции init
в начальном сценарии?
ParallelRunStep имеет механизм повтора в течение определенного времени, чтобы дать возможность восстановления от временных проблем без задержки сбоя задания слишком долго, механизм выглядит следующим образом:
- Когда после запуска узла
init
продолжает завершаться со сбоем на всех агентах, после неудач3 * process_count_per_node
дальнейшие попытки будут прекращены. - Когда после запуска задания
init
продолжает завершаться со сбоем на всех агентах всех узлов, мы прекратим повторные попытки, если задание выполняется более 2 минут и число сбоев составляет2 * node_count * process_count_per_node
. - Если все агенты задерживаются на
init
более3 * run_invocation_timeout + 30
секунд, задание завершится сбоем, так как прогресс будет отсутствовать слишком долго.
Что произойдет при OutOfMemory? Как проверить причину?
ParallelRunStep установит текущую попытку обработать мини-пакет в состояние сбоя и попытается перезапустить завершившийся сбоем процесс. Чтобы найти процесс, потребляющий много памяти, можно проверить ~logs/perf/<node_id>
.
Почему у меня много файлов processNNN?
ParallelRunStep запустит новые рабочие процессы на замену завершившимся аварийно, и каждый процесс создаст файл processNNN
в качестве журнала. Однако если процесс завершился сбоем из-за исключения во время выполнения функции init
пользовательского сценария и ошибка повторяется несколько раз (3 * process_count_per_node
), новый рабочий процесс запущен не будет.
Следующие шаги
См. следующие записные книжки Jupyter, демонстрирующие конвейеры машинного обучения Azure
Ознакомьтесь со справочником по SDK для получения подсказок по работе с пакетом azureml-pipeline-steps.
Просмотрите справочную документацию по классу ParallelRunConfig и документацию по классу ParallelRunStep.
Ознакомьтесь с расширенным руководством по использованию конвейеров с ParallelRunStep. В этом руководстве показано, как передать другой файл в качестве вторичных входных данных.