본문 바로가기
[GPUaaS]

[경영진 보고용] 월별 GPU 사용 PDF 리포트 자동 생성 (Lambda)

by METAVERSE STORY 2026. 1. 7.
반응형

 

 

**경영진 보고용 “월별 GPU 사용 PDF 리포트 자동 생성 Lambda”**의
👉 실제 운영 가능한 고급 구현 예시입니다.

  • GPU-Hour + 사용률 보정 반영
  • 표 + 요약 + 핵심 지표 중심
  • Lambda → PDF 생성 → S3 저장
  • 감사/임원 보고에 바로 제출 가능

 


1️⃣ PDF 리포트 구성 (경영진 최적화)

📄 PDF 구성 순서

  1. 표지
    • 리포트 제목
    • 대상 월
    • 생성 일시
  2. 요약(Summary)
    • 총 GPU 사용 시간
    • 총 비용
    • 평균 GPU 사용률
  3. 팀/프로젝트별 상세 표
  4. 비효율 사용 Top 항목
  5. 결론 & 개선 포인트

👉 기술 세부는 줄이고, 숫자와 메시지 위주


2️⃣ 아키텍처

 
EventBridge (매월 1일) ↓ Lambda (Python) ↓ Prometheus API ↓ GPU 사용량 집계 ↓ PDF 생성 (ReportLab) ↓ S3 저장 ↓ (선택) Email / Slack

3️⃣ Lambda Layer (필수)

PDF 생성을 위해 reportlab 필요

 
pip install reportlab -t python/ zip -r reportlab-layer.zip python

→ Lambda Layer로 등록


4️⃣ Lambda 환경 변수

변수설명
PROMETHEUS_URL Prometheus URL
S3_BUCKET PDF 저장 버킷
GPU_PRICE_A100 단가
GPU_PRICE_T4 단가
COMPANY_NAME 회사명

5️⃣ Lambda Python 코드 (PDF 생성 포함)

 
import os import requests import boto3 from datetime import datetime, timedelta from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Table, TableStyle, Spacer ) from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib import colors PROM_URL = os.environ['PROMETHEUS_URL'] S3_BUCKET = os.environ['S3_BUCKET'] COMPANY = os.environ.get('COMPANY_NAME', 'Company') GPU_PRICE = { "A100": float(os.environ.get("GPU_PRICE_A100", 4000)), "T4": float(os.environ.get("GPU_PRICE_T4", 900)), } s3 = boto3.client('s3') styles = getSampleStyleSheet() def query_prom(query): r = requests.get( f"{PROM_URL}/api/v1/query", params={"query": query}, timeout=15 ) r.raise_for_status() return r.json()['data']['result'] def util_factor(util): if util >= 70: return 1.0 if util >= 40: return 0.8 if util >= 20: return 0.6 return 0.4 def lambda_handler(event, context): today = datetime.utcnow() last_month = (today.replace(day=1) - timedelta(days=1)) month_str = last_month.strftime("%Y-%m") gpu_hour_q = """ sum by (namespace, modelName) ( count_over_time(DCGM_FI_DEV_GPU_UTIL > 0 [30d]) ) """ avg_util_q = """ avg by (namespace, modelName) (DCGM_FI_DEV_GPU_UTIL) """ hours = query_prom(gpu_hour_q) utils = query_prom(avg_util_q) util_map = { (u['metric']['namespace'], u['metric']['modelName']): float(u['value'][1]) for u in utils } rows = [] total_cost = 0 total_hours = 0 for h in hours: ns = h['metric']['namespace'] model = h['metric']['modelName'] gpu_h = float(h['value'][1]) avg_u = util_map.get((ns, model), 0) factor = util_factor(avg_u) cost = gpu_h * GPU_PRICE.get(model, 0) * factor total_cost += cost total_hours += gpu_h rows.append([ ns, model, f"{gpu_h:.1f}", f"{avg_u:.1f}%", factor, f"{cost:,.0f}원" ]) file_path = f"/tmp/GPU_Report_{month_str}.pdf" doc = SimpleDocTemplate(file_path, pagesize=A4) story = [] story.append(Paragraph( f"<b>{COMPANY} GPU 사용 리포트</b>", styles['Title'])) story.append(Spacer(1, 12)) story.append(Paragraph( f"대상 월: {month_str}", styles['Normal'])) story.append(Paragraph( f"총 GPU 사용 시간: {total_hours:.1f} h", styles['Normal'])) story.append(Paragraph( f"총 비용: {total_cost:,.0f} 원", styles['Normal'])) story.append(Spacer(1, 20)) table = Table( [["팀/프로젝트", "GPU", "사용시간", "평균 사용률", "보정", "비용"]] + rows ) table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), colors.lightgrey), ('GRID', (0,0), (-1,-1), 0.5, colors.grey), ('ALIGN', (2,1), (-1,-1), 'RIGHT') ])) story.append(table) doc.build(story) s3_key = f"reports/gpu/GPU_Report_{month_str}.pdf" s3.upload_file(file_path, S3_BUCKET, s3_key) return { "status": "success", "pdf": f"s3://{S3_BUCKET}/{s3_key}" }

6️⃣ 생성되는 PDF 리포트 특징

✔ 한 장으로 전체 GPU 비용 현황 파악
✔ 팀별 비용 책임 명확
✔ “GPU 효율 낮음 → 비용 보정” 논리 명확
임원 / 재무 / 감사 대응에 매우 강함


7️⃣ 경영진 보고용 문구 예시 (중요)

“GPU 비용은 사용 시간뿐 아니라 실제 활용도를 반영해 산정되며,
비효율 사용에 대한 비용 절감 유인이 자동으로 작동합니다.”

 

 

 

반응형

댓글