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

실행 간 파일 관리

관리형 워크플로 작업은 HPC 컴퓨트 노드의 배치 작업처럼 동작합니다. 작업의 로컬 디스크는 스크래치 공간입니다. 작업은 여기에 쓸 수 있지만 작업이 끝나면 워크플로가 이를 삭제합니다. 작업이 끝난 후에도 파일을 보관하려면 개인 스토리지 버킷처럼 동작하는 파일 스토리지에 저장하세요. 업로드한 파일과 워크플로가 저장한 파일은 파일 스토리지에 남으며, 이후 워크플로 실행에서 읽을 수 있습니다.

각 워크플로에는 사용자마다 별도의 파일 스토리지가 있습니다. 같은 워크플로를 실행하는 다른 사용자는 내 파일을 볼 수 없습니다.

File storage for the workflow sits at the center. Your local notebook reaches it with the client file methods file_upload(), files(), file_download(), and file_delete(). File storage is yours only, because other users of the workflow do not see your files. It is kept after each job ends and is shared by all of your runs, and a file with the same name replaces the earlier file. Each job sees file storage as the folder /function_user_data. Run 1 also has a local disk at /tmp, which is deleted when the job ends, and copies finished files from /tmp to /function_user_data. Run 2 reads the files that earlier runs saved.

입력 파일 업로드​

file_upload()로 로컬 노트북에서 파일을 업로드한 다음 files()로 스토리지의 파일을 나열하세요.

run_workflow_remotely.ipynb

from qiskit_ibm_catalog import ManagedWorkflowClient

client = ManagedWorkflowClient()
my_workflow = client.load("my-workflow")

client.file_upload("hamiltonian.npz", my_workflow)
print(client.files(my_workflow))
['hamiltonian.npz']

지원되는 파일 유형​

관리형 워크플로는 확장자가 아니라 업로드된 각 파일의 내용을 확인하며 다른 유형의 파일은 거부합니다.

허용거부
JSON, 일반 텍스트, YAML, Python 파일, NumPy(.npy, .npz), QPY, pickle 파일 같은 바이너리 파일, tar, gzip, zip 아카이브CSV, PNG, PDF, HDF5, 빈 파일

파일 이름​

  • 문자, 숫자, 밑줄(_), 하이픈(-), 마침표(.)만 사용하세요. 관리형 워크플로는 파일을 다운로드하거나 삭제할 때 공백 같은 다른 문자를 이름에서 제거합니다. 예를 들어 my results.json은 업로드할 수 있지만 다운로드할 수 없습니다.

  • 파일 스토리지에는 폴더가 없습니다. file_upload()는 파일 이름만 유지하므로 inputs/params.json은 params.json으로 저장됩니다.

워크플로에서 파일 읽기​

워크플로를 실행할 때 파일 이름을 전달하세요.

run_workflow_remotely.ipynb

job = my_workflow.run(input_file="hamiltonian.npz")

이를 사용하려면 모든 작업이 파일 스토리지를 볼 수 있는 위치인 /function_user_data에서 파일을 읽도록 워크플로 코드를 수정하세요.

source_files/my_workflow.py

from pathlib import Path

import numpy as np
from qiskit_serverless import get_arguments

FILE_STORAGE = Path("/function_user_data")

arguments = get_arguments()
hamiltonian = np.load(FILE_STORAGE / arguments["input_file"])

작업 내부에서는 이 폴더를 통해 파일을 읽고 씁니다. file_upload(), file_download() 같은 클라이언트 파일 메서드는 로컬 노트북용입니다.

아카이브를 읽으려면 로컬 디스크에 압축을 푸세요.

source_files/my_workflow.py

import tarfile

with tarfile.open(FILE_STORAGE / "inputs.tar.gz") as tar:
tar.extractall("/tmp/inputs", filter="data")

임시 파일은 /tmp에 쓰세요. 파일 스토리지는 작업이 폴더처럼 보는 오브젝트 스토리지이므로 로컬 디스크보다 느립니다. 읽기와 쓰기가 많은 작업은 로컬 디스크에서 수행하고, 완성된 파일은 파일 스토리지로 복사하세요.

출력 파일 저장​

로컬 노트북은 결과에서 출력 파일의 이름을 읽습니다.

run_workflow_remotely.ipynb

result = job.result()
print(result["output_files"]) # ['energies.npy', 'summary.json']

이를 사용하려면 각 출력 파일을 /function_user_data의 최상위에 저장하고 save_result()로 파일 이름을 반환하세요.

source_files/my_workflow.py

import json

from qiskit_serverless import save_result

np.save(FILE_STORAGE / "energies.npy", energies)
(FILE_STORAGE / "summary.json").write_text(json.dumps({"min_energy": float(energies.min())}))

save_result({"output_files": ["energies.npy", "summary.json"]})

작업이 /tmp나 현재 폴더 등 /function_user_data 밖에 쓴 파일은 작업이 끝나면 삭제됩니다.

출력 파일 다운로드​

작업이 끝난 후 file_download()로 각 파일을 다운로드하세요. target_name으로 로컬 파일 이름을, download_location으로 기존 로컬 폴더를 지정합니다.

run_workflow_remotely.ipynb

from pathlib import Path

Path("outputs").mkdir(exist_ok=True)

for name in result["output_files"]:
client.file_download(name, my_workflow, target_name=name, download_location="outputs")

target_name이 없으면 file_download()는 로컬 파일 이름에 downloaded_3f2a9c1b_energies.npy처럼 임의의 접두사를 붙이고 사용한 이름을 반환합니다.

많은 출력을 하나의 아카이브로 다운로드​

작업이 많은 출력 파일이나 하위 폴더의 파일을 저장한다면 워크플로에서 이를 하나의 아카이브로 묶고 아카이브만 다운로드하세요.

run_workflow_remotely.ipynb

import tarfile

client.file_download(result["archive"], my_workflow, target_name=result["archive"], download_location="outputs")

with tarfile.open(Path("outputs") / result["archive"]) as tar:
tar.extractall("outputs", filter="data")

이를 사용하려면 출력을 로컬 디스크의 폴더에 쓰고, 그 폴더를 /tmp의 아카이브에 추가한 다음 아카이브를 파일 스토리지로 복사하세요.

source_files/my_workflow.py

import shutil
import tarfile

output_dir = Path("/tmp/outputs")
output_dir.mkdir()
np.save(output_dir / "energies.npy", energies)
# Save other outputs, including subfolders, to output_dir

archive_name = f"{run_name}_outputs.tar.gz"
with tarfile.open(Path("/tmp") / archive_name, "w:gz") as tar:
tar.add(output_dir, arcname=run_name)
shutil.copy(Path("/tmp") / archive_name, FILE_STORAGE / archive_name)

save_result({"archive": archive_name})

아카이브는 로컬 디스크에서 만들어 한 번에 복사하므로 파일 스토리지에는 불완전한 아카이브가 남지 않습니다. 아카이브는 폴더 구조를 유지하며 모든 유형의 파일을 담을 수 있습니다. 이 예제에서는 파일이 outputs/<run_name>/에 압축 해제됩니다.

파일 삭제​

관리형 워크플로는 파일 스토리지의 파일을 삭제하지 않으므로, file_delete()로 삭제할 때까지 파일이 남아 있습니다.

run_workflow_remotely.ipynb

client.file_delete("hamiltonian.npz", my_workflow)

file_delete()는 파일이 없어도 성공으로 보고하므로 먼저 files()로 이름을 확인하세요. 한 실행의 모든 파일을 삭제하려면 다음 절에서 설명하는 대로 실행 이름 접두사로 files()를 필터링하세요.

run_workflow_remotely.ipynb

for name in client.files(my_workflow):
if name.startswith("theta-0.1_"):
client.file_delete(name, my_workflow)

모범 사례: 각 실행의 파일에 고유한 이름 지정​

한 워크플로의 모든 실행은 같은 파일 스토리지를 공유하며, 작업이 저장한 파일은 같은 이름으로 저장된 파일을 대체합니다. 여러 실행을 동시에 시작하고 각 실행이 energies.npy를 저장하면 마지막 것만 남습니다.

모범 사례로, 실행 이름을 인수로 전달하고 실행이 저장하는 모든 파일의 이름을 그 이름으로 시작하세요.

run_workflow_remotely.ipynb

jobs = {}
for theta in [0.1, 0.2, 0.3]:
run_name = f"theta-{theta}"
jobs[run_name] = my_workflow.run(run_name=run_name, theta=theta, input_file="hamiltonian.npz")

source_files/my_workflow.py

run_name = arguments["run_name"]
np.save(FILE_STORAGE / f"{run_name}_energies.npy", energies)

모든 실행이 hamiltonian.npz 같은 같은 입력 파일을 읽기만 하므로 함께 읽을 수 있습니다. 공유 입력은 실행을 시작하기 전에 한 번만 업로드하세요.

나중에 알아볼 수 있고 문자, 숫자, 밑줄, 하이픈, 마침표만 포함하는 실행 이름을 사용하세요. 실행마다 접두사가 하나씩 있으면 한 실행의 파일을 함께 찾고, 다운로드하고, 삭제할 수 있습니다.

모범 사례: 긴 작업에 체크포인트 사용​

취소되거나 실패하거나 24시간 제한에 도달한 작업은 파일 스토리지에 없는 모든 것을 잃습니다. 긴 실행에서는 일정한 간격으로 체크포인트를 파일 스토리지에 저장하고, 같은 실행 이름으로 워크플로를 다시 실행할 때 거기서부터 재개하세요.

source_files/my_workflow.py

import json
import shutil

checkpoint = FILE_STORAGE / f"{run_name}_checkpoint.json"

state = {"step": 0, "params": initial_params}
if checkpoint.exists():
state = json.loads(checkpoint.read_text())

for step in range(state["step"], num_steps):
state["params"] = optimize_step(state["params"])
state["step"] = step + 1

if state["step"] % 10 == 0:
local_copy = Path("/tmp") / checkpoint.name
local_copy.write_text(json.dumps(state))
shutil.copy(local_copy, checkpoint)

중지된 실행을 이어가려면 같은 인수로 run()을 다시 호출하세요.

다음 사항을 염두에 두세요.

  • 체크포인트를 먼저 로컬 디스크에 쓴 다음 복사하세요. 쓰는 도중에 작업이 중단되면 저장된 체크포인트가 불완전해져, 다음 실행에서 읽을 수 없습니다.

  • 단계 비용에 맞는 간격을 선택하세요. 작업 손실이 크지 않도록 충분히 자주 저장하되, 체크포인트 쓰기가 작업을 느리게 할 만큼 너무 자주 저장하지는 마세요.

  • 실행이 성공한 후에는 체크포인트를 삭제하세요. 그러면 같은 이름으로 이후에 실행할 때 처음부터 시작합니다.

취소되는 작업의 경우, SIGTERM handler에서 부분 결과를 저장할 수도 있습니다.

다음 단계​

권장 사항