होम/ब्लॉग/वैरिएशनल क्वांटम एल्गोरिदम में अपने शॉट काउंट को 80% तक कैसे घटाएं
OptimizationVQEQAOAQPU

वैरिएशनल क्वांटम एल्गोरिदम में अपने शॉट काउंट को 80% तक कैसे घटाएं

VQE और QAOA में आवश्यक सर्किट निष्पादनों की संख्या घटाने की व्यावहारिक तकनीकें — शॉट-किफायती ऑप्टिमाइज़र, ग्रेडिएंट आकलन की तरकीबें, और मेज़रमेंट ग्रुपिंग।

FreeQuantumComputing
·· 8 min read

हर बार जब आप वास्तविक हार्डवेयर पर कोई क्वांटम सर्किट चलाते हैं, तो इसमें QPU समय और पैसा खर्च होता है। VQE और QAOA जैसे वैरिएशनल एल्गोरिदम को अभिसरित (converge) होने के लिए लाखों सर्किट निष्पादनों की आवश्यकता हो सकती है — क्लाउड QPU पर $0.075–$0.90 प्रति टास्क की दर से, यह तेज़ी से जुड़ता जाता है।

अच्छी खबर: अधिकांश डिफ़ॉल्ट कार्यान्वयन बेहद शॉट-अकुशल होते हैं। सही तकनीकों के साथ, आप परिणाम की गुणवत्ता से समझौता किए बिना शॉट आवश्यकताओं को 50–90% तक घटा सकते हैं।

शॉट काउंट डिफ़ॉल्ट रूप से इतने अधिक क्यों होते हैं

VQE पॉली ऑपरेटरों के प्रत्याशित मान (expectation values) की गणना करता है। एक हैमिल्टोनियन को पॉली पदों के योग में विघटित किया जाता है, और प्रत्येक पद के लिए एक अलग सर्किट निष्पादन की आवश्यकता होती है। H₂ (4 qubits) जैसे अणु के लिए, लगभग 15 पॉली पद होते हैं। बड़े अणुओं के लिए यह संख्या विस्फोटक रूप से बढ़ जाती है:

अणुQubitsपॉली पदनाइव शॉट्स/इटरेशन
H₂41515,000
LiH12631631,000
BeH₂14666666,000
H₂O141,0861,086,000

200 ऑप्टिमाइज़र इटरेशन के साथ, H₂O को नाइव तरीके से 217 मिलियन शॉट्स की आवश्यकता होती है। नीचे दी गई तकनीकें इसे 80–95% तक घटा देती हैं।

तकनीक 1: मेज़रमेंट ग्रुपिंग (सबसे बड़ी बचत)

कई पॉली पद कम्यूट करते हैं — उन्हें अलग-अलग के बजाय एक ही सर्किट निष्पादन में एक साथ मापा जा सकता है। कम्यूट करने वाले प्रेक्षणीयों (observables) को समूहित करना उपलब्ध सबसे बड़ी एकल कटौती है।

from qiskit.primitives import StatevectorEstimator
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_algorithms import VQE
from qiskit_algorithms.optimizers import COBYLA

# Qiskit automatically groups commuting Paulis in the Estimator primitive
# This reduces shots from O(n_terms) to O(n_groups) — often 5-10x reduction
estimator = StatevectorEstimator()

# With PennyLane, use grouping explicitly:
import pennylane as qml

H = qml.Hamiltonian(coeffs, observables)

# Group commuting terms — usually reduces term count by 5-10x
groups = qml.grouping.group_observables(observables, grouping_type='qwc')
print(f"Original terms: {len(observables)}, Groups: {len(groups)}")
# Original terms: 631, Groups: 68  (for LiH)

अपेक्षित बचत: 5–15× सामान्य रसायन विज्ञान हैमिल्टोनियन पर।

तकनीक 2: शॉट-किफायती ऑप्टिमाइज़र

L-BFGS-B या ADAM जैसे शास्त्रीय ऑप्टिमाइज़र शोर-रहित फ़ंक्शन मूल्यांकनों को मानकर चलते हैं — जब परिणाम शोरयुक्त होते हैं तब वे आवश्यकता से अधिक ग्रेडिएंट मूल्यांकनों का अनुरोध करते हैं। शॉट-किफायती ऑप्टिमाइज़र मेज़रमेंट प्रसरण (variance) के आधार पर शॉट्स को अनुकूली रूप से आवंटित करते हैं।

from pennylane.optimize import AdaptiveOptimizer, ShotAdaptiveOptimizer

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

@qml.qnode(dev)
def circuit(params):
    # ansatz
    ...
    return qml.expval(H)

# ShotAdaptiveOptimizer: allocates more shots to high-variance directions
opt = ShotAdaptiveOptimizer(min_shots=10)

params = np.random.uniform(-np.pi, np.pi, n_params)
for i in range(100):
    params, _, shots_used = opt.step_and_cost(circuit, params)
    print(f"Step {i}: shots used = {shots_used}")

ऑप्टिमाइज़र प्रति मूल्यांकन कम शॉट्स के साथ शुरू करता है और उन्हें केवल तभी बढ़ाता है जब ग्रेडिएंट अनिश्चित होता है। एक सामान्य VQE रन फिक्स्ड-शॉट COBYLA की तुलना में 5–10× कम शॉट्स का उपयोग करता है।

तकनीक 3: पैरामीटर-शिफ्ट ग्रेडिएंट (कम मूल्यांकनों का उपयोग करें)

नाइव फ़ाइनाइट-डिफरेंस ग्रेडिएंट आकलन (f(x+ε) - f(x))/ε में छोटे ε पर उच्च प्रसरण और बड़े ε पर बड़ा पूर्वाग्रह (bias) होता है। पैरामीटर-शिफ्ट नियम प्रति पैरामीटर केवल 2 सर्किट मूल्यांकनों के साथ सटीक ग्रेडिएंट देता है:

# PennyLane uses parameter-shift by default for gradients
@qml.qnode(dev, diff_method="parameter-shift")  # 2 evals per param
def circuit(params):
    ...

# Compare to finite-difference (requires 1 eval per param but biased):
@qml.qnode(dev, diff_method="finite-diff")  # 1 eval but approximate

# For large circuits, use "best" — PennyLane chooses adjoint on simulator,
# parameter-shift on hardware
@qml.qnode(dev, diff_method="best")
def circuit(params):
    ...

n पैरामीटरों के साथ, पैरामीटर-शिफ्ट को प्रति ग्रेडिएंट चरण 2n मूल्यांकनों की लागत आती है। जब n बड़ा हो तो ग्रेडिएंट-मुक्त ऑप्टिमाइज़र (COBYLA, SPSA, Nelder-Mead) का उपयोग करें।

तकनीक 4: SPSA — स्टोकैस्टिक ग्रेडिएंट आकलन

सिमल्टेनियस पर्टर्बेशन स्टोकैस्टिक अप्रोक्सिमेशन (SPSA) सभी पैरामीटरों को एक साथ पर्टर्ब करके, पैरामीटर संख्या की परवाह किए बिना, केवल 2 सर्किट मूल्यांकनों के साथ पूरे ग्रेडिएंट का आकलन करता है:

from qiskit_algorithms.optimizers import SPSA

# SPSA: 2 evaluations per step regardless of parameter count
# vs parameter-shift: 2n evaluations per step
optimizer = SPSA(maxiter=300, learning_rate=0.1, perturbation=0.05)

# For 10 parameters:
# - Parameter shift: 2×10 = 20 evals/step × 300 steps = 6,000 total
# - SPSA: 2 evals/step × 300 steps = 600 total  ← 10x reduction

कब सबसे अच्छा: जब सर्किट में कई पैरामीटर (> 10) हों। इसका समझौता यह है कि प्रति चरण अभिसरण धीमा होता है, लेकिन कुल शॉट्स कम होते हैं।

तकनीक 5: प्रारंभिक समाप्ति + प्रसरण थ्रेशोल्डिंग

जब परिणाम पहले से ही पर्याप्त अच्छा हो तो सर्किट को पूर्णता तक न चलाएं:

from pennylane.optimize import AdamOptimizer
import numpy as np

opt = AdamOptimizer(stepsize=0.02)
params = init_params.copy()
prev_energy = float('inf')

for step in range(max_steps):
    params, energy = opt.step_and_cost(circuit, params)

    # Stop when change is below shot-noise floor
    variance = 1.0 / np.sqrt(shots_per_eval)  # shot noise floor
    if abs(energy - prev_energy) < variance:
        print(f"Converged at step {step}")
        break

    prev_energy = energy

कई VQE रन जल्दी ही पठार (plateau) पर पहुंच जाते हैं — जारी रखना केवल शोर के उतार-चढ़ाव पर शॉट्स बर्बाद करता है।

तकनीक 6: वार्म स्टार्टिंग

QAOA या VQE पैरामीटरों को यादृच्छिक के बजाय किसी संबंधित शास्त्रीय समाधान से आरंभ करें:

# For QAOA on Max-Cut: warm start from a greedy classical solution
import networkx as nx

G = nx.from_edgelist(edges)
classical_cut = nx.algorithms.approximation.one_exchange(G)

# Map classical solution to initial QAOA angles
# γ₀ ≈ π/4 for a good cut, β₀ ≈ π/8
init_gamma = [np.pi / 4]
init_beta = [np.pi / 8]

# Warm-started QAOA typically converges in 30-50% fewer iterations

सब कुछ मिलाना: एक व्यावहारिक VQE टेम्पलेट

import pennylane as qml
import numpy as np
from pennylane.optimize import ShotAdaptiveOptimizer

dev = qml.device("default.qubit", wires=n_qubits, shots=512)

# 1. Group commuting terms (5-10x reduction in circuit count)
grouped_H = qml.Hamiltonian(*qml.grouping.group_observables(H))

@qml.qnode(dev, diff_method="parameter-shift")
def ansatz(params):
    # Hardware-efficient ansatz
    for i in range(n_qubits):
        qml.RY(params[i], wires=i)
    for i in range(n_qubits - 1):
        qml.CNOT(wires=[i, i + 1])
    return qml.expval(grouped_H)

# 2. Use shot-adaptive optimizer
opt = ShotAdaptiveOptimizer(min_shots=50)

# 3. Warm start
params = warm_start_params(H)

# 4. Run with early stopping
for step in range(300):
    params, energy, shots = opt.step_and_cost(ansatz, params)
    if check_convergence(energy, shots):
        break

print(f"Ground state energy: {energy:.4f} Ha")

त्वरित संदर्भ: विधि के अनुसार शॉट बजट

विधिशॉट्स/चरणकिसके लिए सर्वोत्तम
COBYLA + fixed shotsn_terms × shotsछोटी पैरामीटर संख्या
Parameter-shift + Adam2n_params × shotsअवकलनीय (differentiable) सर्किट
SPSA2 × shotsबड़ी पैरामीटर संख्या
ShotAdaptiveOptimizerअनुकूलीसामान्य VQE
Grouped Paulis÷5–15×हमेशा पहले लागू करें

मेज़रमेंट ग्रुपिंग पहले लागू करें — यह सबसे बड़ी एकल बचत है और इसके लिए आपके ऑप्टिमाइज़र या सर्किट में किसी बदलाव की आवश्यकता नहीं होती।

संबंधित: VQE with PennyLane · QPU access guide · HLQuantum