教學課程:使用 Python API 搭配 Azure Batch 執行平行工作負載

使用 Azure Batch 在 Azure 中有效率地執行大規模的平行和高效能運算 (HPC) 批次作業。 本教學課程會逐步解說使用 Batch 執行平行工作負載的 Python 範例。 您會了解 Batch 應用程式的通用工作流程,以及如何以程式設計方式與 Batch 和儲存體資源進行互動。

  • 驗證 Batch 和儲存體帳戶。
  • 將輸入檔案上傳至儲存體。
  • 建立計算節點的集區來執行應用程式。
  • 建立作業和工作來處理輸入檔案。
  • 監控任務執行。
  • 擷取輸出檔案。

在本教學課程中,您會使用 ffmpeg 開放原始碼工具將 MP4 媒體檔案平行轉換為 MP3 格式。

如果您沒有 Azure 帳戶,請在開始之前建立 免費帳戶

先決條件

登入 Azure

登入 Azure 入口網站

取得帳戶認證

在此範例中,您必須提供 Batch 和儲存體帳戶的認證。 在 Azure 入口網站中可以直接取得所需的認證。 (您也可以使用 Azure API 或命令列工具取得這些認證。)

  1. 選取 [所有服務]>[Batch 帳戶],然後選取您的 Batch 帳戶名稱。

  2. 若要查看 Batch 認證,請選取 [金鑰]。 將 [Batch 帳戶]、[URL] 和 [主要存取金鑰] 的值複製到文字編輯器。

  3. 若要查看儲存體帳戶名稱和金鑰,請選取 [儲存體帳戶]。 將 [儲存體帳戶名稱] 和 [金鑰1] 的值複製到文字編輯器。

下載及執行範例應用程式

下載範例應用程式

從 GitHub 下載或複製範例應用程式。 若要使用 Git 用戶端複製範例應用程式存放庫,請使用下列命令:

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

流覽至包含 檔案batch_python_tutorial_ffmpeg.py的目錄。

在您的 Python 環境中,使用 pip安裝必要的套件。

pip install -r requirements.txt

使用程式代碼編輯器開啟 檔案 config.py。 更新批次和儲存帳戶的值,並設定為你帳戶獨有的名稱。 範例使用 DefaultAzureCredential 來認證,因此不再需要帳號金鑰。 例如:

_BATCH_ACCOUNT_NAME = 'yourbatchaccount'
_BATCH_ACCOUNT_URL = 'https://yourbatchaccount.yourbatchregion.batch.azure.com'
_STORAGE_ACCOUNT_NAME = 'mystorageaccount'

在執行範例前,請以Azure CLI(az login)登入,或以其他方式設定憑證,讓 DefaultAzureCredential 能發現(例如管理身份、Visual Studio Code或環境變數)。 確保登入的身份在批次帳號(例如 Azure Batch ContributorReader)以及儲存帳號(例如 Storage Blob Data Contributor)都被賦予適當的 Azure RBAC 角色。

執行應用程式

執行指令碼:

python batch_python_tutorial_ffmpeg.py

當您執行範例應用程式時,主控台輸出大致如下。 在執行期間,集區的計算節點啟動後,您會在 Monitoring all tasks for 'Completed' state, timeout in 00:30:00... 遇到暫停。

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

請前往 Azure 入口網站中的 Batch 帳戶,以監視集區、計算節點、作業和任務。 例如,若要查看集區中計算節點的熱度圖,請選取 [集區]> [LinuxFFmpegPool]

當工作正在執行時,熱度圖會如下所示:

集區熱度圖的螢幕快照。

一般運行時間大約是 5 分鐘 ,當您在其預設組態中執行應用程式。 建立集區佔用大部分的時間。

擷取輸出檔案

您可以使用 Azure 入口網站來下載 ffmpeg 工作所產生的 MP3 輸出檔案。

  1. 按一下 [所有服務]>[儲存體帳戶],然後按一下您的儲存體帳戶名稱。
  2. 按一下 [Blob]> [輸出]
  3. 以滑鼠右鍵按一下其中一個 MP3 輸出檔案,然後按 [下載]。 請依照瀏覽器的提示開啟或儲存檔案。

下載輸出檔案

此範例雖未示範,但您也可以用程式設計方式從計算節點或儲存體容器下載檔案。

檢閱程式碼

後面各節將範例應用程式細分為用來處理 Batch 服務中工作負載的數個步驟。 當您閱讀本文的其餘部分時,請參閱 Python 程式代碼,因為不會討論範例中的每一行程序代碼。

驗證 Blob 和 Batch 用戶端

範例使用 DefaultAzureCredential(來自 azure-identity 套件),同時向 Storage 和 Batch 進行驗證。 DefaultAzureCredential 嘗試依序嘗試多種憑證類型(環境變數、管理身份、Azure CLI登入等),使同一程式碼在本地開發和生產環境中都能運作,且不儲存帳號金鑰。

要與儲存帳號互動,應用程式會使用 azure-storage-blob 套件來建立一個使用 credential 的 BlobServiceClient 物件。

credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
    account_url=f"https://{_STORAGE_ACCOUNT_NAME}.blob.core.windows.net/",
    credential=credential)

應用程式會建立一個 BatchClient 物件,用來建立和管理批次服務中的池、工作與任務。 批次用戶端使用相同的 DefaultAzureCredential 透過 Microsoft Entra ID 進行認證。

batch_client = BatchClient(
    endpoint=_BATCH_ACCOUNT_URL,
    credential=credential)

上傳輸入檔案

應用程式使用blob_client 參考來為輸入的 MP4 檔案建立儲存容器,並為任務輸出建立容器。 然後,它會呼叫 函 upload_file_to_container 式,將本機 InputFiles 目錄中的 MP4 檔案上傳至容器。 儲存體中的檔案會定義為 Batch ResourceFile 物件,Batch 之後可將這類物件下載到計算節點。

blob_service_client.create_container(input_container_name)
blob_service_client.create_container(output_container_name)
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_service_client, input_container_name, file_path)
    for file_path in input_file_paths]

建立計算節點的集區

接著,範例會呼叫 create_pool 以在 Batch 帳戶中建立計算節點集區。 此定義函式使用 Batch BatchPoolCreateOptions 類別來設定節點數量、虛擬機大小及池組態。 此處,VirtualMachineConfiguration物件指定一個BatchVmImageReference,指向Azure Marketplace中發布的 Ubuntu Server 20.04 LTS 映像檔。 Batch 支援 Azure Marketplace 中各式各樣的 VM 映像,以及自訂 VM 映像。

使用已定義的常數可設定節點數目和 VM 大小。 Batch 支援專用節點和現成品節點,而您可以在集區中使用其中一種或同時使用兩種。 專用節點會保留給您的集區使用。 現成品節點則會以較低的價格從 Azure 中的剩餘容量提供。 如果 Azure 沒有足夠的容量,現成節點將無法使用。 根據預設,此範例會建立集區,其大小只有五個 Spot 節點 Standard_A1_v2

除了實體節點屬性外,此池配置還包含一個 BatchStartTask 物件。 BatchStartTask 會在每個節點加入池時執行,每次節點重啟時也會執行。 在此範例中,BatchStartTask 執行 Bash shell 指令,安裝節點上的 ffmpeg 套件及依賴關係。

create_pool 方法將池提交給批次服務。

new_pool = models.BatchPoolCreateOptions(
    id=pool_id,
    virtual_machine_configuration=models.VirtualMachineConfiguration(
        image_reference=models.BatchVmImageReference(
            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=models.BatchStartTask(
        command_line="/bin/bash -c \"apt-get update && apt-get install -y ffmpeg\"",
        wait_for_success=True,
        user_identity=models.UserIdentity(
            auto_user=models.AutoUserSpecification(
                scope=models.AutoUserScope.POOL,
                elevation_level=models.ElevationLevel.ADMIN)),
    )
)
batch_client.create_pool(pool=new_pool)

建立職位

Batch 工作會指定要在其中執行工作的集區及選擇性設定,例如工作的優先順序和排程。 此範例會藉由呼叫 create_job 來建立作業。 這個定義函式使用 BatchJobCreateOptions 類別來在您的池中建立工作。 create_job 方法會將集區提交至 Batch 服務。 一開始這份工作沒有任何任務。

job = models.BatchJobCreateOptions(
    id=job_id,
    pool_info=models.BatchPoolInfo(pool_id=pool_id))

batch_client.create_job(job=job)

建立任務

應用程式會藉由呼叫 add_tasks 在作業中建立工作。 此定義函式使用 BatchTaskCreateOptions 類別建立任務物件清單。 每個工作都會執行 ffmpeg,以使用 resource_files 參數處理輸入command_line物件。 ffmpeg 已在先前建立集區時安裝於每個節點上。 在此,命令列會執行 ffmpeg,將每個輸入 MP4 (影片) 檔案轉換為 MP3 (音訊) 檔案。

此範例會在執行命令列之後,為 MP3 檔案建立 OutputFile 物件。 每個任務的輸出檔案(在此案例中一個)會使用任務的 output_files 屬性上傳至已連結的儲存帳戶中的容器。

接著,應用程式會用 create_tasks 方法將任務加入工作,並排隊在運算節點上執行。

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(models.BatchTaskCreateOptions(
        id='Task{}'.format(idx),
        command_line=command,
        resource_files=[input_file],
        output_files=[models.OutputFile(
            file_pattern=output_file_path,
            destination=models.OutputFileDestination(
                container=models.OutputFileBlobContainerDestination(
                    container_url=output_container_sas_url)),
            upload_options=models.OutputFileUploadConfiguration(
                upload_condition=models.OutputFileUploadCondition.TASK_SUCCESS))]
    )
    )
batch_client.create_tasks(job_id=job_id, task_collection=tasks)

監視工作

當任務被新增至作業時,Batch 會自動將它們排入佇列,並排程它們在相關聯集區中的計算節點上執行。 根據您指定的設定,Batch 會處理所有工作佇列、排程、重試和其他工作管理職責。

監視工作執行的方法有很多種。 此範例中的 wait_for_tasks_to_complete 函式會使用 BatchTaskState 物件,在時限內監視任務是否處於特定狀態,在此情況下為已完成狀態。

while datetime.datetime.now() < timeout_expiration:
    print('.', end='')
    sys.stdout.flush()
    tasks = batch_client.list_tasks(job_id=job_id)

    incomplete_tasks = [task for task in tasks if
                        task.state != models.BatchTaskState.COMPLETED]
    if not incomplete_tasks:
        print()
        return True
    else:
        time.sleep(1)
...

清理資源

應用程式在執行工作之後,會自動刪除它所建立的輸入儲存體容器,並且為您提供用於刪除 Batch 集區和工作的選項。 BatchClient 的 JobOperationsPoolOperations 類別都有 delete 方法,如果您確認刪除,則會呼叫此方法。 雖然您不需支付作業和工作本身的費用,但您需支付計算節點的費用。 因此,我們建議您只在必要時配置集區。 當您刪除集區時,節點上的所有工作輸出也會跟著刪除。 不過,輸入和輸出檔案會保留在記憶體帳戶中。

若不再需要,可刪除資源群組、Batch 帳戶和儲存體帳戶。 若要在 Azure 入口網站中這樣做,請選取 Batch 帳戶的資源群組,然後選擇 [ 刪除資源群組]。

後續步驟

在本教程中,您將學到如何:

  • 驗證 Batch 和儲存體帳戶。
  • 將輸入檔案上傳至儲存體。
  • 建立計算節點的集區來執行應用程式。
  • 建立作業和工作來處理輸入檔案。
  • 監控任務執行。
  • 擷取輸出檔案。

如需使用 Python API 排程及處理 Batch 工作負載的更多範例,請參閱 GitHub 上的 Batch Python 範例