1. ZenML란?
ZenML은 MLOps를 위한 오픈소스 프레임워크로, 재현 가능(Reproducible), 유지보수 가능(Maintainable), 확장 가능(Extensible)한 ML 파이프라인을 구축하기 위한 도구와 추상화를 제공합니다. 코드 중심의 접근 방식을 취하며, 인프라 의존성을 분리하여 ML 워크플로우를 단순화합니다.
🔄 재현성 보장
모든 파이프라인 실행은 자동으로 버전 관리되고, 데이터, 코드, 환경이 캡처되어 동일한 결과를 보장합니다.
🧩 스택 추상화
로컬, 클라우드, 온프레미스 등 다양한 인프라를 추상화하여 코드 변경 없이 MLOps 스택을 교체할 수 있습니다.
📦 통합 생태계
MLflow, Kubeflow, Airflow, Evidently, Seldon Core 등 주요 MLOps 도구들과의 네이티브 통합을 제공합니다.
2. 왜 써야 하는가?
기존의 스크립트 기반 또는 일반 워크플로우 엔진과의 비교를 통해 ZenML의 가치를 확인할 수 있습니다.
| 도구/접근법 | 장점 | 단점 | ZenML의 해결책 |
|---|---|---|---|
| 스크립트 (Jupyter, .py) | 빠른 실험, 유연함 | 재현성 부족, 운영화 어려움, 의존성 관리 복잡 | 자동 버전 관리, 파이프라인 추상화, 컨테이너화 |
| Airflow/Luigi | 워크플로우 오케스트레이션, 스케줄링 | ML 특화 기능 부족, 아티팩트 관리 미비 | ML 아티팩트 저장소, 메타데이터 추적, 실험 관리 |
| MLflow (Projects) | 실험 추적, 모델 레지스트리 | 프로덕션 오케스트레이션, 인프라 추상화 부족 | 프로덕션급 오케스트레이터 통합, 스택 추상화 |
| Kubeflow Pipelines | 쿠버네티스 네이티브, 확장성 | 학습 곡선 가파름, 로컬 개발 복잡 | 로컬 우선 개발, 단순화된 API, 멀티 클라우드 지원 |
핵심 가치: ZenML은 "MLOps를 위한 표준 인터페이스"를 제공합니다. 인프라를 교체해도 파이프라인 코드는 그대로 유지되며, 팀원들이 공통의 언어와 패턴으로 협업할 수 있게 합니다.
3. 핵심 개념
ZenML의 아키텍처는 크게 코어 레이어와 인테그레이션 레이어로 나뉩니다.
+-----------------------------------------------------------------------+
| ZenML Server (Metadata Store) |
| (실행 기록, 아티팩트 메타데이터, 스택 구성) |
+--------------------------^-------------------------------------------+
|
+-----------------------------------------------------------------------+
| Core Layer (Python SDK) |
| +-------------+ +------------+ +------------+ +---------------+ |
| | Pipelines | | Steps | | Artifacts | | Materializers| |
| +-------------+ +------------+ +------------+ +---------------+ |
+-----------------------------------------------------------------------+
|
+-----------------------------------------------------------------------+
| Stack & Integrations Layer |
| +-----------+ +-----------+ +-----------+ +----------------------+ |
| |Artifact | |Metadata | |Orchestrator| |Container Registry | |
| |Store | |Store | | | | | |
| |(S3, GCS, | |(MySQL, | |(Local, | |(ECR, GCR, DockerHub) | |
| | Azure, | | SQLite) | | Kubeflow,| +----------------------+ |
| | MinIO) | +-----------+ | Airflow, | +----------------------+ |
| +-----------+ +-----------+ | VertexAI)| | Experiment Tracker | |
| +-----------+ |Secrets | +-----------+ |(MLflow, WandB, Neptune)| |
| |Model | |Manager | +-----------+ +----------------------+ |
| |Deployer | |(AWS, GCP,| |Step | +----------------------+ |
| |(Seldon, | | Azure, | |Operators | | Feature Store | |
| | KServe) | | Vault) | |(CUDA, | |(Feast, Tecton) | |
| +-----------+ +-----------+ | Spark) | +----------------------+ |
+-----------------------------------------------------------------------+
주요 컴포넌트
- 파이프라인(Pipeline): 여러 스텝을 조합한 워크플로우 정의.
- 스텝(Step): 파이프라인의 개별 작업 단위 (예: 데이터 로드, 전처리, 학습).
- 아티팩트(Artifact): 스텝에서 생성된 데이터 또는 모델 (버전 관리됨).
- 스택(Stack): 실행 인프라 조합 (Artifact Store, Orchestrator, Metadata Store 등).
- 메타데이터 저장소(Metadata Store): 파이프라인 실행 기록, 아티팩트 정보 저장.
4. 퀵스타트
단계 1: 설치
pip install "zenml[server]" # 기본 설치 (로컬 서버 포함)
# 또는 통합 기능과 함께 설치
pip install "zenml[server,mlflow,sklearn,kubernetes]"
단계 2: ZenML 초기화 및 로컬 서버 실행
# ZenML 리포지토리 및 데이터베이스 초기화
zenml init
# 로컬 서버 실행 (웹 대시보드 사용 가능)
zenml up
주의:
zenml up은 로컬에서 메타데이터 저장소와 대시보드를 실행합니다. 프로덕션 환경에서는 외부 데이터베이스(MySQL, PostgreSQL)를 사용해야 합니다.
단계 3: 첫 번째 파이프라인 작성 (pipeline.py)
from zenml import pipeline, step
from zenml.client import Client
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 1. 스텝 정의
@step
def load_data() -> pd.DataFrame:
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target
return df
@step
def train_model(df: pd.DataFrame) -> RandomForestClassifier:
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = RandomForestClassifier(n_estimators=10)
model.fit(X_train, y_train)
# 아티팩트(모델)가 자동으로 저장 및 버전 관리됨
return model
# 2. 파이프라인 정의
@pipeline
def first_zenml_pipeline(data_loader, trainer):
df = data_loader()
model = trainer(df)
# 3. 파이프라인 실행
if __name__ == "__main__":
# 로컬 기본 스택으로 실행
pipeline_instance = first_zenml_pipeline(
data_loader=load_data(),
trainer=train_model()
)
pipeline_instance.run()
print("✅ 파이프라인 실행 완료! 대시보드에서 결과를 확인하세요.")
print(f" 대시보드: {Client().active_stack_model.analytics_dashboard_url}")
단계 4: 실행 및 확인
python pipeline.py
# CLI로 실행 기록 확인
zenml pipeline list
zenml pipeline runs list
# 웹 대시보드 열기 (zenml up 실행 중일 때)
zenml show
5. 핵심 설정 레퍼런스
| 컴포넌트 | 타입 (예시) | 설명 | CLI 설정 예시 |
|---|---|---|---|
| Artifact Store | local, s3, gcs, azure, minio | 파이프라인 아티팩트(데이터, 모델) 저장소 | zenml artifact-store register my_s3 --type=s3 --path=s3://my-bucket |
| Metadata Store | sqlite, mysql, postgresql | 실행 메타데이터 저장소 (필수) | zenml metadata-store register local_sqlite --type=sqlite |
| Orchestrator | local, kubeflow, vertex, airflow | 파이프라인 실행을 관리하는 오케스트레이터 | zenml orchestrator register local_k8s --type=kubeflow --kubernetes_context=my-cluster |
| Experiment Tracker | mlflow, wandb, neptune | 실험 메트릭, 파라미터, 모델 추적 | zenml experiment-tracker register mlflow_tracker --type=mlflow --tracking_uri=http://localhost:5000 |
| Model Deployer | seldon, kserve, mlflow | 학습된 모델 서빙 | zenml model-deployer register seldon_prod --type=seldon --kubernetes_context=prod-cluster |
| Secrets Manager | aws, azure, gcp, vault | API 키, 패스워드 등 민감 정보 관리 | zenml secrets-manager register aws_secrets --type=aws --region_name=us-east-1 |
# 스택 생성 및 활성화 예시
zenml stack register my_prod_stack \
-a my_s3 \
-o local_k8s \
-m local_sqlite \
-e mlflow_tracker
zenml stack set my_prod_stack
6. 실무 팁 & 트러블슈팅
🔧 실무 팁
- 로컬 우선 개발: 초기에는
local스택으로 빠르게 개발한 후, 프로덕션 스택(예: kubeflow, vertex)으로 마이그레이션하세요. - Materializer 커스터마이징: 사용자 정의 객체(예: PyTorch 모델, 특수 데이터프레임)를 저장하려면
BaseMaterializer를 상속받아 구현하세요. - Secret 활용: API 키, DB 비밀번호는 ZenML Secret으로 관리하고, 스텝에서
@step(enable_cache=False, secret="my_secret")처럼 주입받으세요. - 캐싱 전략: 동일 입력에 대한 스텝 재실행을 방지하려면 캐싱을 활용하되, 외부 데이터 소스 변경 시
@step(enable_cache=False)로 캐시를 비활성화하세요.
🚨 자주 겪는 문제 & 해결책
| 문제 | 원인 | 해결책 |
|---|---|---|
ModuleNotFoundError (원격 실행 시) |
원격 환경에 Python 패키지가 설치되지 않음 | zenml orchestrator register ... --requirements_file=requirements.txt로 요구사항 파일 지정 또는 Docker 이미지에 패키지 포함. |
| 파이프라인 실행이 너무 오래 걸림 (캐시 무효화 안됨) | 스텝 입력이 변경되었지만 ZenML이 감지하지 못함 (예: 외부 파일 읽기) | 외부 의존성을 @step의 입력으로 명시하거나, enable_cache=False 설정. 또는 zenml pipeline runs delete [RUN_ID]로 캐시 삭제. |
| 대용량 아티팩트(모델) 업로드 실패 | 로컬 Artifact Store 기본 경로 용량 부족 또는 네트워크 타임아웃 | Artifact Store를 S3/GCS와 같은 클라우드 저장소로 변경. 또는 Materializer에서 압축 방식을 적용. |
| ZenML Server 연결 실패 (원격 협업 시) | 기본 로컬 서버는 팀원이 접근 불가 | 공유 가능한 Metadata Store(MySQL, PostgreSQL)를 설정하고, zenml server deploy로 서버를 배포하거나, 관리형 ZenML Cloud 사용. |
| Kubeflow Orchestrator에서 Docker 이미지 빌드 실패 | Docker 데몬 없음 또는 컨텍스트 오류 | 로컬에 Docker 설치 및 실행, 또는 --build_context_source 옵션으로 미리 빌드된 이미지 사용. |
7. 참고 자료
- 📘 공식 문서 (한국어 일부 제공) - 개념, API 레퍼런스, 튜토리얼
- 🐙 GitHub 저장소 - 소스 코드, 이슈, 컨트리뷰션 가이드
- 🎥 워크샵 & 튜토리얼 영상 - 실습 중심의 학습 자료
- ✍️ 공식 블로그 - 사례 연구, 신기능 소개
- 💬 Slack 커뮤니티 - 실시간 질문 및 토론
- 🧪 예제 프로젝트 모음 - LLMOps, Computer Vision 등 다양한 템플릿