Partager via


Tutoriel : Exécuter une charge de travail parallèle avec Azure Batch à l’aide de l’API Python

Utilisez Azure Batch pour exécuter des programmes de traitement par lots de calcul haute performance (HPC) en parallèle, efficacement et à grande échelle dans Azure. Ce tutoriel décrit un exemple Python d’exécution d’une charge de travail parallèle à l’aide de Batch. Vous apprendrez un flux de travail d'application Batch courant et comment interagir par programme avec les ressources Batch et de stockage.

  • S’authentifier avec des comptes Batch et de stockage.
  • Charger des fichiers d’entrée sur le stockage.
  • Créer un pool de nœuds de calcul pour exécuter une application.
  • Créer un travail et des tâches pour traiter les fichiers d’entrée.
  • Surveiller l’exécution d’une tâche.
  • Récupérer les fichiers de sortie.

Dans ce tutoriel, vous convertissez des fichiers multimédias MP4 au format MP3, en parallèle, à l’aide de l’outil open source ffmpeg.

Si vous ne disposez pas d’un compte Azure, créez-en un gratuitement avant de commencer.

Conditions préalables

Connexion à Azure

Connectez-vous au portail Azure.

Obtenir les informations d’identification du compte

Dans le cadre de cet exemple, vous devez fournir les informations d’identification de vos comptes Azure Batch et de stockage. Pour obtenir rapidement les informations d’identification nécessaires, dirigez-vous vers le portail Azure. (Vous pouvez aussi les obtenir avec les API Azure ou des outils en ligne de commande.)

  1. Sélectionnez Tous les services>Comptes Batch, puis le nom de votre compte Batch.

  2. Pour voir les informations d’identification Batch, sélectionnez Clés. Copiez les valeurs des champs Compte Batch, URL et Clé d’accès principale dans un éditeur de texte.

  3. Pour voir le nom et les clés du compte de stockage, sélectionnez Compte de stockage. Copiez les valeurs des champs Nom du compte de stockage et Clé1 dans un éditeur de texte.

Télécharger et exécuter l’exemple d’application

Télécharger l’exemple d’application

Téléchargez ou clonez l’exemple d’application à partir de GitHub. Pour cloner le référentiel d’exemple d’application avec un client Git, utilisez la commande suivante :

git clone https://github.com/Azure-Samples/batch-python-ffmpeg-tutorial.git

Accédez au répertoire qui contient le fichier batch_python_tutorial_ffmpeg.py.

Dans votre environnement Python, installez les packages requis à l’aide de pip.

pip install -r requirements.txt

Utilisez un éditeur de code pour ouvrir le fichier config.py. Mettez à jour les chaînes d’informations d’identification du compte Batch et du compte de stockage avec les valeurs propres à vos comptes. Par exemple:

_BATCH_ACCOUNT_NAME = 'yourbatchaccount'
_BATCH_ACCOUNT_KEY = 'xxxxxxxxxxxxxxxxE+yXrRvJAqT9BlXwwo1CwF+SwAYOxxxxxxxxxxxxxxxx43pXi/gdiATkvbpLRl3x14pcEQ=='
_BATCH_ACCOUNT_URL = 'https://yourbatchaccount.yourbatchregion.batch.azure.com'
_STORAGE_ACCOUNT_NAME = 'mystorageaccount'
_STORAGE_ACCOUNT_KEY = 'xxxxxxxxxxxxxxxxy4/xxxxxxxxxxxxxxxxfwpbIC5aAWA8wDu+AFXZB827Mt9lybZB1nUcQbQiUrkPtilK5BQ=='

Exécuter l’application

Pour exécuter le script :

python batch_python_tutorial_ffmpeg.py

Lorsque vous exécutez l’exemple d’application, la sortie de la console est identique à ce qui suit. Pendant l’exécution, vous observez une pause à Monitoring all tasks for 'Completed' state, timeout in 00:30:00... lorsque les nœuds de calcul du pool sont démarrés.

Sample start: 11/28/2018 3:20:21 PM

Container [input] created.
Container [output] created.
Uploading file LowPriVMs-1.mp4 to container [input]...
Uploading file LowPriVMs-2.mp4 to container [input]...
Uploading file LowPriVMs-3.mp4 to container [input]...
Uploading file LowPriVMs-4.mp4 to container [input]...
Uploading file LowPriVMs-5.mp4 to container [input]...
Creating pool [LinuxFFmpegPool]...
Creating job [LinuxFFmpegJob]...
Adding 5 tasks to job [LinuxFFmpegJob]...
Monitoring all tasks for 'Completed' state, timeout in 00:30:00...
Success! All tasks completed successfully within the specified timeout period.
Deleting container [input]....

Sample end: 11/28/2018 3:29:36 PM
Elapsed time: 00:09:14.3418742

Accédez à votre compte Batch dans le portail Azure pour surveiller le pool, les nœuds de calcul, les travaux et les tâches. Par exemple, pour afficher une carte thermique des nœuds de calcul dans votre pool, sélectionnez Pools>LinuxFmpegPool.

Lorsque les tâches sont en cours d’exécution, la carte thermique est similaire à ce qui suit :

Capture d’écran de la carte thermique du pool.

Le temps d’exécution classique est d’environ 5 minutes lorsque vous exécutez l’application dans sa configuration par défaut. La création d’un pool est l’opération la plus longue.

Récupérer les fichiers de sortie

Vous pouvez utiliser le portail Azure pour télécharger les fichiers de sortie MP3 générés par les tâches ffmpeg.

  1. Cliquez sur Tous les services>Comptes de stockage, puis sur le nom de votre compte de stockage.
  2. Cliquez sur BLOB>sortie.
  3. Cliquez avec le bouton droit sur l’un des fichiers de sortie MP3 puis cliquez sur Télécharger. Suivez les instructions dans votre navigateur pour ouvrir ou sauvegarder le fichier.

Télécharger le fichier de sortie

Même si ce n’est pas montré dans cet exemple, vous pouvez aussi télécharger les fichiers par programmation depuis les nœuds de calcul ou depuis le conteneur de stockage.

Vérifier le code

Dans les sections suivantes, nous examinons l’exemple d’application en nous servant des opérations qu’elle effectue pour traiter une charge de travail dans le service Batch. Reportez-vous au code Python pendant que vous lisez le reste de cet article, car aucune ligne de code de l’exemple n’est abordée.

Authentifier les clients Blob et Batch

Pour interagir avec un compte de stockage, l’application utilise le package azure-storage-blob pour créer un objet BlockBlobService .

blob_client = azureblob.BlockBlobService(
    account_name=_STORAGE_ACCOUNT_NAME,
    account_key=_STORAGE_ACCOUNT_KEY)

L’application crée un objet BatchServiceClient pour créer et gérer des pools, des travaux et des tâches dans le service Batch. Le client Batch dans l’exemple utilise l’authentification par clé partagée. Batch prend également en charge l’authentification via l’ID Microsoft Entra, pour authentifier des utilisateurs individuels ou une application sans assistance.

credentials = batchauth.SharedKeyCredentials(_BATCH_ACCOUNT_NAME,
                                             _BATCH_ACCOUNT_KEY)

batch_client = batch.BatchServiceClient(
    credentials,
    base_url=_BATCH_ACCOUNT_URL)

Charger des fichiers d’entrée

L’application utilise la blob_client référence pour créer un conteneur de stockage pour les fichiers MP4 d’entrée et un conteneur pour la sortie de tâche. Ensuite, il appelle la upload_file_to_container fonction pour charger des fichiers MP4 dans le répertoire InputFiles local dans le conteneur. Les fichiers de stockage sont définis en tant qu’objets Batch ResourceFile que Batch peut télécharger ultérieurement sur les nœuds de calcul.

blob_client.create_container(input_container_name, fail_on_exist=False)
blob_client.create_container(output_container_name, fail_on_exist=False)
input_file_paths = []

for folder, subs, files in os.walk(os.path.join(sys.path[0], './InputFiles/')):
    for filename in files:
        if filename.endswith(".mp4"):
            input_file_paths.append(os.path.abspath(
                os.path.join(folder, filename)))

# Upload the input files. This is the collection of files that are to be processed by the tasks.
input_files = [
    upload_file_to_container(blob_client, input_container_name, file_path)
    for file_path in input_file_paths]

Créer un pool de nœuds de calcul

Ensuite, l’exemple crée un pool de nœuds de traitement dans le compte Batch, avec un appel à create_pool. Cette fonction définie utilise la classe Batch PoolAddParameter pour définir le nombre de nœuds, la taille de machine virtuelle et une configuration de pool. Ici, un objet VirtualMachineConfiguration spécifie une ImageReference à une image Ubuntu Server 20.04 LTS publiée dans la Place de marché Azure. Azure Batch prend en charge une large gamme d'images de machines virtuelles dans l'Azure Marketplace, ainsi que des images de machines virtuelles personnalisées.

Le nombre de nœuds et la taille de machine virtuelle sont définis à l’aide de constantes définies. Azure Batch prend en charge les nœuds dédiés et les nœuds de faible priorité que vous pouvez utiliser dans vos pools. Les nœuds dédiés sont réservés à votre pool. Les nœuds de faible priorité sont proposés à prix réduit à partir de la capacité de machine virtuelle excédentaire dans Azure. Les nœuds Spot deviennent indisponibles si Azure n’a pas suffisamment de capacité. L’exemple par défaut crée un pool contenant seulement cinq nœuds Spot de taille Standard_A1_v2.

Outre les propriétés de nœud physiques, cette configuration de pool inclut un objet StartTask . StartTask s’exécute sur chaque nœud à mesure que ce nœud joint le pool, et chaque fois qu’un nœud est redémarré. Dans cet exemple, StartTask exécute des commandes d’interpréteur de commandes Bash pour installer le package ffmpeg et les dépendances sur les nœuds.

La méthode pool.add envoie le pool au service Batch.

new_pool = batch.models.PoolAddParameter(
    id=pool_id,
    virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
        image_reference=batchmodels.ImageReference(
            publisher="Canonical",
            offer="UbuntuServer",
            sku="20.04-LTS",
            version="latest"
        ),
        node_agent_sku_id="batch.node.ubuntu 20.04"),
    vm_size=_POOL_VM_SIZE,
    target_dedicated_nodes=_DEDICATED_POOL_NODE_COUNT,
    target_low_priority_nodes=_LOW_PRIORITY_POOL_NODE_COUNT,
    start_task=batchmodels.StartTask(
        command_line="/bin/bash -c \"apt-get update && apt-get install -y ffmpeg\"",
        wait_for_success=True,
        user_identity=batchmodels.UserIdentity(
            auto_user=batchmodels.AutoUserSpecification(
                scope=batchmodels.AutoUserScope.pool,
                elevation_level=batchmodels.ElevationLevel.admin)),
    )
)
batch_service_client.pool.add(new_pool)

Créer un travail

Un job par lots spécifie un pool de ressources pour exécuter des tâches et des paramètres facultatifs tels qu'une priorité et un planning du travail. L’exemple crée un travail avec un appel à create_job. Cette fonction définie utilise la classe JobAddParameter pour créer un job sur votre pool. La méthode job.add envoie le pool au service Batch. Au début, le travail n’a pas de tâches.

job = batch.models.JobAddParameter(
    id=job_id,
    pool_info=batch.models.PoolInformation(pool_id=pool_id))

batch_service_client.job.add(job)

Créer des tâches

L’application crée des tâches dans le travail avec un appel à add_tasks. Cette fonction définie crée une liste d’objets de tâche à l’aide de la classe TaskAddParameter . Chaque tâche exécute ffmpeg pour traiter un objet d’entrée resource_files à l’aide d’un command_line paramètre. ffmpeg a été précédemment installé sur chaque nœud lors de la création du pool. Ici, la ligne de commande exécute ffmpeg pour convertir chaque fichier (vidéo) MP4 en fichier MP3 (audio).

L’exemple crée un objet OutputFile pour le fichier MP3 après l’exécution de la ligne de commande. Les fichiers de sortie de chaque tâche (un, dans ce cas) sont chargés dans un conteneur dans le compte de stockage lié, à l’aide de la propriété de output_files la tâche.

Ensuite, l’application ajoute des tâches au travail avec la méthode task.add_collection , qui les met en file d’attente pour s’exécuter sur les nœuds de calcul.

tasks = list()

for idx, input_file in enumerate(input_files):
    input_file_path = input_file.file_path
    output_file_path = "".join((input_file_path).split('.')[:-1]) + '.mp3'
    command = "/bin/bash -c \"ffmpeg -i {} {} \"".format(
        input_file_path, output_file_path)
    tasks.append(batch.models.TaskAddParameter(
        id='Task{}'.format(idx),
        command_line=command,
        resource_files=[input_file],
        output_files=[batchmodels.OutputFile(
            file_pattern=output_file_path,
            destination=batchmodels.OutputFileDestination(
                container=batchmodels.OutputFileBlobContainerDestination(
                    container_url=output_container_sas_url)),
            upload_options=batchmodels.OutputFileUploadOptions(
                upload_condition=batchmodels.OutputFileUploadCondition.task_success))]
    )
    )
batch_service_client.task.add_collection(job_id, tasks)

Surveiller les tâches

Lorsque des tâches sont ajoutées à un travail, Batch met automatiquement en file d’attente et planifie leur exécution sur les nœuds de calcul dans le pool associé. En fonction des paramètres que vous spécifiez, Batch gère toutes les tâches de mise en file d’attente, de planification, de nouvelle tentative et d’autres tâches d’administration des tâches.

Il existe de nombreuses approches pour surveiller l’exécution des tâches. La wait_for_tasks_to_complete fonction de cet exemple utilise l’objet TaskState pour surveiller les tâches d’un état donné, dans ce cas l’état terminé, dans un délai limité.

while datetime.datetime.now() < timeout_expiration:
    print('.', end='')
    sys.stdout.flush()
    tasks = batch_service_client.task.list(job_id)

    incomplete_tasks = [task for task in tasks if
                        task.state != batchmodels.TaskState.completed]
    if not incomplete_tasks:
        print()
        return True
    else:
        time.sleep(1)
...

Nettoyer les ressources

Après avoir exécuté les tâches, l'application supprime automatiquement le conteneur de stockage d'entrée qu'elle a créé et vous offre la possibilité de supprimer le pool et la tâche du service Azure Batch. Les classes JobOperations et PoolOperations de BatchClient ont toutes deux des méthodes de suppression, appelées si vous confirmez la suppression. Bien que vous ne soyez pas facturé pour les travaux et les tâches à proprement parler, les nœuds de calcul vous sont facturés. Par conséquent, nous vous conseillons d’affecter les pools uniquement en fonction des besoins. Lorsque vous supprimez le pool, tous les résultats de tâche sur les nœuds sont supprimés. Toutefois, les fichiers d’entrée et de sortie restent dans le compte de stockage.

Lorsque vous n’en avez plus besoin, supprimez le groupe de ressources, le compte Batch et le compte de stockage. Pour ce faire, dans le portail Azure, sélectionnez le groupe de ressources du compte Batch et choisissez Supprimer le groupe de ressources.

Étapes suivantes

Dans ce tutoriel, vous avez appris à :

  • S’authentifier avec des comptes Batch et de stockage.
  • Charger des fichiers d’entrée sur le stockage.
  • Créer un pool de nœuds de calcul pour exécuter une application.
  • Créer un travail et des tâches pour traiter les fichiers d’entrée.
  • Surveiller l’exécution d’une tâche.
  • Récupérer les fichiers de sortie.

Pour plus d’exemples d’utilisation de l’API Python pour planifier et traiter des charges de travail Batch, consultez les exemples Batch Python sur GitHub.