Nobisuke
Dekisugi
RAG
Privacy policy
最近 Factoring integers with sublinear resources on a superconducting quantum processor という論文の注目度が高いようです。この論文では、技術として QAOA (A Quantum Approximate Optimization Algorithm) が使われているということで、真面目に触ったことのなかった QAOA を動かしてみたいという内容になります。
ついでに、cuQuantum でも QAOA を動かしてみたいと思います。検証環境は Google Colab を使いました。
量子コンピュータでQAOAとミキサーを使った交通最適化(簡略化版) にサンプルがあります。しかし、今回はこれではなく IBM Quantumで学ぶ量子コンピュータ のほうに載っている、より簡単なサンプルを blueqat で走らせて比較してみたいです。詳しくは書籍に譲って、実装だけ差し替えます。(書籍では Qiskit が使われています。なお Qiskit Aqua はだいぶ前に deprecated になりました)
以下で必要なパッケージをインストールします。今回は fork 版に簡易 cuQuantum 対応を行ったものを使います。以前も作ったことがあったのですが、少しだけ実装を拡張してタグ「cuquantum-0.2」として、
gate_u
に対応 (今回の記事で試したコードで必要なケースがあった)vqe
で cusv
(GPU) および numpy
(CPU) バックエンドでの動作をサポートとしました。元々 vqe
は blueqat 1.0.4 の動作を前提にしたような実装になっているみたいなのですが、blueqat 2.0.0 リリースの際にバックエンドのデフォルトが quimb
になったため、動かなくなっている場所があるように思いました。このため、GPU を使用しない場合には明示的に backend="numpy"
を指定しました。
Copy %%bash pip install git+https://github.com/derwind/Blueqat.git@cuquantum-0.2 pip install -U pip cuquantum-python cupy-cuda11x pip install matplotlib==3.2.2
後は書籍を眺めつつ淡々と blueqat の言葉で書き出していきます。ステップ数は 1 だと期待する結果が出ないことがあったので、2 にしています。
Copy from blueqat.pauli import qubo_bit as q from blueqat import vqe, Circuit from blueqat.pauli import X, Y hamiltonian = (q(0)+q(1)+q(2))**2+q(3)**2+(q(0)+q(1)+q(2))**2+q(0)**2+q(3)**2+(q(1)+q(2))**2+q(0)**2+q(3)**2+(q(1)+q(2)+q(3))**2 step = 2 mixer = 0.5*X[0]*X[1] + 0.5*Y[0]*Y[1] + 0.5*X[2]*X[3] + 0.5*Y[2]*Y[3] init = Circuit(4).h[0].cx[0, 1].x[0].h[2].cx[2, 3].x[2] result = vqe.Vqe(vqe.QaoaAnsatz(hamiltonian, step, init, mixer)).run() result.most_common(10)
(((1, 0, 0, 1), 0.8891627994443914),
((0, 1, 0, 1), 0.08207119568610725),
((1, 0, 1, 0), 0.020402585378244083),
((0, 1, 1, 0), 0.008363419491253656),
((1, 1, 0, 1), 4.1754889062439876e-32),
((1, 0, 1, 1), 1.7923185544953714e-32),
((1, 0, 0, 0), 8.485047362653501e-33),
((0, 0, 0, 1), 6.0474055160629805e-33),
((1, 1, 1, 0), 3.2704942350724783e-33),
((0, 0, 1, 0), 1.6202030750286995e-33))
となりました。ゼロからQAOAを説明してみる。~基本原理からblueqat実行まで~ で量子熊さんが素晴らしい可視化関数を実装されているので拝借して可視化してみます。
Copy import matplotlib.pyplot as plt import numpy as np %matplotlib inline def myplot_histogram(result,n): probs = np.array(list(result.probs.values())) ## z方向に射影測定した時に得られる可能性があるビット列 z_basis = [format(i,"b").zfill(n) for i in range(probs.size)] plt.figure(figsize=(20, 10)) plt.xlabel("states") plt.ylabel("probability(%)") plt.bar(z_basis, probs*100) plt.show() myplot_histogram(result, 10)
「1001」になって欲しかったので良い結果かと思います。ただ、毎回このようになるとは限らず多少揺らぐようです。
因みに上記だと問題のサイズが小さいようで、cuQuantum を使用するとかえって遅くなりましたが、試したい場合は以下のようにします:
Copy ... # vqe.Vqe の引数で「use_gpu=True」をわたす。 result = vqe.Vqe(vqe.QaoaAnsatz(hamiltonian, step, init, mixer), use_gpu=True).run() ...
結果は似たようなものだったので、一応使えてそうと思います。続いて本格的に cuQuantum を使ってみたいと思います。
QAOA について調べていたところ、blueqatでXYミキサーを用いた制約付きQAOA という記事を見つけました。
> 補助量子ビット含めた24量子ビットで実行するとかなり時間がかかり、1晩寝て起きたら終わってました。
> (むしろ実行不可能なのではと思ってましたがいけました)
と書いてあります。Colab 上でメソッド呼び出しを見ていると、numpy バックエンドで時間発展を計算する部分が重そうに見えました。ということで、cuQuantum の出番かなと思います。
Qiita の記事では多少端折られていますが、以下程度を import すれば動作すると思います。
Copy from blueqat import Circuit from blueqat.pauli import X, Y, Z, I import numpy as np from blueqat import vqe
そして Qiita 記事をひたすらコピペしていきます。先程触れたように以下の箇所だけ use_gpu=True
とします。
Copy step = 2 result = vqe.Vqe(vqe.QaoaAnsatz(h, step, Xinit, XYmixer), use_gpu=True).run()
最後に上位30個についてコスト関数を計算すると、
Copy ... states = result.most_common(30) for i in range(len(states)): state = states[i][0] print(state, cost_func(state, Edges))
(0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1) 0
(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 0
(0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1) 0
(0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1) 0
(0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 0
(0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 0
(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 0
(0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 0
(1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1) 0
(1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1) 0
(0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 0
(0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1) 0
(0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1) 1
(0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1) 1
(0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) 1
(0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1) 1
(1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1) 1
となりました。結果に幾らかの揺らぎはあったのですが、綺麗め (?) の結果を貼り付けてみました。
ちなみに気になる「1晩寝て起きたら」のところですが、vqe.Vqe.run
の実行は約 3 分で完了します。何回か試しましたがそれくらいでした。most_common
も初回実行 (?) だと少し時間がかかりましたが、いずれにせよこの辺の処理は併せても数分といったところでした。
何か新しい概念を勉強する上で触って動かせるコードがあると有難いものです。しかし、それが実行に物凄い時間がかかるとなると気楽さが失われます。何とか最小限の手間で快適な勉強環境を構築してみようとしました。いまのところうまく行っていそうに見えるので、引き続き色々試して感覚を養ってみたいと思います。
・・・とは言え、突貫工事で機能拡張をしており、網羅的な動作チェックがまったくできておりませんので、バグってたらすみません。
© 2024, blueqat Inc. All rights reserved