문제 발생
mlflow를 로컬에서 실행하려고 mlflow ui 명령어를 치는데 계속
[ERROR] Worker (pid:3034) was sent SIGSEGV!
이런 에러가 나와서 port도 변경하고 컴퓨터도 재부팅해봤는데 같은 에러가 발생해서 아예 mlflow를 도커로 띄우려고 했다.
도커로 mlflow를 띄우고 ui 접속까지는 성공했는데 모델을 저장하려고 log_artifact() 함수를 사용하면 해당 코드에서 계속
OSError: [Errno 30] Read-only file system: '/mlflow'
이런 파일 권한 에러가 발생했다.
기존 코드
내가 사용한 Dockerfile은 다음과 같다.
FROM continuumio/miniconda3
# MLflow 설치
RUN pip install mlflow
# 환경 변수 설정
ENV MLFLOW_TRACKING_URI=http://127.0.0.1:5000
ENV MLFLOW_BACKEND_STORE_URI=sqlite:///mlflow.db
ENV MLFLOW_DEFAULT_ARTIFACT_ROOT=/mlflow/artifacts
# 작업 디렉토리 생성
RUN mkdir /mlflow
# 컨테이너 실행 시 MLflow 서버 실행
CMD ["mlflow", "server", "--host", "0.0.0.0", "--port", "5000", "--backend-store-uri", "sqlite:///mlflow.db", "--default-artifact-root=/mlflow/artifacts"]
그리고 도커 이미지를 빌드시켜주고,
docker build -t custom-mlflow .
도커 컨테이너를 실행시켜주는 명령어는 아래 명령어를 사용했다.
docker run -d \
-p 5001:5000 \
--name mlflow \
-v $(pwd)/mlflow/db:/mlflow/db \
-v $(pwd)/mlflow/artifacts:/mlflow/artifacts \
custom-mlflow
이렇게 했을 때 mlflow ui는 접속이 되지만 계속 artifacts에 모델 저장하는 코드에서 에러가 발생했다.
에러 코드
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
Cell In[9], line 59
57 image_path = f"kmeans_clusters_{n_clusters}_{init}.png"
58 plt.savefig(image_path)
---> 59 mlflow.log_artifact(image_path)
60 plt.close()
62 # 7. 모델 저장
File ~/study/workspace/team_mlops/ml-project-mlops_5/.venv/lib/python3.10/site-packages/mlflow/tracking/fluent.py:1124, in log_artifact(local_path, artifact_path, run_id)
1096 """
1097 Log a local file or directory as an artifact of the currently active run. If no run is
1098 active, this method will create a new active run.
(...)
1121 mlflow.log_artifact(path)
1122 """
1123 run_id = run_id or _get_or_start_run().info.run_id
-> 1124 MlflowClient().log_artifact(run_id, local_path, artifact_path)
File ~/study/workspace/team_mlops/ml-project-mlops_5/.venv/lib/python3.10/site-packages/mlflow/tracking/client.py:1923, in MlflowClient.log_artifact(self, run_id, local_path, artifact_path)
1919 if run_id.startswith(TRACE_REQUEST_ID_PREFIX):
1920 raise MlflowException(
1921 f"Invalid run id: {run_id}. `log_artifact` run id must map to a valid run."
1922 )
-> 1923 self._tracking_client.log_artifact(run_id, local_path, artifact_path)
...
227 # Cannot rely on checking for EEXIST, since the operating system
228 # could give priority to other errors like EACCES or EROFS
229 if not exist_ok or not path.isdir(name):
OSError: [Errno 30] Read-only file system: '/mlflow'
이렇게 artifacts 관련된 코드에서 같은 에러가 발생했다.
해결 시도 1 - 파일 권한 문제
일단 Read-only라는 에러를 봐서 권한문제인가? 싶어서 권한을 주는 걸로 해결해보려고 했다.
FROM continuumio/miniconda3
# MLflow 설치
RUN pip install mlflow
# 환경 변수 설정
ENV MLFLOW_TRACKING_URI=http://127.0.0.1:5000
ENV MLFLOW_BACKEND_STORE_URI=sqlite:///mlflow.db
ENV MLFLOW_DEFAULT_ARTIFACT_ROOT=/mlflow/artifacts
# 작업 디렉토리 생성
RUN mkdir /mlflow
# 모든 사용자에게 /mlflow 디렉터리와 하위 폴더에 대한 읽기/쓰기 권한 부여
RUN chmod -R 777 /mlflow
# 컨테이너 실행 시 MLflow 서버 실행
CMD ["mlflow", "server", "--host", "0.0.0.0", "--port", "5000", "--backend-store-uri", "sqlite:///mlflow.db", "--default-artifact-root", "/mlflow/artifacts"]
여기서 chmod 명령어를 사용해서 mlflow에 권한을 줘봤다.
BUT 여전히 해결되지 않았다.....
해결 방법 2 - 사용자 권한
해당 문제를 mlops 강사님께도 여쭤봤는데 도커 실행 사용자 권한 문제 같다고도 말씀해 주셨다.
도커 컨테이너 내부에서 MLflow를 실행하는 사용자의 권한 문제를 의심해서 일단 파일이나 디렉터리에 올바른 권한이 부여되어 있지 않으면, 실행 중인 프로세스가 해당 파일 시스템에 접근할 때 에러가 발생할 수 있다.
기본적으로 도커 컨테이너는 루트 사용자로 실행되기 때문에 /mlflow 디렉토리의 소유권이나 권한이 잘못 설정되어 있으면 파일 시스템에 접근할 때 문제가 생길 수 있다. 이 문제를 해결하기 위해 사용자를 생성하고 권한을 부여하는 방법을 시도했다.
FROM continuumio/miniconda3
# MLflow 설치
RUN pip install mlflow
# 디렉토리 생성 및 소유권 설정
RUN mkdir -p /mlflow/artifacts /mlflow/db
RUN chown -R mlflow:mlflow /mlflow
# 환경 변수 설정
ENV MLFLOW_TRACKING_URI=http://127.0.0.1:5000
ENV MLFLOW_BACKEND_STORE_URI=sqlite:///mlflow/db/mlflow.db
ENV MLFLOW_DEFAULT_ARTIFACT_ROOT=/mlflow/artifacts
# 컨테이너 실행 시 mlflow 사용자로 실행
USER mlflow
# 컨테이너 실행 시 MLflow 서버 실행
ENTRYPOINT ["mlflow", "server"]
CMD ["--host", "0.0.0.0", "--port", "5000", "--backend-store-uri", "sqlite:///mlflow/db/mlflow.db", "--default-artifact-root", "/mlflow/artifacts", "--serve-artifacts"]
이렇게 mlflow 유저를 만들어서 mlflow 디렉토리의 소유권을 mlflow 유저에게 부여해 줬다.
그리고 이렇게 만든 유저를 사용자로 실행해 주는 걸로 바꿔줬다.
이렇게 하면 MLflow가 루트 유저 대신 mlflow 유저로 실행되어 파일 시스템 권한 문제를 해결할 수 있을 거라고 생각했다.
그러나!!!!! 이렇게 해줬는데도 계속 같은 에러가 났다..
이 밖에도 마운팅 해놨던 로컬 mflow 폴더의 권한도 확인해서 읽기 쓰기 권한 전부 있고 docker 내부에서도 폴더에 모든 권한이 있는데 계속 같은 에러가 났다.
진짜 며칠 동안 삽질한 끝에 현재 진행 중인 upstage ai lab 슬랙 코딩질문방 채널에 물어봐서 한분이랑 같이 화면공유하면서 해결해 봤다.
해결 방법 3 - mlartifacts 폴더 사용
일단 그분은 mlflow에서 제공해 주는 docker image를 사용하셨다고 한다. (나랑 같은 m1칩을 사용하고 계셨다.) 근데 그분이 내 코드 구조를 보시더니 그분은 artifacts가 저장되는 디렉토리가 mlflow 내부가 아니라 mlartifacts라는 또 다른 디렉토리에 저장된다고 하셨다.
일단 나는 artifacts가 저장되는 경로가 mlflow/artifacts였다. 이 구조를 내가 수동으로 바꿨는지 어떻게 했는지 모르겠지만 일단 이 경로의 마운팅을 제거해 줬다.
수정된 Dockerfile은 다음과 같다.
FROM continuumio/miniconda3
# MLflow 설치
RUN pip install mlflow
# 디렉토리 생성 및 권한 설정
RUN mkdir -p /mlflow/db
# 환경 변수 설정
ENV MLFLOW_TRACKING_URI=http://0.0.0.0:5000
ENV MLFLOW_BACKEND_STORE_URI=sqlite:///mlflow/db/mlflow.db
# 컨테이너 실행 시 MLflow 서버 실행
ENTRYPOINT ["mlflow", "server"]
CMD ["--host", "0.0.0.0", "--port", "5000", "--backend-store-uri", "sqlite:///mlflow/db/mlflow.db"]
이렇게 MLFLOW_DEFAULT_ARTIFACT_ROOT 설정을 제거해 줬다. (사용자 권한 관련 내용도 제거했다.) 그리고 CMD에서도 해당 명령어를 제거해줬다.
그리고 run 해보니까 드디어!! 해당 에러가 나지 않았다!! 그리고 모델이 mlartifacts라는 새로운 폴더에 저장되는 걸 확인했다!!
근데 위 코드로 진행하면 로컬에는 모델이 저장 안 되고 도커 내부에만 저장되니까 로컬에도 저장될 수 있게 mlartifacts 디렉토리를 로컬과 마운팅 시켜줬다.
내 로컬에도 mlartifacts 폴더를 만들고 run 해줄 때 명령어로 마운팅 시켜줬다.
docker run -d -p 5001:5000 --name mlflow \
-v $(pwd)/mlflow/db:/mlflow/db \
-v $(pwd)/mlartifacts:/mlartifacts \
custom-mlflow
이렇게 하니까 에러도 해결됐고 로컬에도 모델이 잘 저장되었다!
결론
확실히 집단지성이 필요하다고 생각되었다.. ㅋㅋㅋ 나 혼자 삽질했을 때는 뭐가 문제인지 전혀 몰랐는데 다른 분이 보시고 mlartifacts 폴더가 없는 걸 이상하게 생각하시고 말씀해 주시니까 진짜 거의 한 몇분만에 해결되었다. 진짜 거의 며칠 동안 이것저것 찾아봤는데 전혀 다른 방법으로 해결이 되어서 조금 허탈하긴 하지만,,, 이 기회에 mlflow를 잘 이해하기 되었다고,,,,,,,생각하면 좋을 거 같다....... 휴우,,,
'MLOps' 카테고리의 다른 글
[MLflow] 로컬 파일 시스템에 기록된 실험 데이터 확인 방법 (0) | 2024.11.02 |
---|---|
Docker 기반 Airflow, MLFlow, FastAPI, Streamlit 적용한 MLOps 프로젝트 후기 (5) | 2024.10.12 |
Docker 환경에서 Airflow의 DAGs 테스트 (파이썬 코드, Slack Webhook, MLFlow) (3) | 2024.09.26 |
FastAPI와 Docker를 활용한 S3 모델 서빙 및 배포 방법 (5) | 2024.09.24 |
TinyBERT로 감정 분석 모델 학습부터 AWS S3에 모델 업로드 (3) | 2024.09.23 |