LabHub

블로그

토스뱅크 ML Engineer (MLOps) 합격 완벽 가이드: MLFlow부터 LLM 플랫폼까지 기술스택 총정리

한국어English日本語

들어가며: 왜 토스뱅크 ML Platform Team인가

토스뱅크는 2021년 출범 이후 국내 인터넷전문은행의 판도를 바꿔왔습니다. 특히 ML Platform Team은 전사 머신러닝 인프라를 책임지는 핵심 조직으로, 금융 도메인 특화 MLOps라는 희소성 높은 경험을 쌓을 수 있는 곳입니다.

이 글은 토스뱅크 ML Engineer (MLOps) JD를 한 줄 한 줄 해부하고, 각 기술스택을 실무 수준까지 깊이 있게 다룹니다. 단순히 "이런 기술이 있다" 수준이 아니라, "면접관이 왜 이 기술을 물어보는지", "실무에서 어떤 문제를 해결하는지"까지 파고들겠습니다.


1. 토스뱅크 ML Platform Team 분석

1-1. 팀 미션

토스뱅크 ML Platform Team의 핵심 미션은 전사 머신러닝 플랫폼 구축 및 운영입니다. 이것이 의미하는 바를 구체적으로 풀어보겠습니다.

1-2. 핀테크 x MLOps의 특수성

일반 IT 회사의 MLOps와 금융 MLOps는 근본적으로 다릅니다.

규제 준수 (Compliance)

실시간성 (Low Latency)

설명가능성 (Explainability)

1-3. 토스의 기술 문화

토스는 사일로 해체마이크로서비스 아키텍처를 지향합니다. ML Platform Team도 이 철학 아래 동작하므로:


2. JD 완전 해부: 라인 바이 라인

토스뱅크 ML Engineer (MLOps) JD의 주요 항목을 하나씩 분석합니다.

자격 요건 분석

"Kubernetes 기반 인프라 운영 경험"

"MLFlow, Airflow, Kubeflow 등 ML 플랫폼 도구 경험"

"모델 서빙 파이프라인 구축 및 운영 경험"

"Feature Store 설계 및 운영 경험"

우대 사항 분석

"LLM 서빙 및 플랫폼 구축 경험"

"GPU 클러스터 운영 및 최적화 경험"

"분산 데이터베이스 운영 경험"


3. 기술스택 딥다이브

이 섹션이 이 글의 핵심입니다. 각 기술을 면접에서 자신 있게 설명할 수 있는 수준까지 다룹니다.

3-1. Kubernetes (기반 인프라)

아키텍처 완전 이해

Kubernetes의 아키텍처는 Control PlaneData Plane(Worker Nodes)으로 나뉩니다.

Control Plane 컴포넌트:

Worker Node 컴포넌트:

Deployment 전략

# Canary Deployment 예시 (Argo Rollouts)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: ml-model-rollout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause:
            duration: 1h
        - setWeight: 30
        - pause:
            duration: 1h
        - setWeight: 60
        - pause:
            duration: 30m
      analysis:
        templates:
          - templateName: model-accuracy-check

ML 모델 배포에서 Canary 배포가 특히 중요한 이유: 새 모델이 프로덕션 트래픽의 일부에서 정확도를 검증한 후에야 전체 배포를 진행합니다.

Resource Management 심화

# GPU Pod의 리소스 설정
apiVersion: v1
kind: Pod
metadata:
  name: triton-server
spec:
  containers:
    - name: triton
      image: nvcr.io/nvidia/tritonserver:24.01-py3
      resources:
        requests:
          cpu: '4'
          memory: '16Gi'
          nvidia.com/gpu: '1'
        limits:
          cpu: '8'
          memory: '32Gi'
          nvidia.com/gpu: '1'
  nodeSelector:
    accelerator: nvidia-a100
  tolerations:
    - key: nvidia.com/gpu
      operator: Exists
      effect: NoSchedule

QoS 클래스 이해:

GPU on Kubernetes

MLOps에서 가장 중요한 부분 중 하나입니다.

NVIDIA Device Plugin:

GPU 공유 전략:

전략설명장점단점
MIG (Multi-Instance GPU)A100을 최대 7개 인스턴스로 분할하드웨어 수준 격리A100/H100만 지원
Time-Slicing시분할로 GPU 공유모든 GPU 지원격리 없음, 간섭 가능
MPS (Multi-Process Service)CUDA 컨텍스트 공유오버헤드 낮음메모리 보호 제한적
vGPUNVIDIA GRID 기반강한 격리라이선스 비용

NVIDIA GPU Operator:

# GPU Operator 설치 (Helm)
# helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
# helm install gpu-operator nvidia/gpu-operator

GitOps with ArgoCD

# ArgoCD Application 예시 - ML Model Deployment
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: fraud-detection-model
spec:
  project: ml-platform
  source:
    repoURL: https://github.com/tossbank/ml-deployments
    targetRevision: main
    path: models/fraud-detection
  destination:
    server: https://kubernetes.default.svc
    namespace: ml-serving
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

실습 로드맵:

  1. Minikube/kind로 로컬 K8s 클러스터 구축
  2. NVIDIA Device Plugin 설치 후 GPU Pod 실행 테스트
  3. Helm Chart 작성으로 Triton Server 배포
  4. ArgoCD 설치 후 GitOps 파이프라인 구축
  5. EKS/GKE에서 실제 GPU 노드 그룹 운영

추천 자료:


3-2. MLFlow (실험 관리 및 모델 레지스트리)

4대 컴포넌트 이해

1. MLFlow Tracking

import mlflow

mlflow.set_tracking_uri("http://mlflow-server:5000")
mlflow.set_experiment("fraud-detection-v2")

with mlflow.start_run(run_name="xgboost-baseline"):
    mlflow.log_param("max_depth", 6)
    mlflow.log_param("learning_rate", 0.1)
    mlflow.log_param("n_estimators", 1000)

    model = train_model(params)

    mlflow.log_metric("auc", 0.9542)
    mlflow.log_metric("f1", 0.8731)
    mlflow.log_metric("precision", 0.9012)
    mlflow.log_metric("recall", 0.8467)

    # 모델 아티팩트 저장
    mlflow.xgboost.log_model(model, "model")

    # 학습 데이터 메타데이터 기록 (금융 규제 대응)
    mlflow.log_param("training_data_version", "2024-03-15")
    mlflow.log_param("data_hash", "sha256:abc123...")

2. MLFlow Projects

3. MLFlow Models

4. MLFlow Model Registry

# 모델 등록
result = mlflow.register_model(
    "runs:/abc123/model",
    "fraud-detection-model"
)

# Stage 전환 (Staging -> Production)
client = mlflow.tracking.MlflowClient()
client.transition_model_version_stage(
    name="fraud-detection-model",
    version=3,
    stage="Production",
    archive_existing_versions=True  # 기존 Production 모델 자동 아카이브
)

Tracking Server 프로덕션 구축

# docker-compose.yaml for MLFlow Server
version: '3'
services:
  mlflow:
    image: ghcr.io/mlflow/mlflow:v2.11.0
    command: >
      mlflow server
      --backend-store-uri postgresql://mlflow:password@postgres:5432/mlflow
      --default-artifact-root s3://tossbank-ml-artifacts/
      --host 0.0.0.0
      --port 5000
    environment:
      AWS_ACCESS_KEY_ID: ...
      AWS_SECRET_ACCESS_KEY: ...
    ports:
      - '5000:5000'

  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: mlflow
      POSTGRES_USER: mlflow
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

왜 PostgreSQL + S3 조합인가?

MLFlow + K8s 연동

# MLFlow 모델을 K8s에 배포
# mlflow models build-docker 명령으로 Docker 이미지 생성
# 또는 KServe InferenceService로 직접 배포

# KServe로 MLFlow 모델 서빙
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: fraud-model
spec:
  predictor:
    mlflow:
      protocolVersion: v2
      storageUri: s3://tossbank-ml-artifacts/fraud-model/v3
      resources:
        requests:
          cpu: '2'
          memory: '4Gi'

실습 체크리스트:

  1. Docker Compose로 MLFlow 서버 구축 (PostgreSQL + MinIO)
  2. XGBoost 모델 학습 → 파라미터/메트릭 로깅
  3. Model Registry에 모델 등록 → Stage 전환
  4. MLFlow Models로 Docker 이미지 빌드 → K8s 배포
  5. A/B 테스트: 두 모델 버전 동시 서빙 후 비교

추천 자료:


3-3. Apache Airflow (워크플로우 오케스트레이션)

아키텍처 깊이 이해

Airflow의 아키텍처는 4개 핵심 컴포넌트로 구성됩니다.

Scheduler:

Webserver:

Workers:

Metadata DB:

Executor 비교 (면접 핵심!)

Executor특징적합한 환경
LocalExecutor단일 머신, 멀티프로세스개발/소규모
CeleryExecutorRedis/RabbitMQ 기반 분산중규모, 안정적
KubernetesExecutor태스크마다 Pod 생성K8s 환경, GPU 워크로드
CeleryKubernetesExecutorCelery + K8s 혼합대규모, 유연성 필요

토스뱅크에서는 KubernetesExecutor 또는 CeleryKubernetesExecutor를 사용할 가능성이 높습니다. GPU 학습 태스크는 K8s Pod로, 경량 태스크는 Celery Worker로 처리하는 하이브리드 전략입니다.

ML 파이프라인 DAG 작성

from airflow import DAG
from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
from airflow.operators.python import PythonOperator
from datetime import datetime, timedelta

default_args = {
    "owner": "ml-platform",
    "retries": 2,
    "retry_delay": timedelta(minutes=5),
    "execution_timeout": timedelta(hours=2),
}

with DAG(
    dag_id="fraud_detection_training_pipeline",
    default_args=default_args,
    schedule_interval="0 2 * * *",  # 매일 새벽 2시
    start_date=datetime(2024, 1, 1),
    catchup=False,
    tags=["ml", "fraud-detection"],
) as dag:

    # 1. 데이터 수집 (경량 - Python)
    extract_data = PythonOperator(
        task_id="extract_data",
        python_callable=extract_training_data,
    )

    # 2. 피처 엔지니어링 (Spark on K8s)
    feature_engineering = KubernetesPodOperator(
        task_id="feature_engineering",
        name="feature-eng-pod",
        namespace="ml-jobs",
        image="tossbank/spark-feature-eng:latest",
        arguments=["--date", "{{ ds }}"],
        resources={
            "requests": {"cpu": "4", "memory": "16Gi"},
            "limits": {"cpu": "8", "memory": "32Gi"},
        },
        is_delete_operator_pod=True,
        get_logs=True,
    )

    # 3. 모델 학습 (GPU Pod)
    train_model = KubernetesPodOperator(
        task_id="train_model",
        name="model-training-pod",
        namespace="ml-jobs",
        image="tossbank/fraud-model-trainer:latest",
        arguments=[
            "--experiment-name", "fraud-detection-v2",
            "--date", "{{ ds }}",
        ],
        resources={
            "requests": {"cpu": "4", "memory": "32Gi", "nvidia.com/gpu": "1"},
            "limits": {"cpu": "8", "memory": "64Gi", "nvidia.com/gpu": "1"},
        },
        node_selector={"accelerator": "nvidia-a100"},
        tolerations=[{
            "key": "nvidia.com/gpu",
            "operator": "Exists",
            "effect": "NoSchedule",
        }],
        is_delete_operator_pod=True,
        get_logs=True,
    )

    # 4. 모델 평가
    evaluate_model = KubernetesPodOperator(
        task_id="evaluate_model",
        name="model-evaluation-pod",
        namespace="ml-jobs",
        image="tossbank/model-evaluator:latest",
        is_delete_operator_pod=True,
        get_logs=True,
    )

    # 5. 모델 배포 (조건부)
    deploy_model = KubernetesPodOperator(
        task_id="deploy_model",
        name="model-deploy-pod",
        namespace="ml-serving",
        image="tossbank/model-deployer:latest",
        arguments=["--model-name", "fraud-detection", "--stage", "canary"],
        is_delete_operator_pod=True,
        get_logs=True,
    )

    extract_data >> feature_engineering >> train_model >> evaluate_model >> deploy_model

XCom으로 태스크 간 데이터 전달

# 모델 학습 태스크에서 메트릭 push
def train_and_push_metrics(**context):
    model, metrics = train_model()
    context["ti"].xcom_push(key="model_auc", value=metrics["auc"])
    context["ti"].xcom_push(key="model_version", value="v3.2.1")

# 평가 태스크에서 메트릭 pull하여 배포 결정
def evaluate_and_decide(**context):
    auc = context["ti"].xcom_pull(task_ids="train_model", key="model_auc")
    if auc >= 0.95:
        return "deploy_model"  # BranchPythonOperator로 분기
    else:
        return "notify_team"

Secrets 관리 (Vault 연동)

토스뱅크 같은 금융사에서는 민감 정보 관리가 필수입니다.

# airflow.cfg
# [secrets]
# backend = airflow.providers.hashicorp.secrets.vault.VaultBackend
# backend_kwargs = {"connections_path": "airflow/connections", "variables_path": "airflow/variables", "url": "https://vault.tossbank.com:8200"}

실습 체크리스트:

  1. Docker Compose로 Airflow 로컬 환경 구축
  2. 간단한 Python DAG 작성 → Webserver에서 실행 확인
  3. KubernetesPodOperator로 GPU 태스크 실행
  4. MLFlow와 연동하여 학습-평가-등록 자동화
  5. SLA miss alert 설정, 모니터링 대시보드 구축

추천 자료:


3-4. Kubeflow (K8s 기반 ML 플랫폼)

핵심 컴포넌트

Kubeflow Pipelines (KFP):

from kfp import dsl
from kfp import compiler

@dsl.component(
    base_image="python:3.11",
    packages_to_install=["pandas", "scikit-learn", "mlflow"]
)
def train_component(
    data_path: str,
    learning_rate: float,
    max_depth: int,
) -> str:
    import pandas as pd
    from sklearn.ensemble import GradientBoostingClassifier
    import mlflow

    # 학습 로직
    df = pd.read_parquet(data_path)
    model = GradientBoostingClassifier(
        learning_rate=learning_rate,
        max_depth=max_depth,
    )
    model.fit(df.drop("target", axis=1), df["target"])

    with mlflow.start_run():
        mlflow.sklearn.log_model(model, "model")
        run_id = mlflow.active_run().info.run_id

    return run_id

@dsl.pipeline(name="Fraud Detection Pipeline")
def fraud_pipeline(data_path: str = "s3://data/fraud/latest"):
    train_task = train_component(
        data_path=data_path,
        learning_rate=0.1,
        max_depth=6,
    )
    train_task.set_gpu_limit(1)
    train_task.set_memory_limit("32Gi")
    train_task.add_node_selector_constraint(
        "accelerator", "nvidia-a100"
    )

compiler.Compiler().compile(fraud_pipeline, "pipeline.yaml")

Katib (하이퍼파라미터 자동 튜닝):

apiVersion: kubeflow.org/v1beta1
kind: Experiment
metadata:
  name: fraud-model-tuning
spec:
  objective:
    type: maximize
    goal: 0.98
    objectiveMetricName: auc
  algorithm:
    algorithmName: bayesianoptimization
  parallelTrialCount: 3
  maxTrialCount: 30
  maxFailedTrialCount: 3
  parameters:
    - name: learning_rate
      parameterType: double
      feasibleSpace:
        min: '0.001'
        max: '0.3'
    - name: max_depth
      parameterType: int
      feasibleSpace:
        min: '3'
        max: '12'
    - name: n_estimators
      parameterType: int
      feasibleSpace:
        min: '100'
        max: '2000'

KServe (모델 서빙):

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: fraud-detector
spec:
  predictor:
    model:
      modelFormat:
        name: xgboost
      storageUri: s3://models/fraud-detection/v3
      resources:
        requests:
          cpu: '2'
          memory: '4Gi'
  transformer:
    containers:
      - image: tossbank/fraud-preprocessor:latest
        name: transformer
  explainer:
    containers:
      - image: tossbank/fraud-explainer:latest
        name: explainer

Kubeflow vs Airflow: 언제 무엇을 쓸 것인가

기준AirflowKubeflow Pipelines
주 용도범용 워크플로우ML 특화 파이프라인
스케줄링강력 (cron, 센서)제한적
K8s 통합KubernetesExecutor네이티브
파이프라인 캐싱없음컴포넌트 단위 캐싱
UI강력한 모니터링파이프라인 시각화
학습 곡선상대적으로 낮음상대적으로 높음

토스뱅크의 예상 조합:

추천 자료:


3-5. JupyterHub (노트북 환경)

JupyterHub on K8s

데이터 사이언티스트의 일상 도구인 JupyterHub를 K8s 위에서 운영하는 것은 MLOps 엔지니어의 중요한 역할입니다.

Zero to JupyterHub:

# values.yaml (Helm)
singleuser:
  image:
    name: tossbank/ml-notebook
    tag: latest
  profileList:
    - display_name: 'CPU Notebook (Small)'
      description: '2 CPU, 4GB RAM'
      kubespawner_override:
        cpu_limit: 2
        mem_limit: '4G'
    - display_name: 'GPU Notebook (A100)'
      description: '8 CPU, 32GB RAM, 1 A100 GPU'
      kubespawner_override:
        cpu_limit: 8
        mem_limit: '32G'
        extra_resource_limits:
          nvidia.com/gpu: '1'
        node_selector:
          accelerator: nvidia-a100
        tolerations:
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule

hub:
  config:
    Authenticator:
      admin_users:
        - admin
    GenericOAuthenticator:
      client_id: jupyterhub
      client_secret: ...
      oauth_callback_url: https://jupyter.tossbank.com/hub/oauth_callback
      authorize_url: https://auth.tossbank.com/oauth/authorize
      token_url: https://auth.tossbank.com/oauth/token

proxy:
  service:
    type: ClusterIP

커스텀 노트북 이미지: GPU 노트북에는 CUDA, cuDNN, PyTorch, TensorFlow, MLFlow 클라이언트 등이 사전 설치되어야 합니다.

FROM nvidia/cuda:12.3.1-cudnn9-runtime-ubuntu22.04

RUN pip install \
    jupyterlab==4.1.0 \
    torch==2.2.0 \
    tensorflow==2.15.0 \
    mlflow==2.11.0 \
    xgboost==2.0.3 \
    scikit-learn==1.4.0 \
    pandas==2.2.0 \
    boto3==1.34.0

# MLFlow 트래킹 서버 기본 설정
ENV MLFLOW_TRACKING_URI=http://mlflow-server:5000

보안 고려사항 (금융사 필수):


3-6. Triton Inference Server (모델 서빙)

이 섹션은 토스뱅크 ML Platform에서 가장 실무적으로 중요한 기술입니다.

아키텍처 이해

Triton은 세 가지 핵심 개념으로 동작합니다.

Model Repository:

model_repository/
├── fraud_detection/
│   ├── config.pbtxt
│   ├── 1/
│   │   └── model.onnx
│   └── 2/
│       └── model.onnx
├── text_classifier/
│   ├── config.pbtxt
│   └── 1/
│       └── model.pt
└── ensemble_pipeline/
    ├── config.pbtxt
    └── 1/

Backend System:

Dynamic Batching (면접 핵심!)

Dynamic Batching은 Triton의 킬러 기능입니다. 개별 추론 요청을 모아서 배치로 처리하여 GPU 활용도를 극대화합니다.

# config.pbtxt
name: "fraud_detection"
platform: "onnxruntime_onnx"
max_batch_size: 64

dynamic_batching {
  preferred_batch_size: [8, 16, 32]
  max_queue_delay_microseconds: 100
}

instance_group [
  {
    count: 2
    kind: KIND_GPU
    gpus: [0]
  }
]

input [
  {
    name: "features"
    data_type: TYPE_FP32
    dims: [128]
  }
]

output [
  {
    name: "probability"
    data_type: TYPE_FP32
    dims: [1]
  }
]

preferred_batch_size 설정 전략:

max_queue_delay_microseconds:

Model Ensemble (파이프라인 서빙)

# ensemble_config.pbtxt
name: "fraud_pipeline"
platform: "ensemble"
max_batch_size: 32

ensemble_scheduling {
  step [
    {
      model_name: "preprocessor"
      model_version: -1
      input_map {
        key: "raw_transaction"
        value: "RAW_INPUT"
      }
      output_map {
        key: "processed_features"
        value: "FEATURES"
      }
    },
    {
      model_name: "fraud_detection"
      model_version: -1
      input_map {
        key: "features"
        value: "FEATURES"
      }
      output_map {
        key: "probability"
        value: "FRAUD_SCORE"
      }
    },
    {
      model_name: "postprocessor"
      model_version: -1
      input_map {
        key: "score"
        value: "FRAUD_SCORE"
      }
      output_map {
        key: "result"
        value: "FINAL_RESULT"
      }
    }
  ]
}

모델 최적화 파이프라인

원본 모델 (PyTorch/TF)
ONNX 변환 (torch.onnx.export)
ONNX 최적화 (onnxoptimizer, onnxsim)
TensorRT 변환 (trtexec)
[FP16/INT8 양자화]
Triton 배포 (TensorRT backend)
# TensorRT 변환 예시
trtexec \
    --onnx=fraud_model.onnx \
    --saveEngine=fraud_model.plan \
    --fp16 \
    --workspace=4096 \
    --minShapes=features:1x128 \
    --optShapes=features:32x128 \
    --maxShapes=features:64x128

Perf Analyzer (성능 벤치마크)

# Triton Perf Analyzer로 성능 측정
perf_analyzer \
    -m fraud_detection \
    -u localhost:8001 \
    --concurrency-range 1:64:4 \
    --input-data random \
    -b 1 \
    --measurement-interval 5000 \
    --percentile 99

결과 분석 포인트:

Triton + K8s 오토스케일링

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: triton-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: triton-server
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: nv_inference_request_success
        target:
          type: AverageValue
          averageValue: '100'
    - type: Pods
      pods:
        metric:
          name: nv_gpu_utilization
        target:
          type: AverageValue
          averageValue: '70'

실습 체크리스트:

  1. ONNX 모델을 Triton에 배포하고 gRPC/HTTP로 추론 요청
  2. Dynamic Batching 설정 후 Perf Analyzer로 성능 비교
  3. Model Ensemble로 전처리-추론-후처리 파이프라인 구축
  4. TensorRT로 모델 최적화 후 FP32 대비 성능 비교
  5. K8s HPA로 오토스케일링 설정 후 부하 테스트

추천 자료:


3-7. ScyllaDB와 Feature Store

ScyllaDB 아키텍처 심화

ScyllaDB는 Cassandra를 C++로 재작성한 고성능 분산 NoSQL입니다. 토스뱅크가 Feature Store의 Online Store로 ScyllaDB를 선택한 이유를 깊이 이해해야 합니다.

Shard-per-Core 아키텍처:

Cassandra와의 결정적 차이:

항목CassandraScyllaDB
언어Java (JVM)C++ (Seastar)
P99 레이턴시수십 ms1-2 ms
GC 이슈있음 (Stop-the-World)없음
CPU 활용JVM 오버헤드코어 100% 활용
스케일링노드 수로코어 수 + 노드 수
호환성-CQL 호환

데이터 모델링 (면접 핵심!)

ScyllaDB 데이터 모델링에서 Partition Key 설계는 성능을 좌우합니다.

-- Feature Store 테이블 설계 예시
CREATE TABLE feature_store.user_features (
    user_id text,
    feature_name text,
    feature_value blob,
    updated_at timestamp,
    PRIMARY KEY ((user_id), feature_name)
) WITH CLUSTERING ORDER BY (feature_name ASC)
  AND compaction = {
    'class': 'TimeWindowCompactionStrategy',
    'compaction_window_unit': 'HOURS',
    'compaction_window_size': 1
  }
  AND gc_grace_seconds = 86400;

-- 실시간 트랜잭션 피처 테이블
CREATE TABLE feature_store.transaction_features (
    user_id text,
    feature_time timestamp,
    feature_name text,
    feature_value double,
    PRIMARY KEY ((user_id), feature_time, feature_name)
) WITH CLUSTERING ORDER BY (feature_time DESC, feature_name ASC)
  AND default_time_to_live = 604800;  -- 7일 TTL

Partition Key 설계 원칙:

Compaction 전략 (면접에서 자주 나옴)

전략특징적합한 워크로드
STCS (Size-Tiered)비슷한 크기의 SSTable 병합쓰기 위주
LCS (Leveled)레벨별 SSTable 관리읽기 위주
TWCS (Time-Window)시간 윈도우별 관리시계열 데이터
ICS (Incremental)ScyllaDB 독자 전략, 점진적 병합범용 (권장)

Feature Store의 Online Store는 읽기 위주 워크로드이므로 LCS 또는 ICS가 적합합니다.

Feature Store 개념 정복

Offline Store vs Online Store:

[배치 학습]                    [실시간 서빙]
    │                              │
    ▼                              ▼
┌──────────┐                ┌──────────┐
Offline  │ ──동기화──→  │ OnlineStore    │                │ Store(Parquet/(ScyllaDB)Hive)    │                │          │
└──────────┘                └──────────┘
    │                              │
    ▼                              ▼
 학습용 피처셋               실시간 추론 피처
(point-in-time correct)     (P99 < 5ms)

Point-in-Time Correctness:

# Feast를 활용한 Feature Store 구축 예시
from feast import FeatureStore, Entity, FeatureView, Field
from feast.types import Float64, String
from feast.infra.online_stores.contrib.scylladb_online_store import ScyllaOnlineStore

# feature_store.yaml
# project: tossbank_features
# registry: s3://tossbank-feast/registry.db
# provider: local
# online_store:
#   type: feast_custom_provider.ScyllaOnlineStore
#   hosts:
#     - scylla-node1:9042
#     - scylla-node2:9042
#   keyspace: feature_store
#   replication_factor: 3

user = Entity(
    name="user_id",
    description="Bank customer ID",
)

user_features = FeatureView(
    name="user_transaction_features",
    entities=[user],
    schema=[
        Field(name="avg_transaction_amount_7d", dtype=Float64),
        Field(name="transaction_count_24h", dtype=Float64),
        Field(name="unique_merchants_30d", dtype=Float64),
        Field(name="max_single_transaction_7d", dtype=Float64),
    ],
    online=True,
    source=transaction_source,  # BatchSource (Spark, BigQuery, etc.)
)

오픈소스 Feature Store 비교:

항목FeastTectonHopsworks
라이선스Apache 2.0상용AGPL/상용
Online StoreRedis, DynamoDB, ScyllaDB 등자체 구현RonDB
Offline StoreBigQuery, Redshift, SparkSpark, SnowflakeHive
실시간 피처제한적강력강력
관리형 서비스없음 (셀프호스팅)SaaSSaaS/자체호스팅

실습 체크리스트:

  1. ScyllaDB Docker 클러스터 (3노드) 구축
  2. CQL로 Feature Store 테이블 설계
  3. Feast + ScyllaDB Online Store 연동
  4. Spark에서 피처 계산 → ScyllaDB Materialization
  5. 실시간 피처 조회 P99 레이턴시 측정

추천 자료:


3-8. LLM 플랫폼 구축 (최신 트렌드!)

2024년 이후 모든 핀테크 기업이 LLM을 도입하고 있으며, 토스뱅크도 예외가 아닙니다. 이 섹션은 면접에서 차별화할 수 있는 핵심 영역입니다.

LLM 서빙 아키텍처

vLLM:

from vllm import LLM, SamplingParams

llm = LLM(
    model="meta-llama/Llama-3-8B-Instruct",
    tensor_parallel_size=2,  # 2 GPU 병렬
    gpu_memory_utilization=0.9,
    max_model_len=8192,
    enforce_eager=False,  # CUDA graph 활성화
)

sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=1024,
)

outputs = llm.generate(prompts, sampling_params)

TensorRT-LLM:

Triton + vLLM Backend:

# config.pbtxt for vLLM backend
name: "llama3-8b"
backend: "vllm"
max_batch_size: 0  # vLLM이 배칭 관리

model_transaction_policy {
  decoupled: True
}

parameters {
  key: "model"
  value: {
    string_value: "meta-llama/Llama-3-8B-Instruct"
  }
}
parameters {
  key: "tensor_parallel_size"
  value: {
    string_value: "2"
  }
}
parameters {
  key: "gpu_memory_utilization"
  value: {
    string_value: "0.9"
  }
}

SGLang:

LLM 서빙 성능 지표

지표설명목표 (프로덕션)
TTFT (Time to First Token)첫 토큰까지 걸리는 시간200ms 이하
TPS (Tokens Per Second)초당 생성 토큰 수30+ TPS/user
Throughput전체 시스템 처리량QPS x 평균 출력 길이
P99 Latency99번째 백분위 지연TTFT의 2배 이하

LLM Gateway 아키텍처

클라이언트 요청
┌─────────────┐
LLM Gateway │ ← 인증, 레이트리밋, 라우팅
 (Kong/Envoy)│ ← 비용 추적, 로깅
└──────┬──────┘
  ┌────┴────┐
  ▼         ▼
┌─────┐  ┌─────┐
│vLLM │  │vLLM │  ← 모델별 서버 풀
│Pool1│  │Pool2│
(8B)(70B)└─────┘  └─────┘

Gateway 핵심 기능:

RAG 파이프라인

사용자 쿼리
┌──────────────┐
Query        │ ← 쿼리 임베딩 생성
Embedding└──────┬───────┘
┌──────────────┐
Vector DB    │ ← 유사 문서 검색 (Top-K)
 (Milvus)└──────┬───────┘
┌──────────────┐
Reranker     │ ← 검색 결과 재정렬
 (Cross-Enc.)└──────┬───────┘
┌──────────────┐
LLM          │ ← Context + Query → 답변 생성
 (Llama 3)└──────────────┘

Vector DB 비교:

DB특징장점단점
Milvus분산 아키텍처, GPU 가속대규모, 높은 성능복잡한 운영
QdrantRust 기반, 필터링 강력빠른 시작, 좋은 API상대적으로 작은 커뮤니티
pgvectorPostgreSQL 확장기존 PG 인프라 활용대규모에서 한계
Weaviate모듈식, 멀티모달쉬운 시작메모리 사용량
Pinecone완전 관리형운영 부담 없음벤더 종속, 비용

Fine-tuning 인프라

# K8s에서 LoRA Fine-tuning Job
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
  name: llama3-lora-finetune
spec:
  pytorchReplicaSpecs:
    Master:
      replicas: 1
      template:
        spec:
          containers:
            - name: trainer
              image: tossbank/lora-trainer:latest
              args:
                - '--model_name=meta-llama/Llama-3-8B'
                - '--lora_r=16'
                - '--lora_alpha=32'
                - '--learning_rate=2e-4'
                - '--num_epochs=3'
                - '--batch_size=4'
                - '--gradient_accumulation_steps=8'
              resources:
                limits:
                  nvidia.com/gpu: '4'
          nodeSelector:
            accelerator: nvidia-a100-80g

LLM 모니터링

모니터링해야 할 핵심 메트릭:

# Prometheus 메트릭 예시
from prometheus_client import Counter, Histogram

llm_tokens_total = Counter(
    "llm_tokens_total",
    "Total tokens processed",
    ["model", "direction", "team"]
)

llm_latency = Histogram(
    "llm_request_duration_seconds",
    "LLM request latency",
    ["model"],
    buckets=[0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
)

실습 체크리스트:

  1. vLLM으로 오픈소스 LLM 로컬 서빙
  2. Triton + vLLM Backend로 프로덕션급 서빙
  3. RAG 파이프라인: Milvus + LangChain + vLLM
  4. LoRA Fine-tuning 후 A/B 서빙
  5. LLM 모니터링 대시보드 (Grafana) 구축

추천 자료:


3-9. GPU 프레임워크와 성능 최적화

CUDA 기초 이해

MLOps 엔지니어가 직접 CUDA 코드를 작성할 일은 드물지만, GPU가 어떻게 동작하는지 이해해야 최적화 판단을 할 수 있습니다.

GPU 메모리 계층:

실전에서 중요한 것:

Mixed Precision Training

import torch
from torch.cuda.amp import autocast, GradScaler

scaler = GradScaler()

for batch in dataloader:
    optimizer.zero_grad()

    with autocast(dtype=torch.float16):
        output = model(batch["input"])
        loss = criterion(output, batch["target"])

    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

정밀도 비교:

타입비트용도성능 향상
FP3232기본 학습기준
FP1616Mixed Precision2x
BF1616큰 모델 학습 (A100+)2x (범위 넓음)
FP88추론/학습 (H100+)4x
INT88추론 최적화4x
INT44LLM 양자화 (GPTQ, AWQ)8x

Multi-GPU 전략

DataParallel (DP): 가장 단순, 단일 노드

DistributedDataParallel (DDP): 프로덕션 표준

import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP

dist.init_process_group("nccl")
model = DDP(model.to(local_rank), device_ids=[local_rank])

FSDP (Fully Sharded Data Parallel): 대규모 모델용

DeepSpeed: Microsoft의 분산 학습 라이브러리

GPU 모니터링

# nvidia-smi 기본 모니터링
nvidia-smi --query-gpu=gpu_name,temperature.gpu,utilization.gpu,utilization.memory,memory.total,memory.used,power.draw --format=csv -l 1

# DCGM (Data Center GPU Manager)
# dcgmi dmon -e 155,156,203,204,1001,1002,1003,1004

Prometheus + DCGM Exporter:

# dcgm-exporter DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
spec:
  selector:
    matchLabels:
      app: dcgm-exporter
  template:
    spec:
      containers:
        - name: dcgm-exporter
          image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.0-3.3.0-ubuntu22.04
          ports:
            - containerPort: 9400

주요 모니터링 메트릭:


3-10. 분산 데이터베이스 기초 (CS 지식)

ScyllaDB/Cassandra를 운영하려면 분산 시스템 기초가 필수입니다.

CAP 이론

ScyllaDB/Cassandra는 AP 시스템 (기본 설정), 하지만 Consistency Level 조절로 CP처럼 동작 가능:

Consistent Hashing

ScyllaDB가 데이터를 분산하는 핵심 메커니즘입니다.

Token Ring (0 ~ 2^63)
      ┌───────────┐
Node A    (token: 0 ~ 33%)
      ├───────────┤
Node B    (token: 33% ~ 66%)
      ├───────────┤
Node C    (token: 66% ~ 100%)
      └───────────┘

Partition KeyMurmur3 HashToken → 담당 노드

면접 포인트:

Gossip Protocol

노드 간 클러스터 상태 정보를 교환하는 프로토콜:

Merkle Tree (Anti-Entropy Repair)

LSM-Tree vs B-Tree

특성LSM-Tree (ScyllaDB)B-Tree (PostgreSQL)
쓰기매우 빠름 (순차 쓰기)느림 (랜덤 쓰기)
읽기상대적으로 느림빠름
공간 효율Compaction 필요즉시 정리
적합 워크로드쓰기 위주, 시계열읽기 위주, OLTP

추천 자료:


4. MLOps 성숙도 모델

Google에서 정의한 MLOps 성숙도 모델을 토스뱅크에 적용해봅니다.

Level 0: 수동 프로세스

데이터 사이언티스트가 Jupyter Notebook에서 모델 학습
     (수동)
모델 파일을 엔지니어에게 전달
     (수동)
엔지니어가 모델을 서버에 배포
     (수동)
모니터링? 뭐 그런 거...

문제점: 느림, 재현 불가, 감사 추적 불가 (금융 규제 위반)

Level 1: ML Pipeline 자동화

Airflow/Kubeflow로 파이프라인 자동화
데이터 수집 → 피처 엔지니어링 → 학습 → 평가 → 배포
자동 스케줄링 (매일/매주 재학습)

개선점: 재현성, 자동 재학습, 기본적 추적

Level 2: CI/CD for ML

코드 변경 → CI (단위 테스트 + 데이터 검증)
자동 학습 → 모델 품질 게이트 (AUC > threshold)
카나리 배포 → A/B 테스트
자동 모니터링 → 드리프트 감지 → 자동 재학습 트리거

개선점: 완전 자동화, 품질 보증, 지속적 개선

토스뱅크의 예상 성숙도

토스뱅크는 Level 1 ~ Level 2 사이로 추정됩니다. ML Platform Team은 Level 2를 완성하고 더 나아가는 역할입니다. 지원자가 기여할 수 있는 영역:


5. 면접 예상 질문 30선

K8s 및 인프라 (10문제)

Q1. K8s에서 GPU 노드를 관리하는 방법을 설명해주세요.

Q2. Pod의 QoS 클래스 3가지와 ML 워크로드에서의 선택 기준은?

Q3. K8s Deployment와 StatefulSet의 차이, 그리고 ML 인프라에서 각각 언제 사용하나요?

Q4. HPA와 VPA의 차이, 모델 서빙에 어떤 것이 적합한가요?

Q5. K8s 네트워크 정책으로 ML 플랫폼의 보안을 어떻게 구현하나요?

Q6. etcd의 역할과 장애 시 클러스터에 미치는 영향은?

Q7. K8s에서 볼륨 관리: PV/PVC/StorageClass 각각의 역할은?

Q8. Helm과 Kustomize의 차이, 언제 무엇을 쓰나요?

Q9. K8s에서 CronJob과 Airflow 스케줄링의 차이점은?

Q10. K8s 클러스터 업그레이드 전략을 설명해주세요.


MLOps 플랫폼 (10문제)

Q11. MLFlow Tracking Server의 프로덕션 아키텍처를 설계해주세요.

Q12. MLFlow Model Registry의 Stage 관리 전략은?

Q13. Airflow에서 KubernetesExecutor를 쓸 때의 장단점은?

Q14. Airflow DAG에서 Data Leakage를 방지하는 방법은?

Q15. Kubeflow Pipelines vs Airflow, 언제 무엇을 쓰나요?

Q16. ML 파이프라인의 데이터 검증(Data Validation)을 어떻게 구현하나요?

Q17. Model Drift를 감지하고 대응하는 전략은?

Q18. Feature Store의 Online/Offline 일관성을 어떻게 보장하나요?

Q19. ML 모델의 A/B 테스트를 인프라 수준에서 어떻게 구현하나요?

Q20. MLOps에서 Reproducibility(재현성)를 보장하는 방법은?


모델 서빙 및 LLM (10문제)

Q21. Triton의 Dynamic Batching이 왜 필요하고, 어떻게 최적화하나요?

Q22. Triton Model Ensemble과 Python Backend의 차이점은?

Q23. 모델 양자화(Quantization) 방법들과 각각의 적합한 상황은?

Q24. vLLM의 PagedAttention이 해결하는 문제는?

Q25. LLM 서빙에서 TTFT와 TPS의 트레이드오프를 설명해주세요.

Q26. ScyllaDB를 Feature Store Online Store로 선택한 이유는?

Q27. RAG 파이프라인의 성능을 최적화하는 방법은?

Q28. LLM Gateway에서 비용 관리를 어떻게 하나요?

Q29. 모델 서빙에서 Canary 배포와 Shadow 배포의 차이는?

Q30. GPU 클러스터의 비용 최적화 전략을 설명해주세요.


6. 8개월 학습 로드맵

1개월차: 기초 다지기

주차주제목표핵심 활동
1주Linux/Docker 기초컨테이너 완전 이해Dockerfile 작성, 멀티스테이지 빌드
2주Python 고급비동기, 데코레이터, 타입힌트FastAPI 프로젝트
3주K8s 입문Pod, Deployment, ServiceMinikube 실습
4주K8s 심화ConfigMap, Secret, RBACkind 클러스터 구축

핵심 프로젝트: Docker로 ML 모델 서빙 API 구축 (FastAPI + PyTorch)

2개월차: Kubernetes 마스터

주차주제목표핵심 활동
1주K8s 네트워킹Service, Ingress, DNSIngress Controller 설정
2주K8s 스토리지PV/PVC, StorageClassStatefulSet 배포
3주Helm/Kustomize패키지 관리커스텀 Helm Chart 작성
4주GPU on K8sDevice Plugin, MIGGPU Pod 실행, 모니터링

핵심 프로젝트: K8s 클러스터에 GPU 기반 추론 서버 배포 자격증 목표: CKA 준비 시작

3개월차: MLFlow + Airflow

주차주제목표핵심 활동
1주MLFlow Tracking실험 추적 완전 이해MLFlow 서버 구축
2주MLFlow Registry모델 버전 관리Stage 전환 파이프라인
3주Airflow 입문DAG 작성, Executor로컬 Airflow 환경 구축
4주Airflow + MLFlowML 파이프라인 자동화학습-평가-등록 DAG

핵심 프로젝트: MLFlow + Airflow로 자동 재학습 파이프라인 구축

4개월차: Triton + 모델 서빙

주차주제목표핵심 활동
1주Triton 기초모델 배포, Dynamic BatchingResNet 모델 Triton 배포
2주Triton 심화Ensemble, Python Backend전처리-추론-후처리 파이프라인
3주모델 최적화ONNX, TensorRT, 양자화FP16/INT8 변환 및 벤치마크
4주KServe + TritonInferenceServiceK8s에서 프로덕션급 서빙

핵심 프로젝트: BERT 모델 → ONNX → TensorRT → Triton 서빙 + 성능 벤치마크

5개월차: Feature Store + ScyllaDB

주차주제목표핵심 활동
1주ScyllaDB 기초아키텍처, CQL, 데이터 모델링ScyllaDB University 수강
2주ScyllaDB 운영Compaction, Repair, 모니터링3노드 클러스터 운영
3주Feature Store 개념Feast, Offline/Online 구분Feast 설치 및 실습
4주Feast + ScyllaDBOnline Store 연동실시간 피처 서빙 구현

핵심 프로젝트: Feast + ScyllaDB Online Store + Spark Offline Store 풀 구축

6개월차: LLM 플랫폼

주차주제목표핵심 활동
1주vLLM 기초LLM 서빙, PagedAttention오픈소스 LLM 로컬 서빙
2주Triton + vLLM프로덕션급 LLM 서빙Triton vLLM Backend 배포
3주RAG 파이프라인Vector DB, Embedding, 생성Milvus + LangChain 구축
4주LLM 모니터링토큰, 비용, 품질 추적Grafana 대시보드 구축

핵심 프로젝트: vLLM + Triton + RAG + 모니터링 풀스택 LLM 플랫폼

7개월차: 통합 및 프로젝트

주차주제목표핵심 활동
1주GitOpsArgoCD, CI/CD for MLArgoCD 파이프라인 구축
2주모니터링Prometheus, Grafana통합 모니터링 대시보드
3주포트폴리오 정리GitHub, 블로그프로젝트 README 작성
4주시스템 디자인 연습ML 시스템 설계면접 예상 질문 풀이

핵심 프로젝트: End-to-End MLOps 플랫폼 (전체 기술스택 통합)

8개월차: 면접 준비

주차주제목표핵심 활동
1주코딩 테스트Python, 알고리즘LeetCode Medium 풀이
2주시스템 디자인ML 시스템 설계모의 면접
3주기술 면접딥다이브 질문 대비본 글의 30선 복습
4주행동 면접STAR 기법프로젝트 경험 정리

7. 이력서 작성 전략

JD 기반 키워드 매핑

이력서에 반드시 포함해야 할 키워드:

STAR 기법 활용

각 프로젝트 경험을 다음 구조로 정리:

금융 도메인 강조


8. 포트폴리오 프로젝트 아이디어

프로젝트 1: MLOps 풀 파이프라인

목표: 데이터 수집부터 모델 서빙까지 완전 자동화된 ML 파이프라인

기술스택:

구성:

  1. Airflow DAG: 데이터 수집 → 전처리 → 학습 → 평가
  2. MLFlow: 실험 추적, 모델 레지스트리
  3. Triton: Dynamic Batching 모델 서빙
  4. ArgoCD: GitOps 기반 자동 배포
  5. Prometheus + Grafana: 모니터링 대시보드

차별화 포인트:

프로젝트 2: Feature Store (Feast + ScyllaDB)

목표: 실시간 피처 서빙이 가능한 Feature Store 구축

기술스택:

구성:

  1. Offline Store: Parquet 파일, Spark로 배치 피처 계산
  2. Online Store: ScyllaDB, P99 5ms 이하 서빙
  3. Feature Registry: Feast에서 피처 정의/등록/검색
  4. Materialization: Offline → Online 동기화 파이프라인
  5. API 서버: 피처 벡터 실시간 조회

차별화 포인트:

프로젝트 3: LLM 서빙 플랫폼

목표: 프로덕션급 LLM 서빙 + RAG + 모니터링

기술스택:

구성:

  1. LLM 서빙: Triton + vLLM Backend (Llama 3 8B)
  2. RAG: 문서 임베딩 → Milvus → Retrieval → Generation
  3. LLM Gateway: 레이트 리밋, 라우팅, 비용 추적
  4. 모니터링: TTFT, TPS, 토큰 사용량, GPU 활용률
  5. 보안: PII 마스킹, Guardrails

차별화 포인트:


실전 퀴즈

Q1. Triton Inference Server에서 Dynamic Batching의 preferred_batch_size를 32로 설정하고 max_queue_delay를 100 마이크로초로 설정했습니다. 요청이 초당 10개만 들어오는 상황에서 예상되는 동작은?

A: 초당 10개 요청은 preferred_batch_size 32를 채우기에 턱없이 부족합니다. max_queue_delay가 100 마이크로초이므로, 대부분의 요청은 100 마이크로초 대기 후 1~2개씩 소규모 배치로 처리됩니다.

이 상황에서의 최적화: preferred_batch_size를 작게 조정하거나 (예: 1, 4, 8), 요청 패턴에 맞게 max_queue_delay를 늘려서 더 많은 요청을 모을 수 있습니다. 단, 레이턴시 SLO와의 트레이드오프를 고려해야 합니다. Model Analyzer를 사용하면 최적의 설정을 자동으로 탐색할 수 있습니다.

Q2. ScyllaDB에서 Partition Key를 날짜 (예: 2024-03-15)로 설정한 Feature Store 테이블이 있습니다. 어떤 문제가 발생할 수 있나요?

A: Hot Partition 문제가 발생합니다. 모든 당일 데이터가 하나의 파티션에 집중되므로, 해당 파티션을 담당하는 노드에 부하가 몰립니다.

해결 방법:

  1. Composite Partition Key: 날짜 + user_id 해시의 버킷 (예: date, bucket)
  2. Time-bucketing: 시간 단위로 분할 (예: 2024-03-15T14)
  3. Shard Key 추가: 임의의 shard 번호 (0-15)를 Partition Key에 추가

Feature Store에서는 user_id를 Partition Key로 사용하는 것이 일반적입니다. 사용자별 조회가 주 패턴이기 때문입니다.

Q3. vLLM의 PagedAttention과 전통적인 KV Cache 관리의 메모리 효율 차이를 설명하세요.

A: 전통적인 방식에서는 각 요청의 KV Cache를 연속된 메모리 블록으로 할당합니다. 이로 인해:

  • 내부 단편화: 최대 시퀀스 길이만큼 미리 할당 (실제 사용량보다 과다)
  • 외부 단편화: 요청 완료 후 빈 공간이 파편화
  • 결과적으로 GPU 메모리의 60-80%만 활용

PagedAttention은 가상 메모리 개념을 적용합니다:

  • KV Cache를 고정 크기 페이지 (Block)로 분할
  • 논리적 KV Cache → 물리적 페이지 매핑 (Page Table)
  • 필요한 만큼만 페이지 할당 (내부 단편화 제거)
  • 비연속 메모리 사용 가능 (외부 단편화 제거)
  • 결과: 메모리 낭비를 최대 96% 줄이고, 동시 처리 가능한 요청 수 2-4배 증가
Q4. Airflow의 KubernetesExecutor에서 GPU 학습 태스크의 Cold Start 문제를 어떻게 완화하나요?

A: KubernetesExecutor는 태스크마다 새 Pod를 생성하므로, GPU 워크로드의 경우 다음과 같은 Cold Start 오버헤드가 있습니다:

  • Pod 스케줄링: 5-10초
  • 컨테이너 이미지 Pull: 30초-수분 (GPU 이미지는 수 GB)
  • GPU 드라이버 초기화: 수 초
  • 모델 로딩: 수 초-수분

완화 전략:

  1. 이미지 Pre-pulling: DaemonSet으로 GPU 노드에 이미지 미리 캐시
  2. PVC 기반 모델 캐시: 모델 파일을 PVC에 저장하여 반복 다운로드 방지
  3. Warm Pod Pool: Airflow 대신 Kubeflow의 Training Operator 사용 (Pod 재활용)
  4. CeleryKubernetesExecutor: 경량 태스크는 Celery, GPU 태스크만 K8s Pod
  5. Resource Quota: GPU 노드를 ML 전용으로 확보 (스케줄링 대기 감소)
Q5. ML 모델의 Canary 배포에서 "성공"을 판단하는 기준을 어떻게 설계하나요? 금융 도메인 특화 관점에서 답해주세요.

A: 금융 ML 모델의 Canary 배포 성공 기준은 일반 서비스보다 훨씬 엄격합니다.

기술적 메트릭 (자동 판단):

  • P99 레이턴시: 기존 모델 대비 120% 이하
  • Error Rate: 기존 모델 대비 동일 이하
  • GPU 활용률: 예상 범위 이내

비즈니스 메트릭 (자동 + 수동 판단):

  • FDS 모델: False Positive Rate 변화율 5% 이내, False Negative Rate 감소 확인
  • 대출 심사: 승인율 변동 3% 이내, 예상 부실률 모니터링
  • 추천 모델: CTR 유지 또는 개선

규제 메트릭 (수동 판단):

  • 설명가능성 검증: SHAP 값 분포가 합리적인지
  • 공정성 검증: 특정 그룹에 대한 편향 없는지
  • 감사 추적: 모든 판단 근거가 기록되는지

배포 전략:

  1. Shadow 배포 (1주): 실 트래픽 복제, 결과 비교만
  2. Canary 5% (3일): 소수 사용자에 적용, 모든 메트릭 모니터링
  3. Canary 30% (3일): 확대 적용
  4. Full 배포: 모든 기준 통과 시

Argo Rollouts의 AnalysisRun으로 자동 판단을 구현하고, 금융 규제 관련 항목은 인간 승인 게이트를 추가합니다.


참고 자료

공식 문서

도서

무료 학습 자료

GitHub 레포지토리

커뮤니티


마무리: 당신만의 MLOps 여정

토스뱅크 ML Platform Team은 금융 x ML x 인프라라는 세 가지 축이 만나는 희소한 교차점에 있습니다. 이 글에서 다룬 기술스택은 방대하지만, 모든 것을 처음부터 완벽하게 알 필요는 없습니다.

핵심은 기초를 단단히 하고, 하나의 기술을 깊이 파고들 수 있는 능력을 보여주는 것입니다. K8s를 모르면서 Triton을 논할 수 없고, 분산 시스템을 이해하지 못하면서 ScyllaDB를 운영할 수 없습니다.

8개월 로드맵을 따라가되, 자신만의 속도를 찾으세요. 가장 중요한 것은 직접 만들어보는 것입니다. 이론 100시간보다 실습 10시간이 면접에서 더 빛납니다.

토스뱅크 ML Platform의 일원이 되어 대한민국 금융 AI의 미래를 함께 만들어가시기를 응원합니다.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다