รันเวิร์กโฟลว์ที่มีการจัดการ
เวอร์ชันของแพ็กเกจ
โค้ดในหน้านี้พัฒนาขึ้นโดยใช้ข้อกำหนดต่อไปนี้ เราแนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit-serverless~=0.38.0
job ของเวิร์กโฟลว์ที่มีการจัดการทำงานเหมือน batch job ที่คุณส่งไปยังตัวจัดตารางเวลาของ HPC run() ส่ง job และคืนออบเจกต์ Job ทันที ใช้ออบเจกต์ Job สำหรับงานที่ squeue ไฟล์เอาต์พุตของ job และ scancel ทำบนคลัสเตอร์ job จะรันต่อไปแม้คุณปิดโน้ตบุ๊กแล้ว
ตัวอย่างในหน้านี้ใช้เวิร์กโฟลว์เล็ก ๆ ที่อ่านมุมหนึ่งค่า theta และล้มเหลวหากมุมอยู่นอกช่วง อัปโหลดตามที่อธิบายในปรับใช้เวิร์กโฟลว์ที่มีการจัดการชิ้นแรกของคุณ
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit_ibm_catalog": "qiskit-ibm-catalog", "qiskit_serverless": "qiskit-serverless"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
# This cell is hidden from users. It creates the working directory.
from pathlib import Path
Path("./source_files").mkdir(exist_ok=True)
%%writefile ./source_files/my_workflow.py
import math
from qiskit_serverless import get_arguments, save_result
arguments = get_arguments()
theta = arguments["theta"]
if not 0 <= theta <= math.pi:
raise ValueError(f"theta must be between 0 and pi, got {theta}")
print(f"Computing the expectation value for theta={theta}", flush=True)
save_result({"theta": theta, "expectation_value": math.cos(theta)})
Writing ./source_files/my_workflow.py
เริ่ม job
รับเวิร์กโฟลว์ด้วยชื่อ แล้วเรียก run() พร้อมอาร์กิวเมนต์ที่เวิร์กโฟลว์อ่าน:
# This cell is hidden from users. It uploads the workflow under a title that
# other test notebooks do not use, and makes load("my-workflow") return it.
# It also silences the account warning that job.cancel() logs.
import logging
from qiskit_ibm_catalog import ManagedWorkflow, ManagedWorkflowClient
logging.getLogger("qiskit_ibm_runtime").setLevel(logging.ERROR)
_test_title = "docs-run-managed-workflow"
ManagedWorkflowClient().upload(
ManagedWorkflow(
title=_test_title,
entrypoint="my_workflow.py",
working_dir="./source_files/",
)
)
_load = ManagedWorkflowClient.load
ManagedWorkflowClient.load = lambda self, title, *a, **k: _load(
self, _test_title if title == "my-workflow" else title, *a, **k
)
run_workflow_remotely.ipynb
from qiskit_ibm_catalog import ManagedWorkflowClient
client = ManagedWorkflowClient()
my_workflow = client.load("my-workflow")
job = my_workflow.run(theta=0.5)
job_id = job.job_id
run() คืนค่าหลังจากเวิร์กโฟลว์จัดคิว job แล้ว บันทึก job ID ไว้เพื่อค้นหา job จากเซสชันใหม่
-
หากต้องการเลือกอาร์กิวเมนต์ที่เวิร์กโฟลว์รับและตรวจสอบก่อน job เริ่ม ดูกำหนดอินพุตและเอาต์พุต
-
หากต้องการรัน job บนขนาดการประมวลผลอื่น ให้ส่ง
function_sizeดูเลือกขนาดสำหรับแต่ละการรัน
ติดตาม job
ตรวจสอบสถานะ
ทันทีหลังจากเรียก run() สถานะมักเป็น QUEUED:
run_workflow_remotely.ipynb
job.status()
'QUEUED'
| สถานะ | ความหมาย |
|---|---|
QUEUED | job รอช่องประมวลผล |
INITIALIZING | เวิร์กโฟลว์กำลังเริ่มสภาพแวดล้อมด้วยโปรไฟล์การประมวลผลของ job |
RUNNING | entrypoint ของเวิร์กโฟลว์กำลังทำงาน |
RUNNING: <stage> | entrypoint รายงานขั้นตอนด้วย update_status() เช่น RUNNING: WAITING_FOR_QPU |
CANCELING | คุณยกเลิก job และเวิร์กโฟลว์กำลังหยุดมัน |
DONE | entrypoint ออกจากการทำงานสำเร็จ |
ERROR | entrypoint เกิดข้อผิดพลาดหรือออกด้วยรหัสที่ไม่ใช่ศูนย์ ดูหาสาเหตุของข้อผิดพลาด |
CANCELED | คุณยกเลิก job หรือ job ถึงขีดจำกัด 24 ชั่วโมง |
DONE, ERROR และ CANCELED เป็นสถานะสุดท้าย และ job.in_terminal_state() คืนค่า True สำหรับสถานะเหล่านี้ ลูปตรวจสถานะที่รอค่าอื่น เช่น SUCCEEDED จะไม่มีวันสิ้นสุด
รอให้ job สิ้นสุด
หากต้องการรอจน job สิ้นสุด ให้เรียก wait_for_final_state() ซึ่งคืนสถานะสุดท้าย และเมื่อใช้ verbose=True จะพิมพ์ทุกครั้งที่สถานะเปลี่ยน หากกำหนด timeout เป็นวินาที wait_for_final_state() จะยก TimeoutError เมื่อหมดเวลาก่อน job สิ้นสุด job จะรันต่อไป:
run_workflow_remotely.ipynb
job.wait_for_final_state(timeout=600, verbose=True)
Waiting for job 3f2a1c0e-6b1d-4c0e-9a51-2f0c4d1e7a90
0:00:00 QUEUED
0:02:10 RUNNING
0:03:05 RUNNING: WAITING_FOR_QPU
0:41:44 DONE
'DONE'
wait_for_final_state() ตรวจสถานะหลัง 1, 2, 4, 8, 16 และ 32 วินาที แล้วทุก 60 วินาที ดังนั้นจึงเห็นการสิ้นสุดของ job สั้น ๆ ภายในไม่กี่วินาที และส่งคำขอน้อยสำหรับ job ยาว หากต้องการตรวจที่ช่วงเวลาคงที่แทน ให้ส่ง poll_interval เป็นวินาที
อ่านบันทึก
ทุกอย่างที่เวิร์กโฟลว์เขียนไปยัง standard output หรือ standard error จะไปอยู่ในบันทึกของ job คุณอ่านได้ด้วย job.logs() ขณะ job รันอยู่ ก่อนที่จะมีผลลัพธ์:
# This cell is hidden from users. It waits for the job to end, so that the
# logs are complete.
job.wait_for_final_state()
run_workflow_remotely.ipynb
print(job.logs())
Computing the expectation value for theta=0.5
# This cell is hidden from users. It checks the logs.
assert "Computing the expectation value for theta=0.5" in job.logs()
-
เวิร์กโฟลว์อัปโหลดบรรทัดบันทึกใหม่ทุกประมาณ 15 วินาที และอีกครั้งสุดท้ายเมื่อ job สิ้นสุดหรือถูกยกเลิก ทันทีหลัง job เริ่ม
job.logs()จะคืนNo logs yet. -
เวิร์กโฟลว์เก็บบันทึกล่าสุด 50 MB ต่อ job และเพิ่มบรรทัดที่ด้านบนเพื่อบอกว่าบันทึกถูกตัดทอน
หากต้องการกำหนดว่าเวิร์กโฟลว์ของคุณบันทึกอะไร ดูเขียนบันทึก หากต้องการแสดงเฉพาะบรรทัดที่ตรงกับ regular expression ให้ส่ง include ไปที่ job.filtered_logs() หากต้องการซ่อนบรรทัด ให้ส่ง exclude
รับผลลัพธ์
job.result() รอจน job สิ้นสุด แล้วคืนค่าที่เวิร์กโฟลว์ส่งให้ save_result():
run_workflow_remotely.ipynb
job.result()
{'theta': 0.5, 'expectation_value': 0.8775825618903728}
# This cell is hidden from users. It checks the result.
assert _ == {"theta": 0.5, "expectation_value": 0.8775825618903728}, _ # noqa: F821
โดยค่าเริ่มต้น job.result() ตรวจสถานะทุก 30 วินาทีและรอโดยไม่จำกัดเวลา ส่ง maxwait เพื่อจำกัดจำนวนครั้งที่ตรวจ ตัวอย่างเช่น job.result(maxwait=40) รอประมาณ 20 นาที หากต้องการตรวจหนึ่งครั้งโดยไม่รอ ให้ส่ง wait=False หาก job.result() หยุดรอก่อน job สิ้นสุด จะคืน {}
ตรวจว่าแต่ละขั้นตอนใช้เวลานานเท่าใด
job.events() แสดงรายการการเปลี่ยนสถานะและขั้นตอนทุกครั้งของ job พร้อมเวลา คุณจึงเห็นว่า job รอการประมวลผลนานเท่าใดและแต่ละขั้นตอนใช้เวลานานเท่าใด:
run_workflow_remotely.ipynb
for event in reversed(job.events()):
print(
event.created,
event.data.get("status") or event.data.get("sub_status"),
)
2026-11-02T14:43:07.134377Z QUEUED
2026-11-02T14:43:24.474199Z PENDING
2026-11-02T14:46:07.309519Z RUNNING
2026-11-02T14:46:21.115038Z SUCCEEDED
# This cell is hidden from users. It checks the events.
_statuses = [e.data.get("status") for e in job.events()]
assert "QUEUED" in _statuses and "SUCCEEDED" in _statuses, _statuses
events ใช้ชื่อสถานะที่จัดเก็บไว้ PENDING คือ INITIALIZING และ SUCCEEDED คือ DONE สำหรับการใช้ QPU ของการรัน ดูค้นหา QPU job ของการรัน
หาสาเหตุของข้อผิดพลาด
เมื่อเวิร์กโฟลว์ยกข้อยกเว้น job จะสิ้นสุดด้วยสถานะ ERROR ตัวอย่างเช่น รันเวิร์กโฟลว์ด้วยมุมที่มันปฏิเสธ:
run_workflow_remotely.ipynb
failed_job = my_workflow.run(theta=-1.0)
# This cell is hidden from users. It waits for the job to end.
failed_job.wait_for_final_state()
run_workflow_remotely.ipynb
failed_job.status()
'ERROR'
บันทึกแสดง traceback:
run_workflow_remotely.ipynb
print(failed_job.logs())
Traceback (most recent call last):
File "/function_user_data/my_workflow.py", line 8, in <module>
raise ValueError(f"theta must be between 0 and pi, got {theta}")
ValueError: theta must be between 0 and pi, got -1.0
job.result() raises a QiskitServerlessException:
run_workflow_remotely.ipynb
from qiskit_serverless.exception import QiskitServerlessException
try:
failed_job.result()
except QiskitServerlessException as error:
print(error)
raise ValueError(f"theta must be between 0 and pi, got {theta}")
ValueError: theta must be between 0 and pi, got -1.0
# This cell is hidden from users. It checks the error.
assert failed_job.status() == "ERROR", failed_job.status()
assert (
"ValueError: theta must be between 0 and pi, got -1.0"
in failed_job.logs()
)
assert failed_job.events(type="ERROR") == []
หากเวิร์กโฟลว์รายงานข้อผิดพลาดด้วย send_error() ให้อ่านด้วย job.events(type="ERROR") และอ่านข้อความของมันด้วย job.error_message() สำหรับ job ที่ไม่มีข้อผิดพลาดที่รายงาน job.events(type="ERROR") คืนลิสต์ว่าง และ job.error_message() คืน {}
run_workflow_remotely.ipynb
for event in job.events(type="ERROR"):
print(event.created, event.data.get("code"), event.data.get("message"))
จัดการ job
ยกเลิก job
ยกเลิก job ด้วย job.cancel() สถานะเปลี่ยนเป็น CANCELING ขณะเวิร์กโฟลว์หยุด job แล้วเปลี่ยนเป็น CANCELED:
run_workflow_remotely.ipynb
job_to_cancel = my_workflow.run(theta=1.0)
job_to_cancel.cancel()
'Job has been stopped. No active runtime job ID associated with this serverless job ID.'
# This cell is hidden from users. It checks the cancellation.
assert (
job_to_cancel.wait_for_final_state() == "CANCELED"
), job_to_cancel.status()
job.cancel() คืนข้อความเกี่ยวกับ job และQPU job ที่เชื่อมโยงของมัน ซึ่งมันพยายามยกเลิกด้วย สำหรับ job ที่กำลังรัน เวิร์กโฟลว์ส่ง SIGTERM ไปยัง entrypoint ของคุณ หากต้องการบันทึกผลลัพธ์บางส่วน ดูล้างข้อมูลเมื่อ job ถูกยกเลิก หาก job สิ้นสุดไปแล้ว job.cancel() จะคืน Job already in terminal state. และไม่เปลี่ยนแปลงอะไร
ค้นหา job จากเซสชันใหม่
ออบเจกต์ Job และเวิร์กโฟลว์มีอยู่เฉพาะในเซสชัน Python ปัจจุบันของคุณ หลังรีสตาร์ตเคอร์เนลของโน้ตบุ๊ก ให้ส่ง job ID ที่บันทึกไว้ไปที่ client.job() หรือแสดงรายการ job ล่าสุดของคุณด้วย client.jobs():
run_workflow_remotely.ipynb
from qiskit_ibm_catalog import ManagedWorkflowClient
client = ManagedWorkflowClient()
job = client.job(job_id)
my_workflow = client.load("my-workflow")
client.jobs(function=my_workflow, status="ERROR", limit=5)
[<Job | e6b1ffa1-cd26-437d-bd53-b265dd4ba952>,
<Job | 11308f2a-8d7a-40a0-a970-7fdeca2b171b>,
<Job | af597785-3470-469a-9051-607e0185892e>,
<Job | a9051931-3bc2-4b80-9ce6-c39d28ce260c>,
<Job | e329e8e3-e955-4188-9bfd-8f3050ee2d39>]
# This cell is hidden from users. It checks the job lookups.
assert job.result()["theta"] == 0.5
assert failed_job.job_id in [j.job_id for j in _] # noqa: F821
client.jobs() คืน 10 job ล่าสุดของคุณ เรียงใหม่สุดก่อน กรองด้วย function, status (จากตารางสถานะ) หรือ created_after (เวลาแบบ ISO 8601) และเลื่อนดูทีละหน้าด้วย limit และ offset หากต้องการแสดงรายการเวิร์กโฟลว์ที่คุณอัปโหลด ให้เรียก client.list()
ตาราง Workloads บน IBM Quantum Platform ก็แสดงรายการ job ของคุณเช่นกัน พร้อมสถานะ โปรไฟล์การประมวลผล และเวลาที่ใช้รัน
ขีดจำกัดเวลา
เวิร์กโฟลว์ที่มีการจัดการจะยกเลิก job ที่รันนานกว่า 24 ชั่วโมง และ job จะสิ้นสุดด้วยสถานะ CANCELED ระหว่างการรันที่ยาวนาน ให้บันทึก checkpoint ลงที่เก็บไฟล์ เพื่อไม่ให้งานสูญหาย
แก้ไขปัญหา job
| ปัญหา | สาเหตุ |
|---|---|
run() ล้มเหลวด้วย Code: 429 และ Active job limit reached. | คุณถึงขีดจำกัด job ที่ใช้งานอยู่ รอให้ job บางส่วนสิ้นสุด หรือยกเลิก job ที่คุณไม่ต้องการแล้ว |
job อยู่ในสถานะ QUEUED ค้าง และ run() เตือนว่า your account, plan or subscription is blocked | job จะไม่เริ่มจนกว่าการบล็อกบัญชี แผน หรือการสมัครใช้งานของคุณจะถูกยกเลิก ติดต่อผู้ดูแลระบบของคุณ |
job.logs() คืน No logs yet. | job อยู่ในคิวหรือเพิ่งเริ่ม รอประมาณ 15 วินาที |
job.result() คืน {} | job ยังไม่สิ้นสุด ถูกยกเลิก หรือไม่ได้บันทึกผลลัพธ์ ดูบันทึกผลลัพธ์ |
job.error_message() คืน {} | เวิร์กโฟลว์ยกข้อยกเว้นโดยไม่ได้รายงานข้อผิดพลาด อ่าน traceback ด้วย job.logs() |
job เป็น CANCELED แต่คุณไม่ได้ยกเลิก | job ถึงขีดจำกัด 24 ชั่วโมง |
ขั้นตอนถัดไป
- เขียนบันทึกและจัดการข้อผิดพลาด เพื่อตั้งค่าบันทึกและข้อผิดพลาดที่ job รายงาน
- รัน parameter sweep เพื่อรันเวิร์กโฟลว์หนึ่งครั้งต่อชุดอินพุตแต่ละชุด