IBM量子真机实现Quantum SVM遇CircuitError参数名冲突问题
问题:运行量子SVM代码时触发CircuitError参数名称冲突错误
基于Qiskit社区的《Quantum Kernel Machine Learning Tutorial》开发量子支持向量机(Quantum SVM)项目,在IBM真实量子机器上运行代码时,触发CircuitError: "name conflict adding parameter 'x[1]'"错误。
实现代码
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler, Session from qiskit_machine_learning.datasets import ad_hoc_data from qiskit import transpile from qiskit.circuit.library import ZZFeatureMap from qiskit_algorithms.state_fidelities import ComputeUncompute from qiskit_machine_learning.kernels import FidelityQuantumKernel from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager # Load Dataset adhoc_dimension = 2 train_features, train_labels, test_features, test_labels, adhoc_total = ad_hoc_data( training_size=20, test_size=5, n=adhoc_dimension, gap=0.3, plot_data=False, one_hot=False, include_sample_total=True, ) # initialize backend service service = QiskitRuntimeService() n_qubits=2 backend = service.least_busy(operational=True, simulator=False, min_num_qubits=n_qubits) adhoc_feature_map = ZZFeatureMap(feature_dimension=adhoc_dimension, reps=2, entanglement="linear") #transpile circuit pass_manager = generate_preset_pass_manager(optimization_level=1, backend=backend) isa_circuit = pass_manager.run(adhoc_feature_map) # calculate kernel matrices with Session(service= service, backend=backend) as session: sampler = Sampler(backend) fidelity = ComputeUncompute(sampler=sampler) adhoc_kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=isa_circuit) adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features,y_vec=train_features) adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features, y_vec=train_features)
完整报错栈信息
--------------------------------------------------------------------------- CircuitError Traceback (most recent call last) Cell In[51], line 7 4 fidelity = ComputeUncompute(sampler=sampler) 6 adhoc_kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=isa_circuit) ----> 7 adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features,y_vec=train_features) 8 adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features, y_vec=train_features) File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_machine_learning/kernels/fidelity_quantum_kernel.py:114, in FidelityQuantumKernel.evaluate(self, x_vec, y_vec) 112 if is_symmetric: 113 left_parameters, right_parameters, indices = self._get_symmetric_parameterization(x_vec) --> 114 kernel_matrix = self._get_symmetric_kernel_matrix( 115 kernel_shape, left_parameters, right_parameters, indices 116 ) 117 else: 118 left_parameters, right_parameters, indices = self._get_parameterization(x_vec, y_vec) File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_machine_learning/kernels/fidelity_quantum_kernel.py:202, in FidelityQuantumKernel._get_symmetric_kernel_matrix(self, kernel_shape, left_parameters, right_parameters, indices) 192 def _get_symmetric_kernel_matrix( 193 self, 194 kernel_shape: tuple[int, int], (...) 197 indices: KernelIndices, 198 ) -> np.ndarray: 199 """ 200 Given a set of parameterization, this computes the kernel matrix. 201 """ --> 202 kernel_entries = self._get_kernel_entries(left_parameters, right_parameters) 203 kernel_matrix = np.ones(kernel_shape) 205 for i, (col, row) in enumerate(indices): File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_machine_learning/kernels/fidelity_quantum_kernel.py:223, in FidelityQuantumKernel._get_kernel_entries(self, left_parameters, right_parameters) 221 if num_circuits != 0: 222 if self.max_circuits_per_job is None: --> 223 job = self._fidelity.run( 224 [self._feature_map] * num_circuits, 225 [self._feature_map] * num_circuits, 226 left_parameters, 227 right_parameters, 228 ) 229 kernel_entries = job.result().fidelities 230 else: 231 # Determine the number of chunks needed File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_algorithms/state_fidelities/base_state_fidelity.py:298, in BaseStateFidelity.run(self, circuits_1, circuits_2, values_1, values_2, **options) 270 def run( 271 self, 272 circuits_1: QuantumCircuit | Sequence[QuantumCircuit], (...) 276 **options, 277 ) -> AlgorithmJob: 278 r""" 279 Runs asynchronously the state overlap (fidelity) calculation between two 280 (parametrized) circuits (first and second) for a specific set of parameter (...) 296 The job's result is an instance of :class:`.StateFidelityResult`. 297 """ --> 298 job = self._run(circuits_1, circuits_2, values_1, values_2, **options) 300 job.submit() 301 return job File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_algorithms/state_fidelities/compute_uncompute.py:147, in ComputeUncompute._run(self, circuits_1, circuits_2, values_1, values_2, **options) 116 def _run( 117 self, 118 circuits_1: QuantumCircuit | Sequence[QuantumCircuit], (...) 122 **options, 123 ) -> AlgorithmJob: 124 r""" 125 Computes the state overlap (fidelity) calculation between two 126 (parametrized) circuits (first and second) for a specific set of parameter (...) 144 AlgorithmError: If the sampler job is not completed successfully. 145 """ --> 147 circuits = self._construct_circuits(circuits_1, circuits_2) 148 if len(circuits) == 0: 149 raise ValueError( 150 "At least one pair of circuits must be defined to calculate the state overlap." 151 ) File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit_algorithms/state_fidelities/base_state_fidelity.py:187, in BaseStateFidelity._construct_circuits(self, circuits_1, circuits_2) 184 # re-parametrize input circuits 185 # TODO: make smarter checks to avoid unnecessary re-parametrizations 186 parameters_1 = ParameterVector("x", circuit_1.num_parameters) --> 187 parametrized_circuit_1 = circuit_1.assign_parameters(parameters_1) 188 parameters_2 = ParameterVector("y", circuit_2.num_parameters) 189 parametrized_circuit_2 = circuit_2.assign_parameters(parameters_2) File ~/Desktop/IMB/machine/lib/python3.11/site-packages/qiskit/circuit/quantumcircuit.py:4345, in QuantumCircuit.assign_parameters(self, parameters, inplace, flat_input, strict) 4343 else: 4344 parameter_binds = _ParameterBindsSequence(target._data.parameters, parameters) -> 4345 target._data.assign_parameters_iterable(parameters) 4347 # Finally, assign the parameters inside any of the calibrations. We don't track these in 4348 # the `ParameterTable`, so we manually reconstruct things. 4349 def map_calibration(qubits, parameters, schedule): CircuitError: "name conflict adding parameter 'x[1]'"
解决思路
问题根源
转译后的ISA电路(isa_circuit)保留了ZZFeatureMap默认的参数名称(如x[0]、x[1]),而ComputeUncompute在构造保真度计算电路时,会自动创建一个名为x的ParameterVector,两者参数名重复,导致冲突报错。
修复方案
方案1:让量子内核自动处理转译(推荐)
不要手动转译特征映射,直接将原始adhoc_feature_map传给FidelityQuantumKernel,内核会结合后端信息自动完成转译,避免参数名冲突:
# 移除手动转译的代码,直接使用原始特征映射 with Session(service= service, backend=backend) as session: sampler = Sampler(backend) fidelity = ComputeUncompute(sampler=sampler) # 这里传入原始的adhoc_feature_map,而非转译后的isa_circuit adhoc_kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=adhoc_feature_map) adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features,y_vec=train_features) adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features, y_vec=train_features)
方案2:手动重命名转译后电路的参数
如果必须使用手动转译后的电路,需要重新命名电路参数,避免与后续自动生成的x参数冲突:
from qiskit.circuit import ParameterVector # 转译电路后,重新命名参数 new_params = ParameterVector("feat", adhoc_feature_map.num_parameters) isa_circuit = isa_circuit.assign_parameters(new_params) # 之后再初始化量子内核 with Session(service= service, backend=backend) as session: sampler = Sampler(backend) fidelity = ComputeUncompute(sampler=sampler) adhoc_kernel = FidelityQuantumKernel(fidelity=fidelity, feature_map=isa_circuit) adhoc_matrix_train = adhoc_kernel.evaluate(x_vec=train_features,y_vec=train_features) adhoc_matrix_test = adhoc_kernel.evaluate(x_vec=test_features, y_vec=train_features)
验证逻辑
两种方案的核心都是确保特征映射的参数名与ComputeUncompute自动生成的参数名不重复。方案1更简洁,符合Qiskit机器学习模块的设计逻辑;方案2适合需要手动控制转译流程的场景。
内容的提问来源于stack exchange,提问作者Pradip Sapkota
相关产品推荐
相关产品推荐

