
LSTM AutoEncoder를 이용한 이상 탐지 모델의 MLOps화 시도
요약
NASA Turbofan 데이터셋을 활용하여 LSTM AutoEncoder 기반의 이상 탐지 모델을 구축하고, 이를 실제 운영 가능한 시스템으로 MLOps화하는 과정을 다룹니다. FastAPI, Docker, Streamlit을 사용하여 모델 추론부터 모니터링까지 포함된 파이프라인을 구현했습니다.
핵심 포인트
- LSTM AutoEncoder를 이용한 시계열 이상 탐지 구현
- FastAPI를 활용한 모델 추론 API 서버 구축
- Docker Compose를 이용한 서비스 배포 및 환경 격리
- Streamlit 대시보드 및 로그 시스템을 통한 모니터링 체계 마련
Kaggle NASA Turbofan 데이터셋을 사용하여 LSTM AutoEncoder를 이용한 이상 탐지 (Anomaly Detection) 모델을 작성했습니다.
NASA Turbofan은 항공기 엔진과 같은 장치가 '정상 상태'에서 '점진적으로 열화'되어 최종적으로 고장에 가까워지는 시계열 데이터 (Time-series data)입니다. 각 unit에는 unit_number와 time_in_cycles가 있으며, 여러 센서 값이 시간 순으로 기록되어 있습니다.
이 데이터에 대해 정상 구간의 시계열 패턴을 LSTM AutoEncoder에 학습시키고, 입력 시퀀스 (Input sequence)를 얼마나 잘 복원할 수 있는지를 봄으로써 이상도 (Anomaly score)를 계산했습니다.
이번에 진행한 작업은 해당 Notebook 상의 모델을 FastAPI로 호출할 수 있는 형태로 만들고, 로그 저장·모니터링·Docker화까지 포함하여 '작은 이상 탐지 시스템'에 가깝게 만드는 것입니다.
최종적으로 완성된 것
- FastAPI 이상 탐지 API
- SQLite / JSONL logging
- 모니터링 메트릭 (Monitoring metrics)
- Streamlit 대시보드
- Docker Compose deployment
이상 탐지 시스템 전체 구성도
MLOps의 목적
MLOps는 머신러닝 (Machine Learning) 모델을 지속적으로 운용·모니터링·개선하기 위한 사고방식입니다.
Notebook 상에서 모델이 동작하는 것만으로는 실제 시스템으로서 운영 환경 (Production)에 올리기가 어렵습니다.
업무에서 사용하려면 예를 들어 다음과 같은 기능이 필요할 것입니다.
- 센서 데이터 수신
- 모델로 이상도 계산
- 이상 여부 판정
- 판정 결과를 애플리케이션이나 대시보드로 반환
- 추론 결과(Inference result)를 로그로 남김
이를 실현하기 위해서는,
입력 → 전처리 (Preprocessing) → 추론 (Inference) → 이상 판정 → 로그 저장 → 모니터링
과 같이 추론을 일련의 파이프라인 (Pipeline)으로 정리할 필요가 있습니다.
이를 실현하는 것이 이번의 목적입니다.
모델의 개요
이번에 사용한 모델은 LSTM AutoEncoder입니다.
AutoEncoder는 입력 데이터를 한 번 압축한 뒤, 거기서 원래 데이터를 복원하는 신경망 (Neural network)입니다. 정상 데이터만으로 학습시키면 정상적인 패턴은 잘 복원할 수 있지만, 생소한 이상 패턴은 잘 복원하지 못합니다.
이 '복원 실패 정도'를 이상 스코어 (Anomaly score)로 사용합니다.
입력 시퀀스 X
→ LSTM AutoEncoder
→ 복원 시퀀스 X_hat
...
NASA Turbofan에서는 동일한 unit 내에서 시계열 윈도우 (Time-series window)를 만드는 것이 중요했습니다.
for unit_id in data["unit_number"].unique():
...
단순히 행을 위에서부터 순서대로 윈도우화하면 다른 unit의 데이터가 섞이게 됩니다. 그렇게 되면 LSTM이 본래 학습해야 할 '동일한 장치 내에서 진행되는 열화 패턴'을 분석할 수 없습니다.
LSTM AutoEncoder는 '시간 흐름에 따른 변화 이상'을 포착하기 위해 채택했습니다.
MLOps화 ① 추론 처리를 함수로 통합
먼저, Notebook 내에서 분산되어 작성했던 추론 처리를 predict_anomaly()로 집약했습니다.
이 함수 안에서 다음을 통합적으로 처리합니다.
- 입력 데이터 전처리
- scaler를 이용한 표준화 (Standardization)
- LSTM AutoEncoder를 이용한 복원
- reconstruction error (재구성 오차) 계산
...등
전처리·후처리·판정 로직까지 포함하여 재사용 가능한 파이프라인으로 만들 필요가 있었습니다.
/predict를 만들기
MLOps화 ② FastAPI로 API 만들기
API에는 FastAPI를 사용했습니다.
작성한 엔드포인트 (Endpoint)는 심플하게,
POST /predict
로 설정했습니다.
입력은 10 사이클 분량의 센서 시퀀스를 JSON으로 받습니다.
{
"sequence": [
{
...
실제로는 sensor_ms1부터 sensor_ms21까지의 센서 값을 포함합니다.
응답 (Response)은 다음과 같은 형태로 구성했습니다.
{
"unit_number": 1,
"time_in_cycles": 10,
...
여기서 의식한 점은 운용에 필요한 메트릭이 무엇인가를 고민하는 것이었습니다.
- 어떤 unit의 몇 번째 사이클인지
- 이상 점수 (Anomaly Score)는 얼마인지
- severity(심각도)는 normal / warning / critical 중 무엇인지
- 어떤 센서의 error (오차)가 큰지
이러한 정보들을 반환함으로써, API의 출력을 모니터링(Monitoring)이나 대시보드(Dashboard)에서 정보로 활용할 수 있습니다.
Pydantic을 이용한 입력값 Validation (검증)
센서 값이 누락되어 있거나, 타입 (Type)이 어긋나 있거나, 빈 데이터가 전송되는 경우도 있습니다. 그럴 때 API 전체가 500 에러로 다운되는 것이 아니라, 422 Validation Error로서 안전하게 반환할 수 있는 것은 매우 중요합니다.
이번에 작성한 프로그램에서는 간략화한 부분도 있지만, 실제 운용에서는 이러한 세세한 부분에 힘을 쏟음으로써 안정적인 시스템을 만들 수 있다고 생각합니다.
MLOps화 ③ severity(심각도) 설계하기
이상 점수는 수치이지만, 실제 업무 판단에서는 수치 그 자체보다 "지금 얼마나 위험한가"가 더 중요합니다.
그래서 추론 결과(Inference Result)를 다음과 같은 3단계로 분류했습니다.
normal
warning
critical
예를 들어, 단발적으로 threshold (임계값)를 초과한 경우에는 warning,
연속적으로 alert (경고)가 발생하고 있는 경우에는 critical로 설정합니다.
이를 베이스로 몇 가지 보충 정보를 더하여, 에러 알림으로부터 사용자가 액션을 취할 수 있도록 구현했습니다.
MLOps화 ④ 추론 로그 저장하기
API화한 후에 중요해지는 것이 로그 (Log)입니다.
추론 결과를 저장해 두지 않으면, 나중에 다음과 같은 일을 할 수 없습니다.
- 언제 이상 판정이 나왔는지 확인하기
- 어떤 입력값으로 오검출(False Positive)했는지 조사하기
- 모니터링 메트릭 (Monitoring Metrics) 만들기
이번에는 JSONL과 SQLite 두 가지 방식으로 저장했습니다.
JSONL
JSONL은 1회의 추론을 1행의 JSON으로 저장하도록 했습니다.
입력과 출력을 가능한 한 그대로 남겨서, 버그 발생 시 등의 트레이스 (Trace) 용도로 사용합니다.
SQLite
SQLite는 사용자 관점에서 모니터링이 필요한 데이터를 저장하기로 했습니다.
DB에 저장함으로써 SQL을 통해 alert 수나 severity 비율, latency (지연 시간)를 집계할 수 있습니다.
이를 Streamlit을 사용한 대시보드에 활용하기로 했습니다.
MLOps화 ⑤ Docker / Docker Compose화
마지막으로, 이 앱을 Docker화했습니다.
Docker화함으로써 로컬 환경에 의존하지 않고 API를 실행할 수 있습니다.
또한 Docker를 리빌드(Rebuild)하더라도 DB 내의 데이터를 영구적으로 보관할 수 있도록, 로그 저장 위치를 volume (볼륨)으로 설정하여 외부에 노출했습니다.
이를 통해 컨테이너를 다시 만들어도 추론 로그가 사라지지 않습니다.
최종적으로는,
・FastAPI
・LSTM AutoEncoder
・SQLite
...
이라는 형태가 되었습니다.
이번에 배운 점
이번에 가장 컸던 배움은, 모델은 AI 시스템의 일부이며 실운용을 고려하면 다양한 기능이 필요하다는 점입니다.
Kaggle에서 쟁점이 되는 것은 모델 생성입니다.
하지만 실제로 사용할 수 있는 형태로 만들기 위해서는 다음과 같은 것들이 필요하지 않을까요?
- API로 처리하기 위한 입력/출력 형식 설계
- 추론 파이프라인 (Inference Pipeline)화
- Validation (검증)
- severity 설계
- request logging (요청 로깅)
- Docker화
마치며
이번에 NASA Turbofan의 이상 탐지 모델을 FastAPI로 API화하고, 로그 저장, 모니터링, Docker Compose화까지 진행했습니다.
처음에는 API에서 추론 처리를 호출할 수 있게 하고 싶다는 정도의 느낌으로 시작했지만, 실운용을 의식하면 할수록 매우 많은 기능이 추가로 필요하다는 것을 알 수 있었습니다.
직접 구현해 보니 아직 실무에서 쓰기에는 부족한 점이 있다고 생각하며, ORM을 통한 DB 계층과 AP 계층의 분리, 에러 핸들링 (Error Handling) 로직의 정밀화, 사용자의 운용을 견딜 수 있는 대시보드를 업무적 관점에서 브러시업(Brush-up)하는 등 더욱 높은 단계로 발전시켜 나가고 싶습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기