inpaintServer/app/core/config.py

132 lines
5.7 KiB
Python

"""
Configuration settings for the inpainting server
"""
import os
import platform
from typing import Dict, Any, Optional, ClassVar
from pydantic_settings import BaseSettings
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
class Settings(BaseSettings):
# System detection
IS_JETSON: ClassVar[bool] = "aarch64" in platform.machine().lower() and "tegra" in platform.release().lower()
PROJECT_ROOT: ClassVar[str] = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# --- 동적 세션 풀 및 메모리 관리 설정 ---
# 각 모델별 최소/최대 세션 수. 서버 시작 시 min 만큼 생성되고, VRAM 여유 시 max까지 확장됨.
SIMPLE_LAMA_MIN_SESSIONS: int = 2 if IS_JETSON else 2
SIMPLE_LAMA_MAX_SESSIONS: int = 4 if IS_JETSON else 4
MIGAN_MIN_SESSIONS: int = 2 if IS_JETSON else 1 # x86에서는 Migan을 기본으로 로드하지 않음
MIGAN_MAX_SESSIONS: int = 4 if IS_JETSON else 4
REMBG_MIN_SESSIONS: int = 2 if IS_JETSON else 1
REMBG_MAX_SESSIONS: int = 4 if IS_JETSON else 3
# 세션 추가 생성 VRAM 임계값 (%). 남은 VRAM이 이 값보다 커야 새 세션 생성.
# 예: 12GB VRAM에 0.3이면, 3.6GB 이상 여유가 있어야 함.
SESSION_VRAM_THRESHOLD: float = 0.3 if IS_JETSON else 0.3 # Jetson에서는 통합 메모리이므로 좀 더 여유롭게 설정
# 유휴 세션 자동 제거 시간 (초). 0이면 비활성화.
SESSION_IDLE_TIMEOUT: int = 1800 # 30분
# --- 마이크로 배치 설정 ---
USE_MICRO_BATCHING: bool = True # SimpleLama에 대한 배치 처리 활성화
MICRO_BATCH_SIZE: int = 4 # 최대 배치 크기
MICRO_BATCH_TIMEOUT_MS: int = 100 # 배치 생성을 위한 최대 대기 시간 (밀리초)
# --- 서버 환경 설정 (클래스 내부로 이동) ---
APP_VERSION: str = "3.0.0-dynamic-pool"
APP_NAME: str = "Inpaint & RemoveBG Server"
API_PREFIX: str = "/api/v1"
HOST: str = "0.0.0.0"
PORT: int = 8008
WORKERS: int = 1 # 개발 모드에서는 1로 고정, 프로덕션에서는 gunicorn으로 관리
# GPU settings (Jetson Xavier 최적화)
CUDA_DEVICE: int = 0
USE_CUDA: bool = True # CUDA 사용 여부 (Jetson에서 항상 True)
USE_FP16: bool = True # FP16 사용 여부 (Jetson 최적화)
FP16_ENABLED: bool = True # 기존 호환성
# ONNX Runtime 최적화 설정
USE_TENSORRT: bool = True # TensorRT 사용 여부 (최고 성능)
TENSORRT_FP16: bool = True # TensorRT FP16 사용
TENSORRT_WORKSPACE_SIZE: int = 2 * 1024 * 1024 * 1024 # 2GB
# Jetson specific settings
JETSON_MODE: bool = IS_JETSON
JETSON_POWER_MODE: str = "MAXN" # MAXN, 5W, 10W, 15W
JETSON_FAN_CONTROL: bool = True
JETSON_TEMP_THRESHOLD: int = 75 # Celsius
# Session pool settings (Jetson Xavier는 32GB 통합 메모리로 더 많은 세션 가능)
SIMPLE_LAMA_SESSIONS: int = 4 if IS_JETSON else 4 # Jetson: 통합 32GB vs 데스크톱: VRAM 제한
MIGAN_SESSIONS: int = 4 if IS_JETSON else 4 # Jetson이 더 많은 세션 운영 가능
REMBG_SESSIONS: int = 3 if IS_JETSON else 2 # 메모리 공유 방식의 이점 활용
# Worker settings (Jetson은 통합 메모리로 더 효율적)
MAX_WORKERS: int = 10 if IS_JETSON else 8
MIN_WORKERS: int = 10 if IS_JETSON else 4
WORKER_TIMEOUT: int = 120 # 2 minutes
# 메모리 관리 (Jetson은 32GB 통합 메모리로 여유로움)
VRAM_THRESHOLD_HIGH: float = 0.85 if IS_JETSON else 0.80 # 워커 추가 생성 중단
VRAM_THRESHOLD_LOW: float = 0.4 if IS_JETSON else 0.40 # 워커 제거 시작
VRAM_CHECK_INTERVAL: int = 30 if IS_JETSON else 15 # Jetson은 덜 자주 체크
# Model paths
SIMPLE_LAMA_MODEL_PATH: str = "app/models/pt/big-lama.pt"
MIGAN_MODEL_PATH: str = "app/models/onnx/migan_pipeline_v2.onnx"
REMBG_MODEL_PATH: str = "app/models/onnx/birefnet-general-lite.onnx"
# MIGAN ONNX settings
MIGAN_ONNX_PATH: Optional[str] = "app/models/onnx/migan_pipeline_v2.onnx" # 커스텀 ONNX 파일 경로
MIGAN_INTRA_THREADS: int = 0
MIGAN_INTER_THREADS: int = 0
# REMBG settings (자동 다운로드 방식)
REMBG_MODEL_NAME: str = "birefnet-general-lite" # 고품질 경량 모델
LOCAL_REMBG_MODEL_PATH: Optional[str] = None # 로컬 파일 사용 안함
# Upload settings (Jetson Xavier는 32GB 메모리로 대용량 처리 가능)
MAX_FILE_SIZE: int = 100 * 1024 * 1024 if IS_JETSON else 50 * 1024 * 1024 # Jetson: 100MB, 데스크톱: 50MB
MAX_IMAGE_SIZE: int = 4096 if IS_JETSON else 3072 # Jetson: 4K, 데스크톱: 3K (VRAM 고려)
ALLOWED_EXTENSIONS: set = {".jpg", ".jpeg", ".png", ".bmp", ".tiff"}
# Monitoring
ENABLE_MONITORING: bool = True
MONITORING_PORT: int = 8888
# Discord 웹훅 알림 설정
DISCORD_WEBHOOK_URL: Optional[str] = None
# Jetson performance settings
JETSON_GPU_FREQ: int = 1200 # MHz
JETSON_CPU_FREQ: int = 1900 # MHz
JETSON_MEMORY_FREQ: int = 1600 # MHz
class Config:
env_file = ".env"
env_file_encoding = 'utf-8'
settings = Settings()
# 파일에서 웹훅 URL 로드 (환경 변수보다 우선순위 낮음)
if not settings.DISCORD_WEBHOOK_URL:
try:
webhook_file = Path(settings.PROJECT_ROOT) / "webhook_url.txt"
if webhook_file.exists():
url = webhook_file.read_text().strip()
if url:
settings.DISCORD_WEBHOOK_URL = url
logger.info(f"파일에서 Discord 웹훅 URL을 로드했습니다: {url[:30]}...")
except Exception as e:
logger.warning(f"webhook_url.txt 파일 로드 실패: {e}")