होम/ब्लॉग/PennyLane के साथ VQE बनाना: एक व्यावहारिक मार्गदर्शिका
VQEPennyLaneAlgorithmsQML

PennyLane के साथ VQE बनाना: एक व्यावहारिक मार्गदर्शिका

PennyLane का उपयोग करते हुए Variational Quantum Eigensolver का चरण-दर-चरण कार्यान्वयन — Hamiltonian सेटअप से लेकर classical optimization loop तक।

FreeQuantumComputing
·· 9 min read

Variational Quantum Eigensolver (VQE) सबसे महत्वपूर्ण near-term क्वांटम एल्गोरिदम में से एक है। यह किसी अणु या पदार्थ की ground state ऊर्जा ज्ञात करता है — एक ऐसी गणना जो classical कंप्यूटरों के लिए exponentially कठिन है लेकिन NISQ उपकरणों पर साध्य है। यह मार्गदर्शिका एक संपूर्ण PennyLane VQE कार्यान्वयन के माध्यम से आपको ले जाती है।

VQE क्या करता है

VQE किसी Hamiltonian H (आमतौर पर किसी अणु की ऊर्जा को दर्शाने वाला) के न्यूनतम eigenvalue को ज्ञात करता है। यह इस प्रकार काम करता है:

  1. एक क्वांटम circuit का उपयोग करके एक parameterized trial state |ψ(θ)⟩ तैयार करना
  2. QPU पर expectation value ⟨ψ(θ)|H|ψ(θ)⟩ को मापना
  3. ऊर्जा को कम करने के लिए θ को अद्यतन करने हेतु एक classical optimizer का उपयोग करना
  4. convergence तक दोहराना

variational सिद्धांत किसी भी state के लिए ⟨ψ(θ)|H|ψ(θ)⟩ ≥ E₀ की गारंटी देता है — इसलिए इस राशि को कम करने से वास्तविक ground state ऊर्जा E₀ पर एक ऊपरी सीमा (upper bound) प्राप्त होती है।

सेटअप करना

PennyLane को इसके chemistry plugin के साथ इंस्टॉल करें:

pip install pennylane pennylane-qchem

हाइड्रोजन अणु (H₂) के लिए — क्लासिक VQE benchmark — हमें दो इलेक्ट्रॉन और चार spin-orbitals (4 qubits) की आवश्यकता होती है:

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

Ansatz को परिभाषित करना

ansatz वह parameterized circuit है जो trial state तैयार करता है। chemistry समस्याओं के लिए, UCCSD (Unitary Coupled-Cluster Singles and Doubles) ansatz मानक है:

# 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 Optimization चलाना

PennyLane के automatic differentiation के साथ, हम सीधे gradient-based optimizers का उपयोग कर सकते हैं:

# 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")

सामान्य output:

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₂ के लिए chemical accuracy।

एक Gradient-Free Optimizer का उपयोग करना

noisy हार्डवेयर के लिए, COBYLA या SPSA जैसे gradient-free optimizers अक्सर बेहतर होते हैं क्योंकि हार्डवेयर gradients noisy होते हैं:

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 कार्यान्वयन शामिल है जो सभी backends में काम करता है:

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")

वास्तविक हार्डवेयर के लिए सुझाव

वास्तविक QPUs (IBM Quantum, IonQ) पर VQE चलाते समय, कई अतिरिक्त बातों पर विचार करना पड़ता है:

प्रति step कम shots का उपयोग करें। प्रति optimization step 1000 shots आमतौर पर gradient अनुमान के लिए पर्याप्त होते हैं। हर step पर 10,000 shots का उपयोग न करें — यह QPU समय बर्बाद करता है।

shallow circuits से शुरू करें। कम CNOT गेट = कम noise। हार्डवेयर के लिए, UCCSD के बजाय hardware-efficient ansatz circuits पर विचार करें।

error mitigation सक्षम करें। HLQuantum का error_mitigation="zne" Zero Noise Extrapolation लागू करता है, जो noisy हार्डवेयर पर परिणामों को उल्लेखनीय रूप से बेहतर बना सकता है:

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

क्वांटम chemistry simulations पर अधिक विवरण के लिए पूर्ण PennyLane guide और HLQuantum algorithms reference देखें।