Closed classaen7 closed 5 months ago
Airflow 상에서 Time Series Model의 HMM
과 LSTM
의 배치서빙이 정상적으로 작동하지 않음
Status는 running으로 나타나지만 모델 추론이 정상적으로 작동하지 않음
명확한 오류 메시지가 나오지 않고 인터넷에 찾아봐도 비슷한 오류를 찾을 수 없었음
1. CPU 연산량 제한
Time Series 모델의 경우 CPU를 통해 연산하므로 이를 확인함
top
명령어로 확인하면 모델 추론이 아예 수행되지 않음을 확인할 수 있음
2. 라이브러리 종속성 문제
LSTM과 동일한 torch
를 사용하는 CNN 예측의 경우 문제 없이 정상적으로 작동함
단일 파이썬 파일로 따로 추출하여 모델 추론을 할 경우 문제 없이 정상적으로 작동함을 확인함
3. Print문으로 어느 코드에서 에러가 발생하는지 확인
# hmm_pred.py
def forecast(self):
model = GaussianHMM(n_components=4)
feature = self.augment_features(self.data)
features = self.extract_features(feature)
model.fit(features) # 정상적으로 작동하지 않음
# lstm_pred.py
with torch.no_grad():
last_seq = torch.tensor(close_data_scaled[-seq_length:], dtype=torch.float32)
for _ in range(future_days):
pred = model(last_seq.view(1, seq_length, -1)) # 정상적으로 작동하지 않음
future_predictions.append(pred.item())
last_seq = torch.cat((last_seq[1:], pred.reshape(1, 1)))
두 경우 모두 모델 추론 단에서 코드가 작동하지 않음
위와 같은 분석을 통해 Airflow의 코드 동작 과정에서 이러한 오류가 발생함을 알 수 있음
Airflow는 다음과 같은 구조를 갖고 있다.
Dags
에서 작성한 파일의 경우 Scheduler를 통해 관리되며 일반적인 파이썬 코드 파일을 실행하는 것과 다르게 작동한다.
airflow scheduler
의 터미널 창을 확인해보면 Dag이 실행되지 않아도 계속해서 여러 라이브러리를 호출하는 출력물이 나온다.
이를 통해 유추해보면 airflow는 일반적인 파이썬 코드 파일 실행과 다르게 내부적으로 계속해서 돌아가는 형식임을 알 수 있다.
lstm_pred.py
에서 작성한 모델 선언을 보면 다음과 같이 되어있다.
model_state_dict = torch.load('./dags/ts_model/weight/lstm_model.pth')
model = LSTMModel()
model.load_state_dict(model_state_dict)
model.eval()
model
이라는 변수가 전역적으로 선언되어 있는데 이 경우 from ts_model import ...
를 통해 패키지가 불러와질때 마다 해당 변수가 선언되게 된다.
파이썬 코드 파일을 실행했을 때는 위의 패키기자 한번만 불러와지기 때문에 model
이라는 변수가 초기에 한번만 선언되어 문제 없이 모델 추론이 되었다.
하지만 airflow scheduler
를 통해 실행된 dag의 경우 반복적으로 ts_model
이라는 패키지를 호출하고 이에 따라 model
이라는 변수가 초기화 되기 때문에 이러한 오류가 발생한 것이었다.
따라서 lstm_pred.py
의 내용을 다음과 같이 변경하였다.
def lstm_model():
model_state_dict = torch.load('./dags/ts_model/weight/lstm_model.pth')
model = LSTMModel()
model.load_state_dict(model_state_dict)
model.eval()
return model
이후 time_series_predict.py
dag의 PythonOperator 내부에서 모델 호출이 한번만 수행되게 변경하여 Inference를 수행하였더니 해당 오류가 해결되었다.
Background
To do