W&B Public APIs를 사용해 데이터를 내보내거나 가져올 수 있습니다.
이 기능을 사용하려면 Python>=3.8이 필요합니다.
W&B는 MLFlow에서 실험, run, 아티팩트, 메트릭 및 기타 메타데이터를 포함한 데이터를 가져오는 것을 지원합니다.
의존성을 설치합니다:
# 참고: py38 이상이 필요합니다
pip install wandb[importers]
W&B에 로그인하세요. 한 번도 로그인한 적이 없다면 화면의 안내에 따라 진행하세요.
기존 MLFlow 서버에서 모든 run을 가져옵니다:
from wandb.apis.importers.mlflow import MlflowImporter
importer = MlflowImporter(mlflow_tracking_uri="...")
runs = importer.collect_runs()
importer.import_runs(runs)
기본적으로 importer.collect_runs()는 MLFlow 서버의 모든 run을 수집합니다. 특정한 일부만 업로드하려면, 직접 run 이터러블을 생성해 importer에 전달할 수 있습니다.
import mlflow
from wandb.apis.importers.mlflow import MlflowRun
client = mlflow.tracking.MlflowClient(mlflow_tracking_uri)
runs: Iterable[MlflowRun] = []
for run in mlflow_client.search_runs(...):
runs.append(MlflowRun(run, client))
importer.import_runs(runs)
Databricks MLflow에서 가져오는 경우, 먼저 Databricks CLI를 구성해야 할 수 있습니다.이전 단계에서 mlflow-tracking-uri="databricks"를 설정하세요.
아티팩트 가져오기를 건너뛰려면 artifacts=False를 인수로 전달하면 됩니다:
importer.import_runs(runs, artifacts=False)
특정 W&B 엔티티와 프로젝트로 가져오려면 Namespace를 전달하면 됩니다:
from wandb.apis.importers import Namespace
importer.import_runs(runs, namespace=Namespace(entity, project))
Public API를 사용하여 W&B에 저장해 둔 데이터를 내보내거나 업데이트할 수 있습니다. 이 API를 사용하기 전에 스크립트에서 데이터를 먼저 로깅해야 합니다. 자세한 내용은 퀵스타트를 확인하세요.
Public API 사용 사례
- 데이터 내보내기: Jupyter Notebook에서 커스텀 분석을 할 수 있도록 데이터프레임을 다운로드합니다. 데이터를 탐색한 후, 새 분석용 run을 생성하고 결과를 로깅하여 발견한 내용을 동기화할 수 있습니다. 예:
wandb.init(job_type="analysis")
- 기존 Runs 업데이트: 특정 W&B run과 연관되어 로깅된 데이터를 업데이트할 수 있습니다. 예를 들어, 처음에는 로깅하지 않았던 아키텍처나 하이퍼파라미터 같은 추가 정보를 포함하도록 여러 run의 config를 업데이트하고자 할 수 있습니다.
사용 가능한 함수에 대한 자세한 내용은 Generated Reference Docs를 참조하세요.
API 키는 사용 중인 머신을 W&B에 인증하는 데 사용됩니다.
API 키를 생성하려면 Personal API key 또는 Service Account API key 탭을 선택해 자세한 내용을 확인하세요.
Personal API key
Service account API key
사용자 ID 소유의 개인 API 키를 생성하려면:
- W&B에 로그인한 다음 사용자 프로필 아이콘을 클릭하고 User Settings를 클릭합니다.
- Create new API key를 클릭합니다.
- API 키에 대한 설명용 이름을 입력합니다.
- Create를 클릭합니다.
- 표시된 API 키를 즉시 복사하여 안전하게 보관합니다.
서비스 계정 소유의 API 키를 생성하려면:
- 팀이나 조직 설정에서 Service Accounts 탭으로 이동합니다.
- 목록에서 서비스 계정을 찾습니다.
- 작업 메뉴(
...)를 클릭한 다음 Create API key를 클릭합니다.
- API 키 이름을 입력한 후 Create를 클릭합니다.
- 표시된 API 키를 바로 복사하여 안전하게 보관합니다.
- Done을 클릭합니다.
하나의 서비스 계정에 대해 여러 개의 API 키를 생성하여 서로 다른 환경이나 워크플로에 사용할 수 있습니다.
전체 API 키는 생성할 때만 한 번 표시됩니다. 대화 상자를 닫으면 전체 API 키를 다시 볼 수 없습니다. 설정에서는 키 ID(키의 첫 부분)만 확인할 수 있습니다. 전체 API 키를 분실한 경우 새 API 키를 생성해야 합니다.
API 키를 안전하게 저장하는 방법은 API 키를 안전하게 저장하기를 참조하세요.
API 키는 W&B 계정에 대한 접근 권한을 제공하므로 비밀번호처럼 보호해야 합니다. 다음 모범 사례를 따르세요:
- Git과 같은 버전 관리 시스템에 API 키를 절대 커밋하지 마세요.
- API 키를 일반 텍스트 설정 파일에 저장하지 마세요.
ps 같은 OS 명령어 출력에서 노출될 수 있으므로, 명령줄 인수로 API 키를 전달하지 마세요.
- 이메일, 채팅, 기타 암호화되지 않은 채널을 통해 API 키를 공유하지 마세요.
- 소스 코드에 API 키를 하드코딩하지 마세요.
API 키가 노출되었다면, 즉시 W&B 계정에서 해당 API 키를 삭제하고 support로 연락하거나 담당 AISE에게 문의하세요.
코드에서 API 키를 사용할 때는 환경 변수로 전달하세요.
export WANDB_API_KEY="your-api-key-here"
이 방식은 키를 소스 코드에 포함하지 않도록 해서 보안을 높이고, 필요할 때 키를 더 쉽게 교체(로테이션)할 수 있게 해 줍니다.
ps와 같은 OS 명령어의 출력에 노출되므로, 명령과 같은 줄에서 환경 변수를 설정하는 방식은 피하세요:# 프로세스 관리자에서 API 키가 노출될 수 있으므로, 아래와 같은 패턴은 피하세요
export WANDB_API_KEY="your-api-key-here" ./my-script.sh
새로운 API 키는 기존 키보다 더 깁니다. 이전 버전의 wandb 또는 weave SDK로 인증할 때 API 키 길이 오류가 발생할 수 있습니다.
해결 방법: SDK를 최신 버전으로 업데이트하세요:
-
wandb SDK v0.22.3+
pip install --upgrade wandb==0.22.3
-
weave SDK v0.52.17+
pip install --upgrade weave==0.52.17
SDK를 바로 업그레이드할 수 없다면, 임시 방편으로 WANDB_API_KEY 환경 변수를 사용해 API 키를 설정하세요.
Public API를 사용할 때는 자주 <entity>/<project>/<run_id> 형식의 run 경로가 필요합니다. 앱 UI에서 해당 run 페이지를 열고 Overview 탭을 클릭하여 run 경로를 확인하세요.
완료되었거나 현재 실행 중인 run에서 데이터를 다운로드할 수 있습니다. 일반적인 사용 예로는 Jupyter 노트북에서 커스텀 분석을 하기 위해 데이터프레임을 다운로드하거나, 자동화된 환경에서 커스텀 로직에 활용하는 경우가 있습니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
가장 많이 사용되는 run 객체의 속성은 다음과 같습니다:
| Attribute | Meaning |
|---|
run.config | 트레이닝 run을 위한 하이퍼파라미터나 데이터셋 Artifact를 생성하는 run을 위한 전처리 방법 등과 같이, run의 설정 정보로 이루어진 사전입니다. 이를 run의 입력값으로 생각할 수 있습니다. |
run.history() | 모델이 트레이닝되는 동안 손실(loss)처럼 변화하는 값을 저장하기 위한 사전들의 리스트입니다. run.log() 명령은 이 객체에 값을 추가합니다. |
run.summary | run의 결과를 요약하는 정보로 이루어진 사전입니다. 정확도와 손실 같은 스칼라 값이나 대용량 파일이 될 수 있습니다. 기본적으로 run.log()는 기록된 시계열의 마지막 값을 summary에 설정합니다. summary의 내용은 직접 설정할 수도 있습니다. summary를 run의 출력값으로 생각할 수 있습니다. |
과거 run의 데이터를 수정하거나 업데이트할 수도 있습니다. 기본적으로 하나의 api 객체 인스턴스는 모든 네트워크 요청을 캐시합니다. 실행 중인 스크립트에서 실시간 정보가 필요한 경우 api.flush()를 호출하여 업데이트된 값을 가져오십시오.
다음 코드 스니펫은 run을 생성하고 일부 데이터를 로깅한 다음 해당 run의 속성에 접근하는 방법을 보여줍니다:
import wandb
import random
with wandb.init(project="public-api-example") as run:
n_epochs = 5
config = {"n_epochs": n_epochs}
run.config.update(config)
for n in range(run.config.get("n_epochs")):
run.log(
{"val": random.randint(0, 1000), "loss": (random.randint(0, 1000) / 1000.00)}
)
다음 섹션에서는 위 run 객체의 각 속성에 대한 서로 다른 출력 결과를 설명합니다
run.config
{
"_runtime": 4,
"_step": 4,
"_timestamp": 1644345412,
"_wandb": {"runtime": 3},
"loss": 0.041,
"val": 525,
}
기본 history 메서드는 메트릭을 고정된 개수의 샘플로 샘플링합니다(기본값은 500개이며 samples __ 인자로 변경할 수 있습니다). 대규모 run의 모든 데이터를 내보내고 싶다면 run.scan_history() 메서드를 사용할 수 있습니다. 자세한 내용은 API Reference를 참조하세요.
DataFrame과 CSV
MongoDB 스타일
이 예제 스크립트는 프로젝트를 찾고 이름, config, 요약 통계를 포함한 run들의 CSV를 출력합니다. 각각 <entity>와 <project>를 여러분의 W&B entity와 프로젝트 이름으로 바꾸세요.import pandas as pd
import wandb
api = wandb.Api()
entity, project = "<entity>", "<project>"
runs = api.runs(entity + "/" + project)
summary_list, config_list, name_list = [], [], []
for run in runs:
# .summary에는 정확도와 같은 메트릭에 대한
# 출력 키/값이 들어 있습니다.
# 큰 파일을 생략하기 위해 ._json_dict를 호출합니다.
summary_list.append(run.summary._json_dict)
# .config에는 하이퍼파라미터가 들어 있습니다.
# _로 시작하는 특수 값을 제거합니다.
config_list.append({k: v for k, v in run.config.items() if not k.startswith("_")})
# .name은 run의 사람이 읽기 쉬운 이름입니다.
name_list.append(run.name)
runs_df = pd.DataFrame(
{"summary": summary_list, "config": config_list, "name": name_list}
)
runs_df.to_csv("project.csv")
run.finish()
W&B API는 또한 api.runs()를 사용해서 프로젝트의 여러 run을 대상으로 쿼리할 수 있는 방법을 제공합니다. 가장 일반적인 사용 사례는 사용자 지정 분석을 위해 run 데이터를 내보내는 것입니다. 쿼리 인터페이스는 MongoDB에서 사용하는 것과 동일합니다.runs = api.runs(
"username/project",
{"$or": [{"config.experiment_name": "foo"}, {"config.experiment_name": "bar"}]},
)
print(f"Found {len(runs)} runs")
api.runs를 호출하면 반복 가능하고 리스트처럼 동작하는 Runs 객체를 반환합니다. 기본적으로 이 객체는 필요에 따라 한 번에 50개의 run을 순차적으로 로드하지만, per_page 키워드 인수를 사용해 페이지당 로드되는 개수를 변경할 수 있습니다.
api.runs는 order 키워드 인수도 받습니다. 기본 정렬 순서는 -created_at입니다. 결과를 오름차순으로 정렬하려면 +created_at을 지정하세요. config나 summary 값으로도 정렬할 수 있습니다. 예를 들어 summary.val_acc 또는 config.experiment_name과 같이 사용할 수 있습니다.
W&B 서버와 통신하는 동안 오류가 발생하면 wandb.CommError가 발생합니다. 원래 예외 객체는 exc 속성을 통해 확인할 수 있습니다.
UI에서 run을 클릭한 다음 run 페이지의 Overview 탭을 클릭하면 최신 git 커밋을 볼 수 있습니다. 최신 git 커밋 정보는 wandb-metadata.json 파일에도 있습니다. 공용 API를 사용하면 run.commit으로 git 해시를 가져올 수 있습니다.
run 실행 중에 run의 name과 ID 가져오기
wandb.init()을 호출한 이후에는 스크립트에서 다음과 같이 무작위 run ID 또는 사람이 읽기 쉬운 run name에 접근할 수 있습니다:
- 고유 run ID (8자 해시):
run.id
- 무작위 run name (사람이 읽기 쉬운 이름):
run.name
run에 유용한 식별자를 어떻게 설정할지 고민 중이라면, 다음과 같이 설정할 것을 권장합니다:
- Run ID: 생성된 해시 값을 그대로 두세요. 이는 해당 프로젝트의 모든 run 사이에서 고유해야 합니다.
- Run name: 짧고 읽기 쉽고, 가능하면 고유하게 설정하여 차트의 각 선이 무엇을 의미하는지 쉽게 구분할 수 있도록 하세요.
- Run notes: 이 공간에는 run에서 무엇을 하고 있는지에 대한 간단한 설명을 적어 두면 좋습니다.
wandb.init(notes="your notes here")로 설정할 수 있습니다.
- Run tags: run 태그에 값을 동적으로 기록하고, UI의 필터를 사용해 관심 있는 run만 남도록 테이블을 필터링하세요. 스크립트에서 태그를 설정한 뒤, UI의 Runs 테이블과 run 페이지의 overview 탭에서 태그를 수정할 수 있습니다. 자세한 사용 방법은 여기를 참조하세요.
데이터를 내보내 matplotlib 또는 seaborn에서 시각화하기
일반적인 내보내기 방식은 API examples를 참고하세요. 커스텀 플롯 또는 확장된 Runs 테이블에서 다운로드 버튼을 클릭해 브라우저에서 CSV 파일을 다운로드할 수도 있습니다.
이 예제는 "<entity>/<project>/<run_id>"에 저장된 run에서 run.log({"accuracy": acc})로 기록된 타임스탬프와 정확도를 출력합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
if run.state == "finished":
for i, row in run.history().iterrows():
print(row["_timestamp"], row["accuracy"])
MongoDB Query Language를 사용해 run을 필터링할 수 있습니다.
runs = api.runs(
"<entity>/<project>",
{"$and": [{"created_at": {"$lt": "YYYY-MM-DDT##", "$gt": "YYYY-MM-DDT##"}}]},
)
run에서 특정 메트릭을 가져오려면 keys 인자를 사용한다. run.history()를 사용할 때 기본 샘플 개수는 500개이다. 특정 메트릭이 포함되지 않은 로그된 스텝은 출력 데이터프레임에서 NaN으로 표시된다. keys 인자는 지정한 메트릭 키를 포함하는 스텝을 API가 더 자주 샘플링하도록 한다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
if run.state == "finished":
for i, row in run.history(keys=["accuracy"]).iterrows():
print(row["_timestamp"], row["accuracy"])
run1과 run2 사이에서 차이가 있는 config 파라미터를 출력합니다.
import pandas as pd
import wandb
api = wandb.Api()
# <entity>, <project>, <run_id>를 실제 값으로 바꾸세요
run1 = api.run("<entity>/<project>/<run_id>")
run2 = api.run("<entity>/<project>/<run_id>")
df = pd.DataFrame([run1.config, run2.config]).transpose()
df.columns = [run1.name, run2.name]
print(df[df[run1.name] != df[run2.name]])
출력 결과:
c_10_sgd_0.025_0.01_long_switch base_adam_4_conv_2fc
batch_size 32 16
n_conv_layers 5 4
optimizer rmsprop adam
이 예제에서는 이전 run의 정확도를 0.9로 설정합니다. 또한 이전 run의 정확도 히스토그램을 numpy_array의 히스토그램으로 변경합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
run.summary["accuracy"] = 0.9
run.summary["accuracy_histogram"] = wandb.Histogram(numpy_array)
run.summary.update()
이 예제는 테이블에서 summary 열의 이름을 변경하는 방법을 보여줍니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
run.summary["new_name"] = run.summary["old_name"]
del run.summary["old_name"]
run.summary.update()
열 이름 바꾸기는 테이블에만 적용됩니다. 차트는 여전히 메트릭의 원래 이름을 사용합니다.
다음 예제는 설정 값 중 하나를 업데이트합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
run.config["key"] = updated_value
run.update()
시스템 리소스 사용량을 CSV 파일로 내보내기
아래 코드 스니펫은 시스템 리소스 사용량을 확인한 후 CSV 파일로 저장합니다.
import wandb
with wandb.Api().run("<entity>/<project>/<run_id>") as run:
system_metrics = run.history(stream="events")
system_metrics.to_csv("sys_metrics.csv")
히스토리에서 데이터를 가져오면 기본적으로 500개 포인트로 샘플링됩니다. run.scan_history()를 사용해 기록된 모든 데이터 포인트를 가져올 수 있습니다. 아래는 히스토리에 기록된 모든 loss 데이터 포인트를 다운로드하는 예시입니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
history = run.scan_history()
losses = [row["loss"] for row in history]
history에서 페이지 단위로 데이터 가져오기
백엔드에서 메트릭을 가져오는 속도가 느리거나 API 요청이 타임아웃되는 경우, scan_history에서 페이지 크기를 줄여 개별 요청이 타임아웃되지 않도록 할 수 있습니다. 기본 페이지 크기는 500이므로, 어떤 값이 가장 잘 작동하는지 확인하기 위해 서로 다른 크기를 시도해 볼 수 있습니다:
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
run.scan_history(keys=sorted(cols), page_size=100)
프로젝트의 모든 run에서 메트릭을 CSV 파일로 내보내기
이 스크립트는 프로젝트의 run들을 가져와 각 run의 이름, 설정(config), 요약 통계 정보가 포함된 데이터프레임과 CSV 파일을 생성합니다. <entity>와 <project>를 각각 W&B 엔티티와 프로젝트 이름으로 바꾸세요.
import pandas as pd
import wandb
api = wandb.Api()
entity, project = "<entity>", "<project>"
runs = api.runs(entity + "/" + project)
summary_list, config_list, name_list = [], [], []
for run in runs:
# .summary는 정확도 등의 메트릭에 대한
# 출력 키/값을 포함합니다.
# 대용량 파일을 제외하기 위해 ._json_dict를 호출합니다.
summary_list.append(run.summary._json_dict)
# .config는 하이퍼파라미터를 포함합니다.
# _로 시작하는 특수 값은 제거합니다.
config_list.append({k: v for k, v in run.config.items() if not k.startswith("_")})
# .name은 run의 사람이 읽을 수 있는 이름입니다.
name_list.append(run.name)
runs_df = pd.DataFrame(
{"summary": summary_list, "config": config_list, "name": name_list}
)
runs_df.to_csv("project.csv")
이 코드 스니펫은 해당 run이 생성된 시점을 가져옵니다.
import wandb
api = wandb.Api()
run = api.run("entity/project/run_id")
start_time = run.created_at
아래 코드 스니펫은 선택한 파일을 완료된 run에 업로드합니다.
import wandb
api = wandb.Api()
run = api.run("entity/project/run_id")
run.upload_file("file_name.extension")
cifar 프로젝트에서 ID가 uxte44z7인 run에 연결된 “model-best.h5” 파일을 찾아 로컬에 저장합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
run.file("model-best.h5").download()
해당 run과 연관된 모든 파일을 찾아 로컬에 저장합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
for file in run.files():
file.download()
이 스니펫은 특정 스윕에 속한 모든 run을 다운로드합니다.
import wandb
api = wandb.Api()
sweep = api.sweep("<entity>/<project>/<sweep_id>")
sweep_runs = sweep.runs
다음 스니펫은 주어진 스윕에서 최적의 run을 가져옵니다.
import wandb
api = wandb.Api()
sweep = api.sweep("<entity>/<project>/<sweep_id>")
best_run = sweep.best_run()
best_run은 스윕 설정의 metric 파라미터로 정의된, 가장 좋은 메트릭 값을 가진 run입니다.
이 스니펫은 모델 파일을 model.h5로 저장한 run이 포함된 스윕에서, 검증 정확도가 가장 높은 모델 파일을 다운로드합니다.
import wandb
api = wandb.Api()
sweep = api.sweep("<entity>/<project>/<sweep_id>")
runs = sorted(sweep.runs, key=lambda run: run.summary.get("val_acc", 0), reverse=True)
val_acc = runs[0].summary.get("val_acc", 0)
print(f"Best run {runs[0].name} with {val_acc}% val accuracy")
runs[0].file("model.h5").download(replace=True)
print("Best model saved to model-best.h5")
특정 확장자를 가진 파일을 run에서 모두 삭제하기
이 스니펫은 지정한 확장자를 가진 파일을 해당 run에서 삭제합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
extension = ".png"
files = run.files()
for file in files:
if file.name.endswith(extension):
file.delete()
이 스니펫은 run에 대한 모든 시스템 리소스 사용량 메트릭이 담긴 데이터프레임을 생성한 뒤, 이를 CSV 파일로 저장합니다.
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
system_metrics = run.history(stream="events")
system_metrics.to_csv("sys_metrics.csv")
사전을 전달하여 요약 메트릭을 업데이트할 수 있습니다.
summary.update({"key": val})
각 run은 run 개요 페이지에 자신을 실행한 명령어를 저장합니다. 이 명령어를 API에서 가져오려면 다음을 실행하세요:
import wandb
api = wandb.Api()
run = api.run("<entity>/<project>/<run_id>")
meta = json.load(run.file("wandb-metadata.json").download())
program = ["python"] + [meta["program"]] + meta["args"]