Skip to main content
IBM Quantum Platform

Gestión del rendimiento: una función Qiskit de Q-CTRL Fire Opal

Consulte la referencia de la API

Nota

Las funciones Qiskit son una función experimental disponible únicamente para los usuarios de los planes IBM Quantum® Premium Plan, Flex Plan y On-Prem (a través de IBM Quantum Platform API). Se trata de versiones preliminares sujetas a cambios.

  • El código de esta página se ha desarrollado siguiendo los siguientes requisitos. Recomendamos utilizar estas versiones o posteriores.

    qiskit[all]~=2.3.1
    qiskit-ibm-runtime~=0.45.1
    

Visión general

La gestión del rendimiento de Fire Opal facilita a cualquiera la obtención de resultados significativos de los ordenadores cuánticos a escala sin necesidad de ser expertos en hardware cuántico. Cuando se ejecutan circuitos con Fire Opal Performance Management, se aplican automáticamente técnicas de supresión de errores basadas en IA, lo que permite escalar problemas más grandes con más puertas y qubits. Este enfoque reduce el número de disparos necesarios para llegar a la respuesta correcta, sin sobrecarga añadida, lo que supone un ahorro significativo tanto en tiempo de cálculo como en costes.

La gestión del rendimiento suprime los errores y aumenta la probabilidad de obtener la respuesta correcta en hardware ruidoso. En otras palabras, aumenta la relación señal/ruido. La siguiente imagen muestra cómo la mayor precisión que permite la Gestión del Rendimiento puede reducir la necesidad de disparos adicionales en el caso de un algoritmo de Transformada Cuántica de Fourier de 10 qubits. Con sólo 30 disparos, Q-CTRL alcanza el umbral de confianza del 99%, mientras que el predeterminado (QiskitRuntime Sampler, optimization_level=3 y resilience_level=1, ibm_sherbrooke) requiere 170.000 disparos. Al obtener la respuesta correcta más rápidamente, se ahorra un tiempo de ejecución de cálculo considerable.

Visualización del tiempo de ejecución mejorado

La función de gestión del rendimiento se puede utilizar con cualquier algoritmo, y se puede emplear fácilmente en lugar de las primitivas estándar de « Qiskit Runtime ». Entre bastidores, varias técnicas de supresión de errores actúan conjuntamente para evitar que se produzcan errores durante la ejecución. Todos los métodos de canalización de Fire Opal vienen preconfigurados y son independientes del algoritmo, lo que significa que siempre obtienes el mejor rendimiento desde el primer momento.

Para acceder a la gestión del rendimiento, póngase en contacto con Q-CTRL.


Descripción

Fire Opal Performance Management dispone de dos opciones de ejecución similares a las primitivas de Qiskit Runtime, por lo que puede intercambiar fácilmente el Q-CTRL Sampler y el Estimator. El flujo de trabajo general para utilizar la función de Gestión del Rendimiento es el siguiente:

  1. Defina su circuito (y operadores en el caso del Estimador).
  2. Pon en marcha el circuito.
  3. Recuperar los resultados.

Para reducir el ruido del hardware, Fire Opal emplea una serie de técnicas de supresión de errores basadas en IA que se muestran en la siguiente imagen. Con Fire Opal, todo el proceso está completamente automatizado sin necesidad de configuración.

La canalización de Fire Opal elimina la necesidad de sobrecargas adicionales, como un mayor tiempo de ejecución cuántica o qubits físicos adicionales. Tenga en cuenta que el tiempo de procesamiento clásico sigue siendo un factor (consulte la sección de puntos de referencia para obtener estimaciones, donde "Tiempo total" refleja tanto el procesamiento clásico como el cuántico). A diferencia de la mitigación de errores, que requiere una sobrecarga en forma de muestreo, la supresión de errores de Fire Opal funciona tanto a nivel de puerta como de pulso para abordar diversas fuentes de ruido y evitar la probabilidad de que se produzca un error. Al evitar errores, se elimina la necesidad de un costoso tratamiento posterior.

La siguiente imagen muestra los métodos de supresión de errores automatizados por Fire Opal Performance Management.

Visualización del proceso de supresión de errores

La función ofrece dos primitivas, «Sampler» y «Estimator», y las entradas y salidas de ambas amplían la especificación implementada para las primitivas de Qiskit Runtime V2.


Referencias comparativas

Los resultados de las pruebas comparativas algorítmicas publicadas demuestran una mejora significativa del rendimiento en varios algoritmos, como Bernstein-Vazirani, la transformada cuántica de Fourier, la búsqueda de Grover, el algoritmo de optimización aproximada cuántica y el eigensolver cuántico variacional. El resto de esta sección proporciona más detalles sobre los tipos de algoritmos que puede ejecutar, así como el rendimiento y los tiempos de ejecución esperados.

Los siguientes estudios independientes demuestran cómo la gestión del rendimiento de Q-CTRL permite la investigación algorítmica a una escala sin precedentes:

La siguiente tabla ofrece una guía aproximada de la precisión y los tiempos de ejecución de pruebas comparativas anteriores en ibm_fez. El rendimiento en otros dispositivos puede variar. El tiempo de uso se basa en una hipótesis de 10.000 disparos por circuito. El "Número de qubits" indicado no es una limitación rígida, sino que representa umbrales aproximados en los que se puede esperar una precisión de solución extremadamente consistente. Se han resuelto con éxito problemas de mayor envergadura, por lo que se recomienda realizar pruebas más allá de estos límites.

Ejemplo
Número de qubits
Precisión
Medida de la precisión
Tiempo total (s)
Tiempo de ejecución (s)
Primitivo (Modo)
Bernstein-Vazirani50Q100 %Tasa de éxito (porcentaje de ejecuciones en las que la respuesta correcta es la cadena de bits de recuento más alto)108Muestreador
Transformada cuántica de Fourier30Q100 %Tasa de éxito (porcentaje de ejecuciones en las que la respuesta correcta es la cadena de bits de recuento más alto)108Muestreador
Estimación cuántica de fase30Q99.9998%Precisión del ángulo encontrado: 1- abs(real_angle - angle_found)/pi108Muestreador
Simulación cuántica: Modelo de Ising (15 pasos)20Q99.775%AA (definidos a continuación)60 (por paso)15 (por paso)Estimador
Simulación cuántica 2: dinámica molecular (20 puntos temporales)34Q96.78%AmeanA_{mean} (definidos a continuación)10 (por punto temporal)6 (por punto temporal)Estimador

Definición de la precisión de la medición de un valor de expectativa: la métrica AA se define del siguiente modo:

A=1ϵidealϵmeasϵmaxidealϵminideal,A = 1 - \frac{|\epsilon^{ideal} - \epsilon^{meas}|}{\epsilon^{ideal}_{max} - \epsilon^{ideal}_{min}},

donde ϵideal\epsilon^{ideal} = valor de expectativa ideal, ϵmeas\epsilon^{meas} = valor de expectativa medido, ϵmaxideal\epsilon^{ideal}_{max} = valor máximo ideal y ϵminideal\epsilon^{ideal}_{min} = valor mínimo ideal. AmeanA_{mean} es simplemente la media del valor de AA en múltiples mediciones.

Esta métrica se utiliza porque es invariable a los cambios globales y a la escala en el rango de valores alcanzables. En otras palabras, independientemente de si se desplaza el rango de posibles valores de expectativas hacia arriba o hacia abajo o se aumenta la dispersión, el valor de AA debería permanecer constante.


Cómo empezar

Fire Opal Performance Management utiliza Qiskit v2.0.0, que es la versión recomendada. Las versiones compatibles son Qiskit >= v2.0.0. Autentíquese utilizando su clave API IBM Quantum Platform y seleccione la función Qiskit de la siguiente manera. (En este fragmento de código se da por hecho que ya has guardado tu cuenta en tu entorno local.)

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# verify that you have access to the function
catalog.list()

Output:

[QiskitFunction(qunova/hivqe-chemistry),
 QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),
 QiskitFunction(algorithmiq/tem),
 QiskitFunction(qedma/qesem),
 QiskitFunction(multiverse/singularity),
 QiskitFunction(ibm/circuit-function),
 QiskitFunction(q-ctrl/optimization-solver),
 QiskitFunction(colibritd/quick-pde),
 QiskitFunction(q-ctrl/performance-management),
 QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]
# Access Function
perf_mgmt = catalog.load("q-ctrl/performance-management")
¿Esta función es compatible con todos los servidores de fondo de IBM?

Si deseas utilizar un backend que esta función no admite actualmente, ponte en contacto con Q-CTRL para que lo incorporen.


Primitiva estimadora

Ejemplo de estimador

Utilice la primitiva Estimator de Fire Opal Performance Management para determinar el valor esperado de un único par circuito-observable.

Además de los paquetes qiskit-ibm-catalog y qiskit , también utilizará el paquete numpy para ejecutar este ejemplo. Puedes instalar este paquete descomentando la siguiente celda si estás ejecutando este ejemplo en un notebook usando el kernel IPython.

# %pip install numpy

1. Crear el circuito

Como ejemplo, genere un operador Hermitiano aleatorio y un observable para introducirlo en la función de Gestión del Rendimiento.

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.quantum_info import random_hermitian, SparsePauliOp

n_qubits = 50

# Generate a random circuit
mat = np.real(random_hermitian(n_qubits, seed=1234))
circuit = iqp(mat)
circuit.measure_all()

# Define observables as a string
observable = SparsePauliOp("Z" * n_qubits)
# Create PUB tuple
estimator_pubs = [(circuit, observable)]

2. Ejecutar el circuito

Ejecute el circuito y defina opcionalmente el fondo y el número de disparos.

# Run the circuit using Estimator
qctrl_estimator_job = perf_mgmt.run(
    primitive="estimator",
    pubs=estimator_pubs,
    backend_name=backend_name,
)

Puedes utilizar las conocidas API de « Qiskit Serverless » para comprobar el estado de tu carga de trabajo de Qiskit Function:

qctrl_estimator_job.status()

Output:

'QUEUED'

3. Recuperar el resultado

# Retrieve the counts from the result list
result = qctrl_estimator_job.result()

Los resultados tienen el mismo formato que los resultados de Estimator:

import numpy

result_str = str(result)

with numpy.printoptions(threshold=200):
    print(
        f"The result of the submitted job had {len(result)} PUB "
        f"and has a value:\n {result[0]}\n"
    )

print("The associated PubResult of this job has the following DataBins:")
print(f"{result[0].data}\n")

print(f"And this DataBin has attributes: {result[0].data.keys()}")

print("The expectation values measured from this PUB are:")
print(f"{result[0].data.evs}")

Output:

The result of the submitted job had 1 PUB
The result of the submitted job had 1 PUB and has a value:
 PubResult(data=DataBin(evs=0.0195, stds=0.9998098569228051), metadata={'precision': None})

The associated PubResult of this job has the following DataBins:
DataBin(evs=0.0195, stds=0.9998098569228051)

And this DataBin has attributes: dict_keys(['evs', 'stds'])
The expectation values measured from this PUB are:
0.0195

Primitiva de muestreador

Ejemplo de muestreador

Utilice la primitiva Sampler de Fire Opal Performance Management para ejecutar un circuito Bernstein-Vazirani. Este algoritmo, utilizado para encontrar una cadena oculta a partir de las salidas de una función de caja negra, es un algoritmo de evaluación comparativa habitual porque hay una única respuesta correcta.

1. Crear el circuito

Defina la respuesta correcta para el algoritmo, la cadena de bits oculta y el circuito Bernstein-Vazirani. Puedes ajustar la anchura del circuito simplemente cambiando la dirección circuit_width.

import qiskit

circuit_width = 35
hidden_bitstring = "1" * circuit_width

# Create circuit, reserving one qubit for BV oracle
bv_circuit = qiskit.QuantumCircuit(circuit_width + 1, circuit_width)
bv_circuit.x(circuit_width)
bv_circuit.h(range(circuit_width + 1))
for input_qubit, bit in enumerate(reversed(hidden_bitstring)):
    if bit == "1":
        bv_circuit.cx(input_qubit, circuit_width)
bv_circuit.barrier()
bv_circuit.h(range(circuit_width + 1))
bv_circuit.barrier()
for input_qubit in range(circuit_width):
    bv_circuit.measure(input_qubit, input_qubit)

# Create PUB tuple
sampler_pubs = [(bv_circuit,)]

2. Ejecutar el circuito

Ejecute el circuito y defina opcionalmente el fondo y el número de disparos.

# Run the circuit using Sampler
qctrl_sampler_job = perf_mgmt.run(
    primitive="sampler",
    pubs=sampler_pubs,
    backend_name=backend_name,
)

Comprueba el estado de tu carga de trabajo de Qiskit Function o obtén los resultados de la siguiente manera:

# Print the ID so you can use it later, if necessary
print(qctrl_sampler_job.job_id)

qctrl_sampler_job.status()

Output:

60fe2fa1-a860-43e4-8615-c6ac4180f93b
'QUEUED'

3. Recuperar el resultado

# Retrieve the job results
sampler_result = qctrl_sampler_job.result()
# Get results for the first (and only) PUB
pub_result = sampler_result[0]
counts = pub_result.data.c.get_counts()

print("Counts for the meas output register (limited to 30 results):")
for i, (bitstring, count) in enumerate(counts.items()):
    if i >= 50:
        print(f"  ... ({len(counts) - 30} more items)")
        break
    print(f"  {bitstring}: {count}")

Output:

Counts for the meas output register (limited to 30 results):
  11111111111111111111111111111111111: 1661
  11111111111111111111111111110111111: 60
  11111111111111111111111111111101111: 54
  11111111111111111111111111111110111: 54
  11111111111111011111111111111111111: 46
  11111111111111111110111111111111111: 44
  11111111111111111111111101111111111: 42
  11111111111111111111111110111111111: 42
  11111111111111110111111111111111111: 41
  11111111111111111111111111111111101: 39
  11111111111111111111101111111111111: 38
  11111111111111111111110111111111111: 38
  11111111111111111111111111101111111: 37
  11111111111111111111111111111111110: 36
  11111111111110111111111111111111111: 35
  11111111111111111111111111111011111: 32
  11111111111111101111111111111111111: 32
  01111111111111111111111111111111111: 27
  11111111111111111011111111111111111: 23
  11111111101111111111111111111111111: 22
  11111111111111111111111111111111011: 21
  11111111011111111111111111111111111: 20
  00000000000000011111111111111111111: 18
  11111111111111111111110101111111111: 18
  00000001111111111111111111111111111: 17
  11111111001111111111111111111111111: 16
  11101111111111111111111111111111111: 16
  11111111111101111111111111111111111: 16
  00000101111111111111111111111111111: 13
  11111111111111111111111011111111111: 13
  11111111111111111111111110101111111: 13
  11111111111111111101111111111111111: 12
  10111111111111111111111111111111111: 12
  11111111111111111111111110001111111: 12
  00000000000000000011111111111111111: 11
  11111111111111111111111111111110110: 10
  00000000000000000000000001111111111: 10
  11111111111011111111111111111111111: 9
  11111111111111101011111111111111111: 9
  00000000011111111111111111111111111: 8
  10101111111111111111111111111111111: 8
  00000000000000000000000001011111111: 8
  11111111111111111111111111111111001: 8
  00000111111111111111111111111111111: 7
  11111111111111111111111111111101110: 7
  11111111110111111111111111111111111: 7
  00000000000001011111111111111111111: 6
  00000000000000001111111111111111111: 6
  00000000000000000001011111111111111: 6
  11111111111111111111111111011111111: 6
  ... (1050 more items)

3. Trazar las cadenas de bits superiores

Traza la cadena de bits con los recuentos más altos para ver si la cadena de bits oculta era el modo.

import matplotlib.pyplot as plt


def plot_top_bitstrings(counts_dict, hidden_bitstring=None):
    # Sort and take the top 100 bitstrings
    top_100 = sorted(counts_dict.items(), key=lambda x: x[1], reverse=True)[
        :100
    ]
    if not top_100:
        print("No bitstrings found in the input dictionary.")
        return

    # Unzip the bitstrings and their counts
    bitstrings, counts = zip(*top_100)

    # Assign colors: purple if the bitstring matches hidden_bitstring,
    # otherwise gray
    colors = [
        "#680CE9" if bit == hidden_bitstring else "gray" for bit in bitstrings
    ]

    # Create the bar plot
    plt.figure(figsize=(15, 8))
    plt.bar(
        range(len(bitstrings)), counts, tick_label=bitstrings, color=colors
    )

    # Rotate the bitstrings for better readability
    plt.xticks(rotation=90, fontsize=8)
    plt.xlabel("Bitstrings")
    plt.ylabel("Counts")
    plt.title("Top 100 Bitstrings by Counts")

    # Show the plot
    plt.tight_layout()
    plt.show()

La cadena de bits oculta aparece resaltada en morado y debe ser la cadena de bits con el mayor número de cuentas.

plot_top_bitstrings(counts, hidden_bitstring)

Output:

Output of the previous code cell

Registro de cambios

  • 2026-02-20: Aviso de obsolescencia: el campo provider_job_ids de metadatos quedará obsoleto en 30 días en la versión 0.13.0. Los usuarios pueden acceder al ID del trabajo a través job_id() del método del servicio de tiempo de ejecución.
  • 11/02/2026: Ahora ofrecemos compatibilidad con ibm_miamiy hemos añadido metadatos de ejecución al PubResult.

Obtener soporte

Para cualquier pregunta o problema, póngase en contacto con Q-CTRL.


Próximos pasos

Recomendaciones
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.