Intro
그동안 ETL 파이프라인 구축 중심의 프로젝트를 해왔는데, 이번에는 처음으로 MLOps 파이프라인을 다뤄보게 되었다. 약 2개월간 진행된 프로젝트를 마치며, 그 과정에서 얻은 기술적인 인사이트와 소프트 스킬에 대한 회고를 남겨본다.
MLOps 오케스트레이션 - Data Factory
이번 프로젝트에서는 MLOps 파이프라인을 오케스트레이션하기 위해 Azure Data Factory (ADF) 를 사용했다.
Azure 공식 문서에 따르면 ADF는 복잡한 하이브리드 ETL, ELT 및 데이터 통합 작업을 위한 완전 관리형 클라우드 서비스다. 일반적으로 Apache Airflow와 비교되곤 하는데, 두 도구 모두 워크플로우 오케스트레이션 도구로서 데이터 이동 및 처리 파이프라인 구축, 배치 파이프라인 스케줄링, 의존성 관리, 작업 실패에 대한 알림 및 재시도 설정 등의 기능을 제공한다.
두 도구의 주요 차이점은 다음과 같다:
- ADF: 완전한 Azure 관리형 서비스로, GUI 기반의 드래그 앤 드롭 방식으로 파이프라인을 구성할 수 있다.
- Airflow: 코드 기반 오케스트레이션 도구로, Python으로 유연한 커스터마이징이 가능하다
기존 데이터 플랫폼이 Azure 기반(Azure SQL, Storage, Databricks 등)이었기 때문에 Azure 생태계와의 통합이 쉬운 ADF를 선택하게 되었다.
직접 사용해본 결과, Airflow처럼 100% 코드 기반은 아니기 때문에 유연성이 다소 떨어지는 점이 아쉬웠다. 원하는 흐름을 만들기 위해 다양한 Activity를 조합하며 타협점을 찾아야 했다는 점도 도전이었다. 반면, ADF는 중앙집중식으로 파이프라인을 관리할 수 있으며, MS 기반 서비스 간의 통합이 자연스럽다는 장점도 있었다.
온프레미스에서 클라우드 환경으로 마이그레이션
1. 마이그레이션을 하게 된 배경
온프레미스에서 잘 운영되던 프로그램을 클라우드 환경으로 이전한 이유는, 중앙집중식 관리를 위한 선택이었다. 특히 Databricks라는 데이터 플랫폼을 도입하면서, 전체 데이터 파이프라인과 MLOps, 분석 실험을 ADF와 Databricks 기반으로 한 곳에서 관리하는 방향으로 전환하게 되었다.
기존 프로그램은 AWS Forecast 서비스를 활용해 API 호출 방식으로 데이터를 학습시키고 예측 결과를 결과 테이블에 저장하는 방식이었다. 자체적인 모델 학습 및 배포가 필요한 구조가 아니었기 때문에, 클라우드 환경으로 이전하더라도 리소스 부담이 크지 않았다.
2. 마이그레이션 시 고려한 사항
Windows .exe 파일을 Databricks에서 실행하는 방법
기존 시스템은 Windows 환경에서 .exe 형태로 만들어진 Python 프로그램을 분석가가 수동 실행하는 방식이었다. 그러나 Databricks는 리눅스 기반이므로 .exe 파일은 사용할 수 없다. 이를 해결하기 위해, python -m 명령어로 main 모듈을 실행하는 방식으로 전환하여 패키지 구조를 유지하면서도 실행 가능하도록 구성했다.
이렇게 하면 패키지 구조를 보존하면서 모듈을 실행시킬 수 있다.
import subprocess
subprocess.run(["python", "-m", "mypackage"])
Python 패키지 버전 호환 문제
운영체제 변경에 따라 패키지 버전 호환성 문제가 발생했다. 이에 따라 필요한 패키지 버전을 재정비하여 Linux 환경에 맞게 설정해야 했다.
반복 작업 자동화 및 모니터링 문제
기존에는 Windows 시스템에서 스케줄링을 설정했지만, 실제 작동 여부를 수동으로 모니터링해야 했다. 주말에는 약 10시간 동안 모니터링을 해야 하는 불편함도 있었다.
이벤트 기반 처리 고려
AWS Forecast의 상태값이 업데이트될 때 이를 감지하여 이벤트 기반 파이프라인으로 구성하면 효율적이었겠지만, 운영 인력의 한계와 새로운 기술에 대한 거부감으로 인해 도입이 어려웠다.
작업 상태 조회 로직 추가
이벤트 기반 처리가 어려운 상황이었기에, MLOps 로그 테이블을 활용하여 파이프라인 실행 전 작업 상태를 조회하고 분기처리하는 SQL 로직을 도입했다.
클러스터 비용 최적화
클러스터 사용 시 비용 효율성도 중요한 고려사항이었다. 처음엔 작업을 10번 반복하고 1시간 대기하는 방식으로 설계했으나, 불필요한 리소스 낭비가 발생했다. 이후 작업 상태에 따라 유연하게 분기 처리하는 방식으로 개선하여 비용을 절감했다.
이러한 고민과 실험을 통해 ADF의 Activity 블록 기반으로 파이프라인을 아래와 같이 설계하게 되었다.
MLflow 의 적용
이번 프로젝트에서는 모든 파이프라인에 MLflow를 바로 적용한 것은 아니었다.
모델 학습 자체를 AWS Forecast API를 통해 수행하는 파이프라인의 경우, 내부에서 학습 로직이 수행되지 않기 때문에 MLflow를 적용하지 않았다. 하지만 또 다른 파이프라인에서는 Databricks 노트북 환경에서 직접 모델을 생성하고 학습 및 추론까지 진행하는 방식이었고, 이에 따라 MLflow를 효과적으로 적용해볼 수 있었다.
MLflow 의 주요 기능
Experiments Tracking
모델 학습 과정에서 발생하는 다양한 지표(metrics) 와 하이퍼파라미터(params) 를 기록하여, 실험을 비교하고 재현할 수 있게 해준다.
Model Registry
학습된 모델을 등록, 버전 관리, 배포 상태 관리(Staging, Production 등) 할 수 있는 기능으로, 협업 시나 운영 환경과의 연계를 보다 체계적으로 구성할 수 있다.
파이프라인에 MLflow 적용한 방식
Experiments 로깅
- 모델 학습 후, 정확도 등의 성능 지표(metrics) 를 MLflow에 기록하여 실험별 성능 비교가 가능하도록 구성했다.
- 또한, 학습에 사용된 하이퍼파라미터도 함께 로깅함으로써, 추후 파리미터에 대한 성능 비교가 가능하도록 구성했다.
MLflow 공식 도큐먼트에서 가져온 예시 코드는 아래와 같다. 실제로도 log_params, log_metric, log_model 함수를 사용해서 실험을 로깅했다.
# Start an MLflow run
with mlflow.start_run():
# Log the hyperparameters -> 하이퍼 파라미터 로깅
mlflow.log_params(params)
# Log the loss metric -> 메트릭 로깅
mlflow.log_metric("accuracy", accuracy)
# Set a tag that we can use to remind ourselves what this run was for
mlflow.set_tag("Training Info", "Basic LR model for iris data")
# Infer the model signature
signature = infer_signature(X_train, lr.predict(X_train))
# Log the model
model_info = mlflow.sklearn.log_model(
sk_model=lr,
artifact_path="iris_model",
signature=signature,
input_example=X_train,
registered_model_name="tracking-quickstart",
)
Artifact 저장
- 학습된 모델에 대한 pickle 파일, output 파일을 artifact로 저장했다. 실험별로 모델 파일을 관리할 수 있다.
- 이후 필요하다면 Model Registry 를 활용하여, 배포 관리를 (Staging, Production) 가능하도록 확장할 수 있을 것이다.
보완할 수 있는 점
1. 현재는 Random Forest 모델을 새로운 데이터로 매번 재학습시키고 있다. 리소스 부담이 크지 않아 실용적인 선택이지만, 데이터가 커질 경우에는 모델을 재사용하거나 부분 학습 방식(Incremental Learning) 으로 변경할 필요가 있다.
2. 아직은 Model Registry를 통한 운영 배포 흐름은 적용하지 않았지만, 향후에 모델 검증, 승인을 추가하여 운영 환경에 자동 반영하는 구조로 확장할 수 있다.
프로젝트를 마무리하며
이번 프로젝트는 처음으로 MLOps 파이프라인을 실제로 배포해보며, 모델 학습과 추론 등 MLOps에 필요한 여러 단계들을 직접 경험할 수 있었던 값진 시간이었다. 특히 MLflow를 실무에 적용해보면서, 모델의 버전 관리나 배포 단계를 체계적으로 관리할 수 있는 도구라는 것을 체감할 수 있었다.
무엇보다 이번 프로젝트는 다른 프로젝트들과 달리 혼자서 투입되어 고객과 직접 소통하며 프로젝트를 리드해야 했다는 점에서 많은 도전이 있었다.
분석가와 협업하면서 ML 파이프라인의 전체 흐름을 이해하고, 관련된 테이블을 확인하며 요구사항을 하나씩 정리해나갔다. 또, 클라우드 환경에서는 비용 이슈가 민감하다 보니, 작업 효율성과 비용 절감을 동시에 고려하며 설계에 대한 고민도 많이 하게 되었다.개인적으로는, 이번 기회를 통해 자율성과 책임을 동시에 경험했다는 점에서 큰 의미가 있었다. 이전에는 “내가 이 정도까지 의견을 내도 될까?” 하는 고민이 많았지만, 이번 경험을 통해 앞으로는 기술적으로 현재 상황에 타당하다고 생각이 된다면 더 주도적으로 방향을 제시하고 의견을 낼 수 있겠다는 자신감이 생겼다. 혼자 리딩하는 것이 힘들었던 만큼 소프트 스킬적으로 많이 성장할 수 있었다.