YOLOv5 Custom Training : Docker to AWS EC2 deploy #3
웹캠 동작 확인
먼저 배포하기 전에 친구한테 웹캠이 있다고 해서 빌려서 모델 테스트를 해봤는데 스마트폰으로 꽃 사진들을 검색해서 인식시켜 봤다,
신기하게도 잘 인식하는 것을 확인 - 뿌듯하다
API 명세서
저번에 flask로 yolov5 모델을 API화 했는데 간단한 API 명세서를 작성해 봤다.
크게 3가지 기능[ 상태확인, 이미지요청, 이미지를 분석한 json 데이터요청 ]
ID | 기능 | 요청방식 | URL | body | response | 설명 |
F1 | 서버 상태 확인 | GET | / | 없음 | JSON | 서버 동작 여부 확인 |
F2 | 이미지 예측 | POST | /predict | multipart/form-data, image 필드 | image/jpeg | 추론된 결과 이미지 반환 |
F3 | 이미지 예측 (JSON) | POST | /predict-json | multipart/form-data, image 필드 | JSON | 클래스, 신뢰도, 바운딩 박스 |
요청 예시 (curl)
curl -X POST <http://localhost:5000/predict> \\
-F image=@sample.jpg --output result.jpg
curl -X POST <http://localhost:5000/predict-json> \\
-F image=@sample.jpg
백엔드 스프링 서버랑 프런트엔드 쪽 코드를 배포해 본 경험은 많았는데
AI모델과 백엔드 서버를 같이 묶어서 도커 컨테이너화 한 다음 AWS에 배포해 본 적은 없어 여러 번 헤맸다..!
🌶️ Flask Code, (app.py) (2025-04-30)
import sys
from flask import Flask, request, jsonify, send_file
import sys
import os
import uuid
import torch
from pathlib import Path
from yolov5.detect import run
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
app = Flask(__name__)
# 기본 설정
BASE_DIR = Path(__file__).resolve().parent.parent # Hanamory/
MODEL_PATH = BASE_DIR / 'yolov5/runs/train/flower2_yolov5_640_b16_ep100/weights/best_linux.pt'
UPLOAD_DIR = Path(__file__).resolve().parent / 'static/uploads'
RESULT_DIR = Path(__file__).resolve().parent / 'static/detect'
IMGSZ = 640
# 디렉토리 미리 생성
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
RESULT_DIR.mkdir(parents=True, exist_ok=True)
@app.route('/', methods=['GET'])
def home():
return jsonify({"message": "YOLOv5 Flask API is running"}), 200
@app.route('/predict', methods=['POST'])
def predict_image():
if 'image' not in request.files:
return jsonify({'error': '이미지가 필요합니다.'}), 400
file = request.files['image']
filename = f"{uuid.uuid4().hex}.jpg"
input_path = UPLOAD_DIR / filename
file.save(str(input_path))
# YOLO 추론
run(
weights=str(MODEL_PATH),
source=str(input_path),
imgsz=(IMGSZ, IMGSZ),
conf_thres=0.4,
save_txt=False,
save_conf=False,
project=str(RESULT_DIR.parent), # static/
name='detect',
exist_ok=True
)
result_path = RESULT_DIR / filename
if not result_path.exists():
return jsonify({'error': '예측 실패'}), 500
return send_file(result_path, mimetype='image/jpeg')
@app.route('/predict-json', methods=['POST'])
def predict_json():
if 'image' not in request.files:
return jsonify({'error': '이미지가 필요합니다.'}), 400
file = request.files['image']
filename = f"{uuid.uuid4().hex}.jpg"
input_path = UPLOAD_DIR / filename
file.save(str(input_path))
model = torch.hub.load('ultralytics/yolov5', 'custom', path=str(MODEL_PATH), force_reload=True)
model.to('cpu') # CPU 추론
results = model(str(input_path))
predictions = []
for *box, conf, cls in results.xyxy[0]:
predictions.append({
'class': model.names[int(cls)],
'confidence': round(float(conf), 4),
'bbox': [round(float(x), 2) for x in box]
})
return jsonify({'predictions': predictions})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
🐳 Dockerfile
FROM python:3.8-slim
RUN apt-get update && apt-get install -y git ffmpeg libgl1 wget
WORKDIR /app
# YOLOv5 코드 복사
COPY yolov5 /app/yolov5
COPY yolov5/requirements.txt /app/yolov5/requirements.txt
# 종속성 설치
RUN pip install --upgrade pip
RUN pip install -r /app/yolov5/requirements.tx
RUN pip install flask
# Flask 백엔드 복사
COPY backend /app/backend
# PYTHONPATH 등록
ENV PYTHONPATH="${PYTHONPATH}:/app"
CMD ["python", "backend/app.py"]
# docker build -t yolov5-flask-api .
# docker run -p 5000:5000 yolov5-flask-api
도커 이미지
CPU 및 GPU 환경, 볼륨 마운트, 디스플레이 서버 사용에 대한 단계별 지침을 통해 Docker 컨테이너에서 YOLOv5 설정하고 실행하는 방법을 알아보세요.
docs.ultralytics.com
yolo 공식문서를 참고해서 dockerfile을 만들어줬고 빌드까지 해줬다.
pytorch같이 용량이 큰 라이브러리까지 설치하면서 빌드하다 보니 도커 이미지 만드는데도 시간이 5분? 조금 더 걸린 것 같다.
근데 에러가 났는데.. 내 데스크톱 개발환경이 windows 기반으로 yolo모델을 설정해 둬서 그런 듯했다. 여기저기 찾아보다가 yolo 공식 깃허브에서 비슷한 사례를 통해 해결할 수 있었다!!
⚙️ TroubleShooting
- 문제: 윈도에서 학습하고 빌드한 모델을 linux 기반 Docker에 올리려고 하니 WindowsPath 관련 error 발생..
https://github.com/ultralytics/yolov5/issues/12911from pathlib import Path plt = platform.system() if plt == 'Windows': pathlib.PosixPath = pathlib.WindowsPath pathlib.WindowsPath = pathlib.PosixPath
- → 해결: detect.py에 pathlib.PosixPath = pathlib.WindowsPath 우회코드를 삽입해 windows환경 파일경로와 linux환경 파일경로를 핸들링
이제 AWS 프리티어 계정을 만들고 EC2 인스턴스를 만들어준다!! 보안그룹이나 생성 디테일은 나중에 aws 전용으로 글을 하나 정리해 두는 게 좋겠다.
이제 ssh로 인스턴스에 접속해서 dockerhub에 도커 이미지를 push 하고 ec2 인스턴스에서 pull로 가져온다
# 1. 패키지 업데이트
sudo apt update
# 2. Docker 설치
sudo apt install docker.io -y
# 3. Docker 실행 권한 부여
sudo usermod -aG docker $USER
# 4. 설정 적용
newgrp docker
**로컬에서 도커 이미지 태그 설정**
> docker tag yolov5-flask-api neogul02/yolov5-flask-api
**Docker Hub에 push(로그인 필요):**
> docker login
> docker push neogul02/yolov5-flask-api
**EC2에서 Pull**
> docker pull neogul02/yolov5-flask-api
> docker run -p 5000:5000 neogul02/yolov5-flask-api
배포 테스트 ( http://[EC2 퍼블릭 IP]:5000 )
임시 퍼블릭 ip 포트로 접속해 보면 성공적으로 배포가 된 걸 볼 수 있다!!
이미지 처리도 잘 될까?
참고자료들
도커 이미지
CPU 및 GPU 환경, 볼륨 마운트, 디스플레이 서버 사용에 대한 단계별 지침을 통해 Docker 컨테이너에서 YOLOv5 설정하고 실행하는 방법을 알아보세요.
docs.ultralytics.com
Troubleshoot and diagnose
Understand how to diagnose and troubleshoot Docker Desktop, and how to check the logs.
docs.docker.com
Docker | IntelliJ IDEA
www.jetbrains.com
[AWS] EC2 인스턴스에 Docker 컨테이너 배포하기
이전에 Google Cloud Platform (GCP)를 이용하여 Docker 컨테이너를 배포하는 방법을 포스팅한 적 있다.이번에는 AWS를 사용하여 배포하는 방법을 살펴보도록 하자. AWS 인스턴스에, Docker 컨테이너를 실행
sjh9708.tistory.com
[INFRA] AWS EC2 프리티어 인스턴스 생성하기
AWS (Amazon Web Services) AWS는 Amazon이 제공하는 클라우드 컴퓨팅 플랫폼 및 인프라 서비스 모음이다. 2006년에 시작된 AWS는 가상 컴퓨터, 스토리지, 데이터베이스, 네트워킹, 분석, 머신 러닝, 모바일,
olrlobt.tistory.com