요구 사항 파일에 새로운 패키지(scikit-image, torchvision, huggingface-hub)를 추가하고, Jetson 관련 주석을 추가하였습니다. 상태 JSON 파일에서 워커 ID를 업데이트하고, API 요청 통계 및 성공률을 수정하였습니다. 배경 제거 API의 응답 형식을 base64로 변경하고, 관련 로직을 개선하였습니다. 설정 파일에서 REMBG 모델을 "briaai/RMBG-1.4"로 변경하였습니다.

This commit is contained in:
AGX 2025-09-01 21:54:54 +09:00
parent 60d6a440cd
commit dc137030b4
28 changed files with 4144 additions and 1743 deletions

2
=0.0.9 Normal file
View File

@ -0,0 +1,2 @@
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: python-multipart in /home/ckh08045/.local/lib/python3.8/site-packages (0.0.6)

View File

@ -124,6 +124,15 @@ def create_response(
_, media_type = encode_image_to_format(image, image_format) _, media_type = encode_image_to_format(image, image_format)
return StreamingResponse(generate(), media_type=media_type) return StreamingResponse(generate(), media_type=media_type)
elif response_format == ResponseFormat.base64:
# Base64 응답
image_b64 = encode_image_to_base64(image)
return JSONResponse(content={
"success": True,
"image": image_b64,
"processing_time": processing_time
})
else: else:
# JSON 응답 (기본값, iopaint 호환) # JSON 응답 (기본값, iopaint 호환)
image_b64 = encode_image_to_base64(image) image_b64 = encode_image_to_base64(image)
@ -310,7 +319,7 @@ async def inpaint_image(
@router.post("/api/v1/remove_bg") @router.post("/api/v1/remove_bg")
async def remove_background( async def remove_background(
request: RemoveBGRequest, request: RemoveBGRequest,
response_format: ResponseFormat = Query(ResponseFormat.binary, description="응답 형식 (기존 클라이언트 호환을 위해 기본값: binary)"), response_format: ResponseFormat = Query(ResponseFormat.base64, description="응답 형식"),
image_format: ImageFormat = Query(ImageFormat.png, description="이미지 형식") image_format: ImageFormat = Query(ImageFormat.png, description="이미지 형식")
): ):
"""배경 제거 API (iopaint 호환)""" """배경 제거 API (iopaint 호환)"""
@ -335,7 +344,7 @@ async def remove_background(
# 모델 선택 # 모델 선택
model_name = request.model_name model_name = request.model_name
if not model_name or model_name == "rembg": if not model_name or model_name == "rembg":
model_name = "birefnet-general-lite" model_name = "briaaiRMBG-1.4"
# 워커에서 배경 제거 실행 # 워커에서 배경 제거 실행
result_image, result_mask = await worker_manager.process_remove_bg( result_image, result_mask = await worker_manager.process_remove_bg(
@ -365,6 +374,15 @@ async def remove_background(
processing_time=processing_time, processing_time=processing_time,
success=True success=True
) )
elif response_format == ResponseFormat.base64:
# Base64 응답은 이미지만 반환
return create_response(
image=result_image,
response_format=response_format,
image_format=image_format,
processing_time=processing_time,
success=True
)
else: else:
# JSON 응답은 이미지와 마스크 모두 반환 # JSON 응답은 이미지와 마스크 모두 반환
result_base64 = encode_image_to_base64(result_image, ext) result_base64 = encode_image_to_base64(result_image, ext)

View File

@ -75,6 +75,9 @@ class Settings(BaseSettings):
MIN_WORKERS: int = 10 if IS_JETSON else 4 MIN_WORKERS: int = 10 if IS_JETSON else 4
WORKER_TIMEOUT: int = 120 # 2 minutes WORKER_TIMEOUT: int = 120 # 2 minutes
# 사용할 REMBG 모델 설정: "briaai/RMBG-1.4" 또는 onnx 파일 경로
REMBG_MODEL: str = "briaaiRMBG-1.4"
# 메모리 관리 (Jetson은 32GB 통합 메모리로 여유로움) # 메모리 관리 (Jetson은 32GB 통합 메모리로 여유로움)
VRAM_THRESHOLD_HIGH: float = 0.85 if IS_JETSON else 0.80 # 워커 추가 생성 중단 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_THRESHOLD_LOW: float = 0.4 if IS_JETSON else 0.40 # 워커 제거 시작
@ -83,7 +86,8 @@ class Settings(BaseSettings):
# Model paths # Model paths
SIMPLE_LAMA_MODEL_PATH: str = "app/models/pt/big-lama.pt" SIMPLE_LAMA_MODEL_PATH: str = "app/models/pt/big-lama.pt"
MIGAN_MODEL_PATH: str = "app/models/onnx/migan_pipeline_v2.onnx" MIGAN_MODEL_PATH: str = "app/models/onnx/migan_pipeline_v2.onnx"
REMBG_MODEL_PATH: str = "app/models/onnx/birefnet-general-lite.onnx" REMBG_MODEL_PATH: str = "app/models/onnx/BriaRMBG1.4_model_fp16.onnx"
# MIGAN ONNX settings # MIGAN ONNX settings
MIGAN_ONNX_PATH: Optional[str] = "app/models/onnx/migan_pipeline_v2.onnx" # 커스텀 ONNX 파일 경로 MIGAN_ONNX_PATH: Optional[str] = "app/models/onnx/migan_pipeline_v2.onnx" # 커스텀 ONNX 파일 경로
@ -91,7 +95,7 @@ class Settings(BaseSettings):
MIGAN_INTER_THREADS: int = 0 MIGAN_INTER_THREADS: int = 0
# REMBG settings (자동 다운로드 방식) # REMBG settings (자동 다운로드 방식)
REMBG_MODEL_NAME: str = "birefnet-general-lite" # 고품질 경량 모델 REMBG_MODEL_NAME: str = "briaai/RMBG-1.4" # BriaAI RMBG 1.4 모델
LOCAL_REMBG_MODEL_PATH: Optional[str] = None # 로컬 파일 사용 안함 LOCAL_REMBG_MODEL_PATH: Optional[str] = None # 로컬 파일 사용 안함
# Upload settings (Jetson Xavier는 32GB 메모리로 대용량 처리 가능) # Upload settings (Jetson Xavier는 32GB 메모리로 대용량 처리 가능)
@ -114,7 +118,7 @@ class Settings(BaseSettings):
class Config: class Config:
env_file = ".env" env_file = ".env"
env_file_encoding = 'utf-8' env_file_encoding = 'utf-8'
protected_namespaces = ()
settings = Settings() settings = Settings()

View File

@ -140,13 +140,9 @@ class SessionPool:
use_cuda=settings.USE_CUDA use_cuda=settings.USE_CUDA
) )
elif model_type == ModelType.REMBG: elif model_type == ModelType.REMBG:
from ..models.rembg_model import RembgProcessor # rembg 대신 BriaAI RMBG 1.4 ONNX 프로세서를 사용
model = RembgProcessor( from ..models.bria_rmbg_onnx import BriaRMBGOnnxProcessor
model_name=getattr(settings, 'REMBG_MODEL_NAME', 'birefnet-general-lite'), model = BriaRMBGOnnxProcessor()
device="cuda" if settings.USE_CUDA else "cpu",
fp16=settings.USE_FP16,
local_rembg_model_path=getattr(settings, 'LOCAL_REMBG_MODEL_PATH', None)
)
else: else:
raise ValueError(f"Unknown model type: {model_type}") raise ValueError(f"Unknown model type: {model_type}")

View File

@ -15,6 +15,7 @@ import numpy as np
from ..utils.gpu_monitor import gpu_monitor from ..utils.gpu_monitor import gpu_monitor
from ..core.config import settings from ..core.config import settings
from ..core.stats_manager import stats_manager from ..core.stats_manager import stats_manager
from ..core.session_pool import ModelType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -405,7 +406,8 @@ class WorkerManager:
try: try:
from ..core.session_pool import session_pool, ModelType from ..core.session_pool import session_pool, ModelType
model_name = kwargs.get('model_name', 'birefnet-general-lite') # 기본 모델명 변경 # model_name = kwargs.get('model_name', 'birefnet-general-lite') # 기본 모델명 변경
model_name = kwargs.get('model_name', 'briaaiRMBG-1.4')
# 세션 풀에서 REMBG 모델 세션 가져와서 처리 # 세션 풀에서 REMBG 모델 세션 가져와서 처리
async with session_pool.get_session(ModelType.REMBG) as session: async with session_pool.get_session(ModelType.REMBG) as session:

View File

@ -0,0 +1,158 @@
"""
BriaAI RMBG 1.4 ONNXRuntime 기반 배경제거 프로세서
rembg를 사용하지 않고 ONNX 모델을 직접 로드하여 추론합니다.
"""
import logging
import time
from typing import Optional, Tuple
import numpy as np
import cv2
from PIL import Image
try:
import onnxruntime as ort
except Exception as e: # pragma: no cover
ort = None # 런타임에서 에러 메시지로 안내
from ..core.config import settings
logger = logging.getLogger(__name__)
class BriaRMBGOnnxProcessor:
"""BriaAI RMBG 1.4 ONNX 모델을 사용하는 배경 제거 프로세서"""
def __init__(self, *args, **kwargs):
self._session: Optional["ort.InferenceSession"] = None
self._input_name: Optional[str] = None
self._output_name: Optional[str] = None
self._model_input_size: Tuple[int, int] = (1024, 1024) # (W, H)
logger.info("BriaRMBGOnnxProcessor 초기화 완료")
async def load_model(self) -> bool:
"""ONNX 세션을 로드합니다."""
if ort is None:
logger.error("onnxruntime 모듈을 불러오지 못했습니다. onnxruntime 패키지를 설치하세요.")
return False
model_path = settings.REMBG_MODEL_PATH
logger.info(f"Bria RMBG ONNX 세션 생성 중... path={model_path}")
try:
sess_options = ort.SessionOptions()
sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
# Jetson에서는 TensorRT EP 호환 이슈가 있을 수 있어 CUDA, CPU 우선 사용
if settings.USE_CUDA:
providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
else:
providers = ["CPUExecutionProvider"]
self._session = ort.InferenceSession(model_path, sess_options=sess_options, providers=providers)
inputs = self._session.get_inputs()
outputs = self._session.get_outputs()
if not inputs or not outputs:
raise RuntimeError("ONNX 모델의 입출력 정의를 찾을 수 없습니다.")
self._input_name = inputs[0].name
self._output_name = outputs[0].name
logger.info(
f"Bria RMBG ONNX 세션 생성 완료, Providers: {self._session.get_providers()} | "
f"Input: {self._input_name}, Output: {self._output_name}"
)
return True
except Exception as e:
logger.error(f"Bria RMBG ONNX 세션 생성 실패: {e}")
return False
def _preprocess(self, image_bgr: np.ndarray) -> Tuple[np.ndarray, Tuple[int, int]]:
"""BGR uint8 이미지를 모델 입력(NCHW float32, 정규화)로 변환"""
orig_h, orig_w = image_bgr.shape[:2]
# BGR -> RGB
image_rgb = image_bgr[:, :, ::-1]
# 리사이즈 (W,H)
target_w, target_h = self._model_input_size
resized = cv2.resize(image_rgb, (target_w, target_h), interpolation=cv2.INTER_LINEAR)
# float32 [0,1] -> normalize(mean=0.5, std=1.0) == x - 0.5
tensor = resized.astype(np.float32) / 255.0
tensor = tensor - 0.5
# HWC -> CHW, 배치 축 추가
nchw = np.transpose(tensor, (2, 0, 1))[np.newaxis, ...]
return nchw, (orig_h, orig_w)
def _infer(self, input_tensor: np.ndarray) -> np.ndarray:
"""ONNX 추론 수행 후 [H,W] 마스크 확률맵 반환(0~1 범위 전처리 전)"""
outputs = self._session.run([self._output_name], {self._input_name: input_tensor})
pred = outputs[0]
# 예상 출력: [1, 1, H, W] 또는 [1, H, W]
pred = np.array(pred)
if pred.ndim == 4:
pred = pred[0, 0]
elif pred.ndim == 3:
pred = pred[0]
# 이제 pred는 [H, W]
return pred
def _postprocess(self, mask_pred: np.ndarray, orig_size: Tuple[int, int]) -> np.ndarray:
"""모델 출력 마스크를 원본 해상도로 보간하고 0..255 uint8로 변환"""
orig_h, orig_w = orig_size
# 모델 출력(H,W)을 원본 크기로 리사이즈 (W,H)
mask_resized = cv2.resize(mask_pred, (orig_w, orig_h), interpolation=cv2.INTER_LINEAR)
# min-max 정규화 안전 처리
ma = float(mask_resized.max())
mi = float(mask_resized.min())
denom = (ma - mi) if (ma - mi) != 0 else 1.0
mask_norm = (mask_resized - mi) / denom
mask_u8 = (mask_norm * 255.0).clip(0, 255).astype(np.uint8)
return mask_u8
async def remove_background(self, image: np.ndarray, model_name: str = None) -> tuple:
"""이미지에서 배경을 제거하여 (배경제거된 BGR 이미지, 알파 마스크) 반환"""
try:
start_time = time.time()
logger.info(f"배경제거 시작(Bria ONNX): image.shape={image.shape}, model_name={model_name}")
if self._session is None:
raise RuntimeError("Bria RMBG ONNX 세션이 로드되지 않았습니다.")
input_tensor, (orig_h, orig_w) = self._preprocess(image)
mask_pred = self._infer(input_tensor)
alpha_mask = self._postprocess(mask_pred, (orig_h, orig_w))
# 흰색 배경 합성 (BGR)
if image.ndim == 3 and image.shape[2] == 3:
mask_3 = np.stack([alpha_mask] * 3, axis=-1)
result_bgr = (
image.astype(np.float32) * (mask_3.astype(np.float32) / 255.0)
+ 255.0 * (1.0 - (mask_3.astype(np.float32) / 255.0))
).clip(0, 255).astype(np.uint8)
else:
# 비정상 입력 대비
result_bgr = image
duration = time.time() - start_time
try:
logger.info(
f"Bria ONNX mask stats: min={int(alpha_mask.min())}, max={int(alpha_mask.max())}, "
f"mean={float(alpha_mask.mean()):.3f}"
)
except Exception:
pass
logger.info(f"'bria-rmbg' processed in {duration:.3f}s")
return result_bgr, alpha_mask
except Exception as e:
logger.error(f"배경 제거 처리 실패(Bria ONNX): {e}", exc_info=True)
return image, None

Binary file not shown.

View File

@ -1,275 +1,92 @@
""" """
REMBG 배경 제거 모델 구현 (실제 rembg 라이브러리 사용) REMBG 배경 제거 모델 구현 (rembg 라이브러리 사용)
""" """
import os
import cv2
from PIL import Image
import logging import logging
import numpy as np import numpy as np
import onnxruntime # ONNX 런타임 직접 사용을 위해 임포트 from PIL import Image
from typing import Union, Tuple, Optional import rembg
import asyncio
from ..core.config import settings from ..core.config import settings
from ..utils.gpu_monitor import gpu_monitor
from ..utils.image_utils import fill_transparent_background_with_white
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class RembgProcessor: class RembgProcessor:
""" """Rembg 라이브러리를 사용한 배경 제거 프로세서"""
rembg 기반 배경제거 모듈 (안전한 의존성 처리)
"""
# 사용하시려는 birefnet 모델을 지원 목록에 추가합니다.
SUPPORTED_MODELS = {
"u2net": "범용 배경제거 | 빠름 | 사람/사물 모두 양호 (기본값)",
"u2netp": "u2net 경량화 | 매우 빠름 | 실시간, 저사양PC",
"u2net_human_seg": "인물 전용 | 빠름 | 사람 경계 정밀",
"u2net_cloth_seg": "옷 전용 | 빠름 | 패션/의류 특화",
"isnet-general-use": "범용 고품질 | 느림 | 디테일 중시, 대용량",
"sam": "SAM 최고 품질 | 매우 느림 | 고성능PC 권장",
"sam-mobile": "SAM 경량화 | 보통 | 모바일, 중간성능",
"birefnet-general-lite": "BiRefNet 경량 모델 | 고품질 저용량 (로컬)"
}
# SUPPORTED_MODELS 키와 실제 rembg sessions 키 간의 매핑
MODEL_NAME_MAPPING = {
"u2net": "u2net",
"u2netp": "u2netp",
"u2net_human_seg": "u2net-human-seg",
"u2net_cloth_seg": "u2net-cloth-seg",
"isnet-general-use": "dis-general-use",
"sam": "sam",
"sam-mobile": "sam", # sam-mobile은 sam과 동일하게 처리
"birefnet-general-lite": "birefnet-general-lite"
}
def __init__(self, model_name: str = "u2net", device: str = "cuda", fp16: bool = True,
local_rembg_model_path: str = None):
self.model_name = model_name
self.device = device
self.fp16 = fp16
self.local_rembg_model_path = local_rembg_model_path
self.sessions = {}
self.loaded = False
self._rembg_available = None
self._init_error = None
self._cuda_providers_tested = False
def _check_rembg_availability(self): def __init__(self, *args, **kwargs):
"""rembg 모듈 사용 가능 여부를 확인하고 캐시. """초기화 시 임의의 인수를 받아 무시 (session_pool 호환성)"""
세션을 생성하지 않아 모델 다운로드를 유발하지 않도록 .""" self._session = None
if self._rembg_available is not None: logger.info("RembgProcessor 초기화 완료")
return self._rembg_available
try:
import rembg # noqa: F401
self._rembg_available = True
logger.info("rembg 모듈 임포트 성공 (세션 생성은 지연 로딩)")
return True
except ImportError as e:
self._init_error = f"rembg 모듈이 설치되지 않음: {e}"
self._rembg_available = False
except Exception as e:
self._init_error = f"rembg 모듈 초기화 실패 (의존성/하드웨어 문제): {e}"
self._rembg_available = False
logger.error(self._init_error)
return False
def get_session(self, model_name, timeout_seconds: int = 90):
"""
모델별 세션을 캐싱하여 반환 (로컬 모델 경로 CUDA 지원 포함)
"""
if not self._check_rembg_availability():
logger.error(f"rembg 사용 불가로 세션 생성 실패: {self._init_error}")
return None
# device 설정에 따라 CUDA 사용 여부 결정 (간소화)
cuda_enabled = self.device == "cuda"
# 실제 모델명을 세션 키에 사용
actual_model_name = self.MODEL_NAME_MAPPING.get(model_name, model_name)
session_key = f"{actual_model_name}_cuda_{cuda_enabled}"
if session_key not in self.sessions:
logger.info(f"🔧 rembg 새 세션 생성 필요: {session_key}")
try:
import rembg
try:
from rembg.sessions import sessions
except ImportError:
# rembg 버전에 따라 import 경로가 다를 수 있음
sessions = None
logger.warning("rembg.sessions import 실패, 기본 방식 사용")
# Jetson 환경에서 TensorRT 충돌을 피하기 위해 프로바이더 명시
providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
logger.info(f"rembg 세션 생성 providers: {providers}")
session = rembg.new_session(
model_name=actual_model_name,
providers=providers
)
self.sessions[session_key] = session
# 실제 사용된 provider 확인 및 로깅 (가드 처리)
actual_providers = []
try:
inner = getattr(session, 'inner_session', None)
if inner and hasattr(inner, 'get_providers'):
actual_providers = inner.get_providers() or []
except Exception as prov_err:
logger.debug(f"rembg provider 확인 실패: {prov_err}")
is_gpu = any(('CUDA' in p) or ('Tensorrt' in p) for p in actual_providers)
status = "GPU 가속" if is_gpu else "CPU 모드"
logger.info(
f"✅ rembg '{actual_model_name}' {status}로 동작 (providers: {actual_providers or '알 수 없음'})"
)
except Exception as e:
logger.error(f"rembg 세션 생성 실패 ('{actual_model_name}'): {e}", exc_info=True)
return None
else:
logger.debug(f"♻️ rembg 기존 세션 재사용: {session_key}")
return self.sessions.get(session_key)
async def load_model(self): async def load_model(self):
"""모델을 비동기적으로 로드합니다.""" """Rembg 세션을 로드합니다."""
if self.loaded:
return
try: try:
logger.info(f"Loading REMBG model ({self.model_name})...") logger.info("Rembg 세션 생성 중...")
# rembg 사용 가능성 확인 # Jetson에서 TensorRT 프로바이더 제외하여 세션 생성
if not self._check_rembg_availability(): if settings.IS_JETSON:
raise RuntimeError(f"REMBG 사용 불가: {self._init_error}") providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
self._session = rembg.new_session(settings.REMBG_MODEL_NAME, providers=providers)
# 세션 생성
session = self.get_session(self.model_name)
if session is None:
raise RuntimeError(f"REMBG 세션 생성 실패: {self.model_name}")
self.loaded = True
logger.info(f"REMBG model ({self.model_name}) loaded successfully")
except Exception as e:
logger.error(f"Failed to load REMBG model: {e}")
raise
def to_white_background(self, img: Image.Image) -> Image.Image:
"""RGBA 이미지를 흰 배경으로 변환"""
if img.mode in ("RGBA", "BGRA"):
bg = Image.new("RGB", img.size, (255, 255, 255))
bg.paste(img, mask=img.split()[-1])
return bg
else:
return img.convert("RGB")
async def remove_background(self, image: Union[str, Image.Image, np.ndarray],
model_name: str = None, **kwargs) -> Tuple[np.ndarray, np.ndarray]:
"""
배경을 제거하고 결과 이미지와 마스크를 반환합니다.
Args:
image: 입력 이미지 (파일 경로, PIL Image, 또는 numpy array)
model_name: 사용할 모델명 (없으면 기본 모델 사용)
**kwargs: 추가 옵션 (alpha_matting )
Returns:
(result_rgb, mask): 결과 이미지(RGB) 마스크
"""
if not self.loaded:
await self.load_model()
try:
# 이미지 로드 및 변환
if isinstance(image, str):
if not os.path.exists(image):
logger.error(f"입력 이미지가 존재하지 않습니다: {image}")
return None, None
img = cv2.imread(image)
if img is None:
logger.error(f"이미지 로드 실패: {image}")
return None, None
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
elif isinstance(image, Image.Image):
img_rgb = np.array(image.convert('RGB'))
elif isinstance(image, np.ndarray):
if len(image.shape) == 3 and image.shape[2] == 3:
# BGR to RGB
img_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
else:
img_rgb = image
else: else:
logger.error(f"지원하지 않는 이미지 타입: {type(image)}") self._session = rembg.new_session(settings.REMBG_MODEL_NAME)
return None, None
# 사용할 모델명 결정
effective_model_name = model_name or self.model_name
if effective_model_name not in self.SUPPORTED_MODELS: logger.info(f"Rembg 세션 생성 완료, 프로바이더: {self._session.providers if hasattr(self._session, 'providers') else 'Unknown'}")
logger.warning(f"지원하지 않는 모델명: {effective_model_name}. u2net으로 대체 사용") return True
effective_model_name = "u2net"
session = self.get_session(effective_model_name)
if session is None:
return None, None
import rembg
import time
start_time = time.time()
# rembg.remove는 RGBA 이미지를 반환
output_image_rgba = rembg.remove(image, session=session)
# 투명 배경을 흰색으로 채우기
output_image_rgb = fill_transparent_background_with_white(output_image_rgba)
# 마스크 생성 (알파 채널 사용)
mask = output_image_rgba[:, :, 3]
logger.debug("Background removal and white filling successful.")
return output_image_rgb, mask
except Exception as e: except Exception as e:
logger.error(f"Error during rembg processing: {e}", exc_info=True) logger.error(f"Rembg 세션 생성 실패: {e}")
return None, None return False
def set_default_model(self, model_name):
if model_name not in self.SUPPORTED_MODELS:
raise ValueError(f"지원하지 않는 모델명: {model_name}")
self.model_name = model_name
logger.info(f"rembg 기본 모델이 '{model_name}'(으)로 변경됨")
def get_default_model(self):
return self.model_name
def get_supported_models(self):
return self.SUPPORTED_MODELS.copy()
def get_model_description(self, model_name):
return self.SUPPORTED_MODELS.get(model_name, "모델 설명 없음")
def is_available(self):
return self._check_rembg_availability()
def get_init_error(self):
return self._init_error
def get_model_info(self) -> dict: async def remove_background(self, image: np.ndarray, model_name: str = None) -> tuple:
"""모델 정보를 반환합니다.""" """이미지에서 배경을 제거합니다."""
return { try:
"model_type": "rembg", logger.info(f"배경제거 시작: image.shape={image.shape}, model_name={model_name}")
"model_name": self.model_name,
"device": self.device, if self._session is None:
"fp16": self.fp16, logger.error("Rembg 세션이 None입니다!")
"loaded": self.loaded, raise RuntimeError("Rembg 세션이 로드되지 않았습니다.")
"available": self.is_available(),
"supported_models": list(self.SUPPORTED_MODELS.keys()), logger.info(f"Rembg 세션 확인 완료: {type(self._session)}")
"local_model_path": self.local_rembg_model_path
} # numpy 배열을 PIL Image로 변환
if len(image.shape) == 3 and image.shape[2] == 3:
# BGR to RGB 변환 (OpenCV 기본값)
rgb_image = image[:, :, ::-1]
else:
rgb_image = image
pil_image = Image.fromarray(rgb_image.astype(np.uint8))
logger.info(f"PIL 이미지 변환 완료: {pil_image.size}, {pil_image.mode}")
# rembg로 배경 제거 (RGBA 반환)
logger.info("rembg.remove() 호출 중...")
result_pil = rembg.remove(pil_image, session=self._session)
logger.info(f"rembg.remove() 완료: {result_pil.size}, {result_pil.mode}")
# 마스크 추출 및 통계 로깅
try:
alpha_channel = np.array(result_pil)[:, :, 3]
logger.info(f"RMBG mask stats: min={int(alpha_channel.min())}, max={int(alpha_channel.max())}, mean={float(alpha_channel.mean()):.3f}")
except Exception:
pass
# RGBA를 RGB로 변환 (흰색 배경 추가)
if result_pil.mode == 'RGBA':
# 흰색 배경 생성
white_bg = Image.new('RGB', result_pil.size, (255, 255, 255))
white_bg.paste(result_pil, mask=result_pil.split()[-1]) # 알파 채널을 마스크로 사용
result_pil = white_bg
# PIL을 numpy 배열로 변환 후 BGR로 변환 (OpenCV 호환)
result_array = np.array(result_pil)
if len(result_array.shape) == 3 and result_array.shape[2] == 3:
result_array = result_array[:, :, ::-1] # RGB to BGR
# 마스크 생성 (간단히 알파 채널을 그레이스케일로)
mask = alpha_channel if 'alpha_channel' in locals() else np.ones((result_array.shape[0], result_array.shape[1]), dtype=np.uint8) * 255
return result_array, mask
except Exception as e:
logger.error(f"배경 제거 처리 실패: {e}", exc_info=True)
return image, None

View File

@ -18,6 +18,7 @@ class ResponseFormat(str, Enum):
json = "json" # JSON 형식 (기본값, iopaint 호환) json = "json" # JSON 형식 (기본값, iopaint 호환)
binary = "binary" # 바이너리 이미지 (기존 클라이언트 호환) binary = "binary" # 바이너리 이미지 (기존 클라이언트 호환)
stream = "stream" # 스트리밍 응답 stream = "stream" # 스트리밍 응답
base64 = "base64" # Base64 문자열 (테스트 및 일부 클라이언트용)
class ImageFormat(str, Enum): class ImageFormat(str, Enum):
@ -38,13 +39,17 @@ class InpaintRequest(BaseModel):
guidance_scale: Optional[float] = Field(7.5, description="가이던스 스케일") guidance_scale: Optional[float] = Field(7.5, description="가이던스 스케일")
strength: Optional[float] = Field(1.0, description="인페인팅 강도") strength: Optional[float] = Field(1.0, description="인페인팅 강도")
model_name: Optional[str] = Field("simple-lama", description="사용할 모델명") model_name: Optional[str] = Field("simple-lama", description="사용할 모델명")
model_config = {
"protected_namespaces": () # 보호 네임스페이스 비활성화
}
class RemoveBGRequest(BaseModel): class RemoveBGRequest(BaseModel):
"""배경 제거 요청 스키마 (iopaint 호환)""" """배경 제거 요청 스키마 (iopaint 호환)"""
image: str = Field(..., description="base64로 인코딩된 이미지") image: str = Field(..., description="base64로 인코딩된 이미지")
model_name: Optional[str] = Field("rembg", description="사용할 모델명") model_name: Optional[str] = Field("rembg", description="사용할 모델명")
model_config = {
"protected_namespaces": () # 보호 네임스페이스 비활성화
}
class InpaintResponse(BaseModel): class InpaintResponse(BaseModel):
"""인페인팅 응답 스키마 (iopaint 호환)""" """인페인팅 응답 스키마 (iopaint 호환)"""

View File

@ -145,6 +145,9 @@ class SimpleLamaInpainter:
image_batch = torch.stack(preprocessed_images).to(self._device) image_batch = torch.stack(preprocessed_images).to(self._device)
mask_batch = torch.stack(preprocessed_masks).to(self._device) mask_batch = torch.stack(preprocessed_masks).to(self._device)
# 원본 이미지와 사이즈 저장
original_images_and_sizes = list(zip(pil_images, [img.size for img in pil_images]))
# 모델 호출 # 모델 호출
logger.info(f"실제 SimpleLama 모델로 {len(images)}개 이미지 인페인팅 수행") logger.info(f"실제 SimpleLama 모델로 {len(images)}개 이미지 인페인팅 수행")
with torch.no_grad(): with torch.no_grad():
@ -153,8 +156,10 @@ class SimpleLamaInpainter:
# 후처리 # 후처리
result_images = [] result_images = []
for inpainted_tensor in inpainted_batch: for i, inpainted_tensor in enumerate(inpainted_batch):
result_pil = self._postprocess(inpainted_tensor) original_image, original_size = original_images_and_sizes[i]
original_mask = pil_masks[i]
result_pil = self._postprocess(inpainted_tensor, original_size, original_image, original_mask)
result_images.append(np.array(result_pil)) result_images.append(np.array(result_pil))
return result_images return result_images
@ -165,9 +170,6 @@ class SimpleLamaInpainter:
image = image.convert("RGB") image = image.convert("RGB")
mask = mask.convert("L") mask = mask.convert("L")
# 원본 크기 저장
original_size = image.size
# 이미지 리사이즈 (모델 요구사항에 맞게) # 이미지 리사이즈 (모델 요구사항에 맞게)
resized_image = image.resize((512, 512), Image.Resampling.LANCZOS) resized_image = image.resize((512, 512), Image.Resampling.LANCZOS)
resized_mask = mask.resize((512, 512), Image.Resampling.NEAREST) resized_mask = mask.resize((512, 512), Image.Resampling.NEAREST)
@ -177,15 +179,21 @@ class SimpleLamaInpainter:
return image_tensor, mask_tensor return image_tensor, mask_tensor
def _postprocess(self, tensor: torch.Tensor) -> Image.Image: def _postprocess(self, tensor: torch.Tensor, original_size: Tuple[int, int], original_image: Image.Image, original_mask: Image.Image) -> Image.Image:
"""모델 출력 텐서를 PIL 이미지로 후처리합니다.""" """모델 출력 텐서를 PIL 이미지로 후처리하고 원본에 합성합니다."""
# simple_lama_inpainting.models.lama.py의 후처리 로직 참고 # 텐서를 PIL 이미지로 변환
result_np = tensor.permute(1, 2, 0).cpu().numpy() result_np = tensor.permute(1, 2, 0).cpu().numpy()
result_np = np.clip(result_np * 255, 0, 255).astype(np.uint8) result_np = np.clip(result_np * 255, 0, 255).astype(np.uint8)
inpainted_image_512 = Image.fromarray(result_np)
# 원본 크기로 복원 (여기서는 512x512 결과를 그대로 사용) # 원본 크기로 리사이즈
# 필요하다면 원본 크기 정보를 받아 리사이즈하는 로직 추가 resized_inpainted_image = inpainted_image_512.resize(original_size, Image.Resampling.LANCZOS)
return Image.fromarray(result_np)
# 원본 마스크를 사용하여 원본 이미지와 합성
original_mask = original_mask.convert("L")
final_image = Image.composite(resized_inpainted_image, original_image, original_mask)
return final_image
@property @property

View File

@ -0,0 +1,211 @@
"""
Simple LAMA 인페인팅 모델 구현
"""
import torch
import numpy as np
import cv2
from PIL import Image
import logging
from typing import Union, Tuple, List
import asyncio
from concurrent.futures import ThreadPoolExecutor
from simple_lama_inpainting import SimpleLama
# 사용하지 않는 import 정리
# from ..utils.image_utils import (
# decode_base64_to_image,
# encode_image_to_base64,
# get_image_size,
# resize_image_if_needed,
# )
logger = logging.getLogger(__name__)
class SimpleLamaInpainter:
def __init__(self, model_path: str, device: str = "cpu", fp16: bool = False):
self.model_path = model_path
self._device = torch.device(device)
self._fp16 = fp16
self._model = None
self.loaded = False
async def load_model(self):
"""모델을 비동기적으로 로드합니다."""
if self.loaded:
return
try:
logger.info("Loading Simple LAMA model...")
# 실제 simple-lama-inpainting 라이브러리 사용
try:
self._model = SimpleLama(device=self._device)
logger.info("실제 SimpleLama 모델 로딩 완료")
except ImportError as e:
logger.warning(f"SimpleLama 라이브러리 import 실패: {e}")
logger.info("fallback 모드로 전환합니다...")
# fallback으로 시뮬레이션 모드 사용
self._model = {"type": "simple_lama_fallback", "device": self._device, "fp16": self._fp16}
except Exception as e:
logger.error(f"SimpleLama 모델 초기화 실패: {e}")
logger.info("fallback 모드로 전환합니다...")
self._model = {"type": "simple_lama_fallback", "device": self._device, "fp16": self._fp16}
self.loaded = True
logger.info("Simple LAMA model loaded successfully")
except Exception as e:
logger.error(f"Failed to load Simple LAMA model: {e}")
raise
def preprocess_image(self, image: Union[Image.Image, np.ndarray]) -> torch.Tensor:
"""이미지를 전처리합니다."""
if isinstance(image, Image.Image):
image = np.array(image)
# RGB로 변환
if image.shape[2] == 4: # RGBA
image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
elif image.shape[2] == 3 and image.dtype == np.uint8:
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 정규화 (0-1)
image = image.astype(np.float32) / 255.0
# 텐서로 변환 (B, C, H, W)
tensor = torch.from_numpy(image).permute(2, 0, 1).unsqueeze(0)
if self._fp16:
tensor = tensor.half()
return tensor.to(self._device)
def preprocess_mask(self, mask: Union[Image.Image, np.ndarray]) -> torch.Tensor:
"""마스크를 전처리합니다."""
if isinstance(mask, Image.Image):
mask = np.array(mask)
# 그레이스케일로 변환
if len(mask.shape) == 3:
mask = cv2.cvtColor(mask, cv2.COLOR_RGB2GRAY)
# 이진화 (0 또는 1)
mask = (mask > 127).astype(np.float32)
# 텐서로 변환 (B, 1, H, W)
tensor = torch.from_numpy(mask).unsqueeze(0).unsqueeze(0)
if self._fp16:
tensor = tensor.half()
return tensor.to(self._device)
def postprocess_result(self, tensor: torch.Tensor) -> np.ndarray:
"""결과를 후처리합니다."""
# CPU로 이동하고 numpy로 변환
if tensor.is_cuda:
tensor = tensor.cpu()
if tensor.dtype == torch.float16:
tensor = tensor.float()
result = tensor.squeeze(0).permute(1, 2, 0).numpy()
# 0-255 범위로 변환
result = np.clip(result * 255.0, 0, 255).astype(np.uint8)
return result
async def inpaint(
self,
images: List[np.ndarray],
masks: List[np.ndarray],
**kwargs,
) -> List[np.ndarray]:
if not self.loaded:
await self.load_model()
if not self.is_ready:
raise RuntimeError("SimpleLama model is not loaded yet.")
# 모델이 GPU에 있는지 확인
if self._device.type != 'cpu':
torch.cuda.empty_cache()
# 전처리
pil_images = [Image.fromarray(img) for img in images]
pil_masks = [Image.fromarray(mask) for mask in masks]
preprocessed_images = []
preprocessed_masks = []
for img, mask in zip(pil_images, pil_masks):
img_tensor, mask_tensor = self._preprocess(img, mask)
preprocessed_images.append(img_tensor)
preprocessed_masks.append(mask_tensor)
image_batch = torch.stack(preprocessed_images).to(self._device)
mask_batch = torch.stack(preprocessed_masks).to(self._device)
# 원본 이미지와 사이즈 저장
original_images_and_sizes = list(zip(pil_images, [img.size for img in pil_images]))
# 모델 호출
logger.info(f"실제 SimpleLama 모델로 {len(images)}개 이미지 인페인팅 수행")
with torch.no_grad():
# 라이브러리의 __call__ 대신 내부 torch 모델을 직접 호출
inpainted_batch = self._model.model(image_batch, mask_batch)
# 후처리
result_images = []
for i, inpainted_tensor in enumerate(inpainted_batch):
original_image, original_size = original_images_and_sizes[i]
original_mask = pil_masks[i]
result_pil = self._postprocess(inpainted_tensor, original_size, original_image, original_mask)
result_images.append(np.array(result_pil))
return result_images
def _preprocess(self, image: Image.Image, mask: Image.Image):
"""단일 이미지를 모델 입력 텐서로 전처리합니다."""
# simple_lama_inpainting.models.lama.py의 전처리 로직 참고
image = image.convert("RGB")
mask = mask.convert("L")
# 이미지 리사이즈 (모델 요구사항에 맞게)
resized_image = image.resize((512, 512), Image.Resampling.LANCZOS)
resized_mask = mask.resize((512, 512), Image.Resampling.NEAREST)
image_tensor = torch.from_numpy(np.array(resized_image, dtype=np.float32) / 255.0).permute(2, 0, 1).unsqueeze(0).squeeze(0)
mask_tensor = torch.from_numpy(np.array(resized_mask, dtype=np.float32) / 255.0).unsqueeze(0).unsqueeze(0).squeeze(0)
return image_tensor, mask_tensor
def _postprocess(self, tensor: torch.Tensor, original_size: Tuple[int, int], original_image: Image.Image, original_mask: Image.Image) -> Image.Image:
"""모델 출력 텐서를 PIL 이미지로 후처리하고 원본에 합성합니다."""
# 텐서를 PIL 이미지로 변환
result_np = tensor.permute(1, 2, 0).cpu().numpy()
result_np = np.clip(result_np * 255, 0, 255).astype(np.uint8)
inpainted_image_512 = Image.fromarray(result_np)
# 원본 크기로 리사이즈
resized_inpainted_image = inpainted_image_512.resize(original_size, Image.Resampling.LANCZOS)
# 원본 마스크를 사용하여 원본 이미지와 합성
original_mask = original_mask.convert("L")
final_image = Image.composite(resized_inpainted_image, original_image, original_mask)
return final_image
@property
def is_ready(self) -> bool:
return self._model is not None
def get_model_info(self) -> dict:
"""모델 정보를 반환합니다."""
return {
"model_type": "simple_lama",
"device": self._device,
"fp16": self._fp16,
"loaded": self.loaded,
"model_path": self.model_path
}

View File

@ -221,6 +221,73 @@ def fill_transparent_background_with_white(image: np.ndarray) -> np.ndarray:
return image return image
def preprocess_for_bria_rmbg(image: np.ndarray) -> np.ndarray:
"""
Bria RMBG 모델을 위한 전처리 (허깅페이스 공식 utilities.py 기반)
preprocessor_config.json:
- do_rescale: true, rescale_factor: 0.00392156862745098 (1/255)
- do_normalize: true, image_mean: [0.5, 0.5, 0.5], image_std: [1, 1, 1]
- do_resize: true, size: {"width": 1024, "height": 1024}
"""
# 그레이스케일 처리 (채널이 부족한 경우)
if len(image.shape) < 3:
image = image[:, :, np.newaxis]
# BGR to RGB 변환 (OpenCV는 BGR 순서)
if len(image.shape) == 3 and image.shape[2] >= 3:
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 1024x1024로 bilinear 리사이즈 후 uint8로 변환
image = cv2.resize(image, (1024, 1024), interpolation=cv2.INTER_LINEAR).astype(np.uint8)
# rescale: 0-255 -> 0-1 (rescale_factor = 1/255)
image = image.astype(np.float32) / 255.0
# normalize: (image - mean) / std
# mean=[0.5, 0.5, 0.5], std=[1.0, 1.0, 1.0]
image = (image - 0.5) / 1.0
# (H, W, C) -> (1, C, H, W) 변환 (배치 차원 추가 + 채널 우선)
image = np.transpose(image, (2, 0, 1)) # (C, H, W)
image = np.expand_dims(image, axis=0) # (1, C, H, W)
return image
def postprocess_for_bria_rmbg(result_tensor: np.ndarray, original_size: Tuple[int, int]) -> np.ndarray:
"""
Bria RMBG 모델 출력을 후처리 (허깅페이스 공식 utilities.py 기반)
torch 코드:
result = torch.squeeze(F.interpolate(result, size=im_size, mode='bilinear'), 0)
ma = torch.max(result)
mi = torch.min(result)
result = (result-mi)/(ma-mi)
im_array = (result*255).permute(1,2,0).cpu().data.numpy().astype(np.uint8)
"""
# (1, 1, H, W) -> (1, H, W) squeeze(0차원 제거)
result = np.squeeze(result_tensor, axis=0) # (1, H, W)
# bilinear interpolation으로 원본 크기 복원
# cv2.resize는 (W, H) 순서 주의
result = cv2.resize(result, (original_size[1], original_size[0]), interpolation=cv2.INTER_LINEAR)
# Min-max 정규화: (result-mi)/(ma-mi)
ma = result.max()
mi = result.min()
if ma > mi:
result = (result - mi) / (ma - mi)
else:
# 모든 값이 같은 경우 (드물지만 방어코드)
result = np.zeros_like(result)
# 0-255 범위로 변환 후 uint8
result = (result * 255).astype(np.uint8)
return result
def resize_image(image: np.ndarray, target_size: Tuple[int, int], keep_aspect: bool = True) -> np.ndarray: def resize_image(image: np.ndarray, target_size: Tuple[int, int], keep_aspect: bool = True) -> np.ndarray:
"""이미지 크기를 조정합니다.""" """이미지 크기를 조정합니다."""
try: try:

File diff suppressed because it is too large Load Diff

View File

@ -1,714 +1,48 @@
Failed to initialize jtop: The jtop.service is not active. Please run: Failed to initialize jtop: The jtop.service is not active. Please run:
sudo systemctl restart jtop.service sudo systemctl restart jtop.service
INFO: Started server process [81535] Traceback (most recent call last):
2025-08-30 02:10:05,479 - uvicorn.error - INFO - Started server process [81535] File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
INFO: Waiting for application startup. return _run_code(code, main_globals, None,
2025-08-30 02:10:05,500 - uvicorn.error - INFO - Waiting for application startup. File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
2025-08-30 02:10:05,518 - main - INFO - 🚀 인페인팅 서버 시작 중... exec(code, run_globals)
2025-08-30 02:10:05,519 - main - INFO - ✅ 공유 객체를 app.state에 저장 완료 File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/__main__.py", line 4, in <module>
2025-08-30 02:10:05,520 - main - INFO - 🔄 상태 저장 백그라운드 작업 생성 중... uvicorn.main()
2025-08-30 02:10:05,527 - main - INFO - ✅ 상태 저장 백그라운드 작업 생성 완료 File "/home/ckh08045/.local/lib/python3.8/site-packages/click/core.py", line 1161, in __call__
2025-08-30 02:10:05,529 - main - INFO - 🚀 세션 풀 초기화 (CUDA 자동 감지) return self.main(*args, **kwargs)
2025-08-30 02:10:05,529 - app.core.session_pool - INFO - Initializing dynamic session pools... File "/home/ckh08045/.local/lib/python3.8/site-packages/click/core.py", line 1082, in main
2025-08-30 02:10:05,530 - app.core.session_pool - INFO - Pre-loading 2 sessions for simple_lama rv = self.invoke(ctx)
2025-08-30 02:10:05,531 - main - INFO - 🔄 상태 저장 백그라운드 작업 시작됨 File "/home/ckh08045/.local/lib/python3.8/site-packages/click/core.py", line 1443, in invoke
2025-08-30 02:10:05,535 - app.core.session_pool - INFO - Creating new session simple_lama_0 for simple_lama... return ctx.invoke(self.callback, **ctx.params)
2025-08-30 02:10:09,061 - app.core.session_pool - INFO - Creating new session simple_lama_1 for simple_lama... File "/home/ckh08045/.local/lib/python3.8/site-packages/click/core.py", line 788, in invoke
2025-08-30 02:10:09,063 - app.models.simple_lama - INFO - Loading Simple LAMA model... return __callback(*args, **kwargs)
2025-08-30 02:10:13,365 - app.models.simple_lama - INFO - 실제 SimpleLama 모델 로딩 완료 File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/main.py", line 416, in main
2025-08-30 02:10:13,366 - app.models.simple_lama - INFO - Simple LAMA model loaded successfully run(
2025-08-30 02:10:13,367 - app.models.simple_lama - INFO - Loading Simple LAMA model... File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/main.py", line 587, in run
2025-08-30 02:10:15,170 - app.models.simple_lama - INFO - 실제 SimpleLama 모델 로딩 완료 server.run()
2025-08-30 02:10:15,171 - app.models.simple_lama - INFO - Simple LAMA model loaded successfully File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/server.py", line 61, in run
2025-08-30 02:10:15,173 - app.core.session_pool - INFO - Successfully created session simple_lama_0 return asyncio.run(self.serve(sockets=sockets))
2025-08-30 02:10:18,257 - app.core.session_pool - INFO - Session Created (simple_lama). Status -> simple_lama: 0, migan: 0, rembg: 0 | VRAM: 0.0/0.0 GB (25.5%) File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
2025-08-30 02:10:18,260 - app.core.session_pool - INFO - Successfully created session simple_lama_1 return loop.run_until_complete(main)
2025-08-30 02:10:21,351 - app.core.session_pool - INFO - Session Created (simple_lama). Status -> simple_lama: 0, migan: 0, rembg: 0 | VRAM: 0.0/0.0 GB (25.5%) File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete
2025-08-30 02:10:21,354 - app.core.session_pool - INFO - Pre-loading 2 sessions for migan File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/server.py", line 68, in serve
2025-08-30 02:10:21,360 - app.core.session_pool - INFO - Creating new session migan_0 for migan... config.load()
2025-08-30 02:10:21,463 - app.core.session_pool - INFO - Creating new session migan_1 for migan... File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/config.py", line 467, in load
2025-08-30 02:10:21,463 - app.models.migan - INFO - Loading MIGAN ONNX model... self.loaded_app = import_from_string(self.app)
2025-08-30 02:10:21,464 - app.models.migan - INFO - MIGAN ONNX 런타임 세션 생성 시도... File "/home/ckh08045/.local/lib/python3.8/site-packages/uvicorn/importer.py", line 21, in import_from_string
2025-08-30 02:10:21,464 - app.models.migan - INFO - MIGAN ONNX providers 설정: ['CUDAExecutionProvider', 'CPUExecutionProvider'] module = importlib.import_module(module_str)
2025-08-30 02:10:23.133477861 [W:onnxruntime:, transformer_memcpy.cc:74 ApplyImpl] 17 Memcpy nodes are added to the graph main_graph for CUDAExecutionProvider. It might have negative impact on performance (including unable to run CUDA graph). Set session_options.log_severity_level=1 to see the detail logs before this message. File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
2025-08-30 02:10:24,696 - app.models.migan - INFO - MIGAN ONNX 세션 생성 완료. Providers: ['CUDAExecutionProvider', 'CPUExecutionProvider'] return _bootstrap._gcd_import(name[level:], package, level)
2025-08-30 02:10:24,697 - app.models.migan - INFO - MIGAN ONNX model loaded successfully File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
2025-08-30 02:10:24,697 - app.models.migan - INFO - Loading MIGAN ONNX model... File "<frozen importlib._bootstrap>", line 991, in _find_and_load
2025-08-30 02:10:24,698 - app.models.migan - INFO - MIGAN ONNX 런타임 세션 생성 시도... File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
2025-08-30 02:10:24,698 - app.models.migan - INFO - MIGAN ONNX providers 설정: ['CUDAExecutionProvider', 'CPUExecutionProvider'] File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
2025-08-30 02:10:25.735198383 [W:onnxruntime:, transformer_memcpy.cc:74 ApplyImpl] 17 Memcpy nodes are added to the graph main_graph for CUDAExecutionProvider. It might have negative impact on performance (including unable to run CUDA graph). Set session_options.log_severity_level=1 to see the detail logs before this message. File "<frozen importlib._bootstrap_external>", line 848, in exec_module
2025-08-30 02:10:25,896 - app.models.migan - INFO - MIGAN ONNX 세션 생성 완료. Providers: ['CUDAExecutionProvider', 'CPUExecutionProvider'] File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
2025-08-30 02:10:25,897 - app.models.migan - INFO - MIGAN ONNX model loaded successfully File "/home/ckh08045/work/inpaintServer/main.py", line 17, in <module>
2025-08-30 02:10:25,897 - app.core.session_pool - INFO - Successfully created session migan_0 from app.core.worker_manager import worker_manager
2025-08-30 02:10:28,989 - app.core.session_pool - INFO - Session Created (migan). Status -> simple_lama: 2, migan: 0, rembg: 0 | VRAM: 0.0/0.0 GB (27.4%) File "/home/ckh08045/work/inpaintServer/app/core/worker_manager.py", line 18, in <module>
2025-08-30 02:10:28,992 - app.core.session_pool - INFO - Successfully created session migan_1 from ..core.session_pool import ModelType
2025-08-30 02:10:32,102 - app.core.session_pool - INFO - Session Created (migan). Status -> simple_lama: 2, migan: 0, rembg: 0 | VRAM: 0.0/0.0 GB (27.4%) File "/home/ckh08045/work/inpaintServer/app/core/session_pool.py", line 106
2025-08-30 02:10:32,109 - app.core.session_pool - INFO - Pre-loading 2 sessions for rembg else:
2025-08-30 02:10:32,111 - app.core.session_pool - INFO - Creating new session rembg_0 for rembg... ^
2025-08-30 02:10:32,118 - app.core.session_pool - INFO - Creating new session rembg_1 for rembg... SyntaxError: invalid syntax
2025-08-30 02:10:32,120 - app.models.rembg_model - INFO - Loading REMBG model (birefnet-general-lite)...
2025-08-30 02:10:34,236 - app.models.rembg_model - INFO - rembg 모듈 임포트 성공 (세션 생성은 지연 로딩)
2025-08-30 02:10:34,236 - app.models.rembg_model - INFO - 🔧 rembg 새 세션 생성 필요: birefnet-general-lite_cuda_True
2025-08-30 02:10:34,237 - app.models.rembg_model - WARNING - rembg.sessions import 실패, 기본 방식 사용
2025-08-30 02:10:34,237 - app.models.rembg_model - INFO - rembg 세션 생성 providers: ['CUDAExecutionProvider', 'CPUExecutionProvider']
2025-08-30 02:10:47,102 - app.models.rembg_model - INFO - ✅ rembg 'birefnet-general-lite' GPU 가속로 동작 (providers: ['CUDAExecutionProvider', 'CPUExecutionProvider'])
2025-08-30 02:10:47,103 - app.models.rembg_model - INFO - REMBG model (birefnet-general-lite) loaded successfully
2025-08-30 02:10:47,103 - app.models.rembg_model - INFO - Loading REMBG model (birefnet-general-lite)...
2025-08-30 02:10:47,104 - app.models.rembg_model - INFO - rembg 모듈 임포트 성공 (세션 생성은 지연 로딩)
2025-08-30 02:10:47,104 - app.models.rembg_model - INFO - 🔧 rembg 새 세션 생성 필요: birefnet-general-lite_cuda_True
2025-08-30 02:10:47,105 - app.models.rembg_model - WARNING - rembg.sessions import 실패, 기본 방식 사용
2025-08-30 02:10:47,105 - app.models.rembg_model - INFO - rembg 세션 생성 providers: ['CUDAExecutionProvider', 'CPUExecutionProvider']
2025-08-30 02:10:59,703 - app.models.rembg_model - INFO - ✅ rembg 'birefnet-general-lite' GPU 가속로 동작 (providers: ['CUDAExecutionProvider', 'CPUExecutionProvider'])
2025-08-30 02:10:59,704 - app.models.rembg_model - INFO - REMBG model (birefnet-general-lite) loaded successfully
2025-08-30 02:10:59,705 - app.core.session_pool - INFO - Successfully created session rembg_0
2025-08-30 02:11:02,815 - app.core.session_pool - INFO - Session Created (rembg). Status -> simple_lama: 2, migan: 2, rembg: 0 | VRAM: 0.0/0.0 GB (31.0%)
2025-08-30 02:11:02,817 - app.core.session_pool - INFO - Successfully created session rembg_1
2025-08-30 02:11:05,936 - app.core.session_pool - INFO - Session Created (rembg). Status -> simple_lama: 2, migan: 2, rembg: 0 | VRAM: 0.0/0.0 GB (31.0%)
2025-08-30 02:11:05,944 - app.core.session_pool - INFO - Session pools initialized successfully
2025-08-30 02:11:05,945 - main - INFO - ✅ 세션 풀 초기화 완료
2025-08-30 02:11:05,946 - app.core.worker_manager - INFO - Starting worker manager...
2025-08-30 02:11:05,949 - app.core.worker_manager - INFO - Worker manager started with 10 workers
2025-08-30 02:11:05,949 - main - INFO - ✅ 워커 매니저 시작 완료
2025-08-30 02:11:05,950 - app.core.batch_manager - INFO - Starting BatchManager...
2025-08-30 02:11:05,951 - app.core.batch_manager - INFO - BatchManager started successfully.
2025-08-30 02:11:05,951 - main - INFO - ✅ 배치 관리자 시작 완료
2025-08-30 02:11:05,952 - main - INFO - 🎉 인페인팅 서버 시작 완료!
2025-08-30 02:11:05,954 - app.utils.discord_notifier - WARNING - Discord 웹훅 URL이 설정되지 않아 알림을 보낼 수 없습니다.
2025-08-30 02:11:05,955 - app.core.session_pool - INFO - Idle session reaper started. Timeout: 1800s, Check Interval: 60s
INFO: Application startup complete.
2025-08-30 02:11:09,078 - uvicorn.error - INFO - Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8008 (Press CTRL+C to quit)
2025-08-30 02:11:09,089 - uvicorn.error - INFO - Uvicorn running on http://0.0.0.0:8008 (Press CTRL+C to quit)
INFO: 127.0.0.1:55558 - "GET /api/v1/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:55560 - "GET /api/v1/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:36726 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53708 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60012 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39570 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48768 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44610 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44116 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45482 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53298 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55100 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35256 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55510 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59790 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51514 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38750 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54862 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46646 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46656 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36272 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41276 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41282 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57580 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58304 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35488 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51250 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51262 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34784 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34788 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53174 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37074 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42532 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37912 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50782 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41282 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50348 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50614 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50620 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39554 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34472 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59332 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38170 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54408 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53164 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57394 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57410 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59078 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54256 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54262 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38444 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52920 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56504 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52406 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52412 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48756 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48766 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34636 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38454 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38934 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41628 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49770 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45282 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55420 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51390 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51404 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43614 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41008 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38196 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40018 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34270 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49372 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50038 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34036 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49796 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49812 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49718 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60908 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48864 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41666 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41674 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35000 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35008 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51984 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57428 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53860 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42404 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46700 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38100 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58730 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54074 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54088 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60366 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50934 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34926 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36874 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46600 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36062 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49560 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55354 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55364 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36702 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36706 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56446 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44762 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60008 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48852 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37748 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41326 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57200 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57872 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54214 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53410 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53424 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49892 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58442 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54808 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37762 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34838 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42518 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56664 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55072 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55076 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53762 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53766 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44150 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39358 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34764 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52880 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52830 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40018 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40024 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55202 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:32946 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55182 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37200 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51956 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52210 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52270 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52286 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51302 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51870 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46236 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59736 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57162 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37400 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51362 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44042 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44048 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49412 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49420 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41564 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41144 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47504 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58604 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38794 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36922 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57216 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57228 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39264 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55712 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59114 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57248 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39214 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39044 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33986 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40552 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40566 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45808 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34042 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54826 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38828 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57722 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56354 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36156 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36172 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56848 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56852 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39782 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46406 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58570 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42250 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48538 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51426 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38244 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58658 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58670 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41604 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52434 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57418 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41572 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53532 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56000 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56002 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41946 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49050 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34028 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49268 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40244 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49940 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49078 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49084 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35546 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35558 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46570 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44484 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56582 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43298 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59146 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50534 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51420 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51428 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46468 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51714 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44818 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46466 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54190 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57976 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47458 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47460 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45636 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46196 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33720 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58076 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46556 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49560 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48194 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36244 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42566 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46464 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36450 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58426 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60808 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51264 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53754 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53760 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56466 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34046 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58062 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46402 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39300 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33604 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54546 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54558 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43954 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43090 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56094 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47164 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53334 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58630 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48202 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33170 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50170 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48892 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48908 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40656 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58154 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46266 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33478 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37912 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53664 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53670 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59390 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41774 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57860 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56684 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38300 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45304 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60212 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60218 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46100 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49412 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44778 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36804 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55340 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37518 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58284 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60668 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57058 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45546 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45558 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56180 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43278 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57874 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50746 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41260 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33382 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34948 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34954 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49512 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51068 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49218 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33938 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57462 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48304 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47720 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47728 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37714 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59332 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59462 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45800 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57226 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35846 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43320 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37916 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49008 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36094 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36102 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59426 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44388 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41486 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49612 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57146 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39740 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46790 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46806 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47512 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43230 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53444 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34750 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39048 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52468 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48852 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48858 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48968 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44402 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51234 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51056 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41206 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46510 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38972 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51590 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35024 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52200 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52208 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36938 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46024 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35716 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42378 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54166 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54818 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53232 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53242 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40904 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41318 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51176 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34610 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52708 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54058 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42420 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42430 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33804 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39280 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53676 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53852 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36042 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54014 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53332 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36310 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35844 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40956 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40958 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51246 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39372 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34540 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36790 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58782 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37654 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51844 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58414 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58422 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34146 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52790 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46204 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37636 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37514 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53850 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51390 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46964 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57018 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39958 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56264 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40098 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47772 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53578 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50904 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50920 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34566 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49614 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46572 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42564 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44410 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46446 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55604 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55618 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43974 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42664 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51384 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58138 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47250 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41730 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36338 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45778 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34104 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56318 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33730 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37716 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39452 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48850 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48862 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53762 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55588 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58852 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49540 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40432 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58414 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58420 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54126 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50882 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33572 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53080 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56496 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46126 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56566 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33288 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33302 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37186 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37200 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35882 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58422 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51442 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54204 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56894 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52896 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42498 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58940 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58952 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58500 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44118 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54404 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51042 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53054 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46934 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46936 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:32962 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60000 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59632 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44440 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54052 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47242 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33616 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53566 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53580 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59032 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59046 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35516 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49068 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59348 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60702 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52170 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53048 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51518 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42688 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42702 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34804 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58830 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55590 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52850 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46674 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44804 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50896 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50902 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47388 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51336 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59850 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54708 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45978 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39996 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60744 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60760 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53322 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60648 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60662 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44348 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55794 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37678 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44958 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60594 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46264 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46274 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54158 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59522 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50704 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:41394 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47508 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33236 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45186 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45196 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35298 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57424 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43936 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42858 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39752 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39768 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45450 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:50728 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38352 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58312 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58326 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36000 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54230 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39140 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39142 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44058 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39486 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44454 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53372 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60494 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56938 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38902 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38904 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43862 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57190 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53756 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51948 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44778 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55164 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55172 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59020 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43922 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58468 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43172 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56638 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55948 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51100 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51108 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35720 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33594 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42922 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39192 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43232 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33170 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:40822 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34828 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34832 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38958 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:39294 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:57880 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34898 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47888 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60396 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59788 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59798 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35144 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35152 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54856 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33396 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48818 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36082 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54950 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48766 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:54512 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51576 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51580 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58962 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:51596 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:37646 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53158 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56512 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48684 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48696 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:52286 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45882 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43724 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55154 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:48194 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:47442 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58936 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58944 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:56704 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34814 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:43998 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:58974 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46332 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:46342 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49574 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60054 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60058 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45212 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:44924 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:38724 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:34390 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:53224 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36312 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:49726 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:59784 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35516 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35518 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:42052 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:60820 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:45948 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:36840 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33870 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:33872 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:35052 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: 127.0.0.1:55622 - "GET /api/v1/stats HTTP/1.1" 200 OK
INFO: Shutting down
2025-08-30 10:43:07,827 - uvicorn.error - INFO - Shutting down
INFO: Waiting for application shutdown.
2025-08-30 10:43:07,929 - uvicorn.error - INFO - Waiting for application shutdown.
2025-08-30 10:43:07,931 - main - INFO - 🛑 인페인팅 서버 종료 중...
2025-08-30 10:43:07,931 - app.core.worker_manager - INFO - Stopping worker manager...
2025-08-30 10:43:07,932 - app.core.worker_manager - INFO - Worker manager stopped
2025-08-30 10:43:07,932 - main - INFO - ✅ 워커 매니저 중지 완료
2025-08-30 10:43:07,933 - app.core.batch_manager - INFO - Stopping BatchManager...
2025-08-30 10:43:07,933 - app.core.batch_manager - INFO - BatchManager stopped.
2025-08-30 10:43:07,934 - main - INFO - ✅ 배치 관리자 중지 완료
2025-08-30 10:43:07,934 - main - INFO - 👋 인페인팅 서버 종료 완료
2025-08-30 10:43:07,936 - app.utils.discord_notifier - WARNING - Discord 웹훅 URL이 설정되지 않아 알림을 보낼 수 없습니다.
INFO: Application shutdown complete.
2025-08-30 10:43:07,936 - uvicorn.error - INFO - Application shutdown complete.
INFO: Finished server process [81535]
2025-08-30 10:43:07,937 - uvicorn.error - INFO - Finished server process [81535]

View File

@ -1 +1 @@
81535 841903

View File

@ -1,722 +1,18 @@
Failed to initialize jtop: The jtop.service is not active. Please run: Failed to initialize jtop: The jtop.service is not active. Please run:
sudo systemctl restart jtop.service sudo systemctl restart jtop.service
INFO: Started server process [81928] INFO: Started server process [840568]
INFO: Waiting for application startup. INFO: Waiting for application startup.
Fan control not available Fan control not available
INFO: Application startup complete. INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8888 (Press CTRL+C to quit) INFO: Uvicorn running on http://0.0.0.0:8888 (Press CTRL+C to quit)
INFO: 127.0.0.1:52212 - "GET /api/simple HTTP/1.1" 200 OK INFO: 127.0.0.1:57182 - "GET /api/simple HTTP/1.1" 200 OK
Task exception was never retrieved Task exception was never retrieved
future: <Task finished name='Task-4' coro=<health_check_and_restart() done, defined at /home/ckh08045/work/inpaintServer/app/monitoring/dashboard.py:2084> exception=AttributeError("module 'asyncio' has no attribute 'to_thread'")> future: <Task finished name='Task-4' coro=<health_check_and_restart() done, defined at /home/ckh08045/work/inpaintServer/app/monitoring/dashboard.py:2084> exception=AttributeError("module 'asyncio' has no attribute 'to_thread'")>
Traceback (most recent call last): Traceback (most recent call last):
File "/home/ckh08045/work/inpaintServer/app/monitoring/dashboard.py", line 2094, in health_check_and_restart File "/home/ckh08045/work/inpaintServer/app/monitoring/dashboard.py", line 2094, in health_check_and_restart
response = await asyncio.to_thread(requests.get, health_url, timeout=10) response = await asyncio.to_thread(requests.get, health_url, timeout=10)
AttributeError: module 'asyncio' has no attribute 'to_thread' AttributeError: module 'asyncio' has no attribute 'to_thread'
INFO: 192.168.0.119:51988 - "GET / HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 51999) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:51988 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:51989 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52012 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52013 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52012 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52013 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52012 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52058 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52061 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 52068) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:52013 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: connection closed
INFO: connection open
INFO: 192.168.0.119:52071 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52073 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52012 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52061 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52058 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52071 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52073 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52071 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52073 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52071 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52322 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52323 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: connection closed
INFO: ('192.168.0.119', 52269) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:52513 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52514 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52513 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52325 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: connection closed
INFO: ('192.168.0.119', 52540) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:52650 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52651 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52651 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52650 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52736 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52739 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52970 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:52986 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:52988 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:52989 - "GET /api/performance-stats HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 53024) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:53198 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:53207 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53212 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53215 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 53256) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:53408 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:53411 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53422 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53423 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:53657 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:53666 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53671 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53672 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 53746) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:53957 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:53971 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53975 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:53977 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 54029) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:54315 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:54323 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54325 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54326 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:54569 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:54570 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54571 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54572 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:54867 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:54872 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54875 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:54876 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55108 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55110 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55111 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55112 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 55157) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:55384 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55394 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55402 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55401 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55632 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55637 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55644 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55647 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55866 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55868 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55869 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55872 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55866 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55868 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55869 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55866 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55868 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55920 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55869 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:55920 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: 192.168.0.119:55977 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55978 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: connection closed
INFO: ('192.168.0.119', 55986) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:55920 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55977 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:55978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:56048 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:56049 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55920 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:55978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:56048 - "GET /api/performance-stats HTTP/1.1" 200 OK
모델 성능 통계 조회 중 예외 발생: HTTPConnectionPool(host='0.0.0.0', port=8008): Read timed out. (read timeout=2)
INFO: 192.168.0.119:56074 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:56226 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56227 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:56228 - "GET /api/performance-stats HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 56285) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:56468 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:56470 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56472 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56473 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:56638 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:56642 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56647 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56648 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 56673) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:56843 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:56853 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56855 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:56856 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 56941) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:57020 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57033 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57036 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57037 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 57083) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:57222 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57227 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57242 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57241 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:57414 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57425 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57427 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57428 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 57457) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:57548 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57550 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57554 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57557 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 57571) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:57670 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57674 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57686 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57685 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:57797 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57810 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57812 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57816 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 57833) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:57981 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:57983 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57985 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:57986 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58003) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:58136 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58140 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58147 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58149 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58168) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:58234 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58245 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58247 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58248 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:58397 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58399 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58402 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58403 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58426) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:58508 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58515 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58519 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58520 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58533) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:58619 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58630 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58632 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58633 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58663) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:58767 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58775 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58781 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58782 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:58950 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:58952 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58955 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:58956 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 58962) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:59068 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59069 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59070 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59071 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59068 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59069 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59070 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59146 - "GET /api/performance-stats HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 59139) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:59068 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59069 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: connection open
INFO: 192.168.0.119:59068 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59146 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59070 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59069 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59070 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59192 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59253 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59277 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 59272) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:59298 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59416 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59425 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59432 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59433 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59547 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59554 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59561 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59563 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:59686 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59697 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59702 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59705 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 59726) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:59836 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59840 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59850 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59851 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 59899) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:59994 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:59996 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59998 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:59999 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:60154 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60159 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60165 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60166 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 60185) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:60299 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60312 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60314 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60315 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 60341) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:60441 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60447 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60448 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60443 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 60460) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:60580 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60581 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60567 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60582 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:60731 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60744 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60746 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60747 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 60758) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:60899 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:60901 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60906 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:60905 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 60919) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:60998 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61003 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61015 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61020 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61048) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:61170 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61185 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61176 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61188 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:61282 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61287 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61294 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61298 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61318) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:61398 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61412 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61416 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61417 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61433) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:61544 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61551 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61554 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61555 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61572) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:61651 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61653 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61657 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61663 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:61768 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61783 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61789 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61790 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61805) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:61916 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:61922 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61923 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:61926 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 61949) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:62081 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62085 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62096 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62097 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 62132) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:62182 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62191 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62197 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62198 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62313 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62321 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62327 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62328 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 62363) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:62520 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62530 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62533 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62534 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 62565) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:62682 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62684 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62695 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62697 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 62737) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:62862 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62870 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62874 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62873 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62873 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62874 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62870 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62862 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62870 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62874 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62873 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62862 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62873 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62874 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 62961) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:62873 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: connection closed
INFO: connection open
INFO: 192.168.0.119:62874 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:62959 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62873 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62959 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:63029 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63045 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:62959 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:62959 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:63045 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63029 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63047 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: connection closed
INFO: ('192.168.0.119', 63184) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:63249 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63261 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63263 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63264 - "GET /api/system-alerts HTTP/1.1" 200 OK
모델 성능 통계 조회 중 예외 발생: HTTPConnectionPool(host='0.0.0.0', port=8008): Read timed out. (read timeout=2)
INFO: 192.168.0.119:63451 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63457 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63462 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63468 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:63665 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63674 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63681 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63683 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 63710) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:63832 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63838 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63843 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:63845 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 63889) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:63991 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:63998 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64006 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64007 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:64138 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64142 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64149 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64150 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64164) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:64278 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64287 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64289 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64290 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64316) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:64504 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64505 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64510 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64511 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64519) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:64589 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64600 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64604 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64606 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:64659 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64669 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64676 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64677 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64691) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:64715 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64719 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64726 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64731 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64756) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:64864 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:64877 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64879 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:64880 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 64913) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:65047 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:65049 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65057 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65059 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65179 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:65183 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65184 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65185 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65179 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:65183 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: ('192.168.0.119', 65209) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:65184 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: connection open
INFO: 192.168.0.119:65183 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65243 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65179 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65243 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:65183 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65184 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65179 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65184 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65179 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 65278) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:65179 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:65184 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: connection open
INFO: 192.168.0.119:65283 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65340 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65341 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65341 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65340 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65385 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:65399 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:65406 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49190 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49194 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49203 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49204 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 49159) - "WebSocket /ws" [accepted]
INFO: connection closed
INFO: connection closed
INFO: connection open
INFO: ('192.168.0.119', 49234) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:49288 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49303 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49304 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49300 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49413 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49417 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49423 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49433 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49659 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49660 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49661 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49662 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49756 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49757 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49758 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49759 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 49772) - "WebSocket /ws" [accepted]
브로드캐스트 오류: list.remove(x): x not in list
INFO: connection closed
INFO: connection open
INFO: 192.168.0.119:49841 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49848 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49854 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49857 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49976 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49977 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49983 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 49988) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:49976 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49977 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49983 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: connection closed
브로드캐스트 오류: list.remove(x): x not in list
INFO: 192.168.0.119:49976 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49977 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49983 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:50180 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:50181 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49976 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49977 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49983 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 50202) - "WebSocket /ws" [accepted]
INFO: 192.168.0.119:50181 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49983 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:49977 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: connection open
INFO: 192.168.0.119:50181 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:49978 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: 192.168.0.119:50398 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:50403 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:50398 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:50403 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:50578 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:50590 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: ('192.168.0.119', 50526) - "WebSocket /ws" [accepted]
INFO: connection closed
INFO: connection open
INFO: connection closed
INFO: 192.168.0.119:50610 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:50611 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 50740) - "WebSocket /ws" [accepted]
INFO: connection closed
INFO: 192.168.0.119:50831 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:50832 - "GET /api/system-alerts HTTP/1.1" 200 OK
브로드캐스트 오류: list.remove(x): x not in list
INFO: 192.168.0.119:50832 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:50831 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51080 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51083 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 51048) - "WebSocket /ws" [accepted]
INFO: connection closed
INFO: connection closed
브로드캐스트 오류: list.remove(x): x not in list
INFO: 192.168.0.119:51187 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:51194 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51205 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51206 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: ('192.168.0.119', 51170) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: ('192.168.0.119', 51368) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: 192.168.0.119:51464 - "GET /api/logs?lines=50 HTTP/1.1" 200 OK
INFO: 192.168.0.119:51468 - "GET /api/performance-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51469 - "GET /api/model-usage-stats HTTP/1.1" 200 OK
INFO: 192.168.0.119:51470 - "GET /api/system-alerts HTTP/1.1" 200 OK
INFO: connection closed
INFO: connection closed
INFO: connection closed
INFO: Shutting down INFO: Shutting down
INFO: Waiting for application shutdown. INFO: Waiting for application shutdown.
INFO: Application shutdown complete. INFO: Application shutdown complete.
INFO: Finished server process [81928] INFO: Finished server process [840568]

View File

@ -1 +1 @@
81928 840568

View File

@ -1,14 +0,0 @@
Collecting fastapi==0.104.1 (from -r requirements.txt (line 1))
Using cached fastapi-0.104.1-py3-none-any.whl.metadata (24 kB)
Collecting uvicorn==0.24.0 (from uvicorn[standard]==0.24.0->-r requirements.txt (line 2))
Using cached uvicorn-0.24.0-py3-none-any.whl.metadata (6.4 kB)
Collecting python-multipart==0.0.6 (from -r requirements.txt (line 3))
Using cached python_multipart-0.0.6-py3-none-any.whl.metadata (2.5 kB)
Collecting pillow==10.0.1 (from -r requirements.txt (line 4))
Using cached Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl.metadata (9.5 kB)
Collecting numpy==1.24.3 (from -r requirements.txt (line 5))
Using cached numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.metadata (5.6 kB)
Collecting opencv-python==4.8.1.78 (from -r requirements.txt (line 6))
Using cached opencv_python-4.8.1.78-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.metadata (19 kB)
ERROR: Could not find a version that satisfies the requirement torch==2.0.1+cu118 (from versions: 1.8.0, 1.8.1, 1.9.0, 1.10.0, 1.10.1, 1.10.2, 1.11.0, 1.12.0, 1.12.1, 1.13.0, 1.13.1, 2.0.0, 2.0.1, 2.1.0, 2.1.1, 2.1.2, 2.2.0, 2.2.1, 2.2.2, 2.3.0, 2.3.1, 2.4.0, 2.4.1)
ERROR: No matching distribution found for torch==2.0.1+cu118

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -35,3 +35,9 @@ nvidia-ml-py3==7.352.0
# onnxruntime-gpu==1.17.0 # Jetson용 휠 파일로 수동 설치 # onnxruntime-gpu==1.17.0 # Jetson용 휠 파일로 수동 설치
#onnxruntime==1.19.2 # CPU 전용 (Jetson에서는 GPU 휠로 교체됨) #onnxruntime==1.19.2 # CPU 전용 (Jetson에서는 GPU 휠로 교체됨)
tensorflow-gpu==2.13.0 tensorflow-gpu==2.13.0
scikit-image
torchvision
huggingface-hub
# For Jetson
# jetson-stats

View File

@ -6,70 +6,70 @@
"workers_by_status": { "workers_by_status": {
"idle": [ "idle": [
{ {
"id": "worker_1cb20176", "id": "worker_f70b814c",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_275875fe", "id": "worker_7ef5e684",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_22db34f9", "id": "worker_63d0f5bb",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_bc8befaf", "id": "worker_9b7b1de3",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_d801fb26", "id": "worker_7952c8ab",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_6afb49c9", "id": "worker_7af356b5",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_0b612d23", "id": "worker_156f8680",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_02e18c3d", "id": "worker_e9ca4545",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_0e6ebed3", "id": "worker_ad1a8fc2",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
"last_task_at": null "last_task_at": null
}, },
{ {
"id": "worker_bee8c543", "id": "worker_3a52ecf2",
"status": "idle", "status": "idle",
"task_count": 0, "task_count": 0,
"error_count": 0, "error_count": 0,
@ -106,38 +106,38 @@
} }
}, },
"api_stats": { "api_stats": {
"total_requests": 618, "total_requests": 7,
"successful_requests": 618, "successful_requests": 7,
"failed_requests": 0, "failed_requests": 0,
"success_rate": 100.0, "success_rate": 100.0,
"endpoint_usage": { "endpoint_usage": {
"GET /api/v1/health": 2, "GET /api/v1/health": 2,
"GET /api/v1/stats": 616 "POST /api/v1/remove_bg": 5
}, },
"endpoint_stats": { "endpoint_stats": {
"GET /api/v1/health": { "GET /api/v1/health": {
"count": 2, "count": 2,
"avg_time": 0.0027375221252441406, "avg_time": 0.0023573637008666992,
"min_time": 0.0012462139129638672, "min_time": 0.0011353492736816406,
"max_time": 0.004228830337524414, "max_time": 0.003579378128051758,
"current_concurrent": 0 "current_concurrent": 0
}, },
"GET /api/v1/stats": { "POST /api/v1/remove_bg": {
"count": 616, "count": 5,
"avg_time": 0.0031845998764038087, "avg_time": 15.194099569320679,
"min_time": 0.0010221004486083984, "min_time": 0.29595065116882324,
"max_time": 0.006818532943725586, "max_time": 74.70842432975769,
"current_concurrent": 0 "current_concurrent": 0
} }
}, },
"average_response_time": 0.00322497431128542, "average_response_time": 10.853601796286446,
"min_response_time": 0.0010221004486083984, "min_response_time": 0.0011353492736816406,
"max_response_time": 0.011610746383666992, "max_response_time": 74.70842432975769,
"current_concurrent": 0, "current_concurrent": 0,
"max_concurrent": 1, "max_concurrent": 1,
"requests_per_second": 0.020076686834362673, "requests_per_second": 0.019528829012151992,
"uptime": 30781.97140288353, "uptime": 358.4444308280945,
"recent_errors": [] "recent_errors": []
}, },
"timestamp": 1756518187.4218173 "timestamp": 1756730843.4636421
} }

2
te.py Normal file
View File

@ -0,0 +1,2 @@
import tensorrt as trt
print(trt.__version__)

BIN
tests/rembg_test/123.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
tests/rembg_test/456.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

BIN
tests/rembg_test/image.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

BIN
tests/test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

117
tests/test_rembg_onnx.py Normal file
View File

@ -0,0 +1,117 @@
import requests
import base64
import time
import os
from PIL import Image
from io import BytesIO
# --- 설정 ---
SERVER_URL = "http://127.0.0.1:8008/api/v1/remove_bg"
IMAGE_PATH = "tests/rembg_test/456.webp"
OUTPUT_PATH = "tests/rembg_test/output_bria.png"
NUM_TESTS = 5
# --- 테스트 준비 ---
def image_to_base64(filepath):
""" 이미지를 읽어 base64로 인코딩합니다. """
try:
with Image.open(filepath) as img:
# RGBA를 가질 수 있는 경우 RGB로 변환하여 데이터 일관성 확보
if img.mode == 'RGBA':
img = img.convert('RGB')
buffered = BytesIO()
img.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode("utf-8")
except FileNotFoundError:
print(f"오류: 테스트 이미지 파일을 찾을 수 없습니다 - {filepath}")
return None
except Exception as e:
print(f"오류: 이미지 처리 중 문제 발생 - {e}")
return None
def save_base64_image(base64_string, filepath):
""" base64 문자열을 이미지 파일로 저장합니다. """
try:
os.makedirs(os.path.dirname(filepath), exist_ok=True)
img_data = base64.b64decode(base64_string)
with open(filepath, 'wb') as f:
f.write(img_data)
print(f"✅ 결과 이미지가 '{filepath}'에 저장되었습니다.")
except Exception as e:
print(f"오류: 결과 이미지 저장 실패 - {e}")
# --- 테스트 실행 ---
if __name__ == "__main__":
print("--- Bria RMBG ONNX 모델 배경 제거 테스트 시작 ---")
# 1. 이미지 인코딩
print(f"테스트 이미지 로딩: {IMAGE_PATH}")
b64_image = image_to_base64(IMAGE_PATH)
if not b64_image:
exit()
# 2. API 요청 및 시간 측정
timings = []
last_response_image = None
for i in range(NUM_TESTS):
print(f"[{i+1}/{NUM_TESTS}] 요청 전송 중...", end=" ", flush=True)
payload = {
"image": b64_image,
}
try:
start_time = time.perf_counter()
response = requests.post(SERVER_URL, json=payload, params={"response_format": "base64", "image_format": "png"})
end_time = time.perf_counter()
duration = (end_time - start_time) * 1000 # ms 단위로 변환
timings.append(duration)
response.raise_for_status()
response_data = response.json()
last_response_image = response_data.get("image")
if i == 0:
print(f"성공! (Cold Start): {duration:.2f} ms")
else:
print(f"성공!: {duration:.2f} ms")
except requests.exceptions.RequestException as e:
print(f"실패. API 요청 오류: {e}")
if hasattr(e, 'response') and e.response is not None:
print("서버 응답:", e.response.text)
break
except Exception as e:
print(f"실패. 예상치 못한 오류: {e}")
break
# 3. 결과 분석 및 저장
if timings:
print("\n--- 테스트 결과 분석 ---")
print(f"총 요청 횟수: {len(timings)}")
if timings:
print(f"첫 요청 시간 (Cold Start): {timings[0]:.2f} ms")
if len(timings) > 1:
warm_timings = timings[1:]
avg_warm_time = sum(warm_timings) / len(warm_timings)
min_warm_time = min(warm_timings)
max_warm_time = max(warm_timings)
print(f"안정화된 추론 시간 (평균): {avg_warm_time:.2f} ms")
print(f"안정화된 추론 시간 (최소): {min_warm_time:.2f} ms")
print(f"안정화된 추론 시간 (최대): {max_warm_time:.2f} ms")
if last_response_image:
save_base64_image(last_response_image, OUTPUT_PATH)
else:
print("오류: 마지막 요청에서 이미지를 받지 못해 결과 파일을 저장할 수 없습니다.")
else:
print("\n테스트가 실행되지 않았습니다.")
print("\n--- 테스트 종료 ---")
print(" 서버 VRAM 사용량 및 모델 로딩 시간은 'main_server.log'를 확인해주세요.")