Skip to documentation
TECHNICAL PROTOCOLINTERNAL

VQE — Technical Protocol & Benchmark Report

Paper-faithful Variational Quantum Eigensolver for peptide ground-state folding (Robert et al. 2021). Full reproduction protocol + fusion4 GPU/CPU benchmark results. Last updated from the live fusion4 run.

DOI 10.1038/s41534-021-00368-4 · npj Quantum Information 7, 38 (2021)

1. Executive summary

This VQE finds the lowest-energy 3D conformation of a short peptide on a tetrahedral lattice with a Miyazawa–Jernigan (MJ) contact potential. It is a faithful reimplementation of Robert et al. 2021: the exact Hamiltonian builder, a RealAmplitudes hardware-efficient ansatz, a CVaR cost, and a Differential-Evolution (DE) classical optimizer. Two facts drive everything below:

  • Energy is reproduced exactly at the paper-narrow CVaR tail (α = 0.001): APRLRFY → −1.425, matching exact diagonalization to 0.000.
  • Ground-state probability P(GS) — the concentration of measurement shots on the true ground state — does not reach the paper's >20% on harder peptides with a single fixed α. The fix is α-annealing (§6), which lifts P(GS) from ~6% to 44–61% while keeping energy exact.

2. Physical model & Hamiltonian

LatticeTetrahedral (4-coordinate) — each backbone turn picks one of 4 directions, constrained so consecutive turns differ.
Energy modelMiyazawa–Jernigan pairwise contact matrix over the 20 standard amino acids (not HP — full MJ).
Qubit countFunction of chain length (number of turns), not residue identity. Length-7 peptide → 9 qubits; length-8 → 13 qubits.
HamiltonianDiagonal in the computational basis (Pauli-Z terms only). H_diag[i] = energy of conformation bitstring i. APRLRFY: 77 Pauli terms, 512 states.
Ground statemin(H_diag); degeneracy = #states within 1e-6. APRLRFY deg = 2; DRVYIHPF deg = 8.

Built by build_qubit_op(sequence). Because H is diagonal, the diagonal is extracted in O(N_terms · 2ⁿ) without a dense matrix (compute_diagonal), giving the exact classical reference for free.

3. Algorithm pipeline

sequence ──► build_qubit_op() ──► qubit_op (diagonal SparsePauliOp)
                  │
                  ├─► compute_diagonal() ──► H_diag ──► classical_energy = min(H_diag)   [exact reference]
                  │
ansatz = RealAmplitudes(n_qubits, reps=2, entanglement="full")
sampled = ansatz.copy(); sampled.measure_all()
                  │
cost = cvar_cost(sampler, sampled, H_diag, alpha, shots=1024)   # CVaR over sampled energies
optimizer = DifferentialEvolution(pop=5·reps·n_qubits, gens=80, restarts=3, F=0.5, CR=0.7)
executor = VariationalExecutor(ansatz, cost, optimizer, seed=42)
best_params, best_energy = executor.run()
                  │
final_counts = sampler.run(sampled, best_params, shots=10240)
P(GS) = Σ counts where |H_diag[bit] - classical_energy| < 1e-6   /  total   (degeneracy-aware)

The quantum part is genuine gate-level simulation: a parameterized RealAmplitudes circuit is transpiled and executed on qiskit-aer (statevector method, GPU via cuStateVec or CPU). No numpy shortcut — the sampler returns real measurement counts that index H_diag.

4. Hyperparameters (verbatim from production)

ParameterValueNotes
shots1024per cost evaluation
alpha (paper)0.001CVaR tail at 1024 shots; _ALPHA_BY_SHOTS = {128:0.01, 1024:0.001}
reps2ansatz depth m=2 (paper)
entanglement"full"all-to-all CX layer
population5·reps·n_qubits9q → 90, 13q → 130
generations80DE generations
restarts3independent DE restarts, best kept
f_mut / cr0.5 / 0.7DE mutation / crossover
seed42executor RNG
n_evals~21,870 (9q)pop·gens·restarts circuit runs

5. CVaR objective & the three α-modes

Instead of the mean energy, the cost is the Conditional Value-at-Risk: sort the per-shot energies ascending, keep the lowest α-fraction, average them. Small α rewards the optimizer for putting anyamplitude on low-energy states (good for finding the GS); large α rewards putting most amplitude there (good for concentrating P(GS)).

CVaR_alpha(energies) = mean( sort(energies)[: ceil(alpha * shots)] )
ModeTrain αBehaviorBest for
paper0.001Narrow tail. Finds the GS energy exactly; P(GS) stays low (~0–6%).Energy accuracy / paper parity
concentrate0.25Wide tail, single phase. Concentrates P(GS) if DE already found the GS; on rugged landscapes a fresh wide-α DE can diverge in energy.Easy peptides (≤9q)
anneal0.05 → 0.25 → 0.4Two-phase (§6). Find at narrow α, then warm-start-widen. Highest P(GS), energy stays exact.Hard peptides / max P(GS)

eval α — for reporting, the final CVaR energy is always re-evaluated at the paper-narrow α = 0.001 regardless of the training α, so reported energies are comparable across modes.

6. α-annealing (the P(GS) fix)

Problem: finding the GS and concentrating probability on it are coupled in a single fixed-α run. A fresh DE at wide α cannot find the GS on a rugged landscape (energy diverges); a fresh DE at narrow α finds it but has no concentration pressure (P(GS) ≈ 6–12%).

Fix — decouple the two:

Phase 1  FIND        DE @ α=0.05, full paper budget          → lands on GS (energy exact)
Phase 2  CONCENTRATE  warm-start a DE population AT the Phase-1 optimum,
                      then optimize @ α=0.25, then @ α=0.40.
                      Population already sits on the GS, so wide α only SHARPENS
                      P(GS) — it does not have to re-find the state.

The warm-started DE (_warm_de) is the only non-paper logic: the project's stock DifferentialEvolution always inits from random, so Phase 2 seeds a Gaussian cloud (σ=0.4) around the Phase-1 parameters and keeps the exact warm point as member 0. Result on DRVYIHPF (13q): P(GS) 6.0% → 24.2% → 42.7% → 60.6% across α = 0.05/0.25/0.40/0.60, energy pinned at −1.925 throughout.

7. Code map

PathRole
backend/services/quantum/algorithms/hamiltonians.pybuild_qubit_op() — tetrahedral MJ Hamiltonian
backend/services/quantum/algorithms/vqe_robert2021.pyProduction algorithm. build_workload() is the real path (called by the registry); run() is a secondary path used by golden tests. α-annealing is wired into build_workload.
backend/services/quantum/execution/variational_executor.pycvar_cost, _cvar_from_counts, VariationalExecutor
backend/services/quantum/jobs/optimizer.pyDifferentialEvolution
run_vqe_exact.pyStandalone driver — single run / --auto-target. Imports the exact project code; only added code is the Aer GPU/CPU sampler adapter.
run_vqe_anneal.pyTwo-phase α-annealing driver (_warm_de).
run_vqe_batch.pyThis report's batch: 10 peptides × {paper, concentrate, anneal} × {CPU, GPU}, crash-safe incremental JSON.

Sampler contract (the only shim): .run(circuits, parameter_values, shots) → list[dict[bitstring,int]]. The Aer adapter caches transpiled circuits, binds parameters per eval, and runs statevector on CPU or GPU (cuStateVec_enable=True on GPU).

8. Reproduction environment (fusion4)

Hostfusion4.blr.cdac.in (10.180.52.57), user ketan
CPU128 cores (Icelake), ~1 TB RAM
GPUNVIDIA, ~48 GB (cuStateVec), CUDA 12.6
Python env/home/ketan/anaconda3/envs/quantum_env — qiskit 1.1.1, qiskit-aer (GPU build)
Working dir/home/ketan/Raja/vqe/ (vendored services/ alongside the drivers)
Resource caps--max-threads 16 + OMP/OPENBLAS/MKL_NUM_THREADS=16 (good-citizen on a shared box)

9. Exact reproduction commands

# single run (paper mode), GPU
python run_vqe_exact.py --sequence APRLRFY --device GPU

# concentrate mode (wide α), CPU
python run_vqe_exact.py --sequence APRLRFY --device CPU --alpha 0.25 --eval-alpha 0.001

# two-phase α-anneal
python run_vqe_anneal.py --sequence DRVYIHPF --device CPU --alpha-find 0.05 --alpha-conc 0.25,0.4

# auto: ascend α, energy-gated, until P(GS) >= 20%
python run_vqe_exact.py --sequence DRVYIHPF --device GPU --auto-target 20

# THE BATCH (10 peptides × 3 modes), capped, crash-safe, nohup
OMP_NUM_THREADS=16 OPENBLAS_NUM_THREADS=16 MKL_NUM_THREADS=16 \
  nohup python run_vqe_batch.py --devices CPU --max-threads 16 \
  --json-out vqe_batch_CPU.json > vqe_batch_CPU.log 2>&1 &

The 10 length-7 peptides (all 9 qubits): APRLRFY, DRVYIHP, KLAKLAK, RGDSPAS, YGGFMRF, GHKGHKG, WLLWLLW, ACDEFGH, HEAGAWG, PPGFSPF. GPU half is deferred behind a watcher (watch_gpu_then_vqe.sh) that auto-launches it when the QAOA-GPU benchmark frees the GPU, so GPU timings are uncontended.

10. Benchmark results (fusion4)

10.1 Reference runs (completed, validated)

PeptideqMode (α)E_vqeE_exactMatchP(GS)DevTime
APRLRFY9paper (0.001)−1.425−1.425✅5.14%CPU791s
APRLRFY9paper (0.001)−1.425−1.425✅0.10%GPU1316s
APRLRFY9concentrate (0.25)−1.425−1.425✅27.0%GPU1605s
DRVYIHPF13concentrate-1φ (0.25)−0.711−1.925❌ diverged0%CPU1485s
DRVYIHPF13auto (0.1)−1.925−1.925✅11.6%GPU1995s
DRVYIHPF13anneal (0.05→0.6)−1.925−1.925✅60.6%CPU2030s

Reading these: energy matches exactly at narrow α on both peptides. Single-phase wide α diverges on the hard 13q peptide (E −0.71 vs −1.925). Only anneal clears >20% P(GS) on the hard one (60.6%). P(GS) at narrow α is intrinsically tiny and shot-noisy — it is not a failure, it is what α = 0.001 is supposed to do.

10.2 Generalization batch — 10 arbitrary length-7 peptides

COMPLETE — CPU, all 10 peptides (7,464 s total)GPU batch deferred behind QAOA (auto-start). Source: vqe_batch_CPU.json.

Question being answered: does an arbitrary length-7 peptide still match exact energy, and what P(GS) does each α-mode reach? Every peptide is 9 qubits (length-determined). All match-flags use tol = max(0.05, 2%·|E|).

PeptideE_exactpaper E / match / P(GS)concentrate E / match / P(GS)anneal E / match / P(GS)
APRLRFY−1.425−1.425 ✅ 0.1%−1.396 ✅ 0.0%−1.425 ✅ 44.2%
DRVYIHP−0.898−0.898 ✅ 5.4%−0.898 ✅ 31.7%−0.898 ✅ 41.4%
KLAKLAK−0.971−0.971 ✅ 6.1%−0.860 ❌ 21.5%−0.971 ✅ 44.0%
RGDSPAS−0.746−0.746 ✅ 0.1%−0.744 ✅ 0.2%−0.746 ✅ 48.9%
YGGFMRF−1.564−1.564 ✅ 0.2%−1.564 ✅ 22.9%−1.564 ✅ 42.5%
GHKGHKG−0.689−0.689 ✅ 0.2%−0.689 ✅ 23.4%−0.689 ✅ 42.0%
WLLWLLW−2.471−2.471 ✅ 0.1%−2.471 ✅ 25.1%−2.471 ✅ 42.4%
ACDEFGH−1.269−1.269 ✅ 6.3%−1.269 ✅ 26.2%−1.269 ✅ 44.7%
HEAGAWG−1.153−1.153 ✅ 5.3%−1.103 ✅ 23.3%−1.153 ✅ 42.6%
PPGFSPF−1.438−1.438 ✅ 0.2%−1.343 ❌ 21.9%−1.438 ✅ 43.7%

10 / 10

paper-mode energy matches exact

10 / 10

anneal matches + P(GS) 41–49%

8 / 10

single-phase concentrate matches

Conclusions. (1) Energy generalizes — every arbitrary length-7 peptide reproduces exact diagonalization at the paper α (10/10). (2) Anneal generalizes — it matches energy on all 10 and concentrates P(GS) into a tight 41–49% band regardless of sequence, confirming the two-phase route is not specific to APRLRFY/DRVYIHPF. (3) Single-phase concentrate is fragile — it diverged in energy on 2/10 (KLAKLAK −0.86 vs −0.97; PPGFSPF −1.34 vs −1.44), the same wide-α failure mode documented in §6, so anneal is the recommended concentration path. CPU wall-time ≈ 4 min per 9-qubit run; peak RSS ≈ 200 MB (see §11).

11. Resource utilization (time, CPU & memory)

Every run is instrumented by a background MemMonitor thread (psutil RSS sampler) plus time.process_time() (cumulative CPU-seconds) and nvidia-smi --query-gpu=memory.used. That separates three distinct things: wall-clock (how long you wait), CPU-time(how many core-seconds the work actually consumed), and peak RAM.

11.1 Measured profile (fusion4, capped at 16 threads)

RunDevqWallCPU-time≈coresPeak host RAMGPU VRAM
APRLRFY · paperCPU9245 s2,651 s10.8200.8 MB—
APRLRFY · concentrateCPU9238 s2,568 s10.8199.8 MB—
APRLRFY · annealCPU9262 s2,850 s10.9201.5 MB—
DRVYIHPF · concentrate-1φCPU131,485 s——214.7 MB—
DRVYIHPF · annealCPU132,030 s134,487 s66.2213.2 MB—
APRLRFY · paperGPU91,316 s——~340 MBsee 11.3
DRVYIHPF · autoGPU131,995 s——~340 MBsee 11.3

Host RAM is tiny and flat: ~200 MB at 9 qubits, ~215 MB at 13 qubits — dominated by the fixed Python/Qiskit/Aer baseline, not the statevector. CPU-time ≫ wall (≈11× at the 16-thread cap) because Aer parallelizes the statevector; the box stayed far under the 65–70% target. The DRVYIHPF-anneal row shows ~66 effective cores because that historical run was launched uncapped — the current batch is capped at 16.

11.2 Why memory is not the bottleneck (the scaling law)

A statevector simulation stores one complex128 (16 bytes) per basis state, so the quantum-state RAM is:

statevector RAM  =  16 bytes x 2^n_qubits   (+ ~200 MB fixed Python/Qiskit/Aer baseline)

   n_qubits      states        statevector       total (≈ baseline + state)
   ─────────────────────────────────────────────────────────────────────────
      9 (len-7)      512           8 KB             ~200 MB   (measured 200.8)
     13 (len-8)    8,192         128 KB             ~215 MB   (measured 214.7)
     20           1.05 M          16 MB             ~220 MB
     26          67.1 M           1 GB              ~1.2 GB
     30           1.07 B          16 GB             ~16 GB    (statevector-bound)
     34          17.2 B          256 GB             needs MPS / tensor-network

For every peptide in this study (9–13 qubits) the statevector is KB-scale — RAM is irrelevant and runtime is set by the number of cost evaluations (~21,870 circuit runs at 9q), not by memory. Memory only becomes the binding constraint past ~30 qubits, where the run switches from statevector to a matrix-product-state backend.

11.3 A caveat on the GPU VRAM numbers

The stored GPU runs report gpu_mem_used_mb ≈ 41,500–42,000 MB. That is not VQE's footprint. nvidia-smi memory.used reports the whole device, and those runs shared the GPU with the QAOA benchmark that was holding ~41 GB. VQE's own VRAM for a 9–13 qubit statevector is sub-megabyte (8 KB–128 KB of amplitudes). The deferred, uncontended GPU batch (auto-starting after QAOA frees the GPU) will record a clean VQE-only VRAM figure — expected to be a few hundred MB of CUDA context, not tens of GB.

Practical takeaway: for these peptide sizes, CPU is both faster and simpler (no host↔device transfer overhead), and memory — host or device — is never the limiting resource.

12. Known deviations & next steps

  • P(GS) vs paper: a single fixed α does not reproduce the paper's >20% on hard peptides. α-annealing does, and is now the recommended/default concentration path (wired into build_workload).
  • GPU vs CPU for small circuits: for 9-qubit circuits, GPU is slower than CPU (host↔device overhead dominates; APRLRFY paper CPU 791s vs GPU 1316s). GPU only wins at higher qubit counts.
  • Warm-DE is the only non-paper logic — everything else is the project's exact code. The warm-start is a strict superset (it can only help concentration).
  • Next: finish the 10-peptide CPU+GPU batch; fill 10.2; then extend anneal sweep to α=0.6 for the length-7 set to confirm the 60% ceiling generalizes beyond DRVYIHPF.