量子コンピューティングのプロジェクトを始めるとき、避けて通れない問いがあります。回路をQiskitで直接記述すべきか、それともその上にあるHLQuantumの抽象化レイヤーを使うべきか。どちらも妥当な選択であり、正解はあなたが何を作ろうとしているかによって変わります。
この記事では、判断の助けとなるよう、具体的でコード中心の比較を提供します。
核心的な違い
Qiskit はIBMの量子SDKです。すべてのゲート、量子ビット、測定、コンパイルステップに対して直接的かつ精密な制御を提供します。IBMハードウェアをネイティブにターゲットとし、IBM固有のワークフローに対して最も深いエコシステムを備えています。
HLQuantum は、Qiskit、Cirq、PennyLane、Braket、CUDA-Q、IonQの上に位置する統一APIです。回路を一度記述すれば、指定したバックエンドへ変換してディスパッチします。低レベルの制御を一部犠牲にする代わりに、移植性とシンプルさを得られます。
並列比較: ベル状態
素のQiskit:
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
sim = AerSimulator()
result = sim.run(qc, shots=1000).result()
print(result.get_counts()) # {'00': 501, '11': 499}
HLQuantum:
import hlquantum as hlq
qc = hlq.Circuit(2)
qc.h(0).cx(0, 1).measure_all()
result = hlq.run(qc, backend='qiskit', shots=1000)
print(result.counts) # {'00': 501, '11': 499}
単一バックエンドであれば、記述量はほぼ同じです。違いが現れるのは、バックエンドを増やしたときです。
並列比較: 複数バックエンドでの実行
素のQiskit(2つ目のバックエンドを追加するには、書き直しが必要):
# Qiskit Aer
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
qc_qiskit = QuantumCircuit(2, 2)
qc_qiskit.h(0); qc_qiskit.cx(0, 1); qc_qiskit.measure_all()
result_qiskit = AerSimulator().run(qc_qiskit, shots=1000).result()
# PennyLane — 全く異なるAPI、回路を書き直す
import pennylane as qml
dev = qml.device('default.qubit', wires=2)
@qml.qnode(dev)
def bell():
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
return qml.probs(wires=[0, 1])
result_pennylane = bell()
# CUDA-Q — さらに別のAPI、また書き直す
import cudaq
@cudaq.kernel
def bell():
qvec = cudaq.qvector(2)
h(qvec[0]); cx(qvec[0], qvec[1]); mz(qvec)
result_cudaq = cudaq.sample(bell, shots_count=1000)
HLQuantum(1つの回路、任意のバックエンド):
import hlquantum as hlq
qc = hlq.Circuit(2)
qc.h(0).cx(0, 1).measure_all()
# 一語でバックエンドを切り替え
result_qiskit = hlq.run(qc, backend='qiskit')
result_pennylane = hlq.run(qc, backend='pennylane')
result_cudaq = hlq.run(qc, backend='cudaq') # GPU
result_cirq = hlq.run(qc, backend='cirq')
result_ionq = hlq.run(qc, backend='ionq', device='aria-1')
result_ibm = hlq.run(qc, backend='qiskit', device='ibm_sherbrooke')
ここでHLQuantumの真価が発揮されます。ローカルシミュレータでプロトタイプを作り、回路を書き直すことなくQPUへデプロイできるのです。
並列比較: VQE
素のQiskit VQE:
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.circuit.library import UCCSD
from qiskit_algorithms import VQE
from qiskit_algorithms.optimizers import COBYLA
from qiskit.primitives import Estimator
driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735')
problem = driver.run()
mapper = JordanWignerMapper()
hamiltonian = mapper.map(problem.second_q_ops()[0])
ansatz = UCCSD(
problem.num_spatial_orbitals,
problem.num_particles,
mapper,
initial_state=problem.reference_state,
)
vqe = VQE(Estimator(), ansatz, COBYLA())
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(f"H2 ground state: {result.eigenvalue.real:.4f} Ha")
HLQuantum VQE:
import hlquantum as hlq
result = hlq.algorithms.vqe(
molecule='H2',
basis='sto-3g',
backend='qiskit',
optimizer='COBYLA',
)
print(f"H2 ground state: {result.energy:.4f} Ha")
# GPUへ切り替え:
result_gpu = hlq.algorithms.vqe(molecule='H2', backend='cudaq')
素のQiskitは、ansatz、mapper、driverに対する完全な制御を与えてくれます。HLQuantumのワンライナーは、バックエンドを比較したり、素早く結果を得たりするのに最適です。一方、カスタムansatzやアルゴリズムのチューニングが必要な場合は素のQiskitのほうが優れています。
素のQiskitを使うべきとき
Qiskitを直接使うべきなのは、次のような場合です。
- IBMハードウェアのみをターゲットにしている — QiskitのトランスパイラとIBM Runtimeプリミティブは、IBMのQPU上で最高のパフォーマンスをもたらします。HLQuantumの抽象化はオーバーヘッドを追加します。
- きめ細かい回路制御が必要 — カスタムなゲート分解、特定のトランスパイラパス、パルスレベルの制御、途中測定を伴う動的回路など。
- IBMエコシステムでの研究を行っている —
qiskit-nature、qiskit-finance、qiskit-optimization、qiskit-machine-learningを使う場合。これらは素のQiskitと最も深く統合されています。 - パフォーマンスが重要 — 直接のQiskitコードは、HLQuantumの変換レイヤーよりオーバーヘッドが少なくなります。
- Qiskitエコシステムに貢献している — Qiskitが参照実装となるプラグイン、チュートリアル、研究論文を書く場合。
HLQuantumを使うべきとき
HLQuantumを使うべきなのは、次のような場合です。
- バックエンドの柔軟性が必要 — シミュレータの性能比較、異なるアーキテクチャでの回路ベンチマーク、あるいは複数のクラウドQPUへのアクセスなど。
- アルゴリズムのプロトタイプを作っている — 一度書けば、どこでもテストできます。ローカルシミュレーションからGPU、実機へと切り替えるときに回路を組み直す必要がありません。
- 教えている、または学んでいる — すべてのバックエンドで一貫した1つのAPIが学習を容易にします。6種類の異なるAPIを学ぶ必要はありません。
- 組み込みアルゴリズムを使いたい —
hlq.algorithms.vqe()、hlq.algorithms.qaoa()、hlq.algorithms.grover()が定型処理を引き受けてくれます。 - マルチバックエンドのアプリケーションを構築している — アプリが、待ち行列が最も短い、あるいはコストが最も低いQPU上で実行される必要がある場合、HLQuantumのディスパッチャがそれを処理します。
移行: Qiskit → HLQuantum
既存のQiskitコードがある場合、HLQuantumはQiskit回路を直接取り込むことができます。
import hlquantum as hlq
from qiskit import QuantumCircuit
# 既存のQiskit回路
qc = QuantumCircuit(3)
qc.h(0); qc.cx(0, 1); qc.cx(1, 2)
# ラップして任意のバックエンドで実行
result = hlq.run(hlq.from_qiskit(qc), backend='pennylane')
result_gpu = hlq.run(hlq.from_qiskit(qc), backend='cudaq')
書き直しは不要です。既存のQiskitコードに、HLQuantumのマルチバックエンド機能を段階的に追加できます。
判断チェックリスト
Starting a new project?
├── Need IBM-specific features (Qiskit Runtime, pulse control)? → Raw Qiskit
├── Need to run on multiple backends or compare performance? → HLQuantum
├── Learning quantum computing for the first time? → HLQuantum
└── Building a research paper targeting IBM hardware? → Raw Qiskit
Migrating existing Qiskit code?
├── Want to add GPU acceleration? → HLQuantum (from_qiskit + cudaq)
├── Want to try IonQ hardware? → HLQuantum (from_qiskit + ionq)
└── Want to stay IBM-only? → Stay with Qiskit
両者は互いに排他的なものではありません。多くのワークフローは、回路設計には素のQiskitで始め、その後マルチバックエンドのデプロイのためにHLQuantumでラップします。
始めましょう: HLQuantum guide · Qiskit SDK guide · Compare all SDKs