[Workshop] Amazon Braket: Get hands-on with quantum computing に参加しました #QTC201 #AWSreInvent

[Workshop] Amazon Braket: Get hands-on with quantum computing に参加しました #QTC201 #AWSreInvent

Clock Icon2024.12.06

re:Invent 2024 現地参加組のカスタマーサクセス部 運用支援チームのいたくらです。

「QTC201 | Amazon Braket: Get hands-on with quantum computing」に参加したのでレポートします。

セッション情報

  • セッション ID : QTC201
  • タイトル: Amazon Braket: Get hands-on with quantum computing
  • スピーカー: Zia Mohammad, Jagadeesh Pusapadi
  • レベル: 200 – Intermediate

ワークショップの概要

Amazon Braket provides access to quantum computing hardware and simulators to speed up scientific research and software development for quantum computing. Join this workshop to implement your first quantum algorithm and gain hands-on experience with running quantum circuits on gate-based devices and simulators. Review service features and examples available in the AWS quantum algorithm library.

Amazon Braketは、量子コンピューティングの科学研究とソフトウェア開発を加速するために、量子コンピューティングのハードウェアとシミュレータへのアクセスを提供します。このワークショップに参加して、初めての量子アルゴリズムを実装し、ゲートベースのデバイスとシミュレータ上で量子回路を実行する実践的な経験を得ることができます。AWSの量子アルゴリズムライブラリで利用可能なサービス機能と例を確認します。

内容

※ ワークショップで使用した資料は英語でしたが、本ブログでは日本語訳で記載しています。

このワークショップは、集中講座のモジュールが提供されました。
以下、集中講座の一覧です。

モジュール レベル
シミュレータと QPU での量子回路の実行 入門
量子ノイズシミュレーション 中級
Amazon Braket Hybrid Jobs でのアルゴリズム実行 中級
Amazon Braket Hybrid Jobs での QAOA を使用した MaxCut 上級
QML:二値分類のための量子変分分類器 上級
QML:アヤメの花の分類のための量子変分分類器 上級
Amazon Braket でのアナログハミルトニアンシミュレーション 上級

※ QML = Quantum Machine Learning(量子機械学習)
※ QAOA = Quantum Approximate Optimization Algorithm(量子近似最適化アルゴリズム)
※ QPU = Quantum Processing Unit(量子プロセッシングユニット)

Amazon Braket のノートブックがあらかじめ用意されていて、このノートブックの中に各講座がモジュールとして格納されていました。
1.png
2.png

このワークショップは入門編のため、モジュール:シミュレータと QPU での量子回路の実行 を実施しました。
このモジュール内に記載されていた実施手順は以下です。

  1. Amazon Braket SDK を使用して量子回路を構築
  2. 量子デバイスオブジェクトをインスタンス化
  3. ターゲットデバイスに量子タスクとして回路を送信
  4. 計算結果を取得
  5. Braket で Qiskit の回路を直接実行

ワークショップ自体は Jupyter Notebook のコマンドを実行するだけで出来てしまったので、本ブログでは復習を兼ねてどのようなことをやっていたのかをご紹介します。

Amazon Braket SDK を使用して量子回路を構築

まずは必要なモジュールのインポートを実施しました。
その後、Braket SDK を使用して、
空の量子回路オブジェクト Circuit() をインスタンス化し、そのオブジェクトに量子ゲートを追加していきました。

補足:
量子ゲートについては以下のサイトが分かりやすかったので興味がある方はご参照ください。
https://rp.kddi-research.jp/atelier/column/archives/318

まずは試しに下図の量子回路を構築しました。

circ.x(0)
circ.cnot(control=0, target=1).ry(1, 0.5)

31-2.png

また、Braket SDK は量子回路の構築機能に加えて、3 種類(状態ベクトルシミュレータ、密度行列シミュレータ、アナログハミルトニアンシミュレーション用シミュレータ)のローカルシミュレータも用意されています。
これは実際の量子デバイスを使用する前の開発やテストフェーズで有用です。

量子デバイスオブジェクトをインスタンス化

前述のローカルシミュレータ(今回は状態ベクトルシミュレータ)をインスタンス化しました。

device = LocalSimulator()

ターゲットデバイスに量子タスクとして回路を送信

量子回路とデバイスのインスタンスがある場合、device.run API を使用して、量子タスクとして回路をデバイス上で実行できました。

task = device.run(circ, shots=1000)
print(task, task.state())

実行結果:LocalQuantumTask('id':ae3394b6-0bf7-4aa1-910b-cd4410bd7d8b) COMPLETED

計算結果を取得

以下を実行することで、量子タスクの計算結果を取得できました。

result = task.result()
print(result)

実行結果:
GateModelQuantumTaskResult(task_metadata=TaskMetadata(braketSchemaHeader=BraketSchemaHeader(name='braket.task_result.task_metadata', version='1'), id='ae3394b6-0bf7-4aa1-910b-cd4410bd7d8b', shots=1000, deviceId='braket_sv', deviceParameters=None, createdAt=None, endedAt=None, status=None, failureReason=None), additional_metadata=AdditionalMetadata(action=Program(braketSchemaHeader=BraketSchemaHeader(name='braket.ir.openqasm.program', version='1'), source='OPENQASM 3.0;\nbit[3] b;\nqubit[3] q;\nh q[0];\ncnot q[0], q[1];\ncnot q[1], q[2];\nb[0] = measure q[0];\nb[1] = measure q[1];\nb[2] = measure q[2];', inputs={}), dwaveMetadata=None, ionqMetadata=None, rigettiMetadata=None, oqcMetadata=None, xanaduMetadata=None, queraMetadata=None, simulatorMetadata=None, iqmMetadata=None), result_types=[], values=[], measurements=array([[0, 0, 0],
       [0, 0, 0],
       [1, 1, 1],
       ...,
       [0, 0, 0],
       [1, 1, 1],
       [1, 1, 1]]), measured_qubits=[0, 1, 2], measurement_counts=Counter({'000': 514, '111': 486}), measurement_probabilities={'000': 0.514, '111': 0.486}, measurements_copied_from_device=True, measurement_counts_copied_from_device=False, measurement_probabilities_copied_from_device=False, _result_types_indices={})

量子タスクの計算結果は GateModelQuantumTaskResult オブジェクトで提供されました。
計算結果を簡単にまとめると以下のような内容でした。

  • 測定された量子ビット: [0, 1, 2]
  • 測定カウント: '000'が514回、'111'が486回
  • 測定確率: '000'が0.514、'111'が0.486

ちなみに、この結果を可視化することも可能です。

counts = result.measurement_counts
print(counts)

# counts を使ったプロット
plt.bar(counts.keys(), counts.values())
plt.xlabel("bitstrings")
plt.ylabel("counts")
plt.show()

実行結果:Counter({'000': 514, '111': 486})

32.png

Braket で Qiskit の回路を直接実行

先ほどは量子回路を直接構築しましたが、ここでは Qiskit という IBM が提供するオープンソースの量子プログラミングフレームワークを使用して量子回路を構築し、実行しました。

Qiskitを使用して量子回路を構築したい場合、オープンソースの Qiskit-Braket プロバイダーを通じて、Amazon Braket の任意のゲートベースデバイスで実行可能です。

provider = BraketProvider()

Qiskit 回路を定義して、

def qiskit_ghz(n):
    circuit = QuantumCircuit(n)
    circuit.h(0)
    for ii in range(0, n - 1):
        circuit.cx(ii, ii + 1)
    return circuit

Qiskit 回路を作成、表示しました。

ghz_qiskit = qiskit_ghz(5)
ghz_qiskit.draw()

33.png

回路を作成後、Braket SDK の LocalSimulator で Qiskit コードを実行しました。

# ローカルシミュレータの初期化
local_simulator = BraketLocalBackend()

# 1000ショットで回路を実行
simulator_task = local_simulator.run(ghz_qiskit, shots=1000)

# 結果の取得と表示
result = simulator_task.result()
result_counts = result.data()["counts"]
print(result_counts)

# 結果の可視化
plt.bar(result_counts.keys(), result_counts.values())
plt.show()

実行結果:{'00000': 503, '11111': 497}

34.png

実行結果は、5 量子ビット GHZ 状態の理想的な振る舞いを示しており、|00000⟩ と |11111⟩ の重ね合わせ状態が約 50:50 の確率で観測されていることを表しています。

ローカルシミュレータで実行できたので、Braket で利用可能な QPU 上で Qiskit 回路を実行しました。

# オンラインのバックエンド一覧の取得
provider.backends(statuses=["ONLINE"])

# 特定のバックエンド(Garnet)で実行
qpu_backend = provider.get_backend("Garnet")
qpu_task = qpu_backend.run(ghz_qiskit, shots=100)

# 量子タスクの状態確認
task_id = qpu_task.task_id()
print(task_id, qpu_task.status())

実行結果:arn:aws:braket:eu-north-1:XXXXXXXXXXXX:quantum-task/a873c2a3-434f-40df-8d38-d7ddf7513d02 JobStatus.DONE
# タスク ID と実行状態(DONE)が表示されている

最後に実行結果のデータ取得と可視化をしてみました。

# データ取得のコード
retrieved_task = qpu_backend.retrieve_job(task_id=task_id)
result = retrieved_task.result()
result_counts = dict(sorted(result.data()["counts"].items()))

# 可視化のコード
plt.bar(result_counts.keys(), result_counts.values())
plt.xlabel("bitstrings")
plt.xticks(rotation=90)
plt.ylabel("counts")
plt.tight_layout()
plt.show()

実行結果:
Measurement counts: {'00000': 52, '00001': 1, '00010': 1, '00111': 1, '01101': 1, '01111': 5, '10111': 1, '11011': 1, '11100': 2, '11101': 3, '11110': 1, '11111': 31}

実行結果を簡単にまとめると以下です。

  • '00000': 52回
  • '11111': 31回
  • その他の状態('00001', '00010', '00111'など): 1-5回程度

可視化すると以下のようになりました。
35.png

実際の QPU での実行では理想的なシミュレーションと比べて、ノイズの影響を受け、予期しない状態も観測されることがわかりました。

最後に

量子コンピュータという単語に惹かれ、好奇心だけで参加してみたワークショップのレポートでした。
学生時代に学んだ電子回路と計算の基本単位が異なっていましたが、回路の概念といったところは同じなんだなと感じました。
(ワークショップ前のスピーカーによる説明は学生時代の講義みたいでちょっと懐かしかったです)
Amazon Braket の基本的な使い方を学べて勉強になりました。

この記事がどなたかのお役に立てれば幸いです。

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。
サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.