こんにちは!キャスレーコンサルティングの松永です。

AIエンジンの移設・構築業務を行っており、クラウド上で動くECS系コンテナの中でGPUで、計算を行うAIバッチの移設を担当しています。

今回はその知識を用いて、機械学習系の環境でよく使うCUDAの公式ライブラリに対応した量子計算モジュールBlueqatのエミュレータ機能の紹介と、その挙動の確認を行いたいと思います。

以下の順番で話を進めます。

量子計算モジュール関連の事前知識 を共有します。
②環境の準備が必要なので、量子計算モジュールの環境を作ります。
③実際に量子計算モジュールBluequatを用いて計算 を行います。

本ブログは、2回構成となります。
次回は、Blueqatを用いて応用をしていきます。

量子計算モジュール関連の事前知識

量子計算とは?

まず世の中に、データをプログラムとしてアプリを起動し、データを処理するという完結性を持つチューリング完全と呼ばれる論理モデルをもつコンピュータが考え出されました。
今の世の中の一般的なコンピュータです。

これを、物理的対象としてとらえる英米の科学者が出てきました。
「PC画面の中のバーチャルな世界は、量としては熱を発したりエネルギーを使う、現実世界の続きの物理の対象ですよ」ということです。

現実世界の続きならば、トランジスタの切り替えを使って実現した回路に、量子の性質を組み込めば色々ともっとお得で高性能な計算が出来そうだというのが、量子コンピュータのアイデアの取り組みのきっかけです。

量子は観察するまでその性質が決まっておらず、性質は確率でしかわかりません
その状態は重ね合わせ状態です。

デジタルなBit(量子ビットはQBitといいます)として理解する場合、0と1という2進数の結果だけを期待します。(確率なので本当はもっといろいろな結果が出ますが、閾値を50%にします)

今のコンピュータが得意なのは、分岐と繰り返しを駆使するしらみつぶし法という方法で、条件に合っているかどうかを候補の数だけ条件にぶつけて結果を出します。

その処理がものすごく速いので、たいてい良い結果が得られます。
が、計算の対象によっては、条件が多すぎで出来ないものもかなりあります。

量子計算だと、QBitの状態が重ね合わせ状態であるため、そこに希望の制約を与えることで、1つ1つを試す前に答えが出ます。QBitに1以上という条件を付ければ、0と1を条件に問う前に1が最初から決まります。これが量子計算です。

条件が簡単すぎると何の意味があるかよくわかりませんが、これが既存のコンピュータと量子コンピュータの大きな原理の違いです。

量子計算器の実用

量子計算器は、初期の研究者の多くがIBMに勤めていたので、伝統的にIBMで行われてきました。
現在はIBM Qというシステムに成果が引き継がれています。

イオントラップ方式といって量子である何かの原子を荷電の状態にして1つ1つ取り扱うことができる方法を考案し、量子ゲート方式というハードウェアを作りました。

近年、D-wave社が量子アニーリング方式で組み合わせ最適化問題に特化した量子計算器を売出し、話題となりました。

量子アニーリングは開発者が日本の先生なので、検索すると情報がたくさんあります。
アニーリング方式は、ゲート方式の一部なため、最近ではまたゲート方式の研究が盛んです。

量子計算器は、重ね合わせ状態を維持するために不安定でよくエラーが発生します。
そのため、一部の計算結果を今のコンピュータとつなげて計算するNISQ(Noisy Intermediate-Scale Quantum Computer) が実用化されています。
また、計算能力もQBitの数が今よりずっと多く扱えないと、スパコンの性能を超えることができません

そこで現在は、将来量子計算器がより高性能化した時のために、将来を見据えて、計算したいアルゴリズムや、計算に最適なプログラム用ライブラリの研究も並行して行われています。

このブログで扱う量子計算モジュールBlueqatは、日本製の量子計算プログラム用ライブラリのモデルです。
python製のモジュールとなります。
量子計算器のコーディングは、pythonが先行しています。
実際に量子を用いて計算をすることもできます。

ライブラリ公開後、実用化されているクラウド経由の量子計算器(例えばD-waveのLeap2、MSのAzure Quantum、AmazonのAmazon Braket)に接続する拡張がオープンソース形式で徐々に追加されて行っており、遠隔から量子計算器に接続できるようになりました。

また、注目すべきは、スパコンがなくても最近のGPUを使って小さな計算モデルを解くことができるという点です。
このブログでは、クラウドを使って量子計算器に接続するのでなく、このエミュレータを使います。

量子計算モジュールBlueqat

Blueqatはどのように作られているのでしょうか?
研究と起業が織りなす領域では、まず体制を調べることが重要です。

Blueqatは、SBIインベストメントなどが出資するMDR株式会社というベンチャー企業が作っています。
東大系のベンチャーで2020年初頭に本郷と丸の内に所在があります。

社員はほぼリモートで、ウェブ上に会社本体があるようです。
シリコンバレーにあってもおかしくないほど情報提供がオープンで、検索するとかなり情報があります。
Githubでモジュールをオープンソースで提供し、最適化問題を解くアルゴリズムなどのコンサルをしている会社です。

MDR株式会社(現在、Blueqatの公式ページになっています)
GitHub Blueqat

情報提供用:
 Slack
 YouTube

Blueqatは、上記のMDR社が開発する国産の量子計算機エミュレータですが、量子計算機エミュレータは実はどれもそれほど大きく違わず、書き方や記号もほぼ同じです。
Blueqatはコミュニティや資料がかなり豊富なので、身に着けるには非常に良い環境が整っています。

量子計算エミュレータの環境

まず初めに、GPUを使うので、GPUを準備します。

GPUではCUDAというミドルウェアを使うのですが、界隈の人でないとエンジニアでも知らないことがあるため補足します。

CUDAについて

CUDAの調査が、このライブラリとの出会いのきっかけだったので少し解説します。

C++風の統合開発環境とライブラリの集まりです。
NVIDIAのハードウェアでしか使えません

ですが、GPGPU(汎用のGPUのこと)のほぼデファクトスタンダートであるため、存在がよく知られています。
GPUを任意の計算で使用するためには、ハードウェアとドライバソフトのほかに、このライブラリがないと動きません。

ドライバを入れた後はアプリを入れれば動くアプリが多い気がしますが、開発ではミドルウェアなどもあります。
CUDAは、GPU計算と別にCUDAを使ったCPUエミュレート機能などもあります。
統合開発環境やミドルウェアのような機能をするCUDAは、より具体的な処理を速くするためにライブラリを入れることもあり、例えばDeepLearningでは、cuDNNを追加で使います。

CUDAがしていること

最近のプログラミング言語の中には、ハードウェアのコアに応じて処理を分けたり、コアごとに並列に処理を書けるものがあります。並列に行う処理を書くとわかることですが、メモリの管理がかなり厄介です。

CPUではせいぜい10数個のコアですが、GPUにはコアが数千数万とあり、そのメモリを考え最適化された処理を行うためにCUDAを使っています。

CUDAがあれば、あるソースの書き方1つで、抽象的に処理を行うことができます。
(後程、pythonを使って、配列の行列をNumpyからCupyに書き換え、同時に処理をCPUからGPUに切り替えて、行列計算を高速化する例をおみせします)

GPU環境の準備

というわけで、CUDAを入れてGPUを動かしたいのですが、GPUで高速なものはそれなりに高価です。
また、GPUを用意してもCUDAがすんなり入るとは限りません。
近年、CUDAは高頻度で更新され、実務ではVersionの一致や更新にかなり神経を使います。
またCUDAのファイルサイズがかなり大きいです。

そういった場合に、手軽にGPU環境を利用する方法としてGoogle colaboratory(以下colab)があります。
これは、機械学習の開発でよく使うpythonエディタJupyterNotebookのウェブサービス版です。

Google colaboratoryは、GoogleDriveの中にファイルを保存し、そのファイルをcolabで開き使います。
開くと最大12時間使えるGoogleのサーバの中にあるインスタンスが起動します。
そのインスタンスはpython3系がセットアップ済みのため、公式パッケージ管理のpipやAnacondaも使用可能です。

colabでは、CPUと同時にGPUとTPUも使えます。
GPUは、NVIDIAの K80 です。
TPUは専用目的ハードウェアのことで、GPUやFPGAよりさらに高速化します。

Google colaboratoryの初期化

Google colaboratoryの動作確認を行うために初期化します。

colabは、連続使用時間が12時間とあるので長い学習には不向きです。
機械学習では、学習処理に長い時間がかかることがよくあります。
これにcolabを使うには、12時間のリミットで学習を一時停止するなどテクニックがいりますが、できているモデルを試すことや、コードの処理をデバッグしたり確認するのに最も向いています。

その用途で使う場合、巨大な数十ギガバイトあるモデルファイルをGoogleDriveに配置する必要があります。
場合によっては、細いローカル回線を使うのではなく、目的ファイルを直接GoogleDriveに取得させ、そのファイルをcolabのインスタンスにマウントする方法なども検索すると出てきます。

まずここでは、CUDAの確認を行い、簡単にcolabを使ってみようと思います。

①Google Driveの新規追加→アプリを追加よりcolabを追加します。

②新規追加されたアプリを開くと以下の画面が出ます。
 (ここ数か月で、新画面バージョンが出ていますので、そちらが出た場合はそちらをお使いください。機能はさほど変わりません)

image.1 Google colab 画面

③ランタイム →ランタイムタイプの変更 →GPU を押します。

!nvcc -V でCUDAバージョン確認。
 !を付けるときは、端末にLinuxコマンドを打つ時に使います。
 つまり、普通のインスタンス上のLinux操作はすべて!を付けます。そして ▶ を押します。
 !nvidia-smiを実行。
 これは、CUDAの利用状況を確認するとき(どれだけコアを使う、メモリを使うなど)に使います。

image.2 CUDA利用環境確認

!dpkg -l | grep "cudnn"で、CUDAのML拡張ライブラリであるcuDNNがインストールされていることも確認しておきます。

image.3 cuDNN使用状況

エンジニアとしてはいろいろ環境が気になります。以下にまとめて表示します。

image.4 各種確認

pip listで使える関連ライブラリを確認します。ちなみに、apt-getなども使えます。

image.5 pythonライブラリの確認

過不足なく何でも使えるという感じです。
機械学習でよく使うPandas、Numpy、Cupy、OpenCV、Chainer、Keras、Tensorflow、Pytorchなども確認できました。

!pip install Blueqatを実行し、今回試すBlueqatを入れます。
ここではBlueqat 0.3.13がインストールされました。

これで、とりあえずGPUを動かす準備は整いました。

Google colaboratoryを試す

準備体操として、機械学習の前処理でよくやる動作確認を行います。
以下では、よく使う前処理やモデルデータを使って性能を確認し、本題のBlueqatを試しに行きます。

負荷のかかる処理とファイルのアップロード

まず、負荷のかかる処理を想定し、動画の静止画切り出しを行います。

apt update
apt -y upgrade
apt install ffmpeg

そして、ffmpegをインストール後、画像の最初のコマンドでcolabインスタンスにPCから、3.6メガのmp4である長さ13秒の動画を置きます。

そのほか、GoogleDriveにアップした動画を読ませることもできます。非常に速く2秒程度でした。

image.6 ffmpegの操作

よく使う処理でテスト

ここでは、機械学習の初期によく使うscikit-learnを試します。
このライブラリは、分類/回帰/クラスタリングなどのデータ分析でよく使います。

ボストン市の住宅価格のデモデータを回帰分析することで、scikit-learnの将来予測の精度を確認します。
Google公式にありましたので、その一部を行いました。

image.7 scikit-learnの操作

画像処理でよく使うcv2なども、画像の表示に工夫が必要でしたが問題なく動作しました。

Cupy Numpy比較

Cupyは、Preferred Networks社(以下PFN)のChainerより分岐したGPU用のモジュールで、CUDAを使って、特に機械学習でよく使う行列を高速で計算できます。

簡単に試してみます。

#
n = 10000

#numpyの計算開始時刻
t1 = time.time()
#numpyによる10000 * 10000 の値が0.0以上、1.0未満の行列の生成
a = np.random.rand(n,n)
b = np.random.rand(n,n)

#行列積の計算
np.dot(a,b)

#numpyの計算終了時刻、cupyの計算開始時刻
t2 = time.time()
#cmpyによる10000 * 10000 の値が0.0以上、1.0未満の行列の生成
a = cp.random.rand(n,n)
b = cp.random.rand(n,n)

#行列積の計算
cp.dot(a,b)

#cupyの計算終了時刻
t3 = time.time()

print ('numpyの計算に要した秒数:',t2-t1)
print ('cupyの計算に要した秒数:',t3-t2)
#

実際が以下となります。
一番下が結果です。

行列計算は、GPU、CUDA、Cupyがなければもう始まらないレベルでGPUが速いです。
(ソースを試す場合、Cupyは2回試してみてください。また、すべてのNumpyの計算がまだCupyで使えるわけではない点は注意です)

image8. Numpy Cupy 比較

一通りのことを確認できたので、ここからBlueqatの動作確認を行います。

量子計算モジュールBluequatを用いた計算

ここではとりあえず、Bluequatの使い方の基本を概観して、Bluequatの通常の量子エミュレート計算と、NVIDIAのライブラリQgateのCPUモードで動かし、最後にCUDAで動かしてみます。

Bluequatは実は情報提供が豊富なため、基本動作はすでにcolab上で動くモデルがあります。
ざっと確認します。

ゲート型量子コンピュータでは1QBitに対し、確率的な状態を作り出すHゲート(アダマールゲート)操作があります。1bitは古典的な1か0の状態が取れますが、この状態を量子計算では、球の軸の上の頂点と下の頂点として表します。上の頂点が0、下の頂点が1です。(ブロッホ球といいます)

頂点以外の球の表出する表面部分が、確率的にはどこも出現する可能性のある点と仮定ができます。
先ほど紹介したHゲートの操作を行うと、ゲートは、この球の軌道部分の確率を出します。
ここが出力される可能性は、約0.5と-0.5の確率的な値が出現することを意味しています。

ゲート操作は、このブロッホ球の状態を変更する操作ともいえます。
ブロッホ球は、量子の状態を球の角度として表すことのできる概念的なモデルとして理解できます。

例えば、上の頂点の0QBitにある0番目のゲートを、古典的な1に変更する場合、180°角度を変更し、逆の頂点1に移動します。

頂点1にある状態のゲートに対して、Hゲート処理を行うと、90°角度が変更され、軌道部分に移動し、-の確率的な状態に変化します。

この角度操作をNISQというハイブリッド型の量子コンピュータではよく使い、一度終わった短い量子計算を古典コンピュータで別角度を与え再計算を行うことを繰り返します。

Blueqatの使い方の詳細は次回となりますが、ここでは基本だけ確認します。
Blueqatは先ほどインストール方法は書きましたので、以下だけ追加します。

#
from blueqat import Circuit
Circuit(20).h[:].m[:].run(shots=100)
#   

上記の2行目は、20量子ビットの計算を意味しています。
ここが重要なので解説します。

以下の図を見てください。

image.9 量子ビットの基本

古典コンピュータでは、1bitは、0か1の状態しかありません。1QBitで同じことをするのは、パウリゲートの1つであるXとあるXゲートです。
Xゲートに0を与えると1になり、1を与えると0になります。

これは、古典的な動きをするので、例えばRGBを表したりできますし、4,8,16,32,64という単位で使えば、汎用コンピュータの計算処理となりえます。

重要なのはHと書かれているアダマールゲートです。
Hゲートは測定が行われるまで確定しておらず、観測行為によって確率的に0か1のどちらかを返します。

先ほどの、コードをもう一度見てみます。

#
Circuit(20).h[:].m[:].run(shots=100)
#

これは、Circuit()によって初期化し、20個のQBitで計算を行い、h[]のアダマールゲートで全部のQBitについて、m[]で観測を行い、.runでコードを実行するという意味をなし、その計算をshots=100で100回繰り返すということを意味しています。

アダマールゲートは、0と1の重ね合わせの状態を場合の数だけ持っていることができ、そのアダマールゲートが20個ある状態です。
上記の計算では、もつれなどを使わなければ、重ね合わせ状態にあるQBitの場合の数をすべて出力するという意味の計算をすることになります。
「もつれ」とは量子エンタングルメントのことで、量子コンピューターでは、結果の数を絞る操作に用います。

Blueqatの本題の計算は別の回に行うことにして、今回はその基本的な重ね合わせ状態の場合の数を全部計算するのに、通常の計算とGPUライブラリと、CUDAを使った計算の比較でベンチマークをとることにします。

ちなみにZゲートというのは、重ね合わせ状態をエミュレータで観察した状態ベクトルにも、+-があり、それを逆転させるゲートです。
ここでは説明を省略します。

ベンチマークは以下のコードで行います。
ちなみに、以下はMDRの社長が自ら行った記事の抜粋です。

#
#
from blueqat import Circuit
import time

#GPUエミュレータ関連
!wget https://github.com/shinmorino/qgate/raw/gh-pages/packages/0.2/qgate-0.2.1-cp36-cp36m-manylinux1_x86_64.whl
!pip install qgate-0.2.1-cp36-cp36m-manylinux1_x86_64.whl blueqat

#通常コード
start = time.time()
Circuit(20).h[:].m[:].run(shots=100)
end = time.time()
print(end - start)

#QgateのCPUモード
start = time.time()
Circuit(20).h[:].m[:].run(backend='qgate',shots=100)
end = time.time()
print(end - start)

#QgateのGPUモード
start = time.time()
Circuit(20).h[:].m[:].run(backend='qgate', runtime='cuda', shots=100)
end = time.time()
print(end - start)
#
#

結果は以下のようになりました。
下の赤線部分です。

やはり、GPUマシンのほうが圧倒的に速いことがわかります。

image.10 Blueqat用のCUDAライブラリを使った場合とつかわない場合の比較

前半のまとめ

最後に前半のまとめとして、Blueqatなど量子計算モジュールが直近どのようなことに役立つかを概観しておきます。

2020年現在、実現しているQBitコンピュータは100QBit程度です。
これが2025年までに100~2000を目指すといわれています。

さらに、エラーが発生しやすいマシンの改良も同時に必要です。
現在のNISQ(量子ハイブリッド計算機)は、短い量子ゲートしか繋げられないため、複雑な計算ができなければ、実用に供しません。

現状のQBit計算をBlueqatで行うとCircuit(50)です。
これは、まだまだGPUでもCPUでも出せる速度です。

現在でも特殊な問題では、50QBitがスパコンの最高性能と同じくらいだそうです。
しかし、多くのスパコンの課題を解くためには、2000QBitほどが望ましいと言われています。
その程度になると、Circuit(2000)はGPUでなく、量子計算機に接続する必要があります。

また、Blueqatなど量子計算エミュレータが現在期待されていることに、機械学習との融合があります
機械学習の行列計算などを組み合わせ最適化によって合理化し速くしたいという要望があります。
しかし、現在のところ機械学習がなんでも速くなるわけではなく、分類問題の中にある生成モデルという学習には高速化の余地があると目されている程度です。
ただし、2015年の論文の実用化なのでもっと良い理論があるかもしれません。

現在でも、例えば写真をゴッホ調に出力するとか、猫と犬をコンピュータが自分で学んでその特徴をデータとして抽出するといったことはできています。
またこれは、あるAIエンジンの学習の結果を受けて別のエンジンがデータをさらに高度化し、それを繰り返すことで精度を高める敵対的生成ネットワークに応用することができます。

これらは、機械学習の中でも高度な業務です。

生成モデルに対しては、量子コンピュータのボルンマシン(量子アニーリング方式の場合、ボルツマンマシン)というモデルを使うそうですが、エンジニアが具体的に使うものとして、Tensor-Flow Quantumがリリースされています。
Tensor-Flow Quantumは、現状の量子計算との融合部分を組み込んだモデルのようです。

繰り返しになりますが、量子計算機は現在のNISQではパズルを解くようなこと、しかもCPUやGPUでもできるようなことしかできません。
しかし、将来その使い方を覚えておくと、計算機科学のアカデミズムが大衆化するといった変化が起こるように思います。

長くなりましたが、最後までお読みいただきましてありがとうございました。

次回は、Blueqatの応用編となります。
次回の2回目のブログもよろしくお願いします。

Daichi Matsunaga
CSVIT事業部 IT(インテグレーションテック)部 Daichi Matsunaga
お役に立てれば幸いです