การจำลองแบบแม่นยำและแบบมีสัญญาณรบกวนด้วย Qiskit Aer primitives
เวอร์ชันของแพ็กเกจ
โค้ดในหน้านี้พัฒนาด้วยข้อกำหนดต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.4.0
qiskit-aer~=0.17
การจำลองแบบแม่นยำด้วย Qiskit primitives แสดงวิธีใช้ reference primitives ที่มาพร้อมกับ Qiskit เพื่อจำลอง quantum circuit อย่างแม่นยำ ในปัจจุบัน quantum processor ที่มีอยู่ยังประสบปัญหาข้อผิดพลาดหรือสัญญาณรบกวน ดังนั้นผลลัพธ์จากการจำลองแบบแม่นยำจึงไม่จำเป็นต้องสะท้อนผลลัพธ์ที่คุณจะได้เมื่อรัน circuit บนฮาร์ดแวร์จริง แม้ว่า reference primitives ใน Qiskit จะไม่รองรับการสร้างแบบจำลองสัญญาณรบกวน แต่ Qiskit Aer มีการใช้งาน primitives ที่รองรับการสร้างแบบจำลองสัญญาณรบกวน Qiskit Aer เป็น quantum circuit simulator ประสิทธิภาพสูงที่คุณสามารถใช้แทน reference primitives เพื่อประสิทธิภาพที่ดีขึ้นและฟีเจอร์ที่มากขึ้น โดยเป็นส่วนหนึ่งของ Qiskit Ecosystem ในบทความนี้ เราจะสาธิตการใช้ Qiskit Aer primitives สำหรับการจำลองแบบแม่นยำและแบบมีสัญญาณรบกวน
- ต้องใช้
qiskit-aerv0.14 หรือใหม่กว่า - แม้ว่า Qiskit Aer primitives จะใช้งาน primitive interfaces แต่ก็ไม่ได้ให้ตัวเลือกเดียวกับ Qiskit Runtime primitives เช่น Resilience level ไม่มีให้ใช้งานใน Qiskit Aer primitives
- ดูรายละเอียดเกี่ยวกับตัวเลือกวิธีการจำลองที่ Aer รองรับได้ที่ เอกสาร AerSimulator
เพื่อสำรวจการจำลองแบบแม่นยำและแบบมีสัญญาณรบกวน ให้สร้าง circuit ตัวอย่างบน 8 qubit:
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
Circuit นี้มีพารามิเตอร์สำหรับแทนค่ามุมการหมุนของ Gate และ เมื่อจำลอง circuit นี้ เราต้องระบุค่าที่ชัดเจนสำหรับพารามิเตอร์เหล่านี้ ในเซลล์ถัดไป เราจะระบุค่าบางส่วนสำหรับพารามิเตอร์เหล่านี้ และใช้ Estimator primitive จาก Qiskit Aer เพื่อคำนวณค่าคาดหวังที่แม่นยำของ observable
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import EstimatorV2 as Estimator
observable = SparsePauliOp("Z" * n_qubits)
params = [0.1] * circuit.num_parameters
exact_estimator = Estimator()
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value
0.8870140234256602
ตอนนี้ มาเริ่มต้นแบบจำลองสัญญาณรบกวนที่รวม depolarizing error 2% บน CX gate ทุกตัวกัน ในทางปฏิบัติ ข้อผิดพลาดที่เกิดจาก two-qubit gate ซึ่งในที่นี้คือ CX gate เป็นแหล่งข้อผิดพลาดหลักเมื่อรัน circuit ดูที่ สร้างแบบจำลองสัญญาณรบกวน สำหรับภาพรวมของการสร้างแบบจำลองสัญญาณรบกวนใน Qiskit Aer
ในเซลล์ถัดไป เราจะสร้าง Estimator ที่รวมแบบจำลองสัญญาณรบกวนนี้ และใช้มันคำนวณค่าคาดหวังของ observable
from qiskit_aer.noise import NoiseModel, depolarizing_error
noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noisy_estimator = Estimator(
options=dict(backend_options=dict(noise_model=noise_model))
)
job = noisy_estimator.run([pub])
result = job.result()
pub_result = result[0]
noisy_value = float(pub_result.data.evs)
noisy_value
0.7247404214143528
อย่างที่เห็น ค่าคาดหวังเมื่อมีสัญญาณรบกวนนั้นห่างจากค่าที่ถูกต้องค่อนข้างมาก ในทางปฏิบัติ คุณสามารถใช้เทคนิคการลดข้อผิดพลาดหลายรูปแบบเพื่อต่อสู้กับผลกระทบของสัญญาณรบกวน แต่การอภิปรายเกี่ยวกับเทคนิคเหล่านี้อยู่นอกขอบเขตของบทความนี้
เพื่อให้เห็นภาพคร่าวๆ ว่าสัญญาณรบกวนส่งผลต่อผลลัพธ์สุดท้ายอย่างไร ให้พิจารณาแบบจำลองสัญญาณรบกวนของเรา ซึ่งเพิ่ม depolarizing error 2% ให้กับแต่ละ CX gate Depolarizing error ที่มีความน่าจะเป็น ถูกกำหนดเป็น quantum channel ที่มีการกระทำต่อ density matrix ดังนี้:
โดยที่ คือจำนวน qubit ซึ่งในกรณีนี้คือ 2 กล่าวคือ ด้วยความน่าจะเป็น สถานะจะถูกแทนที่ด้วย completely mixed state และสถานะจะถูกรักษาไว้ด้วยความน่าจะเป็น หลังจากการใช้งาน depolarizing channel ครั้ง ความน่าจะเป็นที่สถานะจะถูกรักษาไว้จะเป็น ดังนั้น เราคาดว่าความน่าจะเป็นในการรักษาสถานะที่ถูกต้องไว้ตอนสิ้นสุดการจำลองจะลดลงแบบ exponential ตามจำนวน CX gate ใน circuit ของเรา
มาลองนับจำนวน CX gate ใน circuit ของเราและคำนวณ กัน เราเรียก count_ops เพื่อรับ dictionary ที่แมป gate name ไปยังจำนวน และดึงรายการสำหรับ CX gate
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count
0.6542558123199923
ค่านี้ 65% ให้การประมาณคร่าวๆ ของความน่าจะเป็นที่สถานะสุดท้ายของเราถูกต้อง เป็นการประมาณแบบ conservative เพราะไม่ได้คำนึงถึงสถานะเริ่มต้นของการจำลอง
โค้ดเซลล์ต่อไปนี้แสดงวิธีใช้ Sampler primitive จาก Qiskit Aer เพื่อสุ่มตัวอย่างจาก circuit ที่มีสัญญาณรบกวน เราต้องเพิ่มการวัดลงใน circuit ก่อนที่จะรันด้วย Sampler primitive
from qiskit_aer.primitives import SamplerV2 as Sampler
measured_circuit = circuit.copy()
measured_circuit.measure_all()
noisy_sampler = Sampler(
options=dict(backend_options=dict(noise_model=noise_model))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params, 100)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
pub_result.data.meas.get_counts()
{'00000000': 63,
'01000000': 4,
'00100000': 1,
'11000000': 3,
'00010000': 1,
'00000101': 1,
'01011000': 1,
'00000011': 1,
'00000010': 1,
'10000000': 4,
'00101000': 2,
'00000001': 1,
'00011110': 1,
'00000110': 1,
'00001100': 1,
'00001000': 1,
'10000110': 1,
'01010000': 2,
'10100000': 2,
'00010100': 1,
'11100000': 2,
'11110000': 1,
'01100000': 1,
'00110000': 1,
'00000100': 1,
'00001111': 1}
ขั้นตอนถัดไป
- สำหรับการจำลอง circuit ขนาดเล็กและเรียบง่าย ดูที่ การจำลองแบบแม่นยำด้วย Qiskit primitives
- อ่านเอกสาร Qiskit Aer