の組み込みシミュレーターを使用してハイブリッドワークロードを高速化する PennyLane - Amazon Braket

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

の組み込みシミュレーターを使用してハイブリッドワークロードを高速化する PennyLane

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

このページでは、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 の料金ページを見ると、インスタンスの 1 分あたりのコストは 0.00768 USD で、p3.2xlargeインスタンスのコストは 0.06375 USD であることがわかります。 m5.2xlargeここで行ったように、合計 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 回の反復を実行するには、CPU インスタンスを使用して約 2.27,072 USD、または GPU インスタンスを使用して約 0.77,5625 USD のコストがかかります。CPU 使用率はより高価であるだけでなく、実行にさらに時間がかかります。NVIDIA にバックアップされた PennyLaneの埋め込みシミュレーターを使用して AWS、 で利用可能な GPU インスタンスでこのワークフローを加速することで CuQuantum、中間量子ビット数 (20~30) のワークフローを、総コストと時間を削減して実行できます。つまり、ラップトップや同様のサイズのインスタンスですぐに実行できない大きな問題でも、量子コンピューティングを試すことができます。

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

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

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

二項分類の例として、よく知られている UCI リポジトリの Sonar データセットデータセットを使用するデータ並列処理には、次の QML ワークロードを検討してください。Sonar データセットには 208 個のデータポイントがあり、それぞれに 60 個の特徴があり、ソナーシグナルから収集され、マテリアルが跳ね返ります。各データポイントは、地雷の場合は「M」、石の場合は「R」のラベルが付けられます。当社の QML モデルは、入力レイヤー、隠しレイヤーとしての量子回路、および出力レイヤーで構成されています。入力レイヤーと出力レイヤーは、 に実装されている古典ニューラルネットです PyTorch。量子回路は、 の qml.qnn モジュールを使用して PyTorch ニューラルネットと統合 PennyLaneされます。ワークロードの詳細については、サンプルノートブックを参照してください。上記の 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 モジュールは、トレーニング (world_size) の GPUs の合計数と 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 の GPU rank からのみ保存および印刷できます。

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

インスタンスとデータ並列処理を設定して、ハイブリッドジョブを送信できるようになりました。ml.p3.16xlarge インスタンスには 8 GPUs があります。を設定するとinstanceCount=1、ワークロードはインスタンス内の 8 GPUs に分散されます。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 桁削減できます。