ホーム/ブログ/PennyLane で VQE を構築する: 実践ガイド
VQEPennyLaneAlgorithmsQML

PennyLane で VQE を構築する: 実践ガイド

PennyLane を用いた変分量子固有値ソルバーのステップバイステップ実装 — ハミルトニアンの設定から古典的最適化ループまで。

FreeQuantumComputing
·· 9 min read

変分量子固有値ソルバー (VQE) は、最も重要な近未来の量子アルゴリズムの一つです。これは分子や材料の基底状態エネルギーを求めます — この計算は古典コンピュータにとっては指数的に困難ですが、NISQ デバイス上では扱うことができます。本ガイドでは、PennyLane による完全な VQE 実装を順を追って解説します。

VQE が行うこと

VQE はハミルトニアン H (通常は分子のエネルギーを表す) の最小固有値を求めます。その仕組みは次の通りです:

  1. 量子回路を用いてパラメータ化された試行状態 |ψ(θ)⟩ を準備する
  2. QPU 上で期待値 ⟨ψ(θ)|H|ψ(θ)⟩ を測定する
  3. 古典的最適化器を用いてエネルギーを最小化するように θ を更新する
  4. 収束するまで繰り返す

変分原理により、任意の状態に対して ⟨ψ(θ)|H|ψ(θ)⟩ ≥ E₀ が保証されます — したがってこの量を最小化することで、真の基底状態エネルギー E₀ の上界が得られます。

セットアップ

PennyLane を化学プラグインとともにインストールします:

pip install pennylane pennylane-qchem

水素分子 (H₂) — 古典的な VQE ベンチマーク — では、2 個の電子と 4 個のスピン軌道 (4 量子ビット) が必要です:

import pennylane as qml
from pennylane import numpy as np
import pennylane.qchem as qchem

# H2 at equilibrium bond length (Angstrom)
symbols = ["H", "H"]
coordinates = np.array([[0.0, 0.0, -0.6614], [0.0, 0.0, 0.6614]])

# Build the qubit Hamiltonian
H, qubits = qchem.molecular_hamiltonian(
    symbols,
    coordinates,
    basis="sto-3g"
)
print(f"Hamiltonian: {len(H.ops)} terms, {qubits} qubits")
# Hamiltonian: 15 terms, 4 qubits

アンザッツの定義

アンザッツ とは、試行状態を準備するパラメータ化された回路のことです。化学問題では、UCCSD (Unitary Coupled-Cluster Singles and Doubles) アンザッツが標準的に用いられます:

# Get UCCSD circuit parameters
electrons = 2
singles, doubles = qchem.excitations(electrons, qubits)
s_wires, d_wires = qchem.excitations_to_wires(singles, doubles, wires=range(qubits))

# Initial Hartree-Fock state (reference state)
hf_state = qchem.hf_state(electrons, qubits)

dev = qml.device("default.qubit", wires=qubits)

@qml.qnode(dev)
def circuit(weights, wires, s_wires=[], d_wires=[], hf_state=hf_state):
    # Prepare HF reference state
    qml.BasisState(hf_state, wires=wires)

    # Apply UCCSD excitations
    qml.UCCSD(weights, wires, s_wires=s_wires, d_wires=d_wires, init_state=hf_state)

    return qml.expval(H)

VQE 最適化の実行

PennyLane の自動微分を用いれば、勾配ベースの最適化器を直接使用できます:

# Initial parameters (all zeros = Hartree-Fock state)
init_params = np.zeros(len(singles) + len(doubles), requires_grad=True)

# Adam optimizer (works well for VQE)
opt = qml.AdamOptimizer(stepsize=0.4)

# Optimization loop
energy_history = []
params = init_params.copy()

for step in range(200):
    params, energy = opt.step_and_cost(
        lambda p: circuit(p, range(qubits), s_wires=s_wires, d_wires=d_wires),
        params
    )
    energy_history.append(energy)

    if step % 20 == 0:
        print(f"Step {step:3d}: E = {energy:.6f} Ha")

print(f"\nVQE ground state energy: {energy:.6f} Ha")
print(f"Reference (exact): -1.136189 Ha")

典型的な出力:

Step   0: E = -1.117498 Ha
Step  20: E = -1.133254 Ha
Step  40: E = -1.135901 Ha
Step  60: E = -1.136140 Ha
...
VQE ground state energy: -1.136174 Ha
Reference (exact): -1.136189 Ha

VQE は正確なエネルギーの約 0.015 mHa 以内に到達します — H₂ における化学的精度です。

勾配フリー最適化器の使用

ノイズのあるハードウェアでは、ハードウェアの勾配がノイジーであるため、COBYLA や SPSA のような勾配フリー最適化器がしばしば有利です:

from scipy.optimize import minimize

# Objective function (no gradient needed)
def objective(params):
    return float(circuit(params, range(qubits), s_wires=s_wires, d_wires=d_wires))

result = minimize(
    objective,
    x0=init_params,
    method="COBYLA",
    options={"maxiter": 500, "rhobeg": 0.1}
)

print(f"COBYLA energy: {result.fun:.6f} Ha")

HLQuantum で VQE を実行する

HLQuantum には、すべてのバックエンドで動作する組み込みの VQE 実装が含まれています:

import hlquantum as hlq

# Define the Hamiltonian in HLQuantum's format
H = hlq.hamiltonians.h2_molecule(bond_length=1.32)

# Run VQE on any backend
result = hlq.algorithms.vqe(
    hamiltonian=H,
    ansatz="uccsd",
    optimizer="adam",
    max_iterations=200,
    backend="pennylane",   # or "qiskit", "cudaq"
)

print(f"Ground state energy: {result.energy:.6f} Ha")
print(f"Optimal parameters: {result.params}")
print(f"Converged in {result.iterations} iterations")

実機ハードウェア向けのヒント

実際の QPU (IBM Quantum、IonQ) 上で VQE を実行する際には、いくつかの追加的な考慮事項があります:

ステップあたりのショット数を減らす。 最適化ステップあたり 1000 ショットあれば、通常は勾配推定に十分です。毎ステップで 10,000 ショットを使うのはやめましょう — QPU の時間を浪費します。

浅い回路から始める。 CNOT ゲートが少ないほど、ノイズも少なくなります。ハードウェアでは、UCCSD ではなくハードウェア効率的なアンザッツ回路を検討しましょう。

エラー緩和を有効にする。 HLQuantum の error_mitigation="zne" はゼロノイズ外挿 (Zero Noise Extrapolation) を適用し、ノイズのあるハードウェア上で結果を大幅に改善できます:

result = hlq.run(vqe_circuit, backend="qiskit", device="ibm_sherbrooke",
                 error_mitigation="zne", shots=2048)

量子化学シミュレーションの詳細については、完全な PennyLane guideHLQuantum algorithms reference をご覧ください。