
MinIO를 활용한 YOLO 학습 방법을 알아보기 위해 ChatGPT를 활용하였다.
Me : minio 버킷에 저장된 데이터를 바탕으로 darknet yolov4를 학습하고 싶은데 mlflow를 활용해야 할까? 아니면 python 으로 구현할 수 있을까?
ChatGPT : MinIO에 저장된 YOLOv4 학습용 데이터를 활용하기 위해 반드시 MLflow를 사용할 필요는 없습니다. MLflow는 주로 실험 추적(Experiment Tracking), 모델 관리, 배포 등에 특화된 도구이며, 데이터 다운로드 및 모델 학습 자체는 Python 코드로 충분히 구현할 수 있습니다.
MLflow 활용 시:
Python 직접 구현 시:
boto3나 MinIO Python SDK 등을 사용해 MinIO 버킷에서 이미지 및 라벨 데이터를 직접 다운로드. MinIO에서 데이터 가져오기:
import boto3
import os
s3_client = boto3.client(
's3',
endpoint_url='http://127.0.0.1:9000',
aws_access_key_id='your-access-key',
aws_secret_access_key='your-secret-key'
)
bucket_name = "mybucket"
prefix = "my-yolo-dataset/"
# 로컬 디렉토리에 데이터 다운로드
local_data_dir = "./data"
os.makedirs(local_data_dir, exist_ok=True)
response = s3_client.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
while True:
for obj in response.get('Contents', []):
key = obj['Key']
filename = key.replace(prefix, "")
if filename: # prefix 자체가 아닌 경우
local_path = os.path.join(local_data_dir, filename)
# 하위 디렉토리 구조 반영
os.makedirs(os.path.dirname(local_path), exist_ok=True)
s3_client.download_file(bucket_name, key, local_path)
if response.get('IsTruncated'):
response = s3_client.list_objects_v2(
Bucket=bucket_name,
Prefix=prefix,
ContinuationToken=response.get('NextContinuationToken')
)
else:
break
YOLOv4 학습 스크립트 실행:
데이터 다운로드 후 YOLOv4 Darknet 학습을 위한 .cfg, .data, .names 파일, 이미지 및 라벨 세팅을 마친 뒤 아래처럼 Darknet을 실행할 수 있습니다.
./darknet detector train data/obj.data cfg/yolov4.cfg yolov4.conv.137
Python에서 subprocess를 통해 Darknet 학습 호출:
import subprocess
command = ["./darknet", "detector", "train", "data/obj.data", "cfg/yolov4.cfg", "yolov4.conv.137"]
subprocess.run(command, check=True)
mlflow.log_metric, mlflow.log_artifact 등을 통해 모델 가중치 파일을 MLflow에 업로드하고 버전 관리할 수 있습니다.그러나 이 과정은 선택 사항입니다. 학습 파이프라인 자체는 MLflow 없이도 수행할 수 있으며, 필요하다면 나중에 MLflow를 추가해 실험 관리 기능을 확장할 수 있습니다.
Me : Python 스크립트로 학습을 하고 MLflow는 필요 시 실험 추적 및 관리 기능을 제공하는 툴로 활용하고 싶은데 구체적으로 어떻게 구현해야 할까?
ChatGPT : 아래 예제는 Python 스크립트 내부에서 MinIO로부터 YOLO 데이터셋을 가져와 darknet YOLOv4 모델을 학습한 뒤, MLflow를 통해 실험 파라미터 및 결과(메트릭, 모델 가중치 파일)를 기록하는 구현 전략을 제시합니다. 이 예제는 하나의 큰 파이프라인으로, 필요 시 MLflow 추적을 켜거나 끌 수 있습니다.
MinIO에서 YOLO 데이터셋 다운로드:
boto3를 사용해 MinIO로부터 이미지와 annotation 파일 등을 다운로드합니다.
YOLO 학습 스크립트 실행:
subprocess를 이용해 YOLOv4 학습을 위한 Darknet 실행 파일을 호출합니다.
학습 결과 처리:
Darknet 학습 로그를 파싱하거나, 최종 결과(가중치 파일, mAP 계산 결과 등)를 확인합니다.
MLflow로 로깅:
mlflow.set_experiment()를 통해 실험 관리mlflow.log_param()으로 학습 파라미터 기록mlflow.log_metric()으로 mAP, Loss 등 메트릭 기록mlflow.log_artifact()로 최종 가중치 파일 등 산출물 업로드MLflow Tracking UI를 통해 웹 브라우저에서 실험 이력을 확인할 수 있습니다.
import os
import subprocess
import boto3
import mlflow
# ========== 설정 부분 ==========
MINIO_ENDPOINT = "http://127.0.0.1:9000"
ACCESS_KEY = "your-access-key"
SECRET_KEY = "your-secret-key"
BUCKET_NAME = "mybucket"
DATA_PREFIX = "my-yolo-dataset/"
LOCAL_DATA_DIR = "./data" # YOLO 학습용 데이터 저장 디렉토리
DARKNET_PATH = "./darknet"
CONFIG_FILE = "cfg/yolov4.cfg"
DATA_FILE = "data/obj.data"
PRETRAINED_WEIGHTS = "yolov4.conv.137"
EXPERIMENT_NAME = "YOLOv4_Experiment"
USE_MLFLOW = True # 필요시 True/False로 MLflow 로깅 on/off
# ============================
def download_data_from_minio():
"""MinIO에서 YOLO 데이터셋을 다운로드."""
s3_client = boto3.client(
's3',
endpoint_url=MINIO_ENDPOINT,
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY
)
os.makedirs(LOCAL_DATA_DIR, exist_ok=True)
continuation_token = None
while True:
if continuation_token:
response = s3_client.list_objects_v2(
Bucket=BUCKET_NAME,
Prefix=DATA_PREFIX,
ContinuationToken=continuation_token
)
else:
response = s3_client.list_objects_v2(
Bucket=BUCKET_NAME,
Prefix=DATA_PREFIX
)
for obj in response.get('Contents', []):
key = obj['Key']
relative_path = key[len(DATA_PREFIX):]
if relative_path: # prefix 자체가 아닌 경우
local_path = os.path.join(LOCAL_DATA_DIR, relative_path)
os.makedirs(os.path.dirname(local_path), exist_ok=True)
s3_client.download_file(BUCKET_NAME, key, local_path)
if response.get('IsTruncated'):
continuation_token = response.get('NextContinuationToken')
else:
break
def run_darknet_training():
"""Darknet YOLOv4 학습을 subprocess로 실행."""
command = [
DARKNET_PATH, "detector", "train",
DATA_FILE, CONFIG_FILE, PRETRAINED_WEIGHTS,
"-dont_show", "-map" # -map 옵션으로 mAP 계산
]
# Darknet이 학습 중 출력하는 로그를 파일에 저장
with open("training.log", "w") as log_file:
subprocess.run(command, check=True, stdout=log_file, stderr=log_file)
def parse_darknet_log():
"""
Darknet의 training.log를 파싱해 mAP 등 메트릭 추출.
darknet detector train 명령어로 학습 완료 시 로그에 mAP가 표시됨.
로그 파싱 로직은 실제 로그 형식에 맞게 구현 필요.
예: 'mean average precision (mAP@0.5) = 0.836' 형태를 검색
"""
map_value = None
with open("training.log", "r") as f:
lines = f.readlines()
for line in lines:
if "mean average precision (mAP@0.5)" in line:
# 라인 예: 'mean average precision (mAP@0.5) = 0.836...'
parts = line.strip().split("=")
if len(parts) > 1:
try:
map_value = float(parts[1].strip().split()[0])
except:
pass
return map_value
def find_final_weights():
"""
Darknet 학습이 완료되면 backup/ 폴더(또는 cfg에 지정한 output 폴더)에 최종 weights 파일이 생성됨.
예: backup/yolov4_final.weights
"""
# 사용자 환경에 맞게 수정 필요
backup_dir = "./backup"
final_weights = None
for f in os.listdir(backup_dir):
if f.endswith("_final.weights"):
final_weights = os.path.join(backup_dir, f)
break
return final_weights
def main():
# 1. 데이터 다운로드
download_data_from_minio()
# 2. MLflow 설정
if USE_MLFLOW:
mlflow.set_tracking_uri("http://127.0.0.1:5000") # MLflow tracking server URI (변경 가능)
mlflow.set_experiment(EXPERIMENT_NAME)
# 학습 파라미터 예시
learning_rate = 0.001
batch_size = 64
with mlflow.start_run() if USE_MLFLOW else nullcontext(): # mlflow 사용 안할 경우 dummy context
# 파라미터 로깅
if USE_MLFLOW:
mlflow.log_param("learning_rate", learning_rate)
mlflow.log_param("batch_size", batch_size)
mlflow.log_param("config_file", CONFIG_FILE)
mlflow.log_param("data_file", DATA_FILE)
# 3. Darknet 학습 실행
run_darknet_training()
# 4. 학습 결과 파싱 (mAP 등)
map_value = parse_darknet_log()
if map_value is not None and USE_MLFLOW:
mlflow.log_metric("mAP", map_value)
# 5. 최종 모델 가중치 파일 로깅
final_weights = find_final_weights()
if final_weights and USE_MLFLOW:
mlflow.log_artifact(final_weights, artifact_path="model")
# 필요하다면 기타 결과물(예: confusion matrix 이미지, log 파일)도 로깅 가능
if USE_MLFLOW:
mlflow.log_artifact("training.log", artifact_path="logs")
# mlflow 미사용 시 with 구문에서 예외 처리용 context
from contextlib import contextmanager
@contextmanager
def nullcontext():
yield
if __name__ == "__main__":
main()
MinIO 데이터 다운로드:
download_data_from_minio() 함수에서 모든 YOLO 데이터셋 파일을 로컬 ./data 디렉토리에 가져옵니다.
Darknet 실행:
run_darknet_training()에서 subprocess.run()으로 Darknet 훈련 명령을 실행합니다. 학습 로그는 training.log 파일에 기록합니다.
MLflow 설정:
mlflow.set_tracking_uri()로 MLflow 서버 위치를 지정하고, mlflow.set_experiment()로 실험 이름을 지정합니다. mlflow.start_run() 블록 안에서 log_param(), log_metric(), log_artifact()를 호출하면 해당 실험에 결과가 기록됩니다.
결과 파싱 및 로깅:
parse_darknet_log()에서 mAP를 추출하고 mlflow.log_metric("mAP", map_value)로 기록합니다. 최종 가중치 파일(_final.weights)을 찾아 mlflow.log_artifact()로 업로드합니다.
옵션:
USE_MLFLOW = True를 False로 바꾸면 MLflow 없이도 스크립트 실행이 가능합니다.
MLflow Tracking UI를 실행했다면 (예: mlflow ui 실행 후 http://127.0.0.1:5000 접속), 해당 실험(YOLOv4_Experiment)에 대한 러닝 로그, 파라미터, 메트릭, 아티팩트를 웹 UI에서 확인할 수 있습니다.
이렇게 Python 스크립트로 데이터 다운로드, 학습 실행, 결과 파싱까지 진행하고, 필요한 경우 MLflow로 로깅을 활성화하여 모델 실험 관리 기능을 추가할 수 있습니다.