연구 수행 과정과 결과물을 좀 체계적으로 관리하고자 몇 가지 MLOps 플랫폼을 찾아보았고, 다음과 같은 기능을 중점적으로 살펴보았다.
그러던 중 ClearML이라는 플랫폼을 알게되었으며, 설치 및 사용이 다른 플랫폼에 비해 간편하고 원하는 기능들을 대부분 포함하고 있는 것 같아 ClearML을 사용하기로 결정하였다.(다만, Python만 지원하는 것 같아 나중에 C++ 등을 사용하게 되면 다른 플랫폼도 고민해야할듯...)
그런데 ClearML 사용법이 다른 플랫폼 대비 자료가 많지도 않은 것 같고 유튜브 등 여기저기 분산되어 있으며 한글로 정리된 자료도 없어서 사용법을 공부하면서 정리해보고자 포스트를 작성하게 되었다.
환경은 Ubuntu 서버가 2대 이상 있는 것을 가정하고, 그 중 한 대에 ClearML 서버를 설치하여 다른 서버들을 통합 관리 하도록 한다.
따라서 우선 한 대의 메인 서버, A서버를 선택하고, docker를 설치한다(docker 설치 공식 문서: 링크)
A, B 서버 - docker
# Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc -------------------------------------------------- # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update -------------------------------------------------- # docker 설치 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -------------------------------------------------- # (optional) 설치 확인 sudo docker run hello-world
A, B 서버 - nvidia-container-toolkit
# 의존성 설치 sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release -------------------------------------------------- # NVIDIA GPG 키 추가 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \ sudo gpg --dearmor -o /etc/apt/keyrings/nvidia-container-toolkit.gpg -------------------------------------------------- # NVIDIA 레포지토리 추가 distribution=$(. /etc/os-release; echo $ID$VERSION_ID) # 예: ubuntu20.04 curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed 's#deb https://#deb [signed-by=/etc/apt/keyrings/nvidia-container-toolkit.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list -------------------------------------------------- # 설치 sudo apt update sudo apt install -y nvidia-container-toolkit -------------------------------------------------- # 적용 sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker
이후 ClearML 문서(링크)를 따라 ClearML 서버를 설치한다.
주의할 점은 ClearML 문서는 이전버전의 docker를 기준으로 작성되었는지 docker-compose
명령어를 사용하고 있는데, latest 버전에서 해당 명령어는 docker compose
로 변경되었다.
서버는 자동으로 실행되며, 기본적으로는 http://localhost:8080
에서 접속할 수 있다.(웹 브라우저에 입력하면 나온다.)
설정 부분은 host ip 등의 변경을 위한 부분인데, 스킵하고 넘어가면 기본값이 나오고, 나중에 필요하면 변경할 수 있다.
A서버
# echo "vm.max_map_count=262144" > /tmp/99-clearml.conf sudo mv /tmp/99-clearml.conf /etc/sysctl.d/99-clearml.conf sudo sysctl -w vm.max_map_count=262144 sudo service docker restart -------------------------------------------------- # 혹시 docker compose에서 권한 문제가 발생하면 sudo 붙이기 cd docker && docker compose --env-file example.env -f docker compose.yml up -------------------------------------------------- # 이전 버전 삭제 sudo rm -R /opt/clearml/ -------------------------------------------------- # Create local directories for the databases and storage. sudo mkdir -p /opt/clearml/data/elastic_7 sudo mkdir -p /opt/clearml/data/mongo_4/db sudo mkdir -p /opt/clearml/data/mongo_4/configdb sudo mkdir -p /opt/clearml/data/redis sudo mkdir -p /opt/clearml/logs sudo mkdir -p /opt/clearml/config sudo mkdir -p /opt/clearml/data/fileserver -------------------------------------------------- # 권한설정 sudo chown -R 1000:1000 /opt/clearml -------------------------------------------------- # 다운로드 sudo curl https://raw.githubusercontent.com/clearml/clearml-server/master/docker/docker-compose.yml -o /opt/clearml/docker-compose.yml -------------------------------------------------- # 설정 export CLEARML_AGENT_ACCESS_KEY=generate_access_key_here export CLEARML_AGENT_SECRET_KEY=generate_secret_key_here export CLEARML_HOST_IP=server_host_ip_here export CLEARML_AGENT_GIT_USER=git_username_here export CLEARML_AGENT_GIT_PASS=git_password_here -------------------------------------------------- # 서버 설치 docker-compose -f /opt/clearml/docker-compose.yml up -d
A서버
docker compose -f /opt/clearml/docker-compose.yml down docker compose -f /opt/clearml/docker-compose.yml up -d
A서버
sudo tar czvf ~/clearml_backup_data.tgz -C /opt/clearml/data . sudo tar czvf ~/clearml_backup_config.tgz -C /opt/clearml/config .
A서버
# 백업 설정 파일을 압축해제 sudo rm -fR /opt/clearml/data/* /opt/clearml/config/* sudo tar -xzf ~/clearml_backup_data.tgz -C /opt/clearml/data sudo tar -xzf ~/clearml_backup_config.tgz -C /opt/clearml/config -------------------------------------------------- # 권한 설정 sudo chown -R 1000:1000 /opt/clearml
ClearML을 최초 설치하고 웹에서 접속해보면 다음과 같이 나온다.
ClearML 웹 인터페이스
다만 여러 사용자가 서버를 사용한다면 각 사용자마다 계정을 만들어줄 필요가 있다.
이를 위하여 /opt/clearml/config/apiserver.conf
파일을 아래와 같이 수정한다.(해당 경로에 파일이 없다면 새로 만들다).
A서버
auth { # Fixed users login credentials # No other user will be able to login fixed_users { enabled: true pass_hashed: false users: [ { username: "jane" password: "12345678" name: "Jane Doe" }, { username: "john" password: "12345678" name: "John Doe" }, ] } }
ClearML 로그인 화면
ClearML Agent는 연산서버인 B서버에 설치되며, ClearML server로부터 명령, 소스코드 등을 받아 연산을 수행시키는 worker이다.
설치는 다음과 같이 수행한다
'NoneType' object has no attribute '_PENDING'
과 같은 에러가 발생함.B서버
# 최신버전 설치 pip install clearml-agent # 특정 버전 설치 pip install clearml-agent==1.9.3
B서버
clearml-agent init
혹시 명령을 찾을 수 없다는 메세지와 함께 실행이 되지 않는다면 아래와 같이 pip 경로를 추가해주자.
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc source ~/.bashrc
ClearML WebUI에서의 key 생성과정.
"Create new credentials" 버튼을 누르면 필요한 정보가 모두 표시된다..
이때, ClearML을 open source server로 구성한다면 8080, 8008, 8081 포트가 필요하므로, 공유기나 방화벽 설정에서 열어주어야 한다.
A, B 서버
docker pull pytorch/pytorch:2.7.1-cuda11.8-cudnn9-runtime
A 서버
docker run -it --rm \ --gpus all \ -v ~/shared_dir:/workspace/shared_dir \ pytorch/pytorch:2.7.1-cuda11.8-cudnn9-runtime \ bash
A 서버(docker 내부)
pip install clearml clearml-init
task.execute_remotely(queue_name="default", exit_process=True)
를 주석해제하고 원격 서버의 agent가 지정한 큐 이름과 통일시켜야 함from clearml import Task
import matplotlib.pyplot as plt
import numpy as np
import time
from PIL import Image
# 실험 등록 및 원격 실행 요청
task = Task.init(project_name="Demo Project", task_name="Simple Training Demo2", task_type=Task.TaskTypes.training)
#task.execute_remotely(queue_name="default", exit_process=True)
# 간단한 학습 시뮬레이션
losses = []
for step in range(20):
loss = np.exp(-step / 5.0) + np.random.rand() * 0.05
losses.append(loss)
task.get_logger().report_scalar("loss", "train", value=loss, iteration=step)
time.sleep(0.1)
# 결과 이미지
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title("Sample Result Plot")
plt.savefig("result.png")
# 이미지와 모델 업로드
#image_open = Image.open("./result.png")
#task.get_logger().report_image("result_plot", "sine_wave", iteration=0, image=image_open)
with open("dummy_model.txt", "w") as f:
f.write("This simulates a trained model.")
task.upload_artifact("dummy_model", "dummy_model.txt")
A 서버(docker 내부)
python train.py
WebUI를 보면 새로운 작업이 등록된 것을 볼 수 있음
B 서버
#!/bin/bash # 사용할 ClearML 큐 이름 QUEUE_NAME="default" # ClearML Agent 실행 (Docker 모드) clearml-agent daemon \ --queue "$QUEUE_NAME" \ --docker \ --foreground
train.py
에 코드를 추가한다.task.set_base_docker
: 사용할 도커 이미지 지정task.execute_remotely
: 원격 연산 지정. 큐 이름은 원격 서버의 agent에서 지정한 큐 이름과 같아야함Task.force_requirements_env_freeze
: ClearML은 작업 생성시 필요한 파이썬 라이브러리를 자동으로 인식한 후 원격서버에 그대로 설치하는데, 나의 경우 자동 인식한 requiredment를 사용했을 때 일부 라이브러리 설치에 에러가 나서 작업 수행이 안됐다.(A, B 서버 둘 다에 실험 환경이 구축된 도커 이미지를 설치했기 때문에 사실 별다른 추가 라이브러리 설치가 필요없는 상황이기도 하다.) 이 문제를 해결하기 위해 해당 코드를 통해 아래 예시와 같이 추가 설치가 필요한 특정 라이브러리만 requiredments.txt로 만들어 인식하도록 했다.from clearml import Task
import matplotlib.pyplot as plt
import numpy as np
import time
from PIL import Image
# 실험 등록 및 원격 실행 요청
Task.force_requirements_env_freeze(force=True, requirements_file='./requirements.txt')
task = Task.init(project_name="Demo Project", task_name="Simple Training Demo2", task_type=Task.TaskTypes.training)
task.set_base_docker('pytorch/pytorch:2.7.1-cuda11.8-cudnn9-runtime')
task.execute_remotely(queue_name="default", exit_process=True)
#requiredments.txt
clearml==2.0.2
matplotlib == 3.10.3
B서버에 agent 실행 후, A서버에서 작업을 생성하면 자동으로 B서버로 넘어감.
이전에 했었던 작업을 다시 B서버에서 동작시키고 싶을 경우, 그림과 같이 enqueue 버튼을 눌러 B서버의 agent와 같은 queue 작업을 넘겨주면 됨.