주 콘텐츠로 건너뛰기
이 프로젝트는 베타 단계입니다. 버그를 발견하셨나요? GitHub 이슈 만들기. 질문이나 아이디어가 있으신가요? Discussions에서 질문하기 — 피드백을 기다립니다!
이 페이지의 번역 품질은 어떻습니까?

입력과 출력 정의

관리형 워크플로는 원격 컴퓨트에서 실행되는 Python 함수처럼 동작합니다. 로컬 함수와 동일한 코드를 워크플로로 만든 경우를 비교해 보세요.

Local Python

def my_workflow(circuits, shots=4096):
...
return {"counts": counts}

result = my_workflow(circuits=circuits, shots=1024)

관리형 워크플로에서 run()은 호출이고, get_arguments()는 워크플로에 매개변수를 제공하며, save_result()는 return 문에 해당합니다. 워크플로는 원격 컴퓨트에서 별도의 작업으로 실행되므로 로컬 함수 호출과 세 가지 점에서 다릅니다.

  • 클라이언트가 인수와 결과를 인코딩합니다. 각 값은 클라이언트가 인코딩할 수 있어야 하며, 일부 타입은 변경됩니다. 워크플로에서 인수 읽기를 참고하세요.

  • 호출이 기다리지 않습니다. run()은 작업을 즉시 반환하며, 결과는 나중에 job.result()로 읽습니다. 결과 저장을 참고하세요.

  • 호출을 검사하는 것이 없습니다. Python 함수는 알 수 없는 키워드 인수를 거부하지만, 워크플로는 스키마를 연결하지 않으면 이를 무시합니다. 모범 사례: 스키마로 인수 검증하기를 참고하세요.

Your local notebook, run_workflow_remotely.ipynb, calls run(args). A workflow runs an optional schema check, then creates the managed workflow job, source_files/my_workflow.py. The job reads its arguments with get_arguments(), runs your code, such as mapping, transpiling circuits, running primitives, and post-processing, and returns a result with save_result(). A workflow stores the result, and your notebook reads it with job.result().

워크플로에서 인수 읽기​

로컬 노트북에서 워크플로에 입력을 전달합니다.

run_workflow_remotely.ipynb

job = my_workflow.run(circuits=circuits, shots=1024)

이를 활성화하려면 워크플로 코드를 수정해 get_arguments()로 인수를 가져오세요. 이 함수는 키가 인수 이름인 딕셔너리를 반환합니다.

source_files/my_workflow.py

from qiskit_serverless import get_arguments

arguments = get_arguments()
circuits = arguments["circuits"]
shots = arguments.get("shots", 4096)

딕셔너리에는 실행에서 전달한 인수만 들어 있으므로, 선택적 인수에는 기본값과 함께 arguments.get()을 사용하세요. run()이 직접 사용하는 보호된 키워드 config와 function_size를 제외하면 어떤 인수 이름이든 사용할 수 있습니다. run()은 compute_profile도 거부합니다. 컴퓨트 리소스를 선택하려면 function_size를 전달하세요.

작업이 실행되는 크기를 읽으려면 워크플로 코드에서 get_function_size()를 호출하세요.

source_files/my_workflow.py

from qiskit_serverless import get_function_size

size = get_function_size() # For example, "M"

실행에서 function_size를 전달하지 않으면 get_function_size()는 워크플로의 기본 크기를 반환합니다. 실행마다 크기 선택하기를 참고하세요.

지원되는 인수 타입​

각 값은 JSON으로 직렬화할 수 있거나, Qiskit 회로나 NumPy 배열처럼 클라이언트가 인코딩할 수 있는 객체여야 합니다. 클라이언트가 작업을 보내기 전에 각 인수를 인코딩하고 get_arguments()가 워크플로 안에서 이를 디코딩하므로, 워크플로는 원래의 Python 객체를 받습니다.

클라이언트는 int, float, str, bool, None, 그리고 이들의 리스트나 딕셔너리를 그대로 보냅니다. QuantumCircuit, numpy.ndarray, complex 수와 같은 다른 객체는 __type__ 태그와 __value__가 있는 딕셔너리로 인코딩합니다. 인수 스키마를 작성할 때 이 형식이 필요합니다.

JSON에는 일부 타입에 대응하는 형식이 없으므로 이러한 타입은 인코딩 중에 바뀝니다. 튜플은 리스트로, 딕셔너리 키는 문자열로, np.int64 같은 NumPy 정수는 int로 도착합니다. bytes나 np.float32처럼 클라이언트가 인코딩할 수 없는 값이면 run()은 TypeError를 발생시키고 작업을 만들지 않습니다.

일부 객체는 인수로 전달할 수 없습니다. 예를 들어 Backend 객체 대신 백엔드 이름을 문자열로 전달하고, 워크플로 안에서 백엔드를 생성하세요. 워크플로에서 양자 작업 실행하기를 참고하세요.

크기 제한​

한 번 실행의 인수는 인코딩 후 최대 32 MB까지 가능합니다. 예를 들어 깊이가 100인 100큐비트 회로 하나는 약 39 KB로 인코딩되므로, 한 번의 실행에서 이러한 회로 약 800개의 배치를 처리할 수 있습니다. 더 큰 입력은 파일을 업로드하고 파일 이름을 인수로 전달하세요.

결과 저장​

워크플로 끝에서 save_result()를 사용해 결과를 노트북으로 반환하세요. 노트북에서는 job.result()로 결과를 읽습니다.

run_workflow_remotely.ipynb

result = job.result()

이를 활성화하려면 워크플로 코드에서 save_result()를 호출하세요.

source_files/my_workflow.py

from qiskit_serverless import save_result

if not save_result({"counts": counts, "circuit": isa_circuit}):
raise ValueError("The result could not be encoded.")

save_result()는 클라이언트가 인수를 인코딩하는 것과 같은 방식으로 결과를 인코딩하고, job.result()가 이를 디코딩합니다. 따라서 결과에는 회로, NumPy 배열, 프리미티브 작업의 결과와 같은 지원되는 인수 타입이 같은 타입 변경과 함께 들어갈 수 있습니다.

  • 반환값을 확인하세요. save_result()가 값을 인코딩할 수 없으면 오류를 발생시키는 대신 경고를 기록하고 False를 반환합니다. 확인하지 않으면 작업이 결과 없이 DONE 상태로 끝날 수 있습니다.

  • 마지막 save_result()만 저장됩니다. 호출할 때마다 저장된 결과가 대체됩니다. 여러 값을 반환하려면 하나의 딕셔너리에 저장하거나 로그에 기록하세요.

  • 빈 딕셔너리는 결과가 없다는 뜻입니다. 워크플로가 save_result()를 한 번도 호출하지 않으면 job.result()는 {}를 반환합니다.

큰 배열이나 그림과 같은 파일을 반환하려면 파일 저장소에 저장하고 결과에 파일 이름을 반환하세요.

모범 사례: 스키마로 인수 검증하기​

모범 사례로, 인수를 받는 모든 워크플로에 JSON Schema를 연결하세요. 스키마는 워크플로가 받아들이는 인수를 설명하며, 워크플로는 작업을 만들기 전에 매 실행의 인수를 이 스키마와 대조합니다. 인수가 일치하지 않으면 run()은 잘못된 필드를 알려 주는 오류와 함께 즉시 실패하며, 워크플로는 작업을 만들지 않습니다. 스키마가 없으면 잘못된 인수가 작업이 시작된 뒤에야 워크플로에 도달하고, 워크플로는 철자가 틀린 인수 이름을 무시합니다.

워크플로를 업로드할 때 arguments_schema로 스키마를 설정하세요. JSON 문자열이 아니라 딕셔너리를 전달하세요.

run_workflow_remotely.ipynb

from qiskit_ibm_catalog import ManagedWorkflow, ManagedWorkflowClient

arguments_schema = {
"type": "object",
"additionalProperties": False,
"required": ["circuits"],
"properties": {
"circuits": {
"type": "array",
"minItems": 1,
"items": {"$ref": "#/$defs/circuit"},
},
"shots": {"type": "integer", "minimum": 1, "maximum": 100000},
"backend_name": {"type": "string", "minLength": 1},
},
"$defs": {
"circuit": {
"type": "object",
"required": ["__type__", "__value__"],
"properties": {
"__type__": {"const": "QuantumCircuit"},
"__value__": {"type": "string"},
},
}
},
}

client = ManagedWorkflowClient()

my_workflow = client.upload(
ManagedWorkflow(
title="my-workflow",
entrypoint="my_workflow.py",
working_dir="./source_files/",
arguments_schema=arguments_schema,
)
)

스키마를 작성할 때 다음 사항을 염두에 두세요.

  • Qiskit과 NumPy 객체의 인코딩된 형태를 기술하세요. 스키마는 클라이언트가 보내는 형태로 인수를 검사하므로, 회로는 문자열이나 배열이 아니라 {"__type__": "QuantumCircuit", "__value__": "<base64-encoded QPY>"} 같은 객체입니다. __type__ 태그를 확인하고 __value__는 불투명한 문자열로 취급하세요. 회로를 문자열로 기술한 스키마는 유효한 실행을 모두 거부합니다.

  • "additionalProperties": false를 설정하세요. 이 설정이 없으면 워크플로는 shotz처럼 철자가 틀린 인수 이름을 경고 없이 무시하고 기본값으로 실행합니다. 이 설정을 활성화하기 전에 워크플로가 받아들이는 모든 인수를 선언하세요.

  • 인수를 필수로 표시하세요. 워크플로가 기본값 없이 읽는 각 인수를 required에 추가하세요.

인수가 스키마와 일치하지 않으면 오류 메시지에 규칙과 잘못된 값의 위치가 표시됩니다.

'type' validation failed, schema requires 'integer': rejected value '4096'
path: ['shots']

스키마는 각 인수의 타입, 형태, 범위를 검사합니다. 유효한 두 인수가 서로 충돌하는지, 또는 회로가 백엔드에 맞는지는 검사할 수 없습니다. 이러한 검사는 워크플로 코드에서 하세요.

스키마 업데이트 또는 제거​

  • 스키마를 교체하려면 새 arguments_schema를 설정하고 워크플로를 다시 업로드하세요.

  • 스키마를 제거하려면 arguments_schema={}로 워크플로를 업로드하세요.

  • arguments_schema 없이 워크플로를 업로드하면 워크플로는 저장된 스키마를 유지합니다.

현재 적용 중인 스키마를 보려면 my_workflow.arguments_schema를 읽으세요. 값이 None이면 워크플로에 스키마가 없다는 뜻입니다.

실행 전에 인수 확인하기​

validate_arguments()를 호출하면 작업을 시작하지 않고 인수 집합을 스키마와 대조해 확인할 수 있습니다.

run_workflow_remotely.ipynb

my_workflow.validate_arguments({"circuits": [circuit], "shots": 1024})
# {'valid': True}

인수가 유효하지 않으면 validate_arguments()는 run()이 해당 인수에 대해 반환하는 것과 같은 메시지로 QiskitServerlessException을 발생시킵니다. 워크플로에 스키마가 없으면 모든 인수가 유효합니다. run()은 활성 작업 수와 같은 다른 제한도 확인하므로, 유효하다는 결과가 run()의 성공을 보장하지는 않습니다.

스키마 규칙​

스키마가 다음 규칙 중 하나라도 위반하면 관리형 워크플로는 업로드를 거부합니다.

  • 스키마는 최대 64 KiB, 중첩 최대 64단계, 하위 스키마 최대 200개까지 가능합니다.

  • 참조는 #/$defs/circuit처럼 같은 스키마 내부를 가리켜야 하며, 모든 참조가 해석되어야 합니다. URL이나 파일에 대한 참조는 허용되지 않습니다.

  • 스키마는 객체 또는 불리언이어야 합니다.

업로드에서 걸러지지 않는 다음 문제도 피하세요.

  • pattern의 중첩된 한정자. ^(a+)+$ 같은 패턴은 평가하는 데 매우 오래 걸릴 수 있습니다. 워크플로는 CPU 시간 제한이 지나면 검증을 중단하고 실행을 거부합니다. ^ibm_[a-z0-9_]{1,40}$처럼, 이미 한정자를 포함한 그룹을 다시 한정자로 감싸지 않도록 패턴을 작성하세요.

  • 스키마로서의 false. 스키마 false는 모든 실행을 거부합니다. 검증을 없애려면 {}를 사용하세요.

스키마 문제 해결​

문제원인
회로 인수에서 모든 실행이 거부됩니다.스키마가 회로를 문자열이나 배열로 기술합니다. __type__ 태그가 있는 객체로 기술하세요.
유효한 실행이 거부됩니다.additionalProperties가 false인데 스키마가 실행에서 전달한 인수를 선언하지 않았습니다. 오류의 path가 해당 인수를 알려 줍니다.
잘못된 실행이 거부되지 않습니다.워크플로에 스키마가 없습니다. my_workflow.arguments_schema를 확인하세요.
스키마를 설정했는데도 어떤 실행도 검사되지 않습니다.스키마를 JSON 문자열로 전달했습니다. 딕셔너리를 전달하세요.
업로드가 400 오류로 실패합니다.스키마가 스키마 규칙 중 하나를 위반합니다.
검증에 CPU 시간이 너무 많이 걸렸다는 오류가 나옵니다.pattern에 중첩된 한정자가 있습니다. 패턴을 다시 작성하세요.