Řešení potíží s kanály strojového učení

PLATÍ PRO:Sada Python SDK azureml v1

V tomto článku se dozvíte, jak řešit potíže v případě chyb při spuštění kanálu strojového učení v sadě SDK služby Azure Machine Learning a návrháři služby Azure Machine Learning.

Rady pro řešení potíží

Následující tabulka obsahuje běžné problémy při vývoji kanálů a jejich možná řešení. .

Problém Možné řešení
Nejde předat data do adresáře PipelineData Ujistěte se, že jste ve skriptu vytvořili adresář, který odpovídá očekávanému umístění výstupních dat kroků kanálu. Ve většině případů vstupní argument definuje výstupní adresář a pak adresář explicitně vytvoříte. K vytvoření výstupního adresáře použijte os.makedirs(args.output_dir, exist_ok=True). Projděte si kurz, ve kterém najdete příklad skriptu bodování s ukázkou tohoto modelu návrhu.
Chyby závislostí Pokud se ve vzdáleném kanálu zobrazí chyby závislostí, ke kterým při místním testování nedošlo, ověřte, že závislosti a verze vzdáleného prostředí odpovídají závislostem a verzím ve vašem testovacím prostředí. (Viz Vytváření prostředí, ukládání do mezipaměti a opakované použití.
Nejednoznačné chyby s cílovými výpočetními objekty Zkuste odstranit a znovu vytvořit cílové výpočetní objekty. Opětovné vytvoření cílových výpočetních objektů je rychlé a může vyřešit některé přechodné problémy.
Kanál nepoužívá kroky opakovaně Opakované použití kroků je standardně povoleno, ale ujistěte se, že jste ho nezakázali v kroku kanálu. Pokud je opakované použití zakázané, allow_reuse parametr v kroku je nastavený na False.
Kanál se zbytečně opětovně spouští Chcete-li zajistit, aby se kroky znovu spouštěly jenom při změně podkladových dat nebo skriptů, oddělte adresáře zdrojového kódu pro jednotlivé kroky. Pokud používáte stejný zdrojový adresář pro více kroků, může docházet ke zbytečnému opakovanému spouštění. source_directory Použijte parametr u objektu kroku kanálu k nasměrování na izolovaný adresář pro daný krok a ujistěte se, že nepoužíváte stejnou source_directory cestu pro více kroků.
Krok se v průběhu trénovacích epoch zpomaluje nebo dochází k jinému chování ve smyčce Zkuste přepnout všechny zápisy souborů, včetně protokolování, z as_mount() na as_upload(). Režim připojení používá vzdálený virtualizovaný systém souborů a při každém připojení nahrává celý soubor.
Spuštění cílového výpočetního objektu trvá dlouho Obrazy Dockeru pro cílové výpočetní objekty se načítají ze služby Azure Container Registry (ACR). Azure Machine Learning ve výchozím nastavení vytvoří službu ACR, která používá úroveň služby Basic . Změna ACR pro váš pracovní prostor na úroveň Standard nebo Premium může zkrátit dobu potřebnou k vytváření a načítání imagí. Další informace najdete v článku Úrovně služby Azure Container Registry.

Chyby ověřování

Pokud provedete operaci správy cílového výpočetního objektu ze vzdálené úlohy, zobrazí se jedna z následujících chyb:

{"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."}}

Například při pokusu o vytvoření nebo připojení cílového výpočetního objektu z kanálu ML odeslaného ke vzdálenému spuštění se zobrazí chyba.

Řešení potíží ParallelRunStep

Skript pro musí ParallelRunStepobsahovat dvě funkce:

  • init(): Tuto funkci použijte pro jakoukoli nákladnou nebo běžnou přípravu na pozdější odvozování. Můžete ho například použít k načtení modelu do globálního objektu. Tato funkce je volána pouze jednou na začátku procesu.
  • run(mini_batch): Funkce se spustí pro každou mini_batch instanci.
    • mini_batch: ParallelRunStep Vyvolá metodu run a předá metodě jako argument buď seznam, nebo knihovnu pandas DataFrame . Každá položka v mini_batch je cesta k souboru, pokud je vstup a FileDataset nebo pandasDataFrame, pokud je vstup .TabularDataset
    • response: Metoda run() by měla vrátit pandas DataFrame nebo pole. Pro append_row output_action jsou tyto vrácené prvky připojeny do společného výstupního souboru. U summary_only se obsah elementů ignoruje. U všech výstupních akcí každý vrácený výstupní prvek označuje jedno úspěšné spuštění vstupního prvku v minidávce vstupu. Ujistěte se, že výsledek spuštění obsahuje dostatek dat pro mapování vstupu na výsledek výstupu spuštění. Výstup spuštění je zapsaný ve výstupním souboru a není zaručeno, že bude v pořádku. K namapujte ho na vstup pomocí klíče ve výstupu.
%%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

Pokud máte jiný soubor nebo složku ve stejném adresáři jako skript pro odvozování, můžete na něj odkazovat vyhledáním aktuálního pracovního adresáře.

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

Parametry pro ParallelRunConfig

ParallelRunConfig je hlavní konfigurace pro ParallelRunStep instanci v rámci kanálu Azure Machine Learning. Použijete ho k zabalení skriptu a konfiguraci nezbytných parametrů, včetně všech následujících položek:

  • entry_script: Uživatelský skript jako místní cesta k souboru, která se spouští paralelně na více uzlech. Pokud source_directory existuje, použijte relativní cestu. V opačném případě použijte libovolnou cestu, která je na počítači přístupná.
  • mini_batch_size: Velikost minidávce předané do jednoho run() volání. (Volitelné; výchozí hodnota je 10 soubory pro FileDataset a 1MB pro TabularDataset.)
    • Pro FileDatasetje to počet souborů s minimální hodnotou 1. Můžete zkombinovat více souborů do jedné minidávkové dávky.
    • V případě TabularDatasetje to velikost dat. Příklady hodnot jsou 1024, 1024KB, 10MBa 1GB. Doporučená hodnota je 1MB. Minidávka z nikdy TabularDataset nepřekročí hranice souboru. Pokud máte například .csv soubory různých velikostí, nejmenší soubor má velikost 100 kB a největší 10 MB. Pokud nastavíte mini_batch_size = 1MB, pak se soubory o velikosti menší než 1 MB považují za jednu minidávku. Soubory s velikostí větší než 1 MB se rozdělí do několika minidávek.
  • error_threshold: Počet selhání záznamů a TabularDataset selhání FileDataset souborů, které by se měly během zpracování ignorovat. Pokud počet chyb pro celý vstup překročí tuto hodnotu, úloha se přeruší. Prahová hodnota chyby je pro celý vstup, a ne pro jednotlivé minidávce odeslané do run() metody. Rozsah je [-1, int.max]. Část -1 označuje ignorování všech selhání během zpracování.
  • output_action: Jedna z následujících hodnot určuje, jak je výstup uspořádaný:
    • summary_only: Uživatelský skript uloží výstup. ParallelRunStep používá výstup pouze pro výpočet prahové hodnoty chyby.
    • append_row: Pro všechny vstupy se ve výstupní složce vytvoří pouze jeden soubor, který připojí všechny výstupy oddělené řádkem.
  • append_row_file_name: Přizpůsobení názvu výstupního souboru pro append_row output_action (volitelné; výchozí hodnota je parallel_run_step.txt).
  • source_directory: Cesty ke složkám, které obsahují všechny soubory, které se mají spustit na cílovém výpočetním objektu (volitelné).
  • compute_target: Podporuje se pouze AmlCompute .
  • node_count: Počet výpočetních uzlů, které se mají použít ke spuštění uživatelského skriptu.
  • process_count_per_node: Počet procesů na uzel. Osvědčeným postupem je nastavit počet GPU nebo PROCESORu, které má jeden uzel (volitelné; výchozí hodnota je 1).
  • environment: Definice prostředí Python. Můžete ho nakonfigurovat tak, aby používal existující prostředí Pythonu nebo aby nastavil dočasné prostředí. Definice je také zodpovědná za nastavení požadovaných závislostí aplikace (volitelné).
  • logging_level: Úroveň podrobností protokolu. Hodnoty, které zvyšují úroveň podrobností, jsou: WARNING, INFOa DEBUG. (volitelné; výchozí hodnota je INFO)
  • run_invocation_timeout: Časový run() limit volání metody v sekundách. (volitelné; výchozí hodnota je 60)
  • run_max_try: Maximální počet zkoušek run() pro minidávku. Chyba run() se nezdaří, pokud dojde k výjimce nebo pokud se při run_invocation_timeout dosažení hodnoty nic nevrátí (volitelné; výchozí hodnota je 3).

Jako můžete zadat mini_batch_size, node_count, , logging_levelprocess_count_per_node, run_invocation_timeouta run_max_tryPipelineParameter, abyste při opětovném odeslání spuštění kanálu mohli vyladit hodnoty parametrů. V tomto příkladu použijete PipelineParameter pro mini_batch_size a Process_count_per_node a tyto hodnoty změníte, když později znovu odešlete spuštění.

Parametry pro vytvoření kroku paralelního spuštění

Vytvořte Krok paralelního spuštění pomocí skriptu, konfigurace prostředí a parametrů. Zadejte cílový výpočetní objekt, který jste už připojili k pracovnímu prostoru, jako cíl provádění pro váš odvozovací skript. Použijte ParallelRunStep k vytvoření kroku kanálu dávkového odvozování, který přijímá všechny následující parametry:

  • name: Název kroku s následujícími omezeními pojmenování: jedinečný, 3–32 znaků a výraz regex ^[a-z]([-a-z0-9]*[a-z0-9])?$.
  • parallel_run_config: Objekt ParallelRunConfig , jak je definován dříve.
  • inputs: Jedna nebo více datových sad Azure Machine Learning s jedním typem, které se mají rozdělit na oddíly pro paralelní zpracování.
  • side_inputs: Jedno nebo více referenčních dat nebo datových sad používaných jako boční vstupy bez nutnosti dělení.
  • output: Objekt OutputFileDatasetConfig , který odpovídá výstupnímu adresáři.
  • arguments: Seznam argumentů předaných uživatelskému skriptu. Pomocí unknown_args je načtěte do vstupního skriptu (volitelné).
  • allow_reuse: Určuje, jestli má krok opakovaně používat předchozí výsledky při spuštění se stejnými nastaveními nebo vstupy. Pokud je Falsetento parametr , během provádění kanálu se pro tento krok vygeneruje nové spuštění. (volitelné; výchozí hodnota je 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
)

Techniky ladění

Existují tři hlavní techniky ladění kanálů:

  • Ladění jednotlivých kroků kanálu na místním počítači
  • Použití protokolování a Application Insights k izolování a diagnostikování zdroj problému
  • Připojení vzdáleného ladicího programu ke kanálu spuštěnému v Azure

Místní ladění skriptů

Jedním z nejběžnějších selhání kanálu je to, že se skript domény nespustí podle očekávání nebo obsahuje chyby modulu runtime ve vzdáleném výpočetním kontextu, které se obtížně ladí.

Kanály samotné se nedají spouštět místně. Spuštění skriptů v izolaci na místním počítači vám ale umožní ladit rychleji, protože nemusíte čekat na proces sestavení výpočetních prostředků a prostředí. K tomu je potřeba provést určité vývojové práce:

  • Pokud jsou vaše data v cloudovém úložišti dat, musíte si je stáhnout a zpřístupnit je vašemu skriptu. Použití malé ukázky dat je dobrý způsob, jak omezit běh a rychle získat zpětnou vazbu k chování skriptu.
  • Pokud se pokoušíte simulovat zprostředkující krok kanálu, možná budete muset ručně sestavit typy objektů, které konkrétní skript očekává od předchozího kroku.
  • Potřebujete definovat vlastní prostředí a replikovat závislosti definované ve vzdáleném výpočetním prostředí.

Jakmile máte nastavení skriptu pro spuštění v místním prostředí, je jednodušší provádět ladicí úlohy, jako jsou:

  • Připojení vlastní konfigurace ladění
  • Pozastavení provádění a kontrola stavu objektu
  • Zachytávání typů nebo logických chyb, které nebudou zpřístupněny až do běhu

Tip

Jakmile ověříte, že váš skript běží podle očekávání, je vhodným dalším krokem spuštění skriptu v kanálu s jedním krokem, než se ho pokusíte spustit v kanálu s několika kroky.

Konfigurace, zápis a kontrola protokolů kanálu

Místní testování skriptů je skvělý způsob, jak ladit hlavní fragmenty kódu a složitou logiku, než začnete vytvářet kanál. V určitém okamžiku budete muset ladit skripty během vlastního spuštění kanálu, zejména při diagnostice chování, ke kterému dochází během interakce mezi kroky kanálu. Doporučujeme v krokovacích skriptech používat příkazy, abyste během vzdáleného print() spuštění viděli stav objektu a očekávané hodnoty, podobně jako byste ladili kód JavaScriptu.

Možnosti a chování protokolování

Následující tabulka obsahuje informace o různých možnostech ladění kanálů. Nejedná se o vyčerpávající seznam, protože kromě zde zobrazených možností Azure Machine Learning, Pythonu a OpenCensus existují i další možnosti.

Knihovna Typ Příklad Cíl Zdroje informací
Azure Machine Learning SDK Metric run.log(name, val) Uživatelské rozhraní portálu služby Azure Machine Learning Jak sledovat experimenty
Třída azureml.core.Run
Tisk/protokolování v Pythonu Protokol print(val)
logging.info(message)
Protokoly ovladačů, designer služby Azure Machine Learning Jak sledovat experimenty

Protokolování v Pythonu
OpenCensus Python Protokol logger.addHandler(AzureLogHandler())
logging.log(message)
Application Insights – trasování Ladění kanálů ve službě Application Insights

Nástroje pro export OpenCensus pro Azure Monitor
Podrobný návod k protokolování v Pythonu

Příklad možností protokolování

import logging

from azureml.core.run import Run
from opencensus.ext.azure.log_exporter import AzureLogHandler

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)

# Python logging with OpenCensus AzureLogHandler
logger.warning("I am an OpenCensus warning statement, find me in Application Insights!")
logger.error("I am an OpenCensus error statement with custom dimensions", {'step_id': run.id})

Návrhář služby Azure Machine Learning

U kanálů vytvořených v návrháři najdete soubor 70_driver_log buď na stránce pro vytváření obsahu, nebo na stránce podrobností spuštění kanálu.

Povolení protokolování pro koncové body v reálném čase

Pokud chcete řešit potíže a ladit koncové body v reálném čase v návrháři, musíte povolit protokolování Application Insight pomocí sady SDK. Protokolování umožňuje řešit a ladit problémy s nasazením a používáním modelu. Další informace najdete v tématu Protokolování nasazených modelů.

Získání protokolů ze stránky pro vytváření obsahu

Když odešlete spuštění kanálu a zůstanete na stránce pro vytváření, můžete najít soubory protokolu generované pro každou komponentu, jakmile se každá komponenta dokončí.

  1. Vyberte komponentu, která se dokončila na plátně pro vytváření obsahu.

  2. V pravém podokně komponenty přejděte na kartu Výstupy a protokoly .

  3. Rozbalte pravé podokno a výběrem 70_driver_log.txt zobrazte soubor v prohlížeči. Protokoly si také můžete stáhnout místně.

    Rozbalené podokno výstupu v návrháři

Získání protokolů ze spuštění kanálu

Soubory protokolu pro konkrétní spuštění najdete také na stránce podrobností spuštění kanálu, kterou najdete v části Kanály nebo Experimenty ve studiu.

  1. Vyberte spuštění kanálu vytvořeného v návrháři.

    Stránka spuštění kanálu

  2. Vyberte komponentu v podokně náhledu.

  3. V pravém podokně komponenty přejděte na kartu Výstupy a protokoly .

  4. Rozbalením pravého podokna zobrazte souborstd_log.txt v prohlížeči nebo vyberte soubor a stáhněte protokoly místně.

Důležité

Pokud chcete aktualizovat kanál ze stránky podrobností spuštění kanálu, musíte naklonovat spuštění kanálu do nového konceptu kanálu. Spuštění kanálu je snímek kanálu. Podobá se souboru protokolu a nedá se změnit.

Application Insights

Další informace o použití knihovny OpenCensus Python tímto způsobem najdete v této příručce: Ladění kanálů strojového učení v Application Insights a jejich řešení potíží.

Interaktivní ladění s využitím Visual Studio Code

V některých případech možná budete muset interaktivně ladit kód Pythonu použitý v kanálu ML. Pomocí nástrojů Visual Studio Code (VS Code) a debugpy se můžete připojit ke kódu, když běží v trénovacím prostředí. Další informace najdete v průvodci interaktivním laděním v editoru VS Code.

HyperdriveStep a AutoMLStep selžou s izolací sítě

Po použití HyperdriveStep a AutoMLStep se při pokusu o registraci modelu může zobrazit chyba.

  • Používáte sadu Azure Machine Learning SDK v1.

  • Pracovní prostor služby Azure Machine Learning je nakonfigurovaný pro izolaci sítě (VNet).

  • Váš kanál se pokusí zaregistrovat model vygenerovaný předchozím krokem. Například v následujícím příkladu inputs je parametr saved_model z 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)
    

Alternativní řešení

Důležité

K tomuto chování nedochází při použití sady Azure Machine Learning SDK v2.

Chcete-li tuto chybu obejít, použijte třídu Run k získání modelu vytvořeného z HyperdriveStep nebo AutoMLStep. Následuje ukázkový skript, který získá výstupní model z kroku 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") 

Soubor se pak dá použít z 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
)

Další kroky