PennyLane 組み込みシミュレーターでハイブリッドワークロードを実行する - Amazon Braket

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

PennyLane 組み込みシミュレーターでハイブリッドワークロードを実行する

Amazon Braket Hybrid Jobs PennyLane で の埋め込みシミュレーターを使用してハイブリッドワークロードを実行する方法を見てみましょう。Pennylane の GPUベースの埋め込みシミュレーター はlightning.gpuNvidia cuQuantum ライブラリを使用して回路シミュレーションを高速化します。埋め込みGPUシミュレーターは、ユーザーがすぐに使用できるすべての Braket ジョブコンテナに事前設定されています。このページでは、 lightning.gpuを使用してハイブリッドワークロードを高速化する方法を示します。

QAOA ワークロード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)

このページでは、2 つの埋め込み PennyLane 状態ベクトルシミュレーター lightning.qubit ( CPUベース) と lightning.gpu ( GPUベース) を比較します。さまざまな勾配を計算するには、シミュレーターにいくつかのカスタムゲート分解を提供する必要があります。

これで、ハイブリッドジョブ起動スクリプトを準備する準備ができました。QAOA アルゴリズムは、 m5.2xlargeと の 2 つのインスタンスタイプを使用して実行しますp3.2xlargem5.2xlarge インスタンスタイプは、標準のデベロッパーラップトップと同等です。p3.2xlarge は、16GB のメモリを持つ単一の NVIDIA Volta GPUを持つ高速コンピューティングインスタンスです。

すべてのハイブリッドジョブhyperparametersの は同じになります。さまざまなインスタンスとシミュレーターを試すために必要なことは、次のように 2 行変更することです。

# Specify device that the hybrid job will primarily be targeting device = "local:pennylane/lightning.qubit" # Run on a CPU based instance with about as much power as a laptop instance_config = InstanceConfig(instanceType='ml.m5.2xlarge')

または

# Specify device that the hybrid job will primarily be targeting device = "local:pennylane/lightning.gpu" # Run on an inexpensive GPU based instance instance_config = InstanceConfig(instanceType='ml.p3.2xlarge')
注記

GPUベースのインスタンスを使用して を instance_configとして指定し、埋め込み CPUベースのシミュレーター (lightning.qubit) deviceとして を選択した場合GPU、 は使用されません。をターゲットにする場合は、必ず埋め込み GPUベースのシミュレーターを使用してくださいGPU。

まず、2 つのハイブリッドジョブを作成し、18 個の頂点を持つグラフQAOAで を使用して Max-Cut を解決できます。これは 18 量子ビット回路に変換されます。比較的小さく、ラップトップやm5.2xlargeインスタンスですばやく実行できます。

num_nodes = 18 num_edges = 24 seed = 1967 graph = nx.gnm_random_graph(num_nodes, num_edges, seed=seed) # And similarly for the p3 job m5_job = AwsQuantumJob.create( device=device, source_module="qaoa_source", job_name="qaoa-m5-" + str(int(time.time())), image_uri=image_uri, # Relative to the source_module entry_point="qaoa_source.qaoa_algorithm_script", copy_checkpoints_from_job=None, instance_config=instance_config, # general parameters hyperparameters=hyperparameters, input_data={"input-graph": input_file_path}, wait_until_complete=True, )

m5.2xlarge インスタンスの平均反復時間は約 25 秒で、p3.2xlargeインスタンスの平均反復時間は約 12 秒です。この 18 量子ビットワークフローでは、GPUインスタンスは 2 倍の高速化を提供します。Amazon Braket Hybrid Jobs の料金ページを見ると、m5.2xlargeインスタンスの 1 分あたりのコストは 0.00768 USD、p3.2xlargeインスタンスのコストは 0.06375 USD であることがわかります。ここで行ったように、合計 5 回のイテレーションを実行するには、 CPUインスタンスを使用して 0.016 USD、または GPUインスタンスを使用して 0.06375 USD かかります。どちらもかなり安価です。

次に、問題をより困難にし、24 量子ビットに変換される 24 頂点グラフで Max-Cut 問題を解決してみましょう。同じ 2 つのインスタンスでハイブリッドジョブを再度実行し、コストを比較します。

注記

CPU インスタンスでこのハイブリッドジョブを実行する時間は、約 5 時間になる場合があります。

num_nodes = 24 num_edges = 36 seed = 1967 graph = nx.gnm_random_graph(num_nodes, num_edges, seed=seed) # And similarly for the p3 job m5_big_job = AwsQuantumJob.create( device=device, source_module="qaoa_source", job_name="qaoa-m5-big-" + str(int(time.time())), image_uri=image_uri, # Relative to the source_module entry_point="qaoa_source.qaoa_algorithm_script", copy_checkpoints_from_job=None, instance_config=instance_config, # general parameters hyperparameters=hyperparameters, input_data={"input-graph": input_file_path}, wait_until_complete=True, )

m5.2xlarge インスタンスの平均反復時間は約 1 時間ですが、p3.2xlargeインスタンスの平均反復時間は約 2 分です。この大きな問題では、GPUインスタンスは桁違いに高速です。この高速化のメリットを得るために必要なのは、2 行のコードを変更し、インスタンスタイプと使用するローカルシミュレーターを交換することだけです。ここで行ったように、合計 5 回のイテレーションを実行するには、インスタンスを使用して約 2.27,072 USD、またはCPUインスタンスを使用して約 0.77,5625 USD かかりますGPU。CPU 使用量はより高価であるだけでなく、実行に時間がかかります。にバックアップされた PennyLaneの埋め込みシミュレーターを使用して AWS、 で使用可能なGPUインスタンスでこのワークフローを加速することで、中間量子ビット数 (20 から 30 の間) でワークフローを実行することができNVIDIA CuQuantum、合計コストと時間を削減できます。つまり、ラップトップや同様のサイズのインスタンスですぐに実行できない大きな問題でも、量子コンピューティングを試すことができます。

量子機械学習とデータ並列処理

ワークロードタイプがデータセットでトレーニングする量子機械学習 (QML) である場合は、データ並列処理を使用してワークロードをさらに高速化できます。ではQML、モデルには 1 つ以上の量子回路が含まれています。モデルには古典ニューラルネットが含まれる場合と含まれない場合があります。データセットを使用してモデルをトレーニングすると、モデルのパラメータが更新され、損失関数が最小限に抑えられます。損失関数は通常、単一のデータポイントと、データセット全体の平均損失の合計に対して定義されます。ではQML、勾配計算の合計損失を平均する前に、損失は通常連続して計算されます。この手順は、特に数百のデータポイントがある場合に時間がかかります。

1 つのデータポイントからの損失は他のデータポイントに依存しないため、損失は並行して評価できます。異なるデータポイントに関連する損失と勾配を同時に評価できます。これはデータ並列処理と呼ばれます。Amazon Braket Hybrid Jobs SageMakerの分散データ並列ライブラリを使用すると、データ並列処理を活用してトレーニングを高速化することが容易になります。

バイナリ分類の例として、よく知られているUCIリポジトリの Sonar データセットデータセットを使用するデータ並列処理には、次のQMLワークロードを検討してください。Sonar データセットには 208 個のデータポイントがあり、それぞれに 60 個の特徴があり、ソナーシグナルから収集され、マテリアルから跳ね返ります。各データポイントは、地雷の場合は「M」、岩の場合は「R」というラベルが付けられます。このQMLモデルは、入力レイヤー、非表示レイヤーとしての量子回路、および出力レイヤーで構成されます。入出力レイヤーは、 に実装された古典ニューラルネットです PyTorch。量子回路は、 PennyLaneの qml.qnn モジュールを使用して PyTorch ニューラルネットと統合されます。ワークロードの詳細については、サンプルノートブックを参照してください。上記のQAOA例と同様に、 のような埋め込み GPUベースのシミュレータGPUーを使用して の能力を活用し PennyLanelightning.gpu、埋め込み CPUベースのシミュレーターよりもパフォーマンスを向上させることができます。

ハイブリッドジョブを作成するには、 AwsQuantumJob.createを呼び出し、キーワード引数を使用してアルゴリズムスクリプト、デバイス、およびその他の設定を指定できます。

instance_config = InstanceConfig(instanceType='ml.p3.2xlarge') 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_rankrankと をアルゴリズムスクリプトに伝えます。 rankはすべてのインスタンスGPUの の絶対インデックスで、 local_rank はインスタンスGPU内の のインデックスです。例えば、それぞれに 8 個の GPUs が割り当てられる 4 つのインスタンスがある場合、 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)

次に、 world_sizeDistributedSamplerに従って を定義し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.p3.16xlargeインスタンスタイプをサポートしています。ハイブリッドジョブの InstanceConfig引数を使用してインスタンスタイプを設定します。 SageMaker 分散データ並列ライブラリがデータ並列処理が有効になっていることを知るには、 を "sagemaker_distributed_dataparallel_enabled"に設定"true"し、 を使用中のインスタンスタイプ"sagemaker_instance_type"に設定する 2 つのハイパーパラメータを追加する必要があります。これら 2 つのハイパーパラメータはsmdistributedパッケージで使用されます。アルゴリズムスクリプトは明示的に使用する必要はありません。Amazon Braket ではSDK、キーワード引数 が便利ですdistribution。ハイブリッドジョブの作成distribution="data_parallel"では、Amazon Braket は 2 つのハイパーパラメータSDKを自動的に挿入します。Amazon Braket を使用する場合はAPI、これら 2 つのハイパーパラメータを含める必要があります。

インスタンスとデータ並列処理を設定して、ハイブリッドジョブを送信できるようになりました。ml.p3.16xlarge インスタンスGPUsには 8 つあります。を設定するとinstanceCount=1、ワークロードはインスタンスの 8 に分散GPUsされます。を 1 instanceCountつ以上設定すると、ワークロードはすべてのインスタンスでGPUs使用可能な に分散されます。複数のインスタンスを使用する場合、各インスタンスの使用時間に基づいて料金が発生します。例えば、4 つのインスタンスを使用する場合、ワークロードを同時に実行しているインスタンスが 4 つあるため、課金対象時間はインスタンスあたりの実行時間の 4 倍になります。

instance_config = InstanceConfig(instanceType='ml.p3.16xlarge', 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になることがあります。

上記の二項分類問題のために 26 量子ビットの量子回路でモデルをトレーニングする場合の例で、実行時間とコストを比較してみましょう。この例で使用されているml.p3.16xlargeインスタンスの料金は 1 分あたり 0.4692 USD です。データ並列処理を使用しない場合、シミュレーターがモデルを 1 エポック (つまり、208 データポイント以上) でトレーニングするのに約 45 分かかり、コストは約 20 USD です。1 つのインスタンスと 4 つのインスタンスのデータ並列処理では、それぞれ 6 分と 1.5 分しかかからず、どちらも約 2.8 USD になります。4 つのインスタンスでデータ並列処理を使用することで、実行時間を 30 倍向上させるだけでなく、コストを 1 桁削減できます。