Solución de problemas de canalizaciones de aprendizaje automático

SE APLICA A:SDK de Azure Machine Learning v1 para Python

Importante

En este artículo se proporciona información sobre el uso del SDK de Azure Machine Learning v1. EL SDK v1 está en desuso a partir del 31 de marzo de 2025. El soporte técnico finalizará el 30 de junio de 2026. Puede instalar y usar SDK v1 hasta esa fecha. Los flujos de trabajo existentes que usan SDK v1 seguirán funcionando después de la fecha de finalización del soporte técnico. Sin embargo, podrían estar expuestos a riesgos de seguridad o cambios significativos si se producen cambios de arquitectura en el producto.

Se recomienda realizar la transición al SDK v2 antes del 30 de junio de 2026. Para más información sobre SDK v2, consulte ¿Qué es la CLI de Azure Machine Learning y el SDK de Python v2? y la referencia del SDK v2.

Nota:

Paquetes retirados: los siguientes paquetes de SDK v1 se retiran: azureml-pipeline, azureml-pipeline-core, azureml-pipeline-internal, azureml-pipeline-steps y azureml-train-core.

En este artículo, aprenderá a solucionar errores que se producen al ejecutar una canalización de aprendizaje automático en el SDK de Azure Machine Learning y el diseñador de Azure Machine Learning.

Sugerencias de solución de problemas

La tabla siguiente contiene problemas comunes que se pueden producir durante el desarrollo de canalizaciones y posibles soluciones a los mismo.

Problema Posible solución
No se pueden pasar datos al directorio PipelineData Asegúrese de crear un directorio en el script que se corresponda con el lugar en el que la canalización espera los datos de salida del paso. En la mayoría de los casos, un argumento de entrada definirá el directorio de salida y, a continuación, se creará el directorio de forma explícita. Use os.makedirs(args.output_dir, exist_ok=True) para crear el directorio de salida. Si necesita un ejemplo de script de puntuación que muestra este patrón de diseño, acuda al tutorial correspondiente.
Errores de dependencia Si viera errores de dependencia en la canalización remota que no se produjeron durante las pruebas locales, confirme que las dependencias y las versiones del entorno remoto coincidan con las de su entorno de prueba. (Consulte Creación, almacenamiento en caché y reutilización de entornos.
Errores ambiguos con destinos de proceso Pruebe a eliminar y volver a crear los destinos de proceso. Volver a crear objetivos de computación es rápido y puede resolver algunos problemas transitorios.
La canalización no reutiliza los pasos La reutilización de pasos está habilitada de forma predeterminada, pero asegúrese de que no la haya desactivado en algún paso de la canalización. Si deshabilita la reutilización, establezca el parámetro allow_reuse en el paso False.
La canalización se está volviendo a ejecutar innecesariamente Para asegurarse de que los pasos solo se vuelven a ejecutar cuando sus datos o scripts subyacentes cambian, desacople los directorios de código fuente en cada paso. Si usa el mismo directorio de origen para varios pasos, puede experimentar repeticiones innecesarias. Use el parámetro source_directory en un objeto de paso de canalización para apuntar a su directorio aislado para ese paso, y asegúrese de que no está usando la misma ruta de acceso source_directory para varios pasos.
Paso más lento en los tiempos de entrenamiento u otro comportamiento de bucle Intente cambiar cualquier escritura de archivo, incluido el registro, de as_mount() a as_upload(). El modo de montaje usa un sistema de archivos virtualizado remoto y carga todo el archivo cada vez que se anexa a este.
El destino de proceso tarda mucho en iniciarse Las imágenes de Docker de los destinos de proceso se cargan desde Azure Container Registry (ACR). De manera predeterminada, Azure Machine Learning crea una instancia de ACR que usa el nivel de servicio Básico. Cambiar el ACR del área de trabajo al nivel estándar o Premium puede reducir el tiempo necesario para compilar y cargar imágenes. Para obtener más información, consulte Niveles de servicio de Azure Container Registry.

Errores de autenticación

Si realiza una operación de administración en un destino de proceso desde un trabajo remoto, recibirá uno de los siguientes errores:

{"code":"Unauthorized","statusCode":401,"message":"Unauthorized","details":[{"code":"InvalidOrExpiredToken","message":"The request token was either invalid or expired. Please try again with a valid token."}]}
{"error":{"code":"AuthenticationFailed","message":"Authentication failed."}}

Por ejemplo, si intenta crear o asociar un destino de proceso desde una canalización de aprendizaje automático que se envía para ejecución remota, recibirá un error.

Solución de problemas de ParallelRunStep

Nota:

ParallelRunStep forma parte del paquete azureml-pipeline-steps que ha sido retirado. Planee la migración a alternativas de SDK v2. Para más información, consulte Compilación y ejecución de canalizaciones de aprendizaje automático con la CLI/SDK de Azure Machine Learning v2 y Ejecución de la inferencia por lotes mediante puntos de conexión por lotes.

El script para ParallelRunStepdebe contener dos funciones:

  • init(): utilice esta función para cualquier preparación costosa o común para la inferencia posterior. Por ejemplo, para cargar el modelo en un objeto global. Solo se llama a esta función una vez al principio del proceso.
  • run(mini_batch): la función se ejecuta para cada instancia de mini_batch.
    • mini_batch: ParallelRunStep invoca el método run y pasa una lista o DataFrame de Pandas como argumento al método. Cada entrada en mini_batch es una ruta de acceso de archivo si la entrada es un FileDataset, o un DataFrame de pandas DataFrame si la entrada es un TabularDataset.
    • response: el run() método debe devolver un pandas DataFrame o una matriz. Para append_rowoutput_action, estos elementos devueltos se anexan al archivo de salida común. Para summary_only, se omite el contenido de los elementos. Para todas las acciones de salida, cada elemento de salida devuelto indica una ejecución correcta del elemento de entrada en el minilote de entrada. Asegúrese de que se incluyen suficientes datos en el resultado de la ejecución para asignar la entrada al resultado de la salida de la ejecución. La salida de la ejecución se escribe en el archivo de salida y no se garantiza que esté en orden, por lo que deberá usar alguna clave en la salida para asignarla a la entrada.

Nota:

En este ejemplo de código se usan las API de TensorFlow 1.x (tf.Session, tf.reset_default_graph). Estas API se quitaron en TensorFlow 2.x. Si está usando TensorFlow 2.x, use el modo de compatibilidad tf.compat.v1 o vuelva a escribir mediante la ejecución diligente. Para obtener más información, consulte Migración del código de TensorFlow 1 a TensorFlow 2.

%%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

Si tiene otro archivo o carpeta en el mismo directorio que el script de inferencia, puede hacer referencia a él buscando el directorio de trabajo actual.

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

Parámetros para ParallelRunConfig

ParallelRunConfig es la configuración principal de una ParallelRunStep instancia dentro de la canalización de Azure Machine Learning. Úselo para ajustar el script y configurar los parámetros necesarios, incluidas todas las siguientes entradas:

  • entry_script: script de usuario como ruta de acceso de archivo local que se ejecuta en paralelo en varios nodos. Si source_directory está presente, utilice una ruta de acceso relativa. De lo contrario, use cualquier ruta de acceso accesible desde la máquina.
  • mini_batch_size: tamaño del minilote que se pasa a una sola llamada de run(). (Opcional; el valor predeterminado es 10 archivos para FileDataset, y 1MB para TabularDataset).
    • En el caso de FileDataset, es el número de archivos con un valor mínimo de 1. Puede combinar varios archivos en un solo minilote.
    • En el caso de TabularDataset, es el tamaño de los datos. Los valores posibles son 1024, 1024KB, 10MB y 1GB. 1MB es el valor recomendado. El minilote de TabularDataset nunca cruza los límites de archivos. Por ejemplo, si tiene archivos. csv de varios tamaños, el menor es de 100 KB y el mayor es de 10 MB. Si establece mini_batch_size = 1MB, los archivos con un tamaño menor que 1 MB se tratan como un solo minilote. Los archivos de tamaño mayor que 1 MB se dividen en varios minilotes.
  • error_threshold: número de errores de registro de TabularDataset y errores de archivo para FileDataset que el proceso omita. Si el recuento de errores de la entrada supera este valor, el trabajo se anula. El umbral de error se aplica a toda la entrada y no a los mini lotes individuales enviados al run() método . El intervalo es [-1, int.max]. El -1 valor indica que se omiten todos los errores durante el procesamiento.
  • output_action: uno de los valores siguientes indica cómo se organiza la salida:
    • summary_only: el script de usuario almacena la salida. ParallelRunStep usa la salida solo para el cálculo del umbral de error.
    • append_row: en las entradas, solo se crea un archivo en la carpeta de salida para anexar todas las salidas separadas por líneas.
  • append_row_file_name: para personalizar el nombre del archivo de salida para append_rowoutput_action (opcional; el valor predeterminado es parallel_run_step.txt).
  • source_directory: rutas de acceso a las carpetas que contienen todos los archivos que se van a ejecutar en el destino de proceso (opcional).
  • compute_target: solo se admite AmlCompute.
  • node_count: el número de nodos de proceso que se van a usar para ejecutar el script de usuario.
  • process_count_per_node: número de procesos por nodo. Establezca este valor en el número de GPU o CPU que tiene un nodo (opcional; el valor predeterminado es 1).
  • environment: definición del entorno de Python. Puede configurarla para usar un entorno de Python existente o un entorno temporal. La definición también es responsable de establecer las dependencias de la aplicación necesarias (opcional).
  • logging_level: nivel de detalle del registro. Los valores con nivel de detalle en aumento son: WARNING, INFO y DEBUG. (Opcional; el valor predeterminado es INFO).
  • run_invocation_timeout: tiempo de espera de invocación del método run() en segundos. (Opcional; el valor predeterminado es 60).
  • run_max_try: número máximo de intentos de run() para un minilote. run() falla si se lanza una excepción o si no se devuelve nada cuando se alcanza run_invocation_timeout (opcional; el predeterminado es 3).

Puede especificar mini_batch_size, node_count, process_count_per_node, logging_level, run_invocation_timeout, y run_max_try como PipelineParameter valores. Al volver a enviar una ejecución de canalización, puede ajustar estos valores de parámetro. En este ejemplo, se usa PipelineParameter para mini_batch_size y process_count_per_node, y se cambian estos valores cuando se vuelve a enviar una ejecución posteriormente.

Parámetros para crear ParallelRunStep

Cree el ParallelRunStep utilizando el script, la configuración del entorno y los parámetros. Especifique el destino de proceso que ya adjuntó a su área de trabajo como destino de ejecución del script de inferencia. Use ParallelRunStep para crear el paso de canalización de inferencias por lotes, que toma todos los parámetros siguientes:

  • name: nombre del paso. El nombre debe ser único, de 3 a 32 caracteres y coincidir con la expresión regular ^[a-z]([-a-z0-9]*[a-z0-9])?$.
  • parallel_run_config: objeto ParallelRunConfig, tal y como se definió anteriormente.
  • inputs: uno o varios conjuntos de datos de Azure Machine Learning de tipo único para crear particiones para el procesamiento paralelo.
  • side_inputs: uno o varios datos de referencia o conjuntos de datos usados como entradas laterales sin necesidad de crear particiones.
  • output: objeto OutputFileDatasetConfig que corresponde al directorio de salida.
  • arguments: lista de los argumentos pasados al script de usuario. Use unknown_args para recuperarlos en el script de entrada (opcional).
  • allow_reuse: indica si el paso debe reutilizar los resultados anteriores cuando se ejecuta con la misma configuración y entradas. Si establece este parámetro en False, la canalización genera una nueva ejecución para este paso durante la ejecución de la canalización. (Opcional; el valor predeterminado es 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
)

Técnicas de depuración

Hay tres técnicas principales para depurar las canalizaciones:

  • Depure pasos de canalización individuales en el equipo local.
  • Utilice el sistema de registro y Application Insights para identificar y diagnosticar el origen del problema.
  • Conecte un depurador remoto a una canalización que se ejecute en Azure.

Depuración de scripts de forma local

Uno de los errores más comunes en una canalización es que el script de dominio no se ejecute según lo previsto, o que contenga errores en tiempo de ejecución difíciles de depurar en el contexto de proceso remoto.

Las propias canalizaciones no se pueden ejecutar localmente. Pero la ejecución de los scripts de forma aislada en la máquina local le permite depurar más rápido, ya que no es necesario esperar al proceso de compilación de proceso y de entorno. Para ello, se necesita realizar algo de trabajo de desarrollo:

  • Si los datos estuvieran en un almacén de datos en la nube, tendrá que descargarlos y ponerlos a disposición del script. El uso de una pequeña muestra de los datos es una buena forma de reducir el tiempo de ejecución y obtener rápidamente comentarios sobre el comportamiento del script
  • Si intenta simular un paso de canalización intermedio, es posible que tenga que compilar manualmente los tipos de objeto que el script específico espera del paso anterior
  • Es necesario definir su propio entorno y replicar las dependencias definidas en el entorno de proceso remoto

Una vez que tenga una configuración de script que se ejecute en su entorno local, es más fácil realizar tareas de depuración como:

  • Incorporación de una configuración de depuración personalizada
  • Pausa de la ejecución e inspección del estado del objeto
  • Detección de errores lógicos o de tipo que no se expondrían hasta el tiempo de ejecución

Sugerencia

Una vez que pueda comprobar que el script se ejecuta según lo previsto, un buen paso posterior es ejecutar el script en una canalización de un solo paso antes de intentar ejecutarlo en una canalización con varios pasos.

Configuración, escritura y revisión de los registros de canalización

Probar scripts localmente es una excelente manera de depurar fragmentos de código principales y lógica compleja antes de empezar a crear una canalización. En algún momento, debería depurar los scripts durante la ejecución real de la canalización, especialmente cuando se diagnostique el comportamiento que da lugar durante la interacción entre los pasos de la canalización. Haga un uso generoso de las instrucciones print() en los scripts de paso, con el fin de ver el estado del objeto y los valores esperados durante la ejecución remota, de manera similar a como se depuraría el código de JavaScript.

Opciones de registro y comportamiento

En la tabla siguiente se proporciona información sobre las distintas opciones de depuración para las canalizaciones. No se trata de una lista exhaustiva, ya que existen otras opciones aparte de las de Azure Machine Learning y Python que se muestran aquí.

Biblioteca Tipo Ejemplo Destino Recursos
SDK de Azure Machine Learning Métrica run.log(name, val) UI del portal de Azure Machine Learning Seguimiento de experimentos
Clase azureml.core.Run
Impresión/registro de Python Log print(val)
logging.info(message)
Registros de controladores, el diseñador de Azure Machine Learning Seguimiento de experimentos

Registro de Python

Ejemplo de opciones de registro

import logging

from azureml.core.run import Run

run = Run.get_context()

# Azure Machine Learning Scalar value logging
run.log("scalar_value", 0.95)

# Python print statement
print("I am a python print statement, I will be sent to the driver logs.")

# Initialize Python logger
logger = logging.getLogger(__name__)
logger.setLevel(args.log_level)

# Plain Python logging statements
logger.debug("I am a plain debug statement, I will be sent to the driver logs.")
logger.info("I am a plain info statement, I will be sent to the driver logs.")

handler = AzureLogHandler(connection_string='<connection string>')
logger.addHandler(handler)

Nota:

AzureLogHandler del paquete opencensus-ext-azure está en desuso. En el caso de los nuevos proyectos, use el azure-monitor-opentelemetry paquete en su lugar.

Diseñador de Azure Machine Learning

En el caso de las canalizaciones que cree en el diseñador, puede encontrar el archivo 70_driver_log en la página de creación o en la página de detalles de ejecución de la canalización.

Habilitación del registro para puntos de conexión en tiempo real

Para solucionar problemas y depurar puntos de conexión en tiempo real en el diseñador, use el SDK para habilitar el registro de Application Insights. Mediante el registro, puede solucionar problemas de implementación y uso del modelo mediante la depuración. Para más información, consulte Registro para modelos implementados.

Obtención de los registros desde la página de creación

Cuando envía una ejecución de canalización y permanece en la página de creación, puede encontrar los archivos de registro generados para cada componente a medida que cada componente finaliza su ejecución.

  1. Seleccione un componente que termine de ejecutarse en el entorno de creación.

  2. En el panel derecho del componente, vaya a la pestaña Resultados y registros.

  3. Expanda el panel derecho y seleccione el archivo 70_driver_log.txt para verlo en el explorador. También puede descargar registros localmente.

    Panel de salida expandido en el diseñador

Obtención de registros desde las ejecuciones de canalización

También puede encontrar los archivos de registro de ejecuciones específicas en la página de detalles de ejecución de la canalización. Puede encontrar esta página en la sección Canalizaciones o Experimentos de Studio.

  1. Seleccione una ejecución de canalización creada en el diseñador.

    Página de ejecución de la canalización

  2. Seleccione un componente en el panel de vista previa.

  3. En el panel derecho del componente, vaya a la pestaña Resultados y registros.

  4. Expanda el panel derecho para ver el archivo std_log.txt en el explorador o seleccione el archivo para descargar los registros localmente.

Importante

Para actualizar una canalización desde la página de detalles de ejecución de la canalización, tiene que clonar la ejecución de la canalización en un nuevo borrador de canalización. Una ejecución de canalización es una instantánea de la canalización. Es similar a un archivo de registro y no se puede modificar.

Depuración interactiva con Visual Studio Code

En algunos casos, es posible que tenga que depurar interactivamente el código de Python que se usa en la canalización de ML. Mediante Visual Studio Code (VS Code) y debugpy, se puede conectar al código que se ejecuta en el entorno de entrenamiento. Para obtener más información, consulte la guía de depuración interactiva en VS Code.

Error de HyperdriveStep y AutoMLStep con aislamiento de red

Después de usar HyperdriveStep y AutoMLStep, al intentar registrar el modelo, es posible que reciba un error.

  • Está usando el SDK de Azure Machine Learning v1.

  • El área de trabajo de Azure Machine Learning está configurada para el aislamiento de red (VNet).

  • La canalización intenta registrar el modelo generado por el paso anterior. Por ejemplo, en el ejemplo siguiente, el parámetro inputs es el modelo_guardado de un HyperdriveStep:

    register_model_step = PythonScriptStep(script_name='register_model.py',
                                       name="register_model_step01",
                                       inputs=[saved_model],
                                       compute_target=cpu_cluster,
                                       arguments=["--saved-model", saved_model],
                                       allow_reuse=True,
                                       runconfig=rcfg)
    

Solución alternativa

Importante

Este comportamiento no se produce cuando se usa el SDK de Azure Machine Learning v2.

Para solucionar este error, use la clase Run para obtener el modelo creado a partir de HyperdriveStep o AutoMLStep. El script de ejemplo siguiente obtiene el modelo de salida de un HyperdriveStep:

%%writefile $script_folder/model_download9.py
import argparse
from azureml.core import Run
from azureml.pipeline.core import PipelineRun
from azureml.core.experiment import Experiment
from azureml.train.hyperdrive import HyperDriveRun
from azureml.pipeline.steps import HyperDriveStepRun

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--hd_step_name', 
        type=str, dest='hd_step_name', 
        help='The name of the step that runs AutoML training within this pipeline')
        
        
    
    args = parser.parse_args()
    
    current_run = Run.get_context()

    pipeline_run = PipelineRun(current_run.experiment, current_run.experiment.name)

    hd_step_run = HyperDriveStepRun((pipeline_run.find_step_run(args.hd_step_name))[0])
    hd_best_run = hd_step_run.get_best_run_by_primary_metric()

    print(hd_best_run)
    hd_best_run.download_file("outputs/model/saved_model.pb", "saved_model.pb")
    
    
    print("Successfully downloaded model") 

Puede usar el archivo desde un PythonScriptStep:

from azureml.pipeline.steps import PythonScriptStep
conda_dep = CondaDependencies()
conda_dep.add_pip_package("azureml-sdk")
conda_dep.add_pip_package("azureml-pipeline")

rcfg = RunConfiguration(conda_dependencies=conda_dep)

model_download_step = PythonScriptStep(
    name="Download Model 9",
    script_name="model_download9.py", 
    arguments=["--hd_step_name", hd_step_name],
    compute_target=compute_target,
    source_directory=script_folder,
    allow_reuse=False,
    runconfig=rcfg
)

Pasos siguientes

Nota:

Las referencias azureml-pipeline-core y azureml-pipeline-steps en la siguiente sección se aplican a los paquetes de SDK v1 retirados desde el 30 de junio de 2026. Para obtener la ruta de acceso recomendada, consulte Compilación y ejecución de canalizaciones de aprendizaje automático con la CLI o el SDK de Azure Machine Learning v2.