IBM量子硬件上用Scipy minimize运行Estimator时遇AttributeError问题
问题描述
使用scipy.optimize.minimize结合Qiskit Runtime的Estimator在IBM真实量子设备上优化量子电路时,触发错误:AttributeError: 'ParameterExpression' object has no attribute 'name',错误发生在cost_func_estimator函数内调用estimator.run()的位置。
已尝试的操作:
- 确保
init_params仅包含数值而非ParameterExpression - 使用
bind_parameters()赋值参数 - 更新
qiskit和qiskit-ibm-runtime到最新版本
相关代码:
主程序代码:
from scipy.optimize import minimize from qiskit_ibm_runtime import Estimator, Session objective_func_vals = [] with Session(backend=backend) as session: estimator = Estimator(mode=session) estimator.options.default_shots = 1000 estimator.options.dynamical_decoupling.enable = True estimator.options.dynamical_decoupling.sequence_type = "XY4" estimator.options.twirling.enable_gates = True estimator.options.twirling.num_randomizations = "auto" result = minimize( cost_func_estimator, init_params, args=(candidate_circuit, qubitOp, estimator), method="COBYLA", tol=1e-2, callback=callback, ) save_progress(result.x, objective_func_vals, name_saved_file) print(result)
代价函数定义:
def cost_func_estimator(params, ansatz, hamiltonian, estimator): isa_hamiltonian = hamiltonian.apply_layout(ansatz.layout) pub = (ansatz, isa_hamiltonian, params) job = estimator.run([pub]) # 错误触发位置 results = job.result()[0] cost = results.data.evs return cost
解决方案
1. 显式绑定参数到电路,避免直接传递参数列表
Estimator在处理带参数的电路时,若参数为ParameterExpression会因缺失name属性报错。通过assign_parameters提前将数值参数绑定到ansatz电路,生成无参数电路后再传给Estimator,绕开参数匹配问题。
2. 提前完成Hamiltonian的ISA转换
避免在每次代价函数调用时重复执行布局转换,提前在Session外完成Hamiltonian的ISA适配,减少冗余操作和潜在错误。
3. 确保ansatz参数为纯Parameter对象
检查ansatz电路中的参数,确保均为独立的Parameter对象,而非包含运算的ParameterExpression(例如theta + pi/2),后者无name属性会导致Estimator无法识别。
修改后的代码示例:
主程序(提前转换Hamiltonian):
from scipy.optimize import minimize from qiskit_ibm_runtime import Estimator, Session objective_func_vals = [] # 提前将Hamiltonian适配到ansatz的布局 isa_hamiltonian = qubitOp.apply_layout(candidate_circuit.layout) with Session(backend=backend) as session: estimator = Estimator(mode=session) estimator.options.default_shots = 1000 estimator.options.dynamical_decoupling.enable = True estimator.options.dynamical_decoupling.sequence_type = "XY4" estimator.options.twirling.enable_gates = True estimator.options.twirling.num_randomizations = "auto" result = minimize( cost_func_estimator, init_params, args=(candidate_circuit, isa_hamiltonian, estimator), method="COBYLA", tol=1e-2, callback=callback, ) save_progress(result.x, objective_func_vals, name_saved_file) print(result)
修改后的代价函数:
def cost_func_estimator(params, ansatz, isa_hamiltonian, estimator): # 将数值参数绑定到ansatz,生成无参数电路 bound_ansatz = ansatz.assign_parameters(params) # 构造pub时无需再传递params pub = (bound_ansatz, isa_hamiltonian) job = estimator.run([pub]) results = job.result()[0] cost = results.data.evs return cost
额外检查项:
- 确认
init_params的长度与ansatz的parameters列表长度完全一致,顺序严格对应 - 若ansatz是经
transpile转换的ISA电路,确保转换过程未引入ParameterExpression
内容的提问来源于stack exchange,提问作者Clovis Caface
相关产品推荐
相关产品推荐

