본문 바로가기
AI Framework/PyTorch

[PyTorch] 14주차: 모델 배포 및 운영

by cogito21_python 2024. 5. 30.
반응형

강의 목표

  • 모델 배포의 중요성 및 방법 이해
  • PyTorch 모델을 배포하기 위한 다양한 기술 학습
  • 실전 프로젝트를 통해 모델 배포 및 운영 경험

강의 내용

1. 모델 배포의 중요성

  • 배포의 필요성
    • 학습된 모델을 실제 환경에 적용하여 예측 서비스 제공
    • 배포된 모델은 웹 애플리케이션, 모바일 앱, IoT 디바이스 등에서 사용할 수 있음
  • 배포의 주요 고려 사항
    • 성능 최적화: 예측 속도, 메모리 사용량 등
    • 안정성 및 확장성: 다양한 요청 처리 능력
    • 보안: 데이터 보호 및 접근 제어

2. PyTorch 모델 저장 및 로드

  • 모델 가중치 저장 및 로드
    • 모델 가중치만 저장하여 나중에 불러오기
    • 전체 모델 저장 및 로드
     
# 모델 가중치 저장
torch.save(model.state_dict(), 'model_weights.pth')

# 모델 가중치 로드
model = SimpleCNN()
model.load_state_dict(torch.load('model_weights.pth'))
model.eval()

# 전체 모델 저장
torch.save(model, 'model.pth')

# 전체 모델 로드
model = torch.load('model.pth')
model.eval()

 

3. ONNX(Open Neural Network Exchange)로 모델 변환

  • ONNX 개요
    • ONNX는 서로 다른 딥러닝 프레임워크 간의 모델 호환성을 제공
    • PyTorch 모델을 ONNX 형식으로 변환하여 다양한 플랫폼에서 사용 가능
  • PyTorch 모델을 ONNX 형식으로 변환
import torch.onnx

# 모델을 ONNX 형식으로 변환
dummy_input = torch.randn(1, 1, 28, 28)  # 모델 입력에 맞는 더미 데이터 생성
torch.onnx.export(model, dummy_input, 'model.onnx')

 

4. Flask를 이용한 간단한 웹 서비스 구축

  • Flask 개요
    • Flask는 Python으로 작성된 마이크로 웹 프레임워크로, 간단한 API 서버 구축에 유용
  • Flask를 이용한 모델 배포 예시
from flask import Flask, request, jsonify
import torch
from torchvision import transforms
from PIL import Image
import io

app = Flask(__name__)

# 모델 로드
model = torch.load('model.pth')
model.eval()

# 이미지 전처리 함수
def transform_image(image_bytes):
    transform = transforms.Compose([
        transforms.Resize((28, 28)),
        transforms.ToTensor(),
        transforms.Normalize((0.5,), (0.5,))
    ])
    image = Image.open(io.BytesIO(image_bytes))
    return transform(image).unsqueeze(0)

# 예측 함수
def get_prediction(image_bytes):
    tensor = transform_image(image_bytes)
    outputs = model(tensor)
    _, predicted = torch.max(outputs.data, 1)
    return predicted.item()

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        file = request.files['file']
        img_bytes = file.read()
        prediction = get_prediction(img_bytes)
        return jsonify({'prediction': prediction})

if __name__ == '__main__':
    app.run()

 

5. 클라우드 서비스 배포

  • 클라우드 서비스 개요
    • AWS, Google Cloud, Azure 등의 클라우드 플랫폼을 사용하여 모델 배포
    • 주요 서비스: AWS SageMaker, Google AI Platform, Azure Machine Learning
  • AWS SageMaker를 이용한 모델 배포 예시
# AWS SageMaker 개요 및 간단한 사용 예시를 설명합니다.
# 1. 모델 학습 및 저장: 로컬에서 학습한 모델을 S3에 업로드
# 2. SageMaker에서 모델 호스팅: S3에 저장된 모델을 로드하여 엔드포인트 생성
# 3. 엔드포인트를 통해 예측 요청 처리

 

6. 프로젝트 설명 및 진행

  • 프로젝트 개요
    • 모델 배포 및 운영을 위한 실전 프로젝트 수행
    • 모델 배포 후 실제 서비스 환경에서 예측 수행 및 모니터링
  • 데이터셋 선택
    • Kaggle 또는 기타 오픈 데이터셋에서 프로젝트 데이터셋 선택
  • 프로젝트 단계
    • 데이터 전처리 및 준비
    • 모델 설계 및 학습
    • 모델 배포 및 운영
    • 성능 모니터링 및 최적화

7. 프로젝트 예시

  • 예시 프로젝트: 손글씨 숫자 분류 웹 서비스
    • 데이터셋 로드 및 전처리
    • 모델 학습 및 저장
    • Flask를 이용한 웹 서비스 구축
    • 클라우드 서비스에 배포
     
import torch
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import torch.optim as optim
import torch.nn as nn
from torch.utils.data import DataLoader
from flask import Flask, request, jsonify
from PIL import Image
import io

# 데이터 전처리 변환
transform = transforms.Compose([
    transforms.Resize((28, 28)),
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# MNIST 데이터셋 로드
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
val_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)

# 간단한 CNN 모델 정의
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 64 * 7 * 7)  # Flatten the tensor
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 모델 학습
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

num_epochs = 5
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader)}')

# 모델 저장
torch.save(model, 'model.pth')

# Flask 앱 정의
app = Flask(__name__)

# 모델 로드
model = torch.load('model.pth')
model.eval()

# 이미지 전처리 함수
def transform_image(image_bytes):
    transform = transforms.Compose([
        transforms.Resize((28, 28)),
        transforms.ToTensor(),
        transforms.Normalize((0.5,), (0.5,))
    ])
    image = Image.open(io.BytesIO(image_bytes))
    return transform(image).unsqueeze(0)

# 예측 함수
def get_prediction(image_bytes):
    tensor = transform_image(image_bytes)
    outputs = model(tensor)
    _, predicted = torch.max(outputs.data, 1)
    return predicted.item()

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        file = request.files['file']
        img_bytes = file.read()
        prediction = get_prediction(img_bytes)
        return jsonify({'prediction': prediction})

if __name__ == '__main__':
    app.run()

 

8. 프로젝트 발표 및 코드 리뷰

  • 프로젝트 발표
    • 각 그룹 또는 개인은 프로젝트 결과 발표
    • 모델 설계, 훈련 과정, 배포 및 운영 결과 등을 공유
  • 코드 리뷰 및 피드백
    • 각 그룹의 코드를 리뷰하고 피드백 제공
    • 개선할 점 및 좋은 점 공유

9. 실습 및 과제

    • 학습된 모델을 저장하고, Flask를 이용하여 간단한 웹 서비스 구축
    • 클라우드 서비스에 모델 배포 후 테스트 데이터로 예측 수행실습 과제

 

반응형