Generative AI/Python

Tooling and Installation

youngerjesus 2025. 2. 5. 05:45

파이썬 프로젝트를 구현하고 배포하기 위해 필요한 도구와 설치 과정을 간단히 소개하는 내용을 다룸.

 

주요 내용 요약:

  • Python 환경 준비
    • 여러 버전의 Python을 관리하고, 가상 환경을 생성하며, 필요한 라이브러리를 설치하는 방법을 다룹니다.
  • MLOps, LLMOps 도구 소개:
    • 모델 레지스트리, LLM 평가 및 프롬프트 모니터링 등 다양한 MLOps/LLMOps 도구들을 빠르게 훑어봅니다
    • ZenML 같은 오케스트레이션 도구를 사용해 여러 ML 파이프라인을 어떻게 한 프로젝트 안에서 관리할 수 있는지도 다룹니다
  • 데이터베이스 선택:
    • NoSQL과 벡터 저장을 위해 사용할 데이터베이스를 소개하고, 로컬에서 Docker를 사용해 실행하는 방법도 간단히 보여줍니다
  • AWS 설정:
    • AWS CLI를 설치하고, 액세스 키를 설정하여 클라우드 리소스를 프로그래밍적으로 관리하는 방법을 안내합니다
    • Amazon SageMaker에서 오픈 소스 LLM을 학습·배포하는 이유와 절차를 살펴봅니다

 

Python 버전 관리와 의존성 관리

Python 3.11.8 설치:

  • pyenv를 이용한 설치 과정
pyenv install 3.11.8

 

설치된 파이썬 버전 확인:

pyenv versions

 

글로벌 기본 버전 설정:

pyenv global 3.11.8

 

로컬 환경에서만 특정 파이썬 버전 사용하기:

# 프로젝트 폴더 내에서만 특정 파이썬 버전을 사용하려면, 먼저 저장소를 클론(다운로드)하고 폴더로 이동합니다
git clone https://github.com/PacktPublishing/LLM-Engineers-Handbook.git
cd LLM-Engineers-Handbook

# 리포지토리 안에 .python-version 파일이 포함되어 있기 때문에, pyenv는 해당 폴더에 들어오는 순간 그 버전을 사용합니다
# 이를 확인하려면 폴더 안에서 다음 명령어를 실행합니다
python --version

# python-version 파일 생성 방법:
pyenv local 3.11.8

 

팀 프로젝트 설정법:

  • python 버전을 고정해야 하므로 프로젝트 디렉터리 안에 .python-version 파일을 두어야 함.
  • 이 파일은 기본적으로 pyenv local 3.11.8 명령을 실행하면 만들어짐.
  • python-version 파일을 버전 관리(Git 등)에 포함해두면, 다른 팀원들도 같은 폴더로 들어왔을 때 똑같은 Python 버전을 사용하게 됨.

 

만약 파이썬 버전이 바뀌지 않는다면 쉘에 설정을 추가해야함.

  • 추가한 설정: 
    • export PYENV_ROOT="$HOME/.pyenv"
      • pyenv 가 설치된 디렉토리를 지정
      • 보통 홈 디렉토리에 .pyenv 풀더에 설치됨. 
    • command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
      • pyenv 명령어가 없으면 PATH 에 추가 
      • $PYENV_ROOT/bin:$PATH 을 시스템 PATH 의 앞부분에 추가해서 시스템 파이썬 보다 우선순위를 높힘
    • eval "$(pyenv init -)"
      • pyenv 의 shim 을 활성화
      • shim 은 파이썬 명령어를 가로채서 지정된 버전으로 연결해주는 역할
      • 이거 때문에 pyenv 가 관리하는 파이썬 버전이 사용됨. 
# 1. 사용중인 쉘 확인 
echo $SHELL 

# 2. shell 에 따른 설정 추가
# 만약 bash를 사용중이라면 (~/.bashrc 또는 ~/.bash_profile)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

# 만약 zsh를 사용중이라면 (~/.zshrc):
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc

# 3. shell 재시작:
exec $SHELL

# 4. 확인 
# 이제 python과 python3 모두 동일한 버전을 보여야 합니다
python --version    # Should show: Python 3.11.8
python3 --version  # Should show: Python 3.11.8
which python      # Should show: ~/.pyenv/versions/3.11.8/bin/python
which python3     # Should show: ~/.pyenv/versions/3.11.8/bin/python3

 

 

Poetry: dependency and virtual environment management

Poetry를 사용해 Python 프로젝트의 의존성(dependency)와 가상 환경을 관리하는 방법을 다룸.

 

Poetry란 무엇인가?

  • 의존성(Dependency) 관리:
    • Poetry를 사용하면 프로젝트가 필요로 하는 외부 라이브러리(예: requests, numpy)의 버전을 지정하고, 해당 버전들을 자동으로 설치·업데이트할 수 있습니다.
    • pyproject.toml 파일에 의존성 범위(예: requests = "^2.25.1")를 지정하고, Poetry는 이를 기반으로 실제 설치할 구체적인 버전을 결정합니다.
    • 결정된 구체 버전들은 poetry.lock 파일에 기록되어, 팀원들이나 배포 환경에서도 동일한 버전을 재현할 수 있게 만듭니다.
  • 가상 환경(Virtual Environment) 관리:
    • Poetry는 프로젝트마다 별도의 가상 환경을 자동으로 생성·관리합니다.
    • 가상 환경을 사용하면 다른 프로젝트나 글로벌 Python 환경에 설치된 라이브러리들과 겹치거나 충돌이 일어나는 것을 방지할 수 있습니다.
    • 예를 들어, 프로젝트 A가 numpy==1.19.5를 필요로 하고, 프로젝트 B가 numpy==1.26.0을 필요로 한다면, 프로젝트마다 별도의 가상 환경을 둠으로써 둘이 충돌하지 않게 할 수 있습니다
  • vs venv:
    • 가상 환경을 만들어 주는 역할은 하지만, 의존성 버전을 락(lock)하는 기능은 Poetry보다 단순합니다.
    • 의존성 관리는 보통 requirements.txt 형태를 사용하는 형태

 

Poetry 설치 및 사용법:

  • 공식 문서에 따라 Poetry를 설치하면 됨.
  • 여기서는 Poetry 1.8.3 버전을 사용함.

 

프로젝트 의존성 설치:

  • 저장소를 클론 받은 뒤, 프로젝트 폴더에 들어가 다음 명령어를 실행합니다:
    • pyproject.toml과 poetry.lock에 기록된 필요한 라이브러리들을 자동으로 설치합니다.
    • 명령어 끝에 --without aws 옵션을 사용하면 선택적으로 AWS 관련 의존성은 제외하고 설치할 수 있습니다.
    • pyproject.toml에는 버전 범위가 적혀 있지만, 실제 설치되는 버전들은 poetry.lock 파일에 정확한 버전(sub-dependencies 포함)이 고정됩니다.
    • 이 덕분에 같은 프로젝트를 다른 PC나 서버에서 설치했을 때, 동일한 라이브러리 버전을 항상 재현할 수 있어 “내 로컬에서는 잘 되는데…” 같은 문제를 줄여줍니다.
poetry install --without aws

 

 

가상 환경 활성화:

  • Poetry로 설치가 끝난 뒤, 가상 환경을 활성화(activate) 하려면:
  • poetry shell 은 이미 존재하는 가상 환경을 활성화 해주는거임. poetry init -> poetry install 을 하면 가상 환경이 만들어진다. 
# 이 명령어를 사용해 새 쉘을 열거나,
poetry shell

# 형태로 명령어마다 prefix를 달아서 가상 환경을 사용합니다.
poetry run <your_command>

 

 

가상 환경 관련 명령어들: 

# 가상환경 정보 확인
poetry env info

# 가상환경 목록 보기
poetry env list

# 가상환경 삭제
poetry env remove python

# 가상환경 활성화
poetry shell

# 가상환경 경로 확인
poetry env info --path

# 모든 의존성 설치 (개발 환경)
poetry install

# 운영 의존성만 설치 (프로덕션 환경)
poetry install --no-dev

 

 

Appendix) Visual Studio Code 에서 Python Interpreter 를 가상 환경으로 세팅:

  • (mac 기준) Cmd + Shift + P -> Python: Select Interpreter 검색 -> Poetry 로 만든 가상 환경으로 등록

 

 

Poe the Poet

Poe the Poet라는 도구를 사용해 Python 프로젝트의 CLI 명령어(태스크)를 쉽게 정의하고 실행하는 방법을 소개함.

 

Poe the Poet이란 무엇인가?

  • Poe the Poet은 Poetry 위에 플러그인 형태로 동작하는 태스크 실행 도구(Task Execution Tool)입니다.
  • 보통 프로젝트에서 필요한 스크립트나 명령어들은 Makefile, Invoke, 혹은 Shell Script로 작성할 수 있지만, Poe the Poet을 사용하면 기존 pyproject.toml 파일 안에 바로 명령어를 정의하고 사용할 수 있게 됩니다.
  • 이 방식은 Poetry와 자연스럽게 통합되어 있어서, 추가적인 스크립트 파일을 만들 필요가 없고, 프로젝트 구조가 간단해집니다.

 

Poe the Poet 사용법:

  • pyproject.toml의 [tool.poe.tasks] 섹션 아래에 원하는 태스크를 key-value 형태로 정의할 수 있습니다:
  • 예시에서 test, format, start라는 태스크를 정의했습니다:
    • test = “pytest”
      • pytest라는 명령어를 실행합니다
      • Python 생태계에서 가장 널리 쓰이는 테스트 프레임워크 중 하나인 Pytest를 이용해 프로젝트 내의 테스트 코드를 자동으로 찾아 실행해줍니다.
      • 즉, 프로젝트의 테스트 스위트를 돌려서 “코드가 올바르게 동작하는지” 검증하는 역할을 합니다.
    • format = “black .”
      • Black이라는 코드 포매터(tool)를 실행하여, 현재 디렉터리(.) 내의 모든 파이썬 파일을 일관된 스타일로 자동 정렬(포맷팅)해줍니다.
      • 사람이 직접 코드 스타일을 맞추는 수고 없이, Black이 정해둔 규칙대로 한 번에 포맷팅해 주기 때문에, 팀 프로젝트에서 코드 스타일을 통일하기에 유용합니다.
[tool.poe.tasks]
test = "pytest"
format = "black ."
start = "python main.py"

 

명령어 실행:

  • Poetry와 함께 사용할 때는 다음과 같이 실행할 수 있습니다:
  • 이렇게 alias 형태로 태스크를 실행할 수 있어, README나 Shell Script를 뒤져볼 필요 없이 명령어를 직관적으로 관리하고 공유할 수 있습니다.
poetry poe test
poetry poe format
poetry poe start

 

설치 방법:

  • Poe the Poet을 플러그인으로 추가하려면:
  • 이후 poetry poe <task> 명령어를 통해 정의된 태스크를 실행할 수 있게 됩니다.
poetry self add 'poethepoet[poetry_plugin]'

 

 

MLOps and LLMOps tooling

MLOps와 LLMOps 분야에서 어떤 도구들이 사용되고, 어떤 역할을 하는지를 간단히 소개하는 내용을 다룸.

 

여기서는 프로젝트를 구축하면서 다양한 MLOps/LLMOps 툴을 연계해서 사용할 때 구체적인 설정 보다 "어떤 툴을 왜 쓰는가?" 에 집중해서 설명.

 

MLOps/LLMOps 도구들의 역할:

  • MLOps: 머신러닝 모델을 개발, 배포, 모니터링, 버전 관리하는 전체적인 프로세스와 문화.
  • LLMOps: 특히 대규모 언어 모델(LLM)을 대상으로 하는 MLOps 개념. 모델 및 데이터 관리, 파인튜닝, 추론 모니터링 등을 포함.
  • 예: 모델 레지스트리 (모델 버전을 관리하는 도구), 오케스트레이터 (파이프라인 실행 관리), 데이터베이스, etc.

 

로컬 환경에서의 빠른 실행:

  • 도커(Docker) 컨테이너를 이용하면, MLOps/LLMOps 인프라를 로컬에서 쉽게 구성할 수 있습니다.
  • 다음 세 가지 단계를 거치면 ZenML, MongoDB, Qdrant 등의 주요 컴포넌트를 로컬에서 돌려볼 수 있습니다:
    • Docker 27.1.1 이상 설치
    • .env 파일에 필요한 자격 정보(토큰 등) 기입
    • poetry poe local-infrastructure-up 명령어 실행 (책 기준으로 명령어를 만든거임)

 

클라우드 배포도 지원:

  • 책 전반에서 로컬 환경뿐만 아니라, 이후에 각 구성 요소를 클라우드에 배포하는 방법도 다룸.
  • 예: ZenML, 데이터베이스, 모델 레지스트리 등
  • 실제 서비스를 운영하려면, 로컬에서 확인한 설정을 기반으로 클라우드 인프라에서 확장·배포할 수 있습니다.
  • Hugging Face: model registry

 

여기서는 모델 레지스트리(Model Registry)가 무엇인지, MLOps 에서 왜 중요한지 그리고 프로젝트에서 어떤 걸 사용할 수 있는지 소개

모델 레지스트리(Model Registry)란?

  • 머신러닝 모델을 버전, 메타데이터, 성능 지표와 함께 중앙에서 관리하는 저장소.
  • 역할:
    • 모델이 언제, 어떻게, 누가, 어떤 데이터로 학습되었는지 추적 가능
    • 다양한 팀원과 모델을 공유 및 협업
    • CI/CD 파이프라인과 연동되어 지속적 배포(Continuous Deployment)가 용이함

 

Hugging Face를 선택한 이유:

  • Hugging Face는 MLOps 영역에서 모델을 관리하는 대표적인 오픈소스 친화적 플랫폼.
    • 모델을 버전 관리하고, 필요한 메타데이터와 함께 공개적으로 공유할 수 있음.
    • LLM 생태계와 강력하게 통합되어, 미리 존재하는 다양한 프레임워크(예: Unsloth, SageMaker 등)와 쉽게 연동할 수 있음.
  • 여기서는 파인튜닝된 모델들을 전 세계 독자들과 공유하기 용이함.

 

다른 모델 레지스트리 대안:

  • ZenML, Comet, SageMaker 등 많은 도구에도 자체적인 모델 레지스트리가 내장
  • 다만 이 책에서는 “오픈소스 생태계와의 호환성과 공유성”을 우선하여 Hugging Face를 채택.
  • 실제 프로젝트 상황에서는 “프로젝트와 얼마나 잘 통합되는지”를 기준으로 모델 레지스트리를 선택하면 됨.

 

ZenML

ZenML이라는 도구가 머신러닝(ML)부터 운영(Ops)까지 이어지는 과정을 어떻게 간소화하고 자동화해주는지 소개함.

 

ZenML이란 무엇인가?

  • 브리지 역할: ML 모델 연구 단계(주피터 노트북 등)에서 실제 프로덕션 환경으로 넘어갈 때 발생하는 재현성, 버전 관리, 파이프라인 구성, 메타데이터 추적 등의 문제를 해결해 주는 도구
  • 주요 기능:
    • ML 파이프라인 오케스트레이션: 파이프라인 전체를 정의하고, 단계별 실행을 관리합니다.
    • 아티팩트(Artifacts)와 메타데이터 저장/버전 관리: 학습 결과물, 모델 파일, 데이터 버전을 체계적으로 추적합니다.
      • 아티팩트:
        • 머신러닝 파이프라인 실행 과정에서 생성되거나 활용되는 구체적인 결과물 또는 산출물을 말합니다.
        • 예:
          • 모델 파일(예: 학습이 완료된 .pth 파일, .pb 파일 등)
          • 전처리된 데이터셋(예: TFRecord, CSV 등)
          • 평가 결과물(예: 혼동행렬, 로그 파일, 그래프, 시각화 이미지)
          • 임베딩 벡터, 파인튜닝된 파라미터 파일 등
      • 메타데이터:
        • 파이프라인 실행(런)이나 아티팩트에 대한 추가 정보를 말합니다. 즉, “데이터에 관한 데이터”라고 할 수 있습니다.
        • 예:
          • 파이프라인 정보:
            • 언제 실행되었는가
            • 누가 실행했는가
            • 어떤 환경에서 실행되었는가
            • 어떤 하이퍼파라미터로 실행되었는가
          • 아티팩트 관련 정보:
            • 어떤 단계에서 생성되어쓴ㄴ가
            • 어떤 입력이 들어왔는가
    • 인프라 추상화: 다양한 클라우드 서비스와 로컬 환경을 통합해 한 곳에서 관리하도록 돕습니다.
  • ZenML 자체가 컴퓨팅 리소스를 제공하거나 통제하는 것이 아니라, 원하는 인프라(오케스트레이터, 스토리지, 컨테이너 레지스트리 등)와의 연동을 담당함.

 

스택(Stack) 개념:

  • ZenML에서 사용하는 핵심 개념으로, ML 파이프라인을 실행할 인프라(오케스트레이터, 스토리지, 컨테이너 레지스트리 등)를 묶은 구성을 의미합니다.
  • 예를 들어 AWS 스택을 구성한다고 하면, 다음과 같은 서비스들을 하나의 스택으로 묶을 수 있습니다:
    • 오케스트레이터/컴퓨팅: AWS SageMaker
    • 원격 스토리지: AWS S3
    • 컨테이너 레지스트리: AWS ECR
  • ZenML이 스택을 통해 각 인프라 요소를 추상화하여 코드 레벨에서 특정 클라우드 구현에 종속적이지 않게 해줍니다.
  • 즉, Python 코드에 S3나 ECR 관련 구체적인 설정을 직접 쓰지 않아도 되므로, GCP 또는 Azure와 같은 다른 클라우드로 쉽게 전환할 수 있습니다.

 

로컬 ZenML 서버:

  • 로컬에서 ZenML을 실행할 수 있도록, Poetry 설치 시 ZenML 디버깅 서버도 함께 설치됩니다.
  • 명령어 하나로 로컬 웹 UI를 띄워서 파이프라인 실행 상황 등을 확인할 수 있습니다.

 

vs Kubeflow:

  • Kubeflow 역시 머신러닝 파이프라인을 정의하고, 메타데이터·아티팩트 등을 추적하며, 인프라를 어느 정도 추상화해줄 수 있는 대표적인 MLOps 플랫폼 중 하나임.
  • 다만 Kubeflow 는 Kubernetes를 중심으로 설계된 MLOps 플랫폼입니다.
  • 파이프라인, 모델 서빙, 노트북 서버, HP Tuning 등 머신러닝 관련 기능을 통합적으로 제공하지만, 쿠버네티스 환경이 전제
  • ZenML 은 대규모 프로젝트에는 적합하지 않은가? 그렇지 않다.
    • 오케스트레이터들과의 연동을 ZenML 은 담당하기 때문에 받쳐주는 백엔드 오케스트레이터만 든든하다면 문제 없음.
    • SageMaker 도 대규모 학습 지원함.

 

Orchestrator

머신러닝 파이프라인을 자동화하고 관리(오케스트레이션)하는 시스템인 오케스트레이터(Orchestrator)가 무엇인지, 그리고 어떻게 ZenML을 이용해 파이프라인과 단계를 정의하고 실행할 수 있는지 구체적으로 설명합니다

 

오케스트레이터(Orchestrator)란?

  • 머신러닝 파이프라인(데이터 수집, 전처리, 모델 학습, 배포 등)을 자동으로 실행·관리하고, 의존 관계를 처리해주는 시스템입니다.
  • 제공해야 하는 기능:
    • 자동화: 파이프라인 각 단계를 순서에 맞게 자동 실행
    • 확장성: 큰 규모의 ML 작업을 스케줄링하고 리소스를 효율적으로 사용
    • 신뢰성: 실패 처리를 자동화하며, 재실행(retry) 로직 등을 통해 운영환경에서 안정적으로 동작
    • 추적 및 모니터링: 전체 파이프라인의 실행 이력을 시각화하고, 로그와 결과물을 효과적으로 관리

 

ZenML에서의 파이프라인과 스텝:

  • @pipeline 데코레이터
    • ZenML에서 파이프라인은 여러 스텝(step)을 묶어놓은 고수준 구조입니다.
  • digital_data_etl 파이프라인은 2개의 스텝(get_or_create_user, crawl_links)을 순서대로 실행합니다.
from zenml import pipeline
from steps.etl import crawl_links, get_or_create_user

@pipeline
def digital_data_etl(user_full_name: str, links: list[str]) -> None:
    user = get_or_create_user(user_full_name)
    crawl_links(user=user, links=links)

 

@step 데코레이터:

  • 파이썬 함수 하나가 ZenML에서 하나의 단계(스텝)가 됩니다.
  • 스텝마다 특정 로직(예: 데이터 추출, 모델 학습, 평가 등)을 수행할 수 있습니다.
  • 반환값(리턴값)은 ZenML에서 아티팩트로 관리하기 위해 자동으로 직렬화됩니다(추가 상세는 아래 참고).
from zenml import step
@step
def get_or_create_user(user_full_name: str) -> UserDocument:
    # 사용자 생성 혹은 조회 로직
    return user

 

ZenML Dashboard (웹 UI):

  • ZenML은 파이프라인 상태, 실행 기록, 로그 등을 웹 인터페이스에서 확인할 수 있도록 합니다.
  • poetry poe run-digital-data-etl와 같은 CLI 명령으로 파이프라인을 실행한 뒤, http://127.0.0.1:8237/ 대시보드에서 다음을 시각화할 수 있습니다:
    • 어떤 파이프라인들이 있었는지 (ex: digital_data_etl)
    • 각 파이프라인 실행(런)의 성공/실패 여부
    • 각 스텝의 연결 관계(DAG)
    • 스텝별 로그와 설정 정보

 

파이썬 모듈 구조와 ZenML 코드 분리:

  • 글에서 강조하는 중요한 설계 원칙:
    • 애플리케이션 로직(도메인 로직)은 llm_engineering 모듈 안에 집중.
    • ZenML 로직(파이프라인, 스텝)은 pipelines, steps 폴더에서 정의.
  • 이 구조를 통해 ZenML이 아닌 다른 오케스트레이터를 쓰더라도, llm_engineering 내부 로직을 수정할 필요 없이 오케스트레이터 관련 코드만 갈아끼울 수 있습니다.

 

스텝 출력의 직렬화(Serialization):

  • ZenML에서 스텝이 리턴한 객체는 아티팩트(artifact) 로 저장되며, ZenML이 내부적으로 직렬화 과정을 거칩니다.
  • 제약: ZenML이 지원하지 않는 객체 타입(UUID처럼)의 경우, 커스텀 materializer를 제공해줘야 할 수 있습니다.
  • 글에서도 “UUID 직렬화 문제”를 ZenML 팀에 이슈로 제기했고, 추후 버전에서 지원 예정임을 언급.
  • 이처럼 ZenML은 기본적으로 파이썬의 원시 타입(문자열, 숫자, 리스트, 딕셔너리 등)에 대한 직렬화를 지원하지만, 특수 객체 타입은 사용자 정의 로직이 필요할 수 있습니다.

 

Artifacts and metadata

이 글은 ZenML에서 아티팩트(artifact)와 메타데이터(metadata)를 어떻게 관리하고 활용하는지 설명.

 

아티팩트와 메타데이터는 MLOps 프로세스 전체를 투명하게 만들고, 재현성과 협업을 용이하게 하는 핵심 요소임.

 

아티팩트(Artifact)란 무엇인가?

  • 머신러닝 과정 중 생성되는 모든 결과물(파일, 모델, 데이터셋, 로그 등)을 의미합니다.
    • ZenML에서는 스텝 함수가 반환하는 값(파이썬 객체)을 자동으로 아티팩트로 관리하여 버전과 메타데이터를 붙일 수 있게 해줍니다
  • 아티팩트의 특징:
    • 버전 관리: 각 실행 시점에 생성된 아티팩트를 유니크한 식별자(예: UUID)로 추적.
    • 공유 및 재사용: 다른 파이프라인이나 다른 팀원이 이미 생성된 아티팩트를 필요할 때 쉽게 찾아 재사용.
    • 메타데이터 부착: 아티팩트에 사이즈, 구조, 생성 일시 등의 추가 정보를 기록해두어 “무엇인지”를 빠르게 이해 가능.
  • 예시
    • crawled_links 아티팩트: 크롤링된 링크를 ZenML 대시보드에서 확인할 때, 몇 개의 링크를 성공적으로 크롤링했는지와 같은 정보를 메타데이터로 볼 수 있음.
    • instruct_datasets 아티팩트: LLM 모델 파인튜닝에 필요한 instruct 데이터셋. 카테고리, 데이터 개수, 스플릿 정보 등을 메타데이터로 기록.

 

메타데이터(Metadata)의 역할:

  • 아티팩트를 설명하는 추가 정보
    • 예:
      • 데이터셋의 크기, 카테고리, 학습-테스트 비율, 레이블 종류
      • 모델의 성능 지표, 하이퍼파라미터 정보
      • 크롤링한 링크의 도메인 별 개수, 성공/실패 개수 등
  • 작업 재현성과 협업
    • “이 아티팩트가 어떤 단계를 통해 생성되었는지”, “어떤 설정으로 만들어졌는지” 등을 빠르게 파악.
    • 다운로드 전 메타데이터만 보고도 해당 아티팩트의 유용성을 판단할 수 있음.
  • 수동 혹은 자동 추가 가능
    • ZenML에서 step_context.add_output_metadata()를 통해 원하는 정보를 직접 등록할 수 있음.
    • 일부 기본 정보(생성된 시점, UUID, 등)는 ZenML이 자동으로 기록해줌.

 

코드 예시: 아티팩트 메타데이터 추가

@step
def generate_intruction_dataset(
    prompts: Annotated[dict[DataCategory, list[GenerateDatasetSamplesPrompt]], "prompts"]
) -> Annotated[
    InstructTrainTestSplit,
    ArtifactConfig(
        name="instruct_datasets",
        tags=["dataset", "instruct", "cleaned"],
    ),
]:
    # 1. 데이터셋 생성 로직
    datasets = … 

    # 2. 메타데이터 등록
    step_context = get_step_context()
    step_context.add_output_metadata(
        output_name="instruct_datasets",
        metadata=_get_metadata_instruct_dataset(datasets)
    )

    return datasets

def _get_metadata_instruct_dataset(datasets: InstructTrainTestSplit) -> dict[str, Any]:
    # 데이터셋 정보(카테고리, 샘플 개수, etc.)를 리턴
    ...

 

아티팩트 버전 관리와 로드

  • 아티팩트는 UUID로 식별되며, ZenML 대시보드나 CLI에서 해당 UUID를 조회할 수 있음.
  • 필요하다면 다음 예시 코드처럼 특정 UUID를 이용해 과거에 생성된 아티팩트를 다시 불러올 수 있음:
  • 이를 통해 이전 버전 모델이나 데이터셋을 쉽게 재현하거나 분석할 수 있음.
    from zenml.client import Client
    artifact = Client().get_artifact_version('8bba35c4-8ff9-4d8f-a039-08046efc9fdc')
    loaded_artifact = artifact.load()

 


How to run and configure a ZenML pipeline 

이 글은 ZenML 파이프라인을 실행하고, 구성(설정) 파일을 통해 다양한 파라미터를 주입하는 방식을 소개함. 

또한 최종적으로 다른 오케스트레이터(예: Airflow, Prefect, Kubeflow 등)와의 비교를 짧게 언급

ZenML 파이프라인 실행 방식:

  • run.py 파일
    • 깃허브 저장소의 tools/run.py 파일에서, ZenML 파이프라인을 실행하기 위한 간단한 CLI가 구현되어 있습니다
  • 예: run.py 파일
python -m tools.run --run-etl --no-cache --etl-config-filename digital_data_etl_maxime_labonne.yaml
  • --run-etl: ETL 파이프라인을 실행한다는 옵션
  • --no-cache: ZenML 단계 캐싱을 사용하지 않는다는 옵션
  • --etl-config-filename: 해당 실행 시 주입할 설정 파일 지정
  • 이런 long 명령어” 대신, Poe the Poet에 정의된 poetry poe run-digital-data-etl-maxime 같은 짧은 명령어로 실행할 수 있습니다.

 

설정 파일(config file)과 파이프라인 파라미터 주입:

  • YAML 설정 파일:
    • configs/digital_data_etl_maxime_labonne.yaml처럼, 파이프라인에 필요한 파라미터들을 YAML로 정의합니다.
  • 코드 수정 없이 런타임에 구성 변경
    • 설정 파일만 바꾸면, 같은 파이프라인 코드를 재활용하면서도 다른 유저나 링크 목록에 대해 ETL을 수행할 수 있습니다.
    • ZenML 실행 시 with_options()를 이용해 YAML 파일 내용을 전달하며, 실행 이름(run name) 등도 동적으로 지정 가능합니다.
  • 예: Yaml 파일
parameters:
  user_full_name: Maxime Labonne
  links:
    - https://mlabonne.github.io/blog/posts/2024-07-29_Finetune_Llama31.html
    - ...
  • user_full_name, links 등은 실제 파이프라인에서 함수 인자로 사용됩니다.

 

ZenML 파이프라인 함수의 시그니처:

  • 설정 파일에 정의된 user_full_name, links 값이 함수의 파라미터로 전달됩니다.
@pipeline
def digital_data_etl(user_full_name: str, links: list[str]) -> str:
    ...

 

여러 구성 파일 사용:

  • 예: Maxime의 링크 크롤링 vs Paul의 링크 크롤링처럼, 필요한 파라미터(이름, URL 목록)가 다르다면, 서로 다른 YAML 설정 파일을 만들어 동일한 파이프라인 코드를 재사용합니다.
  • 코드 수정을 최소화하고, 각 실행을 구분하여 추적할 수 있다는 이점이 있습니다.

 

ZenML과 다른 오케스트레이터 비교:

  • 글에서는 Airflow, Prefect, Metaflow, Dagster, Kubeflow 등이 언급됩니다.
  • 각 도구별 특장점:
    • Airflow: DAG 개념에 특화된 강력한 일정/워크플로 관리. 빅데이터 파이프라인에 자주 사용.
    • Prefect: Pythonic한 API, 유연한 흐름 제어, 클라우드/온프레미스 운영.
    • Metaflow: Netflix에서 개발, Pythonic 하면서도 데이터 사이언스 워크플로에 초점을 둠.
    • Dagster: Solid, Pipeline 등 자체 개념으로, 데이터 애플리케이션에 특화된 오케스트레이션.
    • Kubeflow: Kubernetes 클러스터 기반, 대규모 ML 워크플로에 적합.
    • ZenML은 이들보다 “스택” 개념으로 클라우드 종속성을 낮추고, Pythonic API로 간편하게 다양한 인프라/도구를 연결할 수 있음.

 

CometML

Comet ML을 사용해 머신러닝 실험을 추적(Experiment Tracking)하고, 성능 지표를 기록·비교하는 방법을 소개

 

머신러닝 실험 추적(Experiment Tracking)의 중요성:

  • 반복적인 실험
    • 머신러닝은 여러 번의 시도·오류(iteration)를 거쳐 최적의 모델과 하이퍼파라미터를 찾는 과정입니다.
    • 각 실험마다 학습 하이퍼파라미터, 모델 구조, 데이터셋 버전, 성능 지표 등을 체계적으로 기록해두면, 나중에 어느 실험이 더 성능이 좋았는지 빠르게 비교할 수 있습니다.
  • 결정 근거 확보
    • “어떤 이유로 이 모델을 선택했는가?”에 대한 근거가 필요할 때, 모든 실험 기록과 로그를 남겨놓으면 투명성과 재현성이 높아집니다

 

Comet ML이 제공하는 주요 기능:

  • 지표(메트릭) 로깅
    • 학습 손실(training loss), 평가 손실(evaluation loss), 그래디언트 norm 등 주요 지표를 실시간으로 추적 가능합니다.
    • Comet 대시보드에서 모든 실험의 손실 곡선을 시각적으로 비교할 수 있습니다
  • 하이퍼파라미터(Hyperparameters) 관리
    • 실험마다 learning_rate, batch_size, optimizer 등 하이퍼파라미터 값을 기록·관리.
    • 하이퍼파라미터 변화를 기준으로 성능 지표를 한눈에 비교할 수 있습니다.
  • 시스템 리소스 모니터링
    • GPU, CPU, 메모리 사용량 등의 정보를 자동으로 수집.
    • 학습 병목(bottleneck)이 발생하는 지점을 파악하거나, 적절한 리소스를 예측하는 데 도움을 줍니다.
  • 온라인 서비스 & 직관적 UI
    • Comet은 클라우드 기반으로 무료 버전을 제공하므로, 로컬 서버 설정 없이 바로 사용 가능합니다.
    • 시각화와 UI가 직관적이라, 처음 접하는 팀원도 쉽게 쓸 수 있습니다.

 

LLM Twin 프로젝트에서의 활용:

  • LLM Twin 모델을 파인튜닝하는 과정에서, Comet을 통해 학습 손실, 평가 손실, 그래디언트 norm 등을 추적했습니다.
  • 실험 결과는 공개되어 있으므로, 누구든 Comet 링크 에서 학습 로그와 지표를 확인할 수 있습니다.
  • 이는 팀원들이 “이전 실험 대비 성능이 얼마나 개선되었는지”, “어떤 하이퍼파라미터 조합이 유효했는지”를 투명하게 확인하게 해 줍니다.

 

다른 실험 추적 도구들과의 비교:

  • 대표적인 대안으로 Weights & Biases(W&B), MLflow, Neptune 등이 있습니다.
  • 전반적으로 기능은 유사하며,
    • W&B: 강력한 커뮤니티와 시각화 기능
    • MLflow: Databricks가 개발, 모델 레지스트리 등과 연계하기 쉬움
    • Neptune: UI, 협업 기능, 데이터셋 추적 강화
  • Comet ML은 상대적으로 쉽고 직관적인 인터페이스가 강점으로 꼽힙니다.