Error mitigation is a family of techniques for recovering accurate expectation values from a noisy quantum computer, without the qubit overhead of full quantum error correction. Rather than detecting and repairing faults as they happen, mitigation runs the noisy circuit as-is — sometimes several deliberately noisier versions of it — and removes the bias from the results in classical post-processing. The price is paid in samples, not qubits. Mitigation repairs expectation values, never states or samples, and its sampling cost grows with the noise it must undo. It is the standard way to get quantitative results from today's pre-error-corrected hardware.
This series introduces the two workhorse techniques, readout mitigation and zero-noise extrapolation (ZNE), from first principles, building each one by hand before composing them into the standard mitigation ladder and running it on real hardware via qBraid. The running experiment throughout is a four-qubit mirror circuit: a block
The techniques are those of Temme, Bravyi and Gambetta (arXiv:1612.02058), which introduced ZNE and probabilistic error cancellation, and Kandala et al. (arXiv:1805.04492), which first demonstrated ZNE on hardware. Familiarity with basic Qiskit concepts including circuits, transpilation, samplers, and counts is assumed; no error-correction background is needed, and Notebook 1 builds the noise vocabulary from scratch.
Use the Launch on qBraid button on this tutorial's page in the qBraid Explore hub. It clones the repository into qBraid Lab. You will use the default environment to run this tutorial, and the notebook will ensure all required packages are installed. Run the notebooks in order, starting with 01_noise_zoo.ipynb. For selecting environments and kernels in qBraid Lab, see the environments guide.
This notebook introduces the mirror circuit and builds the noise vocabulary from scratch: readout error, gate (depolarizing) error, and
This notebook builds readout mitigation by hand. The confusion matrix is measured two ways, first brute-force over all sixteen basis states, then tensored from just two calibration circuits. These are applied by matrix inversion, confronting the negative quasi-probabilities that inversion produces, then by constrained least squares. Bootstrap resampling puts error bars on the mitigated values, and a hard assertion checks that mitigation beats the raw result by more than a factor of ten.
This notebook builds ZNE by hand, starting from a hand-written gate-folding function that scales the noise by odd factors. Linear and exponential fits are compared for extrapolating back to the zero-noise limit, and both classic failure modes are demonstrated: a fit model that does not match the noise, and an extrapolation that runs into the readout-error floor that folding cannot amplify. This will help us build the motivation for composing ZNE with readout mitigation in the final notebook.
4. Hardware Experiments and Built-in Mitigation on an IBM Quantum Computer 04_hardware_experiments.ipynb
This notebook tours the built-in mitigation stack, walking you through resilience levels, ZNE options, twirling, and probabilistic error cancellation with its sampling-overhead math, and maps each option back to the technique built by hand in Notebooks 2 and 3. Then the hand-built ladder is applied to counts from a real QPU, submitted through qBraid. We will see readout calibration plus folded mirror circuits, composed into the final raw-versus-mitigated comparison that closes the series.
The qBraid Lab default environment provides Qiskit, Qiskit Aer, qiskit-ibm-runtime, and qBraid; the install cell at the top of Notebook 1 adds the remaining packages (matplotlib and pylatexenc). For other setups, requirements.txt lists everything needed (pip install -r requirements.txt in a Python 3.10+ virtual environment).
- Run each notebook from top to bottom, in order. If the kernel state becomes inconsistent, use Kernel > Restart Kernel and Run All Cells.
- In Notebook 4, hardware submission is off by default, so Run All Cells is a safe dry run: it uses the cached counts committed in
data/. The committed files are clearly labeled noisy-simulator placeholders ("placeholder": truein their metadata), and the notebook prints a notice when you are looking at them. - To run live, export your IBM API token as
QISKIT_IBM_TOKENbefore launching Jupyter, setRUN_ON_HARDWARE = True, and run all cells. The job is five four-qubit circuits at 5,000 shots — a few seconds of QPU time. Results are cached todata/immediately, replacing the placeholders, so you only ever submit once; re-runs afterwards use the real counts withRUN_ON_HARDWARE = False.
- Import or kernel errors immediately after launch usually mean the environment is still installing. Wait for it to finish, then select the tutorial's kernel from the kernel menu.
- Hardware queue times on QPUs can range from minutes to hours. The job continues on the backend if you disconnect; note the printed job ID so the results can be retrieved later.
- If Notebook 4 raises
Set the QISKIT_IBM_TOKEN environment variable first, the token was not visible to the kernel. You can export it in the shell that launches Jupyter, or paste it into the configuration cell (and take care not to commit it). - Deleting files under
data/is safe: Notebook 4 regenerates placeholder counts from the Aer noise model on its next run.