本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 PennyLane 內嵌模擬器執行混合工作負載
讓我們看看如何在 Amazon Braket Hybrid Jobs 上使用 PennyLane 的內嵌模擬器來執行混合工作負載。Pennylane 的 GPU 型內嵌模擬器 lightning.gpu使用 Nvidia cuQuantum 程式庫lightning.gpu 來加速混合式工作負載。
使用 lightning.gpu處理 QAOA 工作負載
考慮此筆記本device引數指定為格式的字串:"local:<provider>/<simulator_name>"。例如,您會"local:pennylane/lightning.gpu"為 設定 lightning.gpu。您在啟動時提供給混合任務的裝置字串會以環境變數 的形式傳遞給任務"AMZN_BRAKET_DEVICE_ARN"。
device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"] prefix, device_name = device_string.split("/") device = qml.device(simulator_name, wires=n_wires)
在此頁面上,比較兩個內嵌 PennyLane 狀態向量模擬器 lightning.qubit(以 CPU 為基礎) 和 lightning.gpu(以 GPU 為基礎)。為模擬器提供自訂閘道分解,以計算各種漸層。
現在您已準備好準備混合任務啟動指令碼。使用兩種執行個體類型執行 QAOA 演算法: ml.m5.2xlarge和 ml.g4dn.xlarge。ml.m5.2xlarge 執行個體類型與標準開發人員筆記型電腦相當。ml.g4dn.xlarge 是具有單一 NVIDIA T4 GPU 和 16GB 記憶體的加速運算執行個體。
若要執行 GPU,我們首先需要指定相容的映像和正確的執行個體 (預設為ml.m5.2xlarge執行個體)。
from braket.aws import AwsSession from braket.jobs.image_uris import Framework, retrieve_image image_uri = retrieve_image(Framework.PL_PYTORCH, AwsSession().region) instance_config = InstanceConfig(instanceType="ml.g4dn.xlarge")
然後,我們需要將這些輸入混合任務裝飾項目,以及系統和混合任務引數中的更新裝置參數。
@hybrid_job( device="local:pennylane/lightning.gpu", input_data=input_file_path, image_uri=image_uri, instance_config=instance_config) def run_qaoa_hybrid_job_gpu(p=1, steps=10): params = np.random.rand(2, p) braket_task_tracker = Tracker() graph = nx.read_adjlist(input_file_path, nodetype=int) wires = list(graph.nodes) cost_h, _mixer_h = qaoa.maxcut(graph) device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"] prefix, device_name = device_string.split("/") dev= qml.device(simulator_name, wires=len(wires)) ...
注意
如果您將 指定instance_config為使用 GPU 型執行個體,但選擇 device做為內嵌的 CPU 型模擬器 (lightning.qubit),則不會使用 GPU。如果您想要以 GPU 為目標,請務必使用嵌入式 GPU 型模擬器!
m5.2xlarge 執行個體的平均反覆運算時間約為 73 秒,而ml.g4dn.xlarge執行個體的反覆運算時間約為 0.6 秒。對於此 21 qubit 工作流程,GPU 執行個體可提供 100 倍的速度。如果您查看 Amazon Braket Hybrid Jobs 定價頁面m5.2xlarge執行個體的每分鐘成本為 0.00768 USD,而ml.g4dn.xlarge執行個體的每分鐘成本為 0.01227 USD。在此執行個體中,在 GPU 執行個體上執行更快速且更便宜。
Quantum 機器學習和資料平行處理
如果您的工作負載類型是在資料集上訓練的量子機器學習 (QML),您可以使用資料平行處理進一步加速工作負載。在 QML 中,模型包含一或多個量子電路。模型可能也可能不包含傳統神經網路。使用資料集訓練模型時,模型中的參數會更新,以將損失函數降至最低。損失函數通常針對單一資料點定義,以及整個資料集平均損失的總損失。在 QML 中,損失通常會先以序列方式計算,再平均至梯度運算的總損失。此程序耗時,特別是有數百個資料點時。
由於某個資料點的損失不取決於其他資料點,因此可以平行評估損失!您可以同時評估與不同資料點相關聯的損失和梯度。這稱為資料平行處理。使用 SageMaker 的分散式資料平行程式庫,Amazon Braket Hybrid Jobs 可讓您更輕鬆地使用資料平行處理來加速訓練。
請考慮下列資料平行處理的 QML 工作負載,其使用來自已知 UCI 儲存庫的聲納資料集lightning.gpu,以改善與嵌入式 CPU 型模擬器相比的效能。
若要建立混合任務,您可以透過其關鍵字引數呼叫AwsQuantumJob.create並指定演算法指令碼、裝置和其他組態。
instance_config = InstanceConfig(instanceType='ml.g4dn.xlarge') hyperparameters={"nwires": "10", "ndata": "32", ... } job = AwsQuantumJob.create( device="local:pennylane/lightning.gpu", source_module="qml_source", entry_point="qml_source.train_single", hyperparameters=hyperparameters, instance_config=instance_config, ... )
若要使用資料平行處理,您需要修改 SageMaker 分散式程式庫演算法指令碼中的幾行程式碼,以正確平行化訓練。首先,您可以匯入 套件,該smdistributed套件會處理將工作負載分散到多個 GPUs 和多個執行個體的大部分繁重工作。此套件已在 Braket PyTorch 和 TensorFlow 容器中預先設定。dist 模組會告知我們的演算法指令碼,訓練的 GPUs 總數 (world_size) 以及 GPU 核心local_rank的 rank和 。 rank 是 GPU 在所有執行個體的絕對索引,而 local_rank是執行個體內 GPU 的索引。例如,如果有四個執行個體,每個執行個體都有八個 GPUs 配置給訓練,rank範圍從 0 到 31,local_rank範圍從 0 到 7。
import smdistributed.dataparallel.torch.distributed as dist dp_info = { "world_size": dist.get_world_size(), "rank": dist.get_rank(), "local_rank": dist.get_local_rank(), } batch_size //= dp_info["world_size"] // 8 batch_size = max(batch_size, 1)
接著,您可以DistributedSampler根據 world_size和 定義 ,rank然後將其傳遞至資料載入器。此取樣器會避免 GPUs 存取資料集的相同配量。
train_sampler = torch.utils.data.distributed.DistributedSampler( train_dataset, num_replicas=dp_info["world_size"], rank=dp_info["rank"] ) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=batch_size, shuffle=False, num_workers=0, pin_memory=True, sampler=train_sampler, )
接著,您可以使用 DistributedDataParallel類別來啟用資料平行處理。
from smdistributed.dataparallel.torch.parallel.distributed import DistributedDataParallel as DDP model = DressedQNN(qc_dev).to(device) model = DDP(model) torch.cuda.set_device(dp_info["local_rank"]) model.cuda(dp_info["local_rank"])
以上是使用資料平行處理所需的變更。在 QML 中,您通常想要儲存結果並列印訓練進度。如果每個 GPU 執行儲存和列印命令,日誌會充滿重複的資訊,而結果會互相覆寫。若要避免這種情況,您只能從具有 0 rank 的 GPU 儲存和列印。
if dp_info["rank"]==0: print('elapsed time: ', elapsed) torch.save(model.state_dict(), f"{output_dir}/test_local.pt") save_job_result({"last loss": loss_before})
Amazon Braket Hybrid Jobs 支援 SageMaker 分散式資料平行程式庫的ml.g4dn.12xlarge執行個體類型。您可以透過混合任務中的 InstanceConfig 引數來設定執行個體類型。若要讓 SageMaker 分散式資料平行程式庫知道已啟用資料平行處理,您需要新增兩個額外的超參數,將 "sagemaker_distributed_dataparallel_enabled"設定為 "true",並將 "sagemaker_instance_type"設定為您正在使用的執行個體類型。smdistributed 套件會使用這兩個超參數。您的演算法指令碼不需要明確使用它們。在 Amazon Braket SDK 中,它提供方便的關鍵字引數 distribution。在混合任務建立distribution="data_parallel"中使用 時,Amazon Braket SDK 會自動為您插入兩個超參數。如果您使用 Amazon Braket API,則需要包含這兩個超參數。
設定執行個體和資料平行處理後,您現在可以提交混合任務。ml.g4dn.12xlarge 執行個體中有 4 個 GPUs。當您設定 instanceCount=1 時,工作負載會分散到執行個體中的 8 個 GPUs。當您設定instanceCount大於一個時,工作負載會分散到所有執行個體中可用的 GPUs。使用多個執行個體時,每個執行個體會根據您使用的時間而產生費用。例如,當您使用四個執行個體時,計費時間為每個執行個體執行時間的四倍,因為有四個執行個體同時執行您的工作負載。
instance_config = InstanceConfig(instanceType='ml.g4dn.12xlarge', instanceCount=1, ) hyperparameters={"nwires": "10", "ndata": "32", ..., } job = AwsQuantumJob.create( device="local:pennylane/lightning.gpu", source_module="qml_source", entry_point="qml_source.train_dp", hyperparameters=hyperparameters, instance_config=instance_config, distribution="data_parallel", ... )
注意
在上述混合任務建立中, train_dp.py是使用資料平行處理的修改演算法指令碼。請注意,只有在您根據上述章節修改演算法指令碼時,資料平行處理才能正常運作。如果在未正確修改演算法指令碼的情況下啟用資料平行處理選項,混合任務可能會擲回錯誤,或者每個 GPU 可能會重複處理相同的資料配量,這很低效率。
如果正確使用,使用多個執行個體可能會導致時間和成本大幅減少。如需詳細資訊,請參閱範例筆記本