이미지 경로 변경 및 MIGAN 전용 마스크 생성 로직 추가. ROI 최적화 관련 설정을 완전히 폐기하고 성능 개선을 위한 cuDNN 최적화 설정 강화. 전체적인 코드 정리 및 주석 보강.

This commit is contained in:
7600M 2025-10-04 13:30:18 +09:00
parent baf63e2a02
commit aefbc73a24
11 changed files with 2146 additions and 64 deletions

View File

@ -0,0 +1,293 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
동적 세션풀 관리 기반 Worker 테스트 스크립트
- GPU 메모리 자동 감지 최적 세션풀 구성
- LAMA:MIGAN 비율 커스터마이징
- 실시간 메모리 모니터링
"""
import os
import sys
import asyncio
import time
import pathlib
import logging
from typing import Dict, Any, Optional, Tuple
# Add parent directory to sys.path to import worker modules
CURRENT_DIR = pathlib.Path(__file__).parent.absolute()
ROOT_DIR = CURRENT_DIR.parent
sys.path.insert(0, str(ROOT_DIR))
from worker.dynamic_session_pool_manager import (
get_optimal_session_config,
session_pool_manager,
print_config_summary,
SessionPoolConfig
)
# 로깅 설정
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def test_gpu_detection():
"""GPU 감지 테스트"""
print("🔍 GPU 자동 감지 테스트...")
try:
memory_info = session_pool_manager.detect_gpu_info()
print(f"✅ GPU 감지 성공!")
print(f" 이름: {memory_info.gpu_name}")
print(f" 등급: {memory_info.gpu_tier.value}")
print(f" VRAM: {memory_info.total_vram_mb}MB (사용가능: {memory_info.available_vram_mb}MB)")
print(f" CUDA: {memory_info.cuda_capability}")
print(f" FP16: {memory_info.supports_fp16}")
print(f" TensorCores: {memory_info.supports_tensor_cores}")
return memory_info
except Exception as e:
print(f"❌ GPU 감지 실패: {e}")
return None
def test_optimal_configs():
"""다양한 비율로 최적 구성 테스트"""
print("\n🎯 최적 세션풀 구성 테스트...")
test_configs = [
{
"name": "기본 구성 (GPU별 최적화)",
"lama_migan_ratio": None,
"worker_session_ratio": None
},
{
"name": "4:6 비율 (RTX 4080 권장)",
"lama_migan_ratio": (4, 6),
"worker_session_ratio": 3.0
},
{
"name": "3:7 비율 (RTX 3090 권장)",
"lama_migan_ratio": (3, 7),
"worker_session_ratio": 3.0
},
{
"name": "5:5 균형 구성",
"lama_migan_ratio": (5, 5),
"worker_session_ratio": 3.5
},
{
"name": "보수적 구성 (LAMA 중심)",
"lama_migan_ratio": (7, 3),
"worker_session_ratio": 4.0
}
]
results = []
for test_config in test_configs:
try:
print(f"\n📋 {test_config['name']} 테스트...")
config = get_optimal_session_config(
lama_migan_ratio=test_config['lama_migan_ratio'],
worker_session_ratio=test_config['worker_session_ratio']
)
results.append((test_config['name'], config))
print(f" ✅ 성공!")
print(f" 세션풀: MIGAN {config.migan_sessions}개, LAMA {config.lama_sessions}개, OCR {config.ocr_sessions}")
print(f" 워커: {config.workers}")
print(f" 비율: {config.lama_migan_ratio}, 워커:세션 = {config.worker_session_ratio:.1f}:1")
print(f" 메모리: {config.total_vram_usage_mb}MB, 여유: {config.safety_margin_mb}MB")
print(f" 예상 클라이언트: {config.expected_concurrent_clients}")
except Exception as e:
print(f" ❌ 실패: {e}")
return results
def test_memory_monitoring():
"""메모리 모니터링 테스트"""
print("\n📊 메모리 모니터링 테스트...")
try:
# 현재 메모리 상태
memory_status = session_pool_manager.get_current_memory_status()
if "error" in memory_status:
print(f"❌ 메모리 상태 확인 실패: {memory_status['error']}")
return
print(f"✅ 현재 메모리 상태:")
print(f" 할당된 메모리: {memory_status['allocated_mb']}MB")
print(f" 예약된 메모리: {memory_status['reserved_mb']}MB")
print(f" 전체 메모리: {memory_status['total_mb']}MB")
print(f" 사용 가능: {memory_status['free_mb']}MB")
print(f" 사용률: {memory_status['utilization_pct']}%")
# 모니터링 및 조정 테스트
adjusted = session_pool_manager.monitor_and_adjust()
if adjusted:
print("⚠️ 메모리 조정이 수행되었습니다")
else:
print("✅ 메모리 상태 정상")
except Exception as e:
print(f"❌ 메모리 모니터링 실패: {e}")
def generate_production_config(lama_migan_ratio: Tuple[int, int] = (4, 6),
worker_session_ratio: float = 3.0) -> Dict[str, Any]:
"""프로덕션용 설정 생성"""
try:
config = get_optimal_session_config(
lama_migan_ratio=lama_migan_ratio,
worker_session_ratio=worker_session_ratio
)
memory_info = session_pool_manager._memory_info
production_config = {
# GPU 정보
"gpu_info": {
"name": memory_info.gpu_name,
"tier": memory_info.gpu_tier.value,
"total_vram_mb": memory_info.total_vram_mb,
"available_vram_mb": memory_info.available_vram_mb,
"supports_fp16": memory_info.supports_fp16,
"supports_tensor_cores": memory_info.supports_tensor_cores,
},
# 세션풀 설정
"session_pools": {
"migan": {
"count": config.migan_sessions,
"memory_per_session_mb": 1200,
"total_memory_mb": config.migan_sessions * 1200
},
"lama": {
"count": config.lama_sessions,
"memory_per_session_mb": 500,
"total_memory_mb": config.lama_sessions * 500
},
"ocr": {
"count": config.ocr_sessions,
"memory_per_session_mb": 400,
"total_memory_mb": config.ocr_sessions * 400
}
},
# 워커 설정
"workers": {
"count": config.workers,
"worker_session_ratio": config.worker_session_ratio
},
# 성능 예측
"performance": {
"lama_migan_ratio": config.lama_migan_ratio,
"expected_concurrent_clients": config.expected_concurrent_clients,
"estimated_response_time_seconds": "1.2-2.5",
"peak_throughput_req_per_sec": "20-35"
},
# 메모리 사용량
"memory_usage": {
"total_usage_mb": config.total_vram_usage_mb,
"safety_margin_mb": config.safety_margin_mb,
"utilization_percent": round(config.total_vram_usage_mb / memory_info.total_vram_mb * 100, 1)
},
# 라우팅 전략
"routing_strategy": {
"simple_images": "migan",
"complex_images": "lama",
"adjacent_textbox_threshold": 3,
"text_density_threshold": 0.3
}
}
return production_config
except Exception as e:
logger.error(f"프로덕션 설정 생성 실패: {e}")
return {}
def save_production_config(config: Dict[str, Any], filename: str = "production_config.json"):
"""프로덕션 설정을 JSON 파일로 저장"""
import json
try:
config_path = CURRENT_DIR / filename
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print(f"✅ 프로덕션 설정 저장 완료: {config_path}")
except Exception as e:
print(f"❌ 설정 저장 실패: {e}")
def main():
"""메인 테스트 실행"""
print("🚀 동적 세션풀 관리 테스트 시작")
print("=" * 50)
# 1. GPU 감지
memory_info = test_gpu_detection()
if not memory_info:
print("❌ GPU 감지 실패로 테스트 중단")
return
# 2. 다양한 구성 테스트
configs = test_optimal_configs()
# 3. 메모리 모니터링
test_memory_monitoring()
# 4. 구성 요약 출력
print("\n📋 최종 구성 요약:")
print_config_summary()
# 5. 프로덕션 설정 생성 및 저장
print("\n🏭 프로덕션 설정 생성...")
# 4:6 비율로 프로덕션 설정
prod_config_46 = generate_production_config(lama_migan_ratio=(4, 6), worker_session_ratio=3.0)
if prod_config_46:
save_production_config(prod_config_46, "production_config_4_6.json")
# 3:7 비율로 프로덕션 설정
prod_config_37 = generate_production_config(lama_migan_ratio=(3, 7), worker_session_ratio=3.0)
if prod_config_37:
save_production_config(prod_config_37, "production_config_3_7.json")
print("\n🎯 권장사항:")
if memory_info.total_vram_mb >= 15000: # 15GB+
print(" 💎 대용량 VRAM 감지 - 3:7 비율 (MIGAN 중심) 권장")
print(" 📈 예상 성능: 60-70명 동시 처리, 0.8-1.5초 응답시간")
elif memory_info.total_vram_mb >= 12000: # 12GB+
print(" ⚡ 중간급 VRAM 감지 - 4:6 비율 (균형) 권장")
print(" 📈 예상 성능: 40-50명 동시 처리, 1.2-2.5초 응답시간")
else:
print(" 💼 보급형 VRAM 감지 - 5:5 또는 6:4 비율 (LAMA 중심) 권장")
print(" 📈 예상 성능: 20-30명 동시 처리, 2.0-3.5초 응답시간")
print("\n✅ 동적 세션풀 관리 테스트 완료!")
if __name__ == "__main__":
main()

877
test1/log.log Normal file
View File

@ -0,0 +1,877 @@
[migan로그]
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer_plugin.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer_plugin.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvonnxparser.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvonnxparser.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvparsers.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvparsers.so.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[2025-08-23 21:09:23,888] [MainThread] [INFO] [ocr_module.py:__init__:55] ✅ FastDeploy PPOCRv3(TRT FP16, cached) 초기화 완료
INFO:GUI_WorkerLogger:✅ FastDeploy PPOCRv3(TRT FP16, cached) 초기화 완료
[2025-08-23 21:09:23,888] [MainThread] [INFO] [celery_worker.py:get_ocr:151] [GPUMem][after OCR init] used=401.9MB free=3694.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after OCR init] used=401.9MB free=3694.1MB total=4096.0MB
[2025-08-23 21:09:23,888] [MainThread] [INFO] [celery_worker.py:_warm_up_models:218] 마스크 모듈 초기화 완료
INFO:GUI_WorkerLogger:마스크 모듈 초기화 완료
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] 🔥 고급 텍스트 렌더링 모듈 초기화 완료
INFO:GUI_WorkerLogger:🔥 고급 텍스트 렌더링 모듈 초기화 완료
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] Cairo 지원: False
INFO:GUI_WorkerLogger:Cairo 지원: False
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] 기본 폰트 경로: /app/worker/fonts/NanumSquareRoundR.ttf
INFO:GUI_WorkerLogger:기본 폰트 경로: /app/worker/fonts/NanumSquareRoundR.ttf
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:get_roi_inpainter:170] cuDNN 최적화 설정 완료
INFO:GUI_WorkerLogger:cuDNN 최적화 설정 완료
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:_warm_up_models:222] ROI 인페인팅 모듈 초기화 완료
INFO:GUI_WorkerLogger:ROI 인페인팅 모듈 초기화 완료
[2025-08-23 21:09:23,889] [MainThread] [INFO] [celery_worker.py:get_roi_inpainter:172] [GPUMem][after ROI Inpainter init] used=401.9MB free=3694.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after ROI Inpainter init] used=401.9MB free=3694.1MB total=4096.0MB
[2025-08-23 21:09:24,316] [MainThread] [INFO] [celery_worker.py:<module>:232] SimpleLama 인스턴스 생성 완료
INFO:GUI_WorkerLogger:SimpleLama 인스턴스 생성 완료
[2025-08-23 21:09:24,317] [MainThread] [INFO] [celery_worker.py:get_migan_inpainter:179] TensorRT 엔진 캐시 디렉토리: /app/temp_files/trt_cache
INFO:GUI_WorkerLogger:TensorRT 엔진 캐시 디렉토리: /app/temp_files/trt_cache
[2025-08-23 21:09:24,317] [MainThread] [INFO] [celery_worker.py:_warm_up_models:226] MIGAN 인페인팅 모듈 초기화 완료
INFO:GUI_WorkerLogger:MIGAN 인페인팅 모듈 초기화 완료
[2025-08-23 21:09:24,317] [MainThread] [INFO] [celery_worker.py:get_migan_inpainter:181] [GPUMem][after MIGAN Inpainter init] used=615.9MB free=3480.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after MIGAN Inpainter init] used=615.9MB free=3480.1MB total=4096.0MB
INFO:worker.celery_worker:✅ 모델 사전 로딩 완료 (성능 최적화 포함)
/usr/local/lib/python3.10/dist-packages/celery/platforms.py:829: SecurityWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
Please specify a different user using the --uid option.
User information: uid=0 euid=0 gid=0 egid=0
warnings.warn(SecurityWarning(ROOT_DISCOURAGED.format(
-------------- 7600M@c6c11810abef v5.3.6 (emerald-rush)
--- ***** -----
-- ******* ---- Linux-6.8.0-64-generic-x86_64-with-glibc2.35 2025-08-23 21:09:24
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: image_worker:0x7d5a7e9df070
- ** ---------- .> transport: redis://192.168.0.129:6379/0
- ** ---------- .> results: redis://192.168.0.129:6379/1
- *** --- * --- .> concurrency: 1 (thread)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
.> inpaint exchange=inpaint(direct) key=inpaint
.> rembg exchange=rembg(direct) key=rembg
.> translate exchange=translate(direct) key=translate
[tasks]
. worker.rembg_task
. worker.translate_task
[2025-08-23 21:09:24,366: WARNING/MainProcess] /usr/local/lib/python3.10/dist-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
warnings.warn(
[2025-08-23 21:09:24,369: INFO/MainProcess] Connected to redis://192.168.0.129:6379/0
[2025-08-23 21:09:24,369: WARNING/MainProcess] /usr/local/lib/python3.10/dist-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
warnings.warn(
[2025-08-23 21:09:24,371: INFO/MainProcess] mingle: searching for neighbors
[2025-08-23 21:09:25,377: INFO/MainProcess] mingle: all alone
[2025-08-23 21:09:25,385: INFO/MainProcess] 7600M@c6c11810abef ready.
[2025-08-23 21:09:28,153: INFO/MainProcess] Events of group {task} enabled by remote.
[2025-08-23 21:09:45,608: INFO/MainProcess] Task worker.translate_task[662c047f-e7a1-4855-b54f-980b54819431] received
[2025-08-23 21:09:45,609] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:09:45,609: INFO/MainProcess] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:09:45,610] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before DECODE] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,610: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before DECODE] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,615] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after DECODE] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,615: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after DECODE] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,615] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][DECODE] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:09:45,615: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][DECODE] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:09:45,616] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before OCR] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,616: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before OCR] used=597.9MB free=3498.1MB total=4096.0MB
[2025-08-23 21:09:45,616] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:09:45,616: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:09:46,078] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:09:46,078: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:09:46,078] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:09:46,078: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:09:46,078] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after OCR] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:46,078: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after OCR] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:46,078] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][OCR] Δused=166.0MB, elapsed=0.463s
[2025-08-23 21:09:46,078: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][OCR] Δused=166.0MB, elapsed=0.463s
[2025-08-23 21:09:46,105] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before TRANSLATE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:46,105: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before TRANSLATE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:46,105: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:09:47,574: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:09:47,575] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after TRANSLATE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,575: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after TRANSLATE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,575] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][TRANSLATE] Δused=0.0MB, elapsed=1.470s
[2025-08-23 21:09:47,575: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][TRANSLATE] Δused=0.0MB, elapsed=1.470s
[2025-08-23 21:09:47,575] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before MASK] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,575: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before MASK] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,587] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 MIGAN용(expand=3, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 9.84% (96,388/979,200 픽셀)
[2025-08-23 21:09:47,587: INFO/MainProcess] 🔧 MIGAN용(expand=3, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 9.84% (96,388/979,200 픽셀)
[2025-08-23 21:09:47,587] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after MASK] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,587: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after MASK] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,587] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][MASK] Δused=0.0MB, elapsed=0.012s
[2025-08-23 21:09:47,587: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][MASK] Δused=0.0MB, elapsed=0.012s
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before INPAINT] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,590: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before INPAINT] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] 선택된 인페인팅 방법: migan
[2025-08-23 21:09:47,590: INFO/MainProcess] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] 선택된 인페인팅 방법: migan
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 9.8%, 최대 크기 제한: 1600px
[2025-08-23 21:09:47,590: INFO/MainProcess] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 9.8%, 최대 크기 제한: 1600px
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:693] 설정 변경으로 인한 세션 재초기화 필요
[2025-08-23 21:09:47,590: INFO/MainProcess] 설정 변경으로 인한 세션 재초기화 필요
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:693] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:09:47,590: INFO/MainProcess] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:09:47,590] [ThreadPoolExecutor-0_0] [INFO] [migan_inpainting_module.py:_prepare_session:378] CUDA 세션 생성 시도
[2025-08-23 21:09:47,590: INFO/MainProcess] CUDA 세션 생성 시도
[2025-08-23 21:09:47,768] [ThreadPoolExecutor-0_0] [INFO] [migan_inpainting_module.py:_prepare_session:378] CUDA 세션 생성 성공: ['CUDAExecutionProvider', 'CPUExecutionProvider']
[2025-08-23 21:09:47,768: INFO/MainProcess] CUDA 세션 생성 성공: ['CUDAExecutionProvider', 'CPUExecutionProvider']
[2025-08-23 21:09:47,768] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:693] 입력 0: image, 형태: ['batch_size', 3, 'height', 'width'], 타입: tensor(uint8)
[2025-08-23 21:09:47,768: DEBUG/MainProcess] 입력 0: image, 형태: ['batch_size', 3, 'height', 'width'], 타입: tensor(uint8)
[2025-08-23 21:09:47,769] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:693] 입력 1: mask, 형태: ['batch_size', 1, 'height', 'width'], 타입: tensor(uint8)
[2025-08-23 21:09:47,769: DEBUG/MainProcess] 입력 1: mask, 형태: ['batch_size', 1, 'height', 'width'], 타입: tensor(uint8)
[2025-08-23 21:09:47,769] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:693] 출력 0: result, 형태: ['ScatterNDresult_dim_0', 3, 'ScatterNDresult_dim_2', 'ScatterNDresult_dim_3'], 타입: tensor(uint8)
[2025-08-23 21:09:47,769: DEBUG/MainProcess] 출력 0: result, 형태: ['ScatterNDresult_dim_0', 3, 'ScatterNDresult_dim_2', 'ScatterNDresult_dim_3'], 타입: tensor(uint8)
[2025-08-23 21:09:47,812] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:09:47,812: DEBUG/MainProcess] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:09:57,277] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] MIGAN 인페인팅 완료: 총 9.687s (추론: 9.461s)
[2025-08-23 21:09:57,277: INFO/MainProcess] MIGAN 인페인팅 완료: 총 9.687s (추론: 9.461s)
[2025-08-23 21:09:57,442] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][662c047f-e7a1-4855-b54f-980b54819431] 경량 정리 완료: Python객체=227개, GPU캐시=0.0MB
[2025-08-23 21:09:57,442: DEBUG/MainProcess] [MEMORY][662c047f-e7a1-4855-b54f-980b54819431] 경량 정리 완료: Python객체=227개, GPU캐시=0.0MB
[2025-08-23 21:09:57,442] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after INPAINT] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,442: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after INPAINT] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,442] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][INPAINT] Δused=550.0MB, elapsed=9.853s
[2025-08-23 21:09:57,442: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][INPAINT] Δused=550.0MB, elapsed=9.853s
[2025-08-23 21:09:57,467: INFO/MainProcess] worker.translate_task[662c047f-e7a1-4855-b54f-980b54819431]: [TRACE][662c047f-e7a1-4855-b54f-980b54819431][font] 요청된 폰트 번호: 5
[2025-08-23 21:09:57,468] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before RENDER] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,468: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][before RENDER] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,468] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:09:57,468: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:09:57,470] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:09:57,470: DEBUG/MainProcess] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:09:57,486] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:09:57,486: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:09:57,488] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:09:57,488: DEBUG/MainProcess] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:09:57,510] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:09:57,510: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:09:57,512] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 171, 165) → 텍스트(0, 0, 0) (비율: 9.38)
[2025-08-23 21:09:57,512: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 171, 165) → 텍스트(0, 0, 0) (비율: 9.38)
[2025-08-23 21:09:57,527] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:09:57,527: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:09:57,529] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:09:57,529: DEBUG/MainProcess] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:09:57,546] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:09:57,546: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:09:57,546] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:09:57,546: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:09:57,546] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after RENDER] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,546: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][after RENDER] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:09:57,546] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][RENDER] Δused=0.0MB, elapsed=0.079s
[2025-08-23 21:09:57,546: INFO/MainProcess] [GPUMem][662c047f-e7a1-4855-b54f-980b54819431][RENDER] Δused=0.0MB, elapsed=0.079s
[2025-08-23 21:09:57,572: INFO/MainProcess] worker.translate_task[662c047f-e7a1-4855-b54f-980b54819431]: [DEBUG] artifacts saved: /app/temp_files/debug/c9efd18d_*.png
[2025-08-23 21:09:57,572] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] translate_task done
[2025-08-23 21:09:57,572: INFO/MainProcess] [TRACE][662c047f-e7a1-4855-b54f-980b54819431] translate_task done
[2025-08-23 21:09:57,612: INFO/MainProcess] Task worker.translate_task[662c047f-e7a1-4855-b54f-980b54819431] succeeded in 12.003001395147294s: {'status': 'SUCCESS', 'result_image': 'iVBORw0KGgoAAAANSUhEUgAAAzAAAASwCAIAAACrfTgaAAAgAElEQVR4AezBfYydZZ0H/O/3PtOZQ1to4QFBtEv1OuXFI7KKa1psKm6pkjJYKiusCtlEspjsxvS4Ga3GiS9xx67IWE6IWY1vfwhJI6xF6qBrM1ZSSdssJMaZBrK57ocHEUSlWEpppzNz399n5moves7MOe2ZTvGwzu/zoSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY4wxxpj2oSQYY14dkkiiniSSeC2RhIAkXkskAZCEIEkSGGPMXyNKgjHm1SGJJOpJIonXEkkISOK1RBIASQiSJIExxvw1oiQYY+Y2SYhI4jVDEg...', ...}
[2025-08-23 21:10:22,817: INFO/MainProcess] Task worker.translate_task[fe66228f-3867-4e5f-9dce-65d0a25b8f90] received
[2025-08-23 21:10:22,818] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:10:22,818: INFO/MainProcess] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:10:22,818] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before DECODE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,818: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before DECODE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,821] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after DECODE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,821: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after DECODE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,821] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:10:22,821: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:10:22,821] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before OCR] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,821: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before OCR] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,821] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:10:22,821: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:10:22,893] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:10:22,893: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:10:22,893] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:10:22,893: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:10:22,893] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after OCR] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,893: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after OCR] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,893] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][OCR] Δused=0.0MB, elapsed=0.072s
[2025-08-23 21:10:22,893: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][OCR] Δused=0.0MB, elapsed=0.072s
[2025-08-23 21:10:22,919] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before TRANSLATE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,919: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before TRANSLATE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:22,919: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:10:23,254: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:10:23,254] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after TRANSLATE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,254: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after TRANSLATE] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,254] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][TRANSLATE] Δused=0.0MB, elapsed=0.335s
[2025-08-23 21:10:23,254: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][TRANSLATE] Δused=0.0MB, elapsed=0.335s
[2025-08-23 21:10:23,254] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before MASK] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,254: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before MASK] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,260] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 MIGAN용(expand=9, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 13.66% (133,749/979,200 픽셀)
[2025-08-23 21:10:23,260: INFO/MainProcess] 🔧 MIGAN용(expand=9, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 13.66% (133,749/979,200 픽셀)
[2025-08-23 21:10:23,260] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after MASK] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,260: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after MASK] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,260] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][MASK] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:10:23,260: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][MASK] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:10:23,262] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before INPAINT] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,262: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before INPAINT] used=1313.9MB free=2782.1MB total=4096.0MB
[2025-08-23 21:10:23,263] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] 선택된 인페인팅 방법: migan
[2025-08-23 21:10:23,263: INFO/MainProcess] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] 선택된 인페인팅 방법: migan
[2025-08-23 21:10:23,263] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 13.7%, 최대 크기 제한: 1600px
[2025-08-23 21:10:23,263: INFO/MainProcess] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 13.7%, 최대 크기 제한: 1600px
[2025-08-23 21:10:23,263] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:693] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:10:23,263: INFO/MainProcess] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:10:23,301] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:10:23,301: DEBUG/MainProcess] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:10:23,539] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] MIGAN 인페인팅 완료: 총 0.276s (추론: 0.232s)
[2025-08-23 21:10:23,539: INFO/MainProcess] MIGAN 인페인팅 완료: 총 0.276s (추론: 0.232s)
[2025-08-23 21:10:23,706] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][fe66228f-3867-4e5f-9dce-65d0a25b8f90] 경량 정리 완료: Python객체=207개, GPU캐시=0.0MB
[2025-08-23 21:10:23,706: DEBUG/MainProcess] [MEMORY][fe66228f-3867-4e5f-9dce-65d0a25b8f90] 경량 정리 완료: Python객체=207개, GPU캐시=0.0MB
[2025-08-23 21:10:23,706] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,706: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,706] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][INPAINT] Δused=512.0MB, elapsed=0.444s
[2025-08-23 21:10:23,706: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][INPAINT] Δused=512.0MB, elapsed=0.444s
[2025-08-23 21:10:23,731: INFO/MainProcess] worker.translate_task[fe66228f-3867-4e5f-9dce-65d0a25b8f90]: [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90][font] 요청된 폰트 번호: 5
[2025-08-23 21:10:23,731] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,731: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][before RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,731] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:10:23,731: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:10:23,734] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:10:23,734: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:10:23,747] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:10:23,747: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:10:23,749] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:10:23,749: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:10:23,770] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:10:23,770: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:10:23,772] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(182, 169, 160) → 텍스트(0, 0, 0) (비율: 9.17)
[2025-08-23 21:10:23,772: DEBUG/MainProcess] WCAG 대비 보정: 배경(182, 169, 160) → 텍스트(0, 0, 0) (비율: 9.17)
[2025-08-23 21:10:23,786] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:10:23,786: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:10:23,788] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 170, 163) → 텍스트(0, 0, 0) (비율: 9.29)
[2025-08-23 21:10:23,788: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 170, 163) → 텍스트(0, 0, 0) (비율: 9.29)
[2025-08-23 21:10:23,804] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:10:23,804: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:10:23,804] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:10:23,804: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:10:23,804] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,804: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][after RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:23,804] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][RENDER] Δused=0.0MB, elapsed=0.073s
[2025-08-23 21:10:23,804: INFO/MainProcess] [GPUMem][fe66228f-3867-4e5f-9dce-65d0a25b8f90][RENDER] Δused=0.0MB, elapsed=0.073s
[2025-08-23 21:10:23,830: INFO/MainProcess] worker.translate_task[fe66228f-3867-4e5f-9dce-65d0a25b8f90]: [DEBUG] artifacts saved: /app/temp_files/debug/a3404d1f_*.png
[2025-08-23 21:10:23,830] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] translate_task done
[2025-08-23 21:10:23,830: INFO/MainProcess] [TRACE][fe66228f-3867-4e5f-9dce-65d0a25b8f90] translate_task done
[2025-08-23 21:10:23,866: INFO/MainProcess] Task worker.translate_task[fe66228f-3867-4e5f-9dce-65d0a25b8f90] succeeded in 1.0485097700729966s: {'status': 'SUCCESS', 'result_image': 'iVBORw0KGgoAAAANSUhEUgAAAzAAAASwCAIAAACrfTgaAAAgAElEQVR4AezBf6zmZX3n/+drIGW2sAqNLUjLgr3uAekNpS2umbGTqS5MS2AsIFVbhTSpWZvsxnDcHB2bntQ23SNbyxHvGLNtWu0fSkKK27GMR10n49RMyTBbSBrPmUg21y3B1l9dsOiXRVyceX3Pfc19zX3uez73OWdmzpmDh/fjIduEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEEEIIIYT1I9uEcLYYs8CMIyqxysxYYnWYAXFWmeWJs8cMiLPBjBKrwPSIVWB6xEub6DMjTJ9ECC89sk0Ia8+YE8w4ohKrySxDnBrTJ/rMEHFWmeWJs8cMiLPBjBJLMT1iKWZAnD4zRLy0CczJTJ9ECC...', ...}
[2025-08-23 21:10:37,660: INFO/MainProcess] Task worker.translate_task[e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] received
[2025-08-23 21:10:37,660] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:10:37,660: INFO/MainProcess] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:10:37,661] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before DECODE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,661: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before DECODE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,664] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after DECODE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,664: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after DECODE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,664] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:10:37,664: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:10:37,664] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before OCR] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,664: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before OCR] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,664] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:10:37,664: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:10:37,728] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:10:37,728: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:10:37,728] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:10:37,728: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:10:37,728] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after OCR] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,728: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after OCR] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,729] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][OCR] Δused=0.0MB, elapsed=0.064s
[2025-08-23 21:10:37,729: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][OCR] Δused=0.0MB, elapsed=0.064s
[2025-08-23 21:10:37,755] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before TRANSLATE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,755: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before TRANSLATE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:37,755: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:10:38,070: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:10:38,070] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after TRANSLATE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,070: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after TRANSLATE] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,070] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][TRANSLATE] Δused=0.0MB, elapsed=0.316s
[2025-08-23 21:10:38,070: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][TRANSLATE] Δused=0.0MB, elapsed=0.316s
[2025-08-23 21:10:38,070] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before MASK] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,070: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before MASK] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,075] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 MIGAN용(expand=7, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 12.67% (124,087/979,200 픽셀)
[2025-08-23 21:10:38,075: INFO/MainProcess] 🔧 MIGAN용(expand=7, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 12.67% (124,087/979,200 픽셀)
[2025-08-23 21:10:38,076] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after MASK] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,076: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after MASK] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,076] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][MASK] Δused=0.0MB, elapsed=0.005s
[2025-08-23 21:10:38,076: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][MASK] Δused=0.0MB, elapsed=0.005s
[2025-08-23 21:10:38,078] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,078: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,078] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] 선택된 인페인팅 방법: migan
[2025-08-23 21:10:38,078: INFO/MainProcess] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] 선택된 인페인팅 방법: migan
[2025-08-23 21:10:38,078] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 12.7%, 최대 크기 제한: 1600px
[2025-08-23 21:10:38,078: INFO/MainProcess] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 12.7%, 최대 크기 제한: 1600px
[2025-08-23 21:10:38,078] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:693] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:10:38,078: INFO/MainProcess] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:10:38,117] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:10:38,117: DEBUG/MainProcess] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:10:38,300] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] MIGAN 인페인팅 완료: 총 0.222s (추론: 0.174s)
[2025-08-23 21:10:38,300: INFO/MainProcess] MIGAN 인페인팅 완료: 총 0.222s (추론: 0.174s)
[2025-08-23 21:10:38,467] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] 경량 정리 완료: Python객체=197개, GPU캐시=0.0MB
[2025-08-23 21:10:38,467: DEBUG/MainProcess] [MEMORY][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] 경량 정리 완료: Python객체=197개, GPU캐시=0.0MB
[2025-08-23 21:10:38,467] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,467: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after INPAINT] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,467] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][INPAINT] Δused=0.0MB, elapsed=0.389s
[2025-08-23 21:10:38,467: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][INPAINT] Δused=0.0MB, elapsed=0.389s
[2025-08-23 21:10:38,492: INFO/MainProcess] worker.translate_task[e1a901c7-f0da-4011-99ad-9ebabbb3fb5c]: [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][font] 요청된 폰트 번호: 5
[2025-08-23 21:10:38,492] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,492: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][before RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,492] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:10:38,492: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:10:38,494] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:10:38,494: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:10:38,507] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:10:38,507: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:10:38,510] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:10:38,510: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:10:38,532] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:10:38,532: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:10:38,534] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(182, 168, 160) → 텍스트(0, 0, 0) (비율: 9.10)
[2025-08-23 21:10:38,534: DEBUG/MainProcess] WCAG 대비 보정: 배경(182, 168, 160) → 텍스트(0, 0, 0) (비율: 9.10)
[2025-08-23 21:10:38,548] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:10:38,548: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:10:38,550] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:10:38,550: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:10:38,566] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:10:38,566: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:10:38,566] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:10:38,566: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:10:38,566] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,566: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][after RENDER] used=1825.9MB free=2270.1MB total=4096.0MB
[2025-08-23 21:10:38,566] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][RENDER] Δused=0.0MB, elapsed=0.074s
[2025-08-23 21:10:38,566: INFO/MainProcess] [GPUMem][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c][RENDER] Δused=0.0MB, elapsed=0.074s
[2025-08-23 21:10:38,592: INFO/MainProcess] worker.translate_task[e1a901c7-f0da-4011-99ad-9ebabbb3fb5c]: [DEBUG] artifacts saved: /app/temp_files/debug/54194cd0_*.png
[2025-08-23 21:10:38,592] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] translate_task done
[2025-08-23 21:10:38,592: INFO/MainProcess] [TRACE][e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] translate_task done
[2025-08-23 21:10:38,627: INFO/MainProcess] Task worker.translate_task[e1a901c7-f0da-4011-99ad-9ebabbb3fb5c] succeeded in 0.966100683901459s: {'status': 'SUCCESS', 'result_image': 'iVBORw0KGgoAAAANSUhEUgAAAzAAAASwCAIAAACrfTgaAAAgAElEQVR4AezBfYzdZZ3//+frQGxXWAWjgigLep1y4xFZxTWtNlW/UCVQBWTFVSGbSBaT3RjGzWg1TryJO7IqI5wYsxrv/lASIq5lqYOu3VpN5VvYhW+MM41kcx0Jut4uKPpjERd7Xr+eT8/lmTM9ZzrtDGeq8348ZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQQgghhLByZJsQRsuYQcQfGxuJeWwkjio2B0gcVWz2s02lVhNhVRAhrDKyTQgjZMx+ZjEkKmKxzNHERmIeG4mjiDFdAsTRw2Y/21TUwYiYPiIUYnmYA0...', ...}
[2025-08-23 21:12:51,963: INFO/MainProcess] Task worker.translate_task[32feee3c-5759-4d82-817b-35efa536e14f] received
[2025-08-23 21:12:51,970] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:12:51,970: INFO/MainProcess] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:12:51,974] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before DECODE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,974: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before DECODE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,977] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after DECODE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,977: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after DECODE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,977] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][DECODE] Δused=0.0MB, elapsed=0.004s
[2025-08-23 21:12:51,977: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][DECODE] Δused=0.0MB, elapsed=0.004s
[2025-08-23 21:12:51,977] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before OCR] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,977: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before OCR] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:51,979] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:12:51,979: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:12:52,053] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:12:52,053: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:12:52,053] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:12:52,053: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:12:52,053] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after OCR] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,053: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after OCR] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,053] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][OCR] Δused=0.0MB, elapsed=0.076s
[2025-08-23 21:12:52,053: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][OCR] Δused=0.0MB, elapsed=0.076s
[2025-08-23 21:12:52,081] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before TRANSLATE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,081: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before TRANSLATE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,081: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:12:52,474: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:12:52,474] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after TRANSLATE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,474: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after TRANSLATE] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,474] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][TRANSLATE] Δused=0.0MB, elapsed=0.393s
[2025-08-23 21:12:52,474: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][TRANSLATE] Δused=0.0MB, elapsed=0.393s
[2025-08-23 21:12:52,474] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before MASK] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,474: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before MASK] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,480] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 MIGAN용(expand=7, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 12.67% (124,087/979,200 픽셀)
[2025-08-23 21:12:52,480: INFO/MainProcess] 🔧 MIGAN용(expand=7, min_area=64, dilate=2, closing=True, bridge_h=10, bridge_v=10) 마스크 사용: 커버리지 12.67% (124,087/979,200 픽셀)
[2025-08-23 21:12:52,481] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after MASK] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,481: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after MASK] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,481] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][MASK] Δused=0.0MB, elapsed=0.007s
[2025-08-23 21:12:52,481: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][MASK] Δused=0.0MB, elapsed=0.007s
[2025-08-23 21:12:52,483] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before INPAINT] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,483: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before INPAINT] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:52,483] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] 선택된 인페인팅 방법: migan
[2025-08-23 21:12:52,483: INFO/MainProcess] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] 선택된 인페인팅 방법: migan
[2025-08-23 21:12:52,484] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 12.7%, 최대 크기 제한: 1600px
[2025-08-23 21:12:52,484: INFO/MainProcess] [INPAINT] MIGAN 처리 통계: 마스크 커버리지 12.7%, 최대 크기 제한: 1600px
[2025-08-23 21:12:52,484] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:693] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:12:52,484: INFO/MainProcess] 설정 업데이트 완료: ['onnx_path', 'use_cuda', 'use_tensorrt', 'trt_fp16_enable', 'trt_engine_cache_enable', 'max_image_size', 'output_max_width', 'enable_output_resize']
[2025-08-23 21:12:52,525] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:12:52,525: DEBUG/MainProcess] 추론 입력 - 이미지: (1, 3, 1200, 816), 마스크: (1, 1, 1200, 816)
[2025-08-23 21:12:52,667] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] MIGAN 인페인팅 완료: 총 0.183s (추론: 0.129s)
[2025-08-23 21:12:52,667: INFO/MainProcess] MIGAN 인페인팅 완료: 총 0.183s (추론: 0.129s)
[2025-08-23 21:12:53,025] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][32feee3c-5759-4d82-817b-35efa536e14f] 경량 정리 완료: Python객체=197개, GPU캐시=0.0MB
[2025-08-23 21:12:53,025: DEBUG/MainProcess] [MEMORY][32feee3c-5759-4d82-817b-35efa536e14f] 경량 정리 완료: Python객체=197개, GPU캐시=0.0MB
[2025-08-23 21:12:53,025] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after INPAINT] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,025: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after INPAINT] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,025] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][INPAINT] Δused=0.0MB, elapsed=0.542s
[2025-08-23 21:12:53,025: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][INPAINT] Δused=0.0MB, elapsed=0.542s
[2025-08-23 21:12:53,050: INFO/MainProcess] worker.translate_task[32feee3c-5759-4d82-817b-35efa536e14f]: [TRACE][32feee3c-5759-4d82-817b-35efa536e14f][font] 요청된 폰트 번호: 5
[2025-08-23 21:12:53,050] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before RENDER] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,050: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][before RENDER] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,050] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:12:53,050: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:12:53,053] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:12:53,053: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 254, 253) → 텍스트(0, 0, 0) (비율: 20.81)
[2025-08-23 21:12:53,069] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:12:53,069: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:12:53,071] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:12:53,071: DEBUG/MainProcess] WCAG 대비 보정: 배경(254, 253, 252) → 텍스트(0, 0, 0) (비율: 20.67)
[2025-08-23 21:12:53,093] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:12:53,093: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:12:53,095] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(182, 168, 160) → 텍스트(0, 0, 0) (비율: 9.10)
[2025-08-23 21:12:53,095: DEBUG/MainProcess] WCAG 대비 보정: 배경(182, 168, 160) → 텍스트(0, 0, 0) (비율: 9.10)
[2025-08-23 21:12:53,109] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:12:53,109: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:12:53,111] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:12:53,111: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:12:53,127] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:12:53,127: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:12:53,127] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:12:53,127: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:12:53,127] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after RENDER] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,127: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][after RENDER] used=1917.9MB free=2178.1MB total=4096.0MB
[2025-08-23 21:12:53,127] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][RENDER] Δused=0.0MB, elapsed=0.077s
[2025-08-23 21:12:53,127: INFO/MainProcess] [GPUMem][32feee3c-5759-4d82-817b-35efa536e14f][RENDER] Δused=0.0MB, elapsed=0.077s
[2025-08-23 21:12:53,153: INFO/MainProcess] worker.translate_task[32feee3c-5759-4d82-817b-35efa536e14f]: [DEBUG] artifacts saved: /app/temp_files/debug/346074b3_*.png
[2025-08-23 21:12:53,153] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] translate_task done
[2025-08-23 21:12:53,153: INFO/MainProcess] [TRACE][32feee3c-5759-4d82-817b-35efa536e14f] translate_task done
[lama 로그]
[RMBG][ORT] providers: ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'AzureExecutionProvider', 'CPUExecutionProvider']
⚠️ Cairo/Pango 미지원, Pillow 폴백 사용: Namespace Pango not available
[CUDA-WARMUP] device_count = 1
[2025-08-23 21:15:35,091] [MainThread] [INFO] [celery_worker.py:<module>:87] [GPUMem] NVML init ok. device_index=0
translate_batch in: ['测试']
translate_batch out: ['시험']
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvcaffe_parser.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvcaffe_parser.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer_plugin.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer_plugin.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvinfer.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvonnxparser.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvonnxparser.so.
INFO:root:Create a symbolic link pointing to /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvparsers.so.8 named /usr/local/lib/python3.10/dist-packages/fastdeploy/libs/third_libs/tensorrt/lib/libnvparsers.so.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[INFO] fastdeploy/runtime/runtime.cc(273)::CreatePaddleBackend Runtime initialized with Backend::PDINFER in Device::GPU.
[2025-08-23 21:15:37,445] [MainThread] [INFO] [ocr_module.py:__init__:55] ✅ FastDeploy PPOCRv3(TRT FP16, cached) 초기화 완료
INFO:GUI_WorkerLogger:✅ FastDeploy PPOCRv3(TRT FP16, cached) 초기화 완료
[2025-08-23 21:15:37,445] [MainThread] [INFO] [celery_worker.py:get_ocr:151] [GPUMem][after OCR init] used=401.9MB free=3694.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after OCR init] used=401.9MB free=3694.1MB total=4096.0MB
[2025-08-23 21:15:37,445] [MainThread] [INFO] [celery_worker.py:_warm_up_models:218] 마스크 모듈 초기화 완료
INFO:GUI_WorkerLogger:마스크 모듈 초기화 완료
[2025-08-23 21:15:37,445] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] 🔥 고급 텍스트 렌더링 모듈 초기화 완료
INFO:GUI_WorkerLogger:🔥 고급 텍스트 렌더링 모듈 초기화 완료
[2025-08-23 21:15:37,445] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] Cairo 지원: False
INFO:GUI_WorkerLogger:Cairo 지원: False
[2025-08-23 21:15:37,445] [MainThread] [INFO] [celery_worker.py:_warm_up_models:219] 기본 폰트 경로: /app/worker/fonts/NanumSquareRoundR.ttf
INFO:GUI_WorkerLogger:기본 폰트 경로: /app/worker/fonts/NanumSquareRoundR.ttf
[2025-08-23 21:15:37,446] [MainThread] [INFO] [celery_worker.py:get_roi_inpainter:170] cuDNN 최적화 설정 완료
INFO:GUI_WorkerLogger:cuDNN 최적화 설정 완료
[2025-08-23 21:15:37,446] [MainThread] [INFO] [celery_worker.py:_warm_up_models:222] ROI 인페인팅 모듈 초기화 완료
INFO:GUI_WorkerLogger:ROI 인페인팅 모듈 초기화 완료
[2025-08-23 21:15:37,446] [MainThread] [INFO] [celery_worker.py:get_roi_inpainter:172] [GPUMem][after ROI Inpainter init] used=401.9MB free=3694.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after ROI Inpainter init] used=401.9MB free=3694.1MB total=4096.0MB
[2025-08-23 21:15:37,876] [MainThread] [INFO] [celery_worker.py:<module>:232] SimpleLama 인스턴스 생성 완료
INFO:GUI_WorkerLogger:SimpleLama 인스턴스 생성 완료
[2025-08-23 21:15:37,876] [MainThread] [INFO] [celery_worker.py:get_migan_inpainter:179] TensorRT 엔진 캐시 디렉토리: /app/temp_files/trt_cache
INFO:GUI_WorkerLogger:TensorRT 엔진 캐시 디렉토리: /app/temp_files/trt_cache
[2025-08-23 21:15:37,876] [MainThread] [INFO] [celery_worker.py:_warm_up_models:226] MIGAN 인페인팅 모듈 초기화 완료
INFO:GUI_WorkerLogger:MIGAN 인페인팅 모듈 초기화 완료
[2025-08-23 21:15:37,876] [MainThread] [INFO] [celery_worker.py:get_migan_inpainter:181] [GPUMem][after MIGAN Inpainter init] used=615.9MB free=3480.1MB total=4096.0MB
INFO:GUI_WorkerLogger:[GPUMem][after MIGAN Inpainter init] used=615.9MB free=3480.1MB total=4096.0MB
INFO:worker.celery_worker:✅ 모델 사전 로딩 완료 (성능 최적화 포함)
/usr/local/lib/python3.10/dist-packages/celery/platforms.py:829: SecurityWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
Please specify a different user using the --uid option.
User information: uid=0 euid=0 gid=0 egid=0
warnings.warn(SecurityWarning(ROOT_DISCOURAGED.format(
-------------- 7600M@b62c0650d845 v5.3.6 (emerald-rush)
--- ***** -----
-- ******* ---- Linux-6.8.0-64-generic-x86_64-with-glibc2.35 2025-08-23 21:15:37
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: image_worker:0x76cf14f4f070
- ** ---------- .> transport: redis://192.168.0.129:6379/0
- ** ---------- .> results: redis://192.168.0.129:6379/1
- *** --- * --- .> concurrency: 1 (thread)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
.> inpaint exchange=inpaint(direct) key=inpaint
.> rembg exchange=rembg(direct) key=rembg
.> translate exchange=translate(direct) key=translate
[tasks]
. worker.rembg_task
. worker.translate_task
[2025-08-23 21:15:37,926: WARNING/MainProcess] /usr/local/lib/python3.10/dist-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
warnings.warn(
[2025-08-23 21:15:37,929: INFO/MainProcess] Connected to redis://192.168.0.129:6379/0
[2025-08-23 21:15:37,929: WARNING/MainProcess] /usr/local/lib/python3.10/dist-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
warnings.warn(
[2025-08-23 21:15:37,930: INFO/MainProcess] mingle: searching for neighbors
[2025-08-23 21:15:38,937: INFO/MainProcess] mingle: all alone
[2025-08-23 21:15:38,946: INFO/MainProcess] 7600M@b62c0650d845 ready.
[2025-08-23 21:15:43,151: INFO/MainProcess] Events of group {task} enabled by remote.
[2025-08-23 21:17:03,914: INFO/MainProcess] Task worker.translate_task[0a89977d-c795-49af-961e-9cccdc8e9aeb] received
[2025-08-23 21:17:03,915] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:03,915: INFO/MainProcess] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:03,916] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before DECODE] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,916: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before DECODE] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,922] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after DECODE] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,922: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after DECODE] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,922] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][DECODE] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:17:03,922: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][DECODE] Δused=0.0MB, elapsed=0.006s
[2025-08-23 21:17:03,922] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before OCR] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,922: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before OCR] used=579.9MB free=3516.1MB total=4096.0MB
[2025-08-23 21:17:03,922] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:03,922: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:04,403] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:04,403: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:04,403] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:04,403: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:04,403] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after OCR] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,403: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after OCR] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,403] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][OCR] Δused=166.0MB, elapsed=0.481s
[2025-08-23 21:17:04,403: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][OCR] Δused=166.0MB, elapsed=0.481s
[2025-08-23 21:17:04,429] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before TRANSLATE] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,429: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before TRANSLATE] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,429: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:17:04,753: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:17:04,753] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after TRANSLATE] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,753: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after TRANSLATE] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,753] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][TRANSLATE] Δused=0.0MB, elapsed=0.325s
[2025-08-23 21:17:04,753: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][TRANSLATE] Δused=0.0MB, elapsed=0.325s
[2025-08-23 21:17:04,754] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before MASK] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,754: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before MASK] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,755] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:04,755: INFO/MainProcess] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:04,755] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:04,755: INFO/MainProcess] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:04,755] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after MASK] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,755: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after MASK] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,756] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:04,756: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:04,758] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before INPAINT] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,758: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before INPAINT] used=745.9MB free=3350.1MB total=4096.0MB
[2025-08-23 21:17:04,758] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:04,758: INFO/MainProcess] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:04,760] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:04,760: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:04,760] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:04,760: INFO/MainProcess] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:04,760] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:04,760: INFO/MainProcess] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:04,761] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:684] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:04,761: INFO/MainProcess] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:04,761] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:04,761: INFO/MainProcess] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:04,762] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:04,762: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:04,762] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:04,762: INFO/MainProcess] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:04,763] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:04,763: INFO/MainProcess] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:04,763] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:04,763: INFO/MainProcess] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:04,763] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 처리 준비: 버킷=webtoon_standard, 전략=full, 버킷화=0.000s, 스케일링=0.000s, 전략선택=0.002s
[2025-08-23 21:17:04,763: INFO/MainProcess] 🔧 처리 준비: 버킷=webtoon_standard, 전략=full, 버킷화=0.000s, 스케일링=0.000s, 전략선택=0.002s
[2025-08-23 21:17:04,763] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 전체 이미지 처리 시작 (버킷: webtoon_standard)
[2025-08-23 21:17:04,763: INFO/MainProcess] 전체 이미지 처리 시작 (버킷: webtoon_standard)
[2025-08-23 21:17:05,950] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 📊 성능 기록: webtoon_standard (full) = 1.19s, 평균: 1.19s
[2025-08-23 21:17:05,950: INFO/MainProcess] 📊 성능 기록: webtoon_standard (full) = 1.19s, 평균: 1.19s
[2025-08-23 21:17:05,950] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🎯 인페인팅 완료: 총 1.189s (인페인팅: 1.187s, 복원: 0.000s)
[2025-08-23 21:17:05,950: INFO/MainProcess] 🎯 인페인팅 완료: 총 1.189s (인페인팅: 1.187s, 복원: 0.000s)
[2025-08-23 21:17:06,123] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][0a89977d-c795-49af-961e-9cccdc8e9aeb] 경량 정리 완료: Python객체=20개, GPU캐시=0.0MB
[2025-08-23 21:17:06,123: DEBUG/MainProcess] [MEMORY][0a89977d-c795-49af-961e-9cccdc8e9aeb] 경량 정리 완료: Python객체=20개, GPU캐시=0.0MB
[2025-08-23 21:17:06,123] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after INPAINT] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,123: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after INPAINT] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,124] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][INPAINT] Δused=18.0MB, elapsed=1.366s
[2025-08-23 21:17:06,124: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][INPAINT] Δused=18.0MB, elapsed=1.366s
[2025-08-23 21:17:06,150: INFO/MainProcess] worker.translate_task[0a89977d-c795-49af-961e-9cccdc8e9aeb]: [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb][font] 요청된 폰트 번호: 5
[2025-08-23 21:17:06,150] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before RENDER] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,150: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][before RENDER] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,150] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:06,150: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:06,153] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:17:06,153: DEBUG/MainProcess] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:17:06,166] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:06,166: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:06,168] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:06,168: DEBUG/MainProcess] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:06,190] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:06,190: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:06,192] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 170, 164) → 텍스트(0, 0, 0) (비율: 9.30)
[2025-08-23 21:17:06,192: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 170, 164) → 텍스트(0, 0, 0) (비율: 9.30)
[2025-08-23 21:17:06,207] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:06,207: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:06,209] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:17:06,209: DEBUG/MainProcess] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:17:06,224] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:06,224: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:06,224] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:06,224: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:06,224] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after RENDER] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,224: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][after RENDER] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:06,225] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][RENDER] Δused=0.0MB, elapsed=0.074s
[2025-08-23 21:17:06,225: INFO/MainProcess] [GPUMem][0a89977d-c795-49af-961e-9cccdc8e9aeb][RENDER] Δused=0.0MB, elapsed=0.074s
[2025-08-23 21:17:06,251: INFO/MainProcess] worker.translate_task[0a89977d-c795-49af-961e-9cccdc8e9aeb]: [DEBUG] artifacts saved: /app/temp_files/debug/cfd8d887_*.png
[2025-08-23 21:17:06,251] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] translate_task done
[2025-08-23 21:17:06,251: INFO/MainProcess] [TRACE][0a89977d-c795-49af-961e-9cccdc8e9aeb] translate_task done
[2025-08-23 21:17:06,293: INFO/MainProcess] Task worker.translate_task[0a89977d-c795-49af-961e-9cccdc8e9aeb] succeeded in 2.377605739980936s: {'status': 'SUCCESS', 'result_image': 'iVBORw0KGgoAAAANSUhEUgAAAzAAAASwCAIAAACrfTgaAAAgAElEQVR4AezBjZElaUCey3zHCgKr8UMRuIUV9HOrzqnpnWZHl5+QthH7Za5yHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx3Ecx3F8n1WO4ziO4ziO77PKcRzHcRzH8X1WOY7jOI7jOL7PKsdxHMdxHMf3WeU4juM4juP4Pqscx3Ecx3Ec32eV4ziO4ziO4/uschzHcRzHcXyfVY7jOI7jOI7vs8pxHMdxHMfxfVY5juM4juM4vs8qx3Ecx3Ecx/dZ5TiO4ziO4/g+qxzHcRzHcRzfZ5XjOI7jOI7j+6xyHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx3Ecx3F8n1WO4ziO4ziO77PKcRzHcRzH8X1WOY7jOI7jOL7PKsdxHMdxHMf3WeU4juM4juP4Pqscx3Ecx3Ec32eV4ziO4ziO4/uschzHcRzHcXyfVY7jOI7jOI7vs8pxHMdxHMfxfVY5juM4juM4vs8qx3Ecx3Ecx/dZ5TiO4ziO4/g+qxzHcRzHcRzfZ5XjOI7jOI7j+6xyHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx/8d1TZfVdv8d1J52ea/kwqVlx8/fjiO4/ifaJXjOP7vqLb5qtrmv5PKyzb/nVSovPz48cNxHMf/RKscx/H3Vvlpm/82KlRetnnZ5jiO43+QVY7j+3z0IebT3GJpHjEjluZXI5bmVyPE/EbMr0aMfBqNWJqfRi...', ...}
[2025-08-23 21:17:21,750: INFO/MainProcess] Task worker.translate_task[db613d37-cd69-4902-8cee-176c6e857cb1] received
[2025-08-23 21:17:21,751] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:21,751: INFO/MainProcess] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:21,752] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before DECODE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,752: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before DECODE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,754] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after DECODE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,754: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after DECODE] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,754] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:17:21,754: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:17:21,755] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before OCR] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,755: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before OCR] used=763.9MB free=3332.1MB total=4096.0MB
[2025-08-23 21:17:21,755] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:21,755: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:21,827] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:21,827: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:21,827] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:21,827: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:21,827] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:21,827: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:21,827] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][OCR] Δused=128.0MB, elapsed=0.073s
[2025-08-23 21:17:21,827: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][OCR] Δused=128.0MB, elapsed=0.073s
[2025-08-23 21:17:21,853] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:21,853: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:21,853: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:17:22,184: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:17:22,184] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,184: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,184] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][TRANSLATE] Δused=0.0MB, elapsed=0.331s
[2025-08-23 21:17:22,184: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][TRANSLATE] Δused=0.0MB, elapsed=0.331s
[2025-08-23 21:17:22,184] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,184: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,186] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:22,186: INFO/MainProcess] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:22,186] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:22,186: INFO/MainProcess] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:22,186] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,186: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,186] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:22,186: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:22,189] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,189: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:22,189] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:22,189: INFO/MainProcess] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:22,189] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:22,189: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:22,189] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:22,189: INFO/MainProcess] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:22,190] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:22,190: INFO/MainProcess] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:22,190] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:684] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:22,190: INFO/MainProcess] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:22,190] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:22,190: INFO/MainProcess] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:22,191: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:22,191: INFO/MainProcess] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:22,191: INFO/MainProcess] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:22,191: INFO/MainProcess] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 처리 준비: 버킷=webtoon_standard, 전략=full, 버킷화=0.001s, 스케일링=0.000s, 전략선택=0.001s
[2025-08-23 21:17:22,191: INFO/MainProcess] 🔧 처리 준비: 버킷=webtoon_standard, 전략=full, 버킷화=0.001s, 스케일링=0.000s, 전략선택=0.001s
[2025-08-23 21:17:22,191] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 전체 이미지 처리 시작 (버킷: webtoon_standard)
[2025-08-23 21:17:22,191: INFO/MainProcess] 전체 이미지 처리 시작 (버킷: webtoon_standard)
[2025-08-23 21:17:26,944] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 📊 성능 기록: webtoon_standard (full) = 4.75s, 평균: 2.97s
[2025-08-23 21:17:26,944: INFO/MainProcess] 📊 성능 기록: webtoon_standard (full) = 4.75s, 평균: 2.97s
[2025-08-23 21:17:26,945] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🎯 인페인팅 완료: 총 4.755s (인페인팅: 4.753s, 복원: 0.000s)
[2025-08-23 21:17:26,945: INFO/MainProcess] 🎯 인페인팅 완료: 총 4.755s (인페인팅: 4.753s, 복원: 0.000s)
[2025-08-23 21:17:27,120] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][db613d37-cd69-4902-8cee-176c6e857cb1] 경량 정리 완료: Python객체=334개, GPU캐시=0.0MB
[2025-08-23 21:17:27,120: DEBUG/MainProcess] [MEMORY][db613d37-cd69-4902-8cee-176c6e857cb1] 경량 정리 완료: Python객체=334개, GPU캐시=0.0MB
[2025-08-23 21:17:27,121] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,121: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,121] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][INPAINT] Δused=0.0MB, elapsed=4.932s
[2025-08-23 21:17:27,121: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][INPAINT] Δused=0.0MB, elapsed=4.932s
[2025-08-23 21:17:27,147: INFO/MainProcess] worker.translate_task[db613d37-cd69-4902-8cee-176c6e857cb1]: [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1][font] 요청된 폰트 번호: 5
[2025-08-23 21:17:27,147] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before RENDER] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,147: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][before RENDER] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,147] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:27,147: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:27,150] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:17:27,150: DEBUG/MainProcess] WCAG 대비 보정: 배경(252, 252, 252) → 텍스트(0, 0, 0) (비율: 20.47)
[2025-08-23 21:17:27,163] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:27,163: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:27,165] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:27,165: DEBUG/MainProcess] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:27,187] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:27,187: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:27,189] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 170, 164) → 텍스트(0, 0, 0) (비율: 9.30)
[2025-08-23 21:17:27,189: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 170, 164) → 텍스트(0, 0, 0) (비율: 9.30)
[2025-08-23 21:17:27,204] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:27,204: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:27,206] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:17:27,206: DEBUG/MainProcess] WCAG 대비 보정: 배경(184, 173, 167) → 텍스트(0, 0, 0) (비율: 9.57)
[2025-08-23 21:17:27,221] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:27,221: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:27,222] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:27,222: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:27,222] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after RENDER] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,222: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][after RENDER] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:27,222] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][RENDER] Δused=0.0MB, elapsed=0.075s
[2025-08-23 21:17:27,222: INFO/MainProcess] [GPUMem][db613d37-cd69-4902-8cee-176c6e857cb1][RENDER] Δused=0.0MB, elapsed=0.075s
[2025-08-23 21:17:27,248: INFO/MainProcess] worker.translate_task[db613d37-cd69-4902-8cee-176c6e857cb1]: [DEBUG] artifacts saved: /app/temp_files/debug/f8a1e012_*.png
[2025-08-23 21:17:27,248] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] translate_task done
[2025-08-23 21:17:27,248: INFO/MainProcess] [TRACE][db613d37-cd69-4902-8cee-176c6e857cb1] translate_task done
[2025-08-23 21:17:27,283: INFO/MainProcess] Task worker.translate_task[db613d37-cd69-4902-8cee-176c6e857cb1] succeeded in 5.531947165029123s: {'status': 'SUCCESS', 'result_image': 'iVBORw0KGgoAAAANSUhEUgAAAzAAAASwCAIAAACrfTgaAAAgAElEQVR4AezBjZElaUCey3zHCgKr8UMRuIUV9HOrzqnpnWZH/CikbS77Za5yHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx3Ecx3F8n1WO4ziO4ziO77PKcRzHcRzH8X1WOY7jOI7jOL7PKsdxHMdxHMf3WeU4juM4juP4Pqscx3Ecx3Ec32eV4ziO4ziO4/uschzHcRzHcXyfVY7jOI7jOI7vs8pxHMdxHMfxfVY5juM4juM4vs8qx3Ecx3Ecx/dZ5TiO4ziO4/g+qxzHcRzHcRzfZ5XjOI7jOI7j+6xyHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx3Ecx3F8n1WO4ziO4ziO77PKcRzHcRzH8X1WOY7jOI7jOL7PKsdxHMdxHMf3WeU4juM4juP4Pqscx3Ecx3Ec32eV4ziO4ziO4/uschzHcRzHcXyfVY7jOI7jOI7vs8pxHMdxHMfxfVY5juM4juM4vs8qx3Ecx3Ecx/dZ5TiO4ziO4/g+qxzHcRzHcRzfZ5XjOI7jOI7j+6xyHMdxHMdxfJ9VjuM4juM4ju+zynEcx3Ecx/F9VjmO4ziO4zi+zyrHcRzHcRzH91nlOI7jOI7j+D6rHMdxHMdxHN9nleM4juM4juP7rHIcx/8b1TZfVdv8d1J52ea/kwqVlx8/fjiO4/ifaJXjOP7fqLb5qtrmv5PKyzb/nVSovPz48cNxHMf/RKscx/H3Vvlpm/82KlRetnnZ5jiO43+QVY7j+3z0IebT3GJpxIhZmqX51Yil+dUIMb8R86sRI59GI5bmp9...', ...}
[2025-08-23 21:17:31,924: INFO/MainProcess] Task worker.translate_task[00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] received
[2025-08-23 21:17:31,925] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:31,925: INFO/MainProcess] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] translate_task start (file=6.jpg, user=tester)
[2025-08-23 21:17:31,925] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before DECODE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,925: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before DECODE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,928] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after DECODE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,928: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after DECODE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,928] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:569] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:17:31,928: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][DECODE] Δused=0.0MB, elapsed=0.003s
[2025-08-23 21:17:31,928] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,928: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,928] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:579] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:31,928: INFO/MainProcess] 🔍 OCR(ndarray) 감지 시작
[2025-08-23 21:17:31,990] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:580] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:31,990: INFO/MainProcess] 중국어 텍스트 4개 필터링 완료
[2025-08-23 21:17:31,991] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:580] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:31,991: DEBUG/MainProcess] [{'text': '现代极简风格', 'confidence': 0.9964253902435303, 'polygon': [[221, 70], [552, 70], [552, 117], [221, 117]], 'bbox': (221, 70, 332, 48), 'method': 'polygon'}, {'text': '更易搭配各种使用场景', 'confidence': 0.9955397844314575, 'polygon': [[151, 141], [622, 141], [622, 180], [151, 180]], 'bbox': (151, 141, 472, 40), 'method': 'polygon'}, {'text': '半圆两端设计', 'confidence': 0.9963843822479248, 'polygon': [[87, 288], [462, 288], [462, 345], [87, 345]], 'bbox': (87, 288, 376, 58), 'method': 'polygon'}, {'text': '承载各种欢乐', 'confidence': 0.9927356243133545, 'polygon': [[86, 368], [461, 368], [461, 425], [86, 425]], 'bbox': (86, 368, 376, 58), 'method': 'polygon'}]
[2025-08-23 21:17:31,991] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,991: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after OCR] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:31,991] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:577] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][OCR] Δused=0.0MB, elapsed=0.063s
[2025-08-23 21:17:31,991: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][OCR] Δused=0.0MB, elapsed=0.063s
[2025-08-23 21:17:32,016] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,016: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,016: WARNING/MainProcess] translate_batch in: ['现代极简风格', '更易搭配各种使用场景', '半圆两端设计', '承载各种欢乐']
[2025-08-23 21:17:32,341: WARNING/MainProcess] translate_batch out: ['현대 미니멀리스트 스타일', '다양한 사용 시나리오와 더 쉽게 일치 할 수 있습니다', '양쪽 끝에 반원의 디자인', '모든 종류의 기쁨을 가지고 다니십시오']
[2025-08-23 21:17:32,341] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,341: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after TRANSLATE] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,341] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:589] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][TRANSLATE] Δused=0.0MB, elapsed=0.325s
[2025-08-23 21:17:32,341: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][TRANSLATE] Δused=0.0MB, elapsed=0.325s
[2025-08-23 21:17:32,341] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,341: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,342] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:32,342: INFO/MainProcess] 🔧 ROI용 강화 마스크 생성 (잔상 방지 처리)
[2025-08-23 21:17:32,343] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:32,343: INFO/MainProcess] 🔧 ROI최적화 마스크 사용: 커버리지 12.14% (118,836/979,200 픽셀)
[2025-08-23 21:17:32,343] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,343: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after MASK] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,343] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:598] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:32,343: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][MASK] Δused=0.0MB, elapsed=0.002s
[2025-08-23 21:17:32,345] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,345: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before INPAINT] used=891.9MB free=3204.1MB total=4096.0MB
[2025-08-23 21:17:32,345] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:32,345: INFO/MainProcess] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] 선택된 인페인팅 방법: roi
[2025-08-23 21:17:32,346] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:32,346: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:32,346] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:742] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:32,346: INFO/MainProcess] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:32,346] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:32,346: INFO/MainProcess] [INPAINT] ROI 처리 통계: 3개 컴포넌트 → 2개 ROI, 메모리 효율성: 77.8%
[2025-08-23 21:17:32,346] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:684] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:32,346: INFO/MainProcess] 🔧 형상 버킷 최적화: 1200×816 → 1200×832 (webtoon_standard)
[2025-08-23 21:17:32,347] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:32,347: INFO/MainProcess] 🔧 패딩 적용: 1200×816 → 1200×832 (padding: top=0, bottom=0, left=8, right=8)
[2025-08-23 21:17:32,347] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:32,347: INFO/MainProcess] 마스크 컴포넌트 3개 발견
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:32,348: INFO/MainProcess] [STRATEGY] 🎯 핵심 지표: S=1.0MP, A=11.9%, N=3, H=3706MB
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:32,348: INFO/MainProcess] [STRATEGY] 선택된 전략: full (이유: small_image(S=1.0MP) or small_roi(A=11.9%, N=3) + gpu_plenty(H=3706MB))
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:32,348: INFO/MainProcess] [STRATEGY] 성능 예측: ROI오버헤드=0.090s, 처리시간=0.499s, 효율비=0.18
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [WARNING] [celery_worker.py:translate_task:750] ⚡ ROI 폴백 트리거: webtoon_standard 평균 2.97s > 예측 0.50s × 4
[2025-08-23 21:17:32,348: WARNING/MainProcess] ⚡ ROI 폴백 트리거: webtoon_standard 평균 2.97s > 예측 0.50s × 4
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [WARNING] [autoretry.py:run:38] 🔄 전략 변경: full → roi (성능 히스토리 기반)
[2025-08-23 21:17:32,348: WARNING/MainProcess] 🔄 전략 변경: full → roi (성능 히스토리 기반)
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔧 처리 준비: 버킷=webtoon_standard, 전략=roi, 버킷화=0.001s, 스케일링=0.000s, 전략선택=0.001s
[2025-08-23 21:17:32,348: INFO/MainProcess] 🔧 처리 준비: 버킷=webtoon_standard, 전략=roi, 버킷화=0.001s, 스케일링=0.000s, 전략선택=0.001s
[2025-08-23 21:17:32,348] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] ROI 순차 처리 시작
[2025-08-23 21:17:32,348: INFO/MainProcess] ROI 순차 처리 시작
[2025-08-23 21:17:32,349] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:722] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:32,349: INFO/MainProcess] 컴포넌트 병합: 3 → 2
[2025-08-23 21:17:32,349] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:722] ROI 처리: 642x171 (11.0% of image, 종횡비:3.8)
[2025-08-23 21:17:32,349: INFO/MainProcess] ROI 처리: 642x171 (11.0% of image, 종횡비:3.8)
[2025-08-23 21:17:32,349] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:722] 🔧 마스크 모듈 최적화 마스크 사용 (추가 정제 생략)
[2025-08-23 21:17:32,349: INFO/MainProcess] 🔧 마스크 모듈 최적화 마스크 사용 (추가 정제 생략)
[2025-08-23 21:17:32,349] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:_process_roi_sequential:1457] 크기 정규화: 642x171 → 648x176 (패딩: t2b3l3r3)
[2025-08-23 21:17:32,349: INFO/MainProcess] 크기 정규화: 642x171 → 648x176 (패딩: t2b3l3r3)
[2025-08-23 21:17:32,473] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:_process_roi_sequential:1457] 크기 복원: 648x176 → 642x171
[2025-08-23 21:17:32,473: INFO/MainProcess] 크기 복원: 648x176 → 642x171
[2025-08-23 21:17:32,478] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:722] ROI 처리: 517x208 (10.8% of image, 종횡비:2.5)
[2025-08-23 21:17:32,478: INFO/MainProcess] ROI 처리: 517x208 (10.8% of image, 종횡비:2.5)
[2025-08-23 21:17:32,478] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:inpaint_with_roi:722] 🔧 마스크 모듈 최적화 마스크 사용 (추가 정제 생략)
[2025-08-23 21:17:32,478: INFO/MainProcess] 🔧 마스크 모듈 최적화 마스크 사용 (추가 정제 생략)
[2025-08-23 21:17:32,479] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:_process_roi_sequential:1457] 크기 정규화: 517x208 → 520x208 (패딩: t0b0l1r2)
[2025-08-23 21:17:32,479: INFO/MainProcess] 크기 정규화: 517x208 → 520x208 (패딩: t0b0l1r2)
[2025-08-23 21:17:36,500] [ThreadPoolExecutor-0_0] [INFO] [roi_inpainting_module.py:_process_roi_sequential:1457] 크기 복원: 520x208 → 517x208
[2025-08-23 21:17:36,500: INFO/MainProcess] 크기 복원: 520x208 → 517x208
[2025-08-23 21:17:36,504] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] ROI 순차 처리 완료: 2/2 성공
[2025-08-23 21:17:36,504: INFO/MainProcess] ROI 순차 처리 완료: 2/2 성공
[2025-08-23 21:17:36,504] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:750] 📊 성능 기록: webtoon_standard (roi) = 4.16s, 평균: 3.36s
[2025-08-23 21:17:36,504: INFO/MainProcess] 📊 성능 기록: webtoon_standard (roi) = 4.16s, 평균: 3.36s
[2025-08-23 21:17:36,504] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🎯 인페인팅 완료: 총 4.157s (인페인팅: 4.155s, 복원: 0.000s)
[2025-08-23 21:17:36,504: INFO/MainProcess] 🎯 인페인팅 완료: 총 4.157s (인페인팅: 4.155s, 복원: 0.000s)
[2025-08-23 21:17:36,673] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] [MEMORY][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] 경량 정리 완료: Python객체=324개, GPU캐시=0.0MB
[2025-08-23 21:17:36,673: DEBUG/MainProcess] [MEMORY][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] 경량 정리 완료: Python객체=324개, GPU캐시=0.0MB
[2025-08-23 21:17:36,673] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after INPAINT] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,673: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after INPAINT] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,673] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:662] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][INPAINT] Δused=2.0MB, elapsed=4.328s
[2025-08-23 21:17:36,673: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][INPAINT] Δused=2.0MB, elapsed=4.328s
[2025-08-23 21:17:36,699: INFO/MainProcess] worker.translate_task[00f64ea3-d61d-4b2b-9fb2-f9790fc5d068]: [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][font] 요청된 폰트 번호: 5
[2025-08-23 21:17:36,699] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:98] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before RENDER] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,699: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][before RENDER] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,699] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:36,699: INFO/MainProcess] 🔥 고급 텍스트 렌더링 시작: 4개 텍스트
[2025-08-23 21:17:36,702] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:36,702: DEBUG/MainProcess] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:36,715] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:36,715: DEBUG/MainProcess] 텍스트 1/4 렌더링 완료
[2025-08-23 21:17:36,717] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:36,717: DEBUG/MainProcess] WCAG 대비 보정: 배경(253, 253, 253) → 텍스트(0, 0, 0) (비율: 20.65)
[2025-08-23 21:17:36,739] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:36,739: DEBUG/MainProcess] 텍스트 2/4 렌더링 완료
[2025-08-23 21:17:36,741] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:17:36,741: DEBUG/MainProcess] WCAG 대비 보정: 배경(183, 171, 164) → 텍스트(0, 0, 0) (비율: 9.37)
[2025-08-23 21:17:36,756] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:36,756: DEBUG/MainProcess] 텍스트 3/4 렌더링 완료
[2025-08-23 21:17:36,758] [ThreadPoolExecutor-0_0] [DEBUG] [celery_worker.py:translate_task:766] WCAG 대비 보정: 배경(185, 174, 168) → 텍스트(0, 0, 0) (비율: 9.68)
[2025-08-23 21:17:36,758: DEBUG/MainProcess] WCAG 대비 보정: 배경(185, 174, 168) → 텍스트(0, 0, 0) (비율: 9.68)
[2025-08-23 21:17:36,773] [ThreadPoolExecutor-0_0] [DEBUG] [autoretry.py:run:38] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:36,773: DEBUG/MainProcess] 텍스트 4/4 렌더링 완료
[2025-08-23 21:17:36,773] [ThreadPoolExecutor-0_0] [INFO] [autoretry.py:run:38] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:36,773: INFO/MainProcess] 🔥 고급 텍스트 렌더링 완료
[2025-08-23 21:17:36,774] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:track_phase:103] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after RENDER] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,774: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][after RENDER] used=893.9MB free=3202.1MB total=4096.0MB
[2025-08-23 21:17:36,774] [ThreadPoolExecutor-0_0] [INFO] [celery_worker.py:translate_task:765] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][RENDER] Δused=0.0MB, elapsed=0.075s
[2025-08-23 21:17:36,774: INFO/MainProcess] [GPUMem][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068][RENDER] Δused=0.0MB, elapsed=0.075s
[2025-08-23 21:17:36,800: INFO/MainProcess] worker.translate_task[00f64ea3-d61d-4b2b-9fb2-f9790fc5d068]: [DEBUG] artifacts saved: /app/temp_files/debug/a8182df4_*.png
[2025-08-23 21:17:36,800] [ThreadPoolExecutor-0_0] [INFO] [trace.py:__protected_call__:760] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] translate_task done
[2025-08-23 21:17:36,800: INFO/MainProcess] [TRACE][00f64ea3-d61d-4b2b-9fb2-f9790fc5d068] translate_task done

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 KiB

After

Width:  |  Height:  |  Size: 521 KiB

View File

@ -16,12 +16,12 @@ import requests
API_ROOT = "http://localhost:7890" # 메인 서버 주소
IMAGE_PATH = pathlib.Path("8.jpg")
IMAGE_PATH = pathlib.Path("7.jpg")
TIMEOUT = 120 # 초
unwanted_texts = {
"할인": "", "무료": "", "증정": "", "이벤트": "", "특가": "", "세일": "",
"사은품": "", "보증": "", "품절": "", "행사": "", "할인가": "",
"사은품": "", "보증": "", "품절": "", "행사": "", "할인가": "", "10년보증": "",
"무료배송": "", "가격설명": ""
}
@ -38,23 +38,42 @@ toggle_states = {"inpaint_method": "lama:cuda", "min_masks_for_lama": 2, 'title'
toggle_states.update({
# 🔥 MIGAN 인페인팅 사용 설정
"inpaint_method": "migan", # ROI → MIGAN 변경
# "inpaint_method": "migan", # ROI → MIGAN 변경
"migan_use_cuda": True, # CUDA 사용
"migan_use_tensorrt": True, # TensorRT 최적화
"migan_use_tensorrt": False, # TensorRT 최적화
"migan_trt_fp16_enable": True, # FP16 활성화
"migan_trt_engine_cache_enable": True, # 엔진 캐시 활성화
"migan_max_image_size": 1600, # 최대 이미지 크기
"migan_output_max_width": 800, # 출력 최대 가로
"migan_enable_output_resize": True, # 출력 리사이즈 활성화
"migan_enable_output_resize": False, # 출력 리사이즈 활성화
"migan_mask_expansion": 7,
"migan_mask_dilate_iters": 2,
"migan_mask_enable_closing": True,
"migan_mask_closing_kernel": 7,
"migan_mask_min_component_area": 64,
"overwrite_force_margin_px": 5,
"migan_mask_bridge_h_px": 10,
"migan_mask_bridge_v_px": 10,
# 기존 ROI 설정들 (MIGAN에서는 사용되지 않지만 호환성 유지)
"use_roi_optimized_mask": True, # True: 새 방식, False: 기존 방식
"enable_mask_refinement": False, # ROI 마스크 정제 비활성화
"context_expansion_ratio": 0.4, # 최소 확장
"blend_mode": "simple", # 단순 블렌딩
"performance_mode": True, # 빠른 경로 사용
"max_image_size": 1280, # 더 작은 크기 제한
"roi_area_high": 0.0 # 기본값: 0.60 → 0.0으로 변경 # 풀프레임 인페인팅 강제
# 🔥 ROI 완전 비활성화
"roi_area_high": 0.0, # 강제 full 전략
"roi_area_low": 0.0, # 폴백 차단
"memory_high_threshold": 10000, # 메모리 제약 무시
"memory_low_threshold": 0, # 메모리 폴백 차단
# 🔥 추가 최적화
"enable_mask_refinement": False, # 마스크 정제 비활성화
"blend_mode": "simple", # 단순 블렌딩
"performance_mode": True, # 성능 모드
"disable_roi_fallback": True, # 🔥 ROI 폴백 로직 완전 비활성화
"roi_area_high": 1.0, # 🔥 100% 임계값으로 설정 → 항상 full 전략 강제
"context_expansion_ratio": 0.1, # 컨텍스트 확장 최소화
"small_image_mp": 10.0, # 모든 이미지를 작은 이미지로 간주
"roi_count_threshold": 100, # ROI 개수 임계값 높임
"max_image_size": 2048, # 크기 제한 완화
"use_roi_optimized_mask": True, # ROI 최적화 마스크 사용
})
def call_translate(img_path: pathlib.Path):

View File

@ -597,22 +597,50 @@ def translate_task(self, *, image_b64: str, filename: str,
with track_phase("MASK", trace_id):
# 🔥 A/B 테스트: 기존 방식 vs ROI 최적화 방식
use_roi_optimized_mask = toggle_states.get('use_roi_optimized_mask', False) # True → False로 변경
if use_roi_optimized_mask:
# 🔥 ROI 최적화: 적응형 마스크 생성
mask = get_mask().create_masks_np(
src_bgr, chn,
for_roi_processing=True,
# 🔥 텍스트 개수에 따른 적응형 expansion
expansion_size=min(8, max(4, 10 - len(chn))), # 텍스트 많으면 작게, 적으면 크게
blur_size=0 # ROI 모드에서는 블러 없음
# 인페인팅 방법 선결정 (MIGAN이면 전용 마스크 사용)
_method = _parse_inpaint_method(toggle_states)
use_roi_optimized_mask = toggle_states.get('use_roi_optimized_mask', False)
if _method == "migan":
# 🔥 MIGAN 전용 마스크: 테스트/운영에서 토글로 즉시 튜닝 가능
exp_from_toggle = toggle_states.get('migan_mask_expansion')
area_from_toggle = toggle_states.get('migan_mask_min_component_area')
dilate_iters = toggle_states.get('migan_mask_dilate_iters')
closing_enable = toggle_states.get('migan_mask_enable_closing', True)
closing_kernel = toggle_states.get('migan_mask_closing_kernel', 3)
bridge_h = toggle_states.get('migan_mask_bridge_h_px', 0)
bridge_v = toggle_states.get('migan_mask_bridge_v_px', 0)
adaptive_exp = min(10, max(5, 12 - len(chn)))
expansion_sz = int(exp_from_toggle) if isinstance(exp_from_toggle, (int, str)) and str(exp_from_toggle).isdigit() else adaptive_exp
min_area = int(area_from_toggle) if isinstance(area_from_toggle, (int, str)) and str(area_from_toggle).isdigit() else 32
mask = get_mask().create_masks_migan_np(
src_bgr, chn,
expansion_size=expansion_sz,
min_component_area=min_area,
dilate_iters=int(dilate_iters) if isinstance(dilate_iters, (int, str)) and str(dilate_iters).isdigit() else 1,
enable_closing=bool(closing_enable),
closing_kernel=int(closing_kernel) if isinstance(closing_kernel, (int, str)) and str(closing_kernel).isdigit() else 3,
bridge_h_px=int(bridge_h) if isinstance(bridge_h, (int, str)) and str(bridge_h).isdigit() else 0,
bridge_v_px=int(bridge_v) if isinstance(bridge_v, (int, str)) and str(bridge_v).isdigit() else 0
)
mask_type = "ROI최적화"
mask_type = f"MIGAN용(expand={expansion_sz}, min_area={min_area}, dilate={dilate_iters or 1}, closing={closing_enable}, bridge_h={bridge_h or 0}, bridge_v={bridge_v or 0})"
else:
# 기존 방식: 전체 후처리 적용
mask = get_mask().create_masks_np(src_bgr, chn)
mask_type = "기존방식"
# ROI 인페인팅/기타: 기존 로직 유지
if use_roi_optimized_mask:
# 🔥 ROI 최적화: 적응형 마스크 생성
mask = get_mask().create_masks_np(
src_bgr, chn,
for_roi_processing=True,
# 🔥 텍스트 개수에 따른 적응형 expansion
expansion_size=min(8, max(4, 10 - len(chn))),
blur_size=0 # ROI 모드에서는 블러 없음
)
mask_type = "ROI최적화"
else:
# 기존 방식: 전체 후처리 적용 (LAMA 등)
mask = get_mask().create_masks_np(src_bgr, chn)
mask_type = "기존방식"
# 🔥 마스크 통계 로깅
mask_pixels = np.sum(mask > 0)

View File

@ -0,0 +1,417 @@
"""
동적 메모리 기반 세션풀 관리 시스템
- GPU 메모리 자동 감지
- LAMA:MIGAN 비율 기반 최적 세션풀 구성
- 실시간 메모리 모니터링 동적 조정
"""
import logging
import time
from typing import Dict, Tuple, Optional, Any
from dataclasses import dataclass
from enum import Enum
import torch
import psutil
class GPUTier(Enum):
"""GPU 등급 분류"""
RTX_3050_4GB = "rtx_3050_4gb"
RTX_3060_12GB = "rtx_3060_12gb"
RTX_3070_8GB = "rtx_3070_8gb"
RTX_3080_10GB = "rtx_3080_10gb"
RTX_3090_24GB = "rtx_3090_24gb"
RTX_4060_16GB = "rtx_4060_16gb"
RTX_4070_12GB = "rtx_4070_12gb"
RTX_4080_16GB = "rtx_4080_16gb"
RTX_4090_24GB = "rtx_4090_24gb"
UNKNOWN = "unknown"
@dataclass
class SessionPoolConfig:
"""세션풀 구성"""
migan_sessions: int
lama_sessions: int
ocr_sessions: int
workers: int
total_vram_usage_mb: int
safety_margin_mb: int
expected_concurrent_clients: int
@property
def total_sessions(self) -> int:
return self.migan_sessions + self.lama_sessions + self.ocr_sessions
@property
def lama_migan_ratio(self) -> str:
total = self.lama_sessions + self.migan_sessions
if total == 0:
return "0:0"
lama_pct = round((self.lama_sessions / total) * 10)
migan_pct = 10 - lama_pct
return f"{lama_pct}:{migan_pct}"
@property
def worker_session_ratio(self) -> float:
if self.total_sessions == 0:
return 0.0
return self.workers / self.total_sessions
@dataclass
class MemoryInfo:
"""메모리 정보"""
total_vram_mb: int
available_vram_mb: int
used_vram_mb: int
gpu_name: str
gpu_tier: GPUTier
cuda_capability: str
supports_fp16: bool
supports_tensor_cores: bool
class DynamicSessionPoolManager:
"""동적 세션풀 관리자"""
# 🎯 세션별 메모리 사용량 (MB)
MEMORY_USAGE = {
'migan_session': 1200, # MIGAN 웜업 후 메모리
'lama_session': 500, # LAMA 세션 메모리
'ocr_session': 400, # OCR 세션 메모리
'system_overhead': 500, # 시스템 오버헤드
}
# 🎯 GPU별 최적 구성 템플릿
GPU_TEMPLATES = {
GPUTier.RTX_4080_16GB: {
'target_vram_usage_pct': 70,
'lama_migan_ratio': (4, 6), # 4:6
'worker_session_ratio': 3.0,
'max_concurrent_clients': 50,
},
GPUTier.RTX_3090_24GB: {
'target_vram_usage_pct': 70,
'lama_migan_ratio': (3, 7), # 3:7
'worker_session_ratio': 3.0,
'max_concurrent_clients': 70,
},
GPUTier.RTX_3080_10GB: {
'target_vram_usage_pct': 65,
'lama_migan_ratio': (5, 5), # 5:5
'worker_session_ratio': 3.5,
'max_concurrent_clients': 30,
},
GPUTier.RTX_3070_8GB: {
'target_vram_usage_pct': 60,
'lama_migan_ratio': (6, 4), # 6:4 (LAMA 중심)
'worker_session_ratio': 4.0,
'max_concurrent_clients': 20,
},
GPUTier.RTX_3050_4GB: {
'target_vram_usage_pct': 55,
'lama_migan_ratio': (8, 2), # 8:2 (LAMA 중심)
'worker_session_ratio': 5.0,
'max_concurrent_clients': 10,
},
}
def __init__(self, logger: Optional[logging.Logger] = None):
self.logger = logger or logging.getLogger(__name__)
self._memory_info: Optional[MemoryInfo] = None
self._current_config: Optional[SessionPoolConfig] = None
self._last_memory_check = 0
self._memory_check_interval = 30 # 30초마다 메모리 체크
def detect_gpu_info(self) -> MemoryInfo:
"""GPU 정보 자동 감지"""
if not torch.cuda.is_available():
raise RuntimeError("CUDA GPU를 사용할 수 없습니다")
device = torch.cuda.current_device()
props = torch.cuda.get_device_properties(device)
# GPU 메모리 정보
total_memory = torch.cuda.get_device_properties(device).total_memory
total_vram_mb = int(total_memory / (1024 * 1024))
# 현재 사용 중인 메모리
torch.cuda.empty_cache() # 캐시 정리
allocated = torch.cuda.memory_allocated(device)
reserved = torch.cuda.memory_reserved(device)
used_vram_mb = int(max(allocated, reserved) / (1024 * 1024))
available_vram_mb = total_vram_mb - used_vram_mb
# GPU 이름 및 등급 판정
gpu_name = props.name
gpu_tier = self._classify_gpu_tier(gpu_name, total_vram_mb)
# CUDA 기능 확인
capability = f"{props.major}.{props.minor}"
supports_fp16 = props.major >= 7 # Volta 이상
supports_tensor_cores = props.major >= 7
memory_info = MemoryInfo(
total_vram_mb=total_vram_mb,
available_vram_mb=available_vram_mb,
used_vram_mb=used_vram_mb,
gpu_name=gpu_name,
gpu_tier=gpu_tier,
cuda_capability=capability,
supports_fp16=supports_fp16,
supports_tensor_cores=supports_tensor_cores
)
self.logger.info(f"🔍 GPU 감지: {gpu_name} ({gpu_tier.value})")
self.logger.info(f"💾 VRAM: {total_vram_mb}MB 총용량, {available_vram_mb}MB 사용가능")
self.logger.info(f"⚡ CUDA {capability}, FP16: {supports_fp16}, TensorCores: {supports_tensor_cores}")
self._memory_info = memory_info
return memory_info
def _classify_gpu_tier(self, gpu_name: str, total_vram_mb: int) -> GPUTier:
"""GPU 이름과 메모리로 등급 분류"""
gpu_name_lower = gpu_name.lower()
# RTX 40 시리즈
if "4090" in gpu_name_lower:
return GPUTier.RTX_4090_24GB
elif "4080" in gpu_name_lower:
return GPUTier.RTX_4080_16GB
elif "4070" in gpu_name_lower:
return GPUTier.RTX_4070_12GB
elif "4060" in gpu_name_lower:
return GPUTier.RTX_4060_16GB
# RTX 30 시리즈
elif "3090" in gpu_name_lower:
return GPUTier.RTX_3090_24GB
elif "3080" in gpu_name_lower:
return GPUTier.RTX_3080_10GB
elif "3070" in gpu_name_lower:
return GPUTier.RTX_3070_8GB
elif "3060" in gpu_name_lower:
return GPUTier.RTX_3060_12GB
elif "3050" in gpu_name_lower:
return GPUTier.RTX_3050_4GB
# 메모리 기반 추정
elif total_vram_mb >= 22000: # 22GB+
return GPUTier.RTX_3090_24GB
elif total_vram_mb >= 15000: # 15GB+
return GPUTier.RTX_4080_16GB
elif total_vram_mb >= 11000: # 11GB+
return GPUTier.RTX_3060_12GB
elif total_vram_mb >= 9000: # 9GB+
return GPUTier.RTX_3080_10GB
elif total_vram_mb >= 7000: # 7GB+
return GPUTier.RTX_3070_8GB
elif total_vram_mb >= 3500: # 3.5GB+
return GPUTier.RTX_3050_4GB
else:
return GPUTier.UNKNOWN
def calculate_optimal_config(self,
custom_lama_migan_ratio: Optional[Tuple[int, int]] = None,
custom_worker_session_ratio: Optional[float] = None) -> SessionPoolConfig:
"""최적 세션풀 구성 계산"""
if not self._memory_info:
self.detect_gpu_info()
memory_info = self._memory_info
gpu_tier = memory_info.gpu_tier
# GPU별 템플릿 가져오기
if gpu_tier in self.GPU_TEMPLATES:
template = self.GPU_TEMPLATES[gpu_tier].copy()
else:
# 알 수 없는 GPU의 경우 보수적 설정
template = {
'target_vram_usage_pct': 50,
'lama_migan_ratio': (7, 3),
'worker_session_ratio': 4.0,
'max_concurrent_clients': 15,
}
self.logger.warning(f"⚠️ 알 수 없는 GPU: {memory_info.gpu_name}, 보수적 설정 적용")
# 사용자 지정 비율 적용
if custom_lama_migan_ratio:
template['lama_migan_ratio'] = custom_lama_migan_ratio
if custom_worker_session_ratio:
template['worker_session_ratio'] = custom_worker_session_ratio
# 사용 가능한 VRAM 계산
target_usage_mb = int(memory_info.available_vram_mb * template['target_vram_usage_pct'] / 100)
safety_margin_mb = memory_info.available_vram_mb - target_usage_mb
# 시스템 오버헤드 제외
available_for_sessions = target_usage_mb - self.MEMORY_USAGE['system_overhead']
if available_for_sessions <= 0:
raise RuntimeError(f"❌ 세션풀 생성에 필요한 메모리가 부족합니다: {available_for_sessions}MB")
# LAMA:MIGAN 비율 적용
lama_ratio, migan_ratio = template['lama_migan_ratio']
total_ratio = lama_ratio + migan_ratio
# 세션 개수 계산
migan_memory_budget = int(available_for_sessions * migan_ratio / total_ratio)
lama_memory_budget = int(available_for_sessions * lama_ratio / total_ratio)
migan_sessions = max(1, migan_memory_budget // self.MEMORY_USAGE['migan_session'])
lama_sessions = max(1, lama_memory_budget // self.MEMORY_USAGE['lama_session'])
# OCR 세션 (남은 메모리로)
used_memory = (migan_sessions * self.MEMORY_USAGE['migan_session'] +
lama_sessions * self.MEMORY_USAGE['lama_session'])
remaining_memory = available_for_sessions - used_memory
ocr_sessions = max(2, remaining_memory // self.MEMORY_USAGE['ocr_session'])
# 워커 수 계산
total_sessions = migan_sessions + lama_sessions + ocr_sessions
workers = int(total_sessions * template['worker_session_ratio'])
# 총 메모리 사용량 계산
total_usage = (migan_sessions * self.MEMORY_USAGE['migan_session'] +
lama_sessions * self.MEMORY_USAGE['lama_session'] +
ocr_sessions * self.MEMORY_USAGE['ocr_session'] +
self.MEMORY_USAGE['system_overhead'])
config = SessionPoolConfig(
migan_sessions=migan_sessions,
lama_sessions=lama_sessions,
ocr_sessions=ocr_sessions,
workers=workers,
total_vram_usage_mb=total_usage,
safety_margin_mb=safety_margin_mb,
expected_concurrent_clients=template['max_concurrent_clients']
)
self._current_config = config
# 설정 로깅
self.logger.info(f"🎯 최적 세션풀 구성 계산 완료:")
self.logger.info(f" 💾 VRAM 사용: {total_usage}MB / {memory_info.available_vram_mb}MB ({template['target_vram_usage_pct']}%)")
self.logger.info(f" 🔄 세션풀: MIGAN {migan_sessions}개, LAMA {lama_sessions}개, OCR {ocr_sessions}")
self.logger.info(f" ⚡ 비율: LAMA:MIGAN = {config.lama_migan_ratio}, 워커:세션 = {config.worker_session_ratio:.1f}:1")
self.logger.info(f" 👥 예상 동시 클라이언트: {config.expected_concurrent_clients}")
return config
def get_current_memory_status(self) -> Dict[str, Any]:
"""현재 메모리 상태 확인"""
if not torch.cuda.is_available():
return {"error": "CUDA 사용 불가"}
device = torch.cuda.current_device()
allocated = torch.cuda.memory_allocated(device)
reserved = torch.cuda.memory_reserved(device)
total = torch.cuda.get_device_properties(device).total_memory
return {
"allocated_mb": int(allocated / (1024 * 1024)),
"reserved_mb": int(reserved / (1024 * 1024)),
"total_mb": int(total / (1024 * 1024)),
"free_mb": int((total - max(allocated, reserved)) / (1024 * 1024)),
"utilization_pct": round(max(allocated, reserved) / total * 100, 1)
}
def monitor_and_adjust(self) -> bool:
"""메모리 모니터링 및 동적 조정"""
current_time = time.time()
# 주기적 체크만 수행
if current_time - self._last_memory_check < self._memory_check_interval:
return False
self._last_memory_check = current_time
# 현재 메모리 상태 확인
memory_status = self.get_current_memory_status()
if "error" in memory_status:
return False
# 메모리 사용률이 90% 초과 시 경고
if memory_status["utilization_pct"] > 90:
self.logger.warning(f"⚠️ 높은 VRAM 사용률: {memory_status['utilization_pct']}%")
self.logger.warning(f" 사용량: {memory_status['allocated_mb']}MB / {memory_status['total_mb']}MB")
return True
# 메모리 사용률이 95% 초과 시 긴급 정리
if memory_status["utilization_pct"] > 95:
self.logger.error(f"🚨 긴급: VRAM 사용률 {memory_status['utilization_pct']}% - 캐시 정리 실행")
torch.cuda.empty_cache()
return True
return False
def generate_config_summary(self) -> str:
"""구성 요약 생성"""
if not self._current_config or not self._memory_info:
return "❌ 구성 정보 없음"
config = self._current_config
memory = self._memory_info
summary = f"""
🚀 동적 세션풀 구성 요약
🔧 GPU: {memory.gpu_name} ({memory.gpu_tier.value})
💾 VRAM: {memory.total_vram_mb}MB (사용가능: {memory.available_vram_mb}MB)
기능: FP16={memory.supports_fp16}, TensorCores={memory.supports_tensor_cores}
🎯 세션풀 구성:
- MIGAN: {config.migan_sessions} ({config.migan_sessions * 1200}MB)
- LAMA: {config.lama_sessions} ({config.lama_sessions * 500}MB)
- OCR: {config.ocr_sessions} ({config.ocr_sessions * 400}MB)
- 워커: {config.workers}
📊 성능 지표:
- LAMA:MIGAN 비율: {config.lama_migan_ratio}
- 워커:세션 비율: {config.worker_session_ratio:.1f}:1
- 예상 동시 클라이언트: {config.expected_concurrent_clients}
- VRAM 사용률: {config.total_vram_usage_mb}MB ({config.total_vram_usage_mb/memory.total_vram_mb*100:.1f}%)
- 안전 여유분: {config.safety_margin_mb}MB
"""
return summary
# 전역 인스턴스
session_pool_manager = DynamicSessionPoolManager()
def get_optimal_session_config(lama_migan_ratio: Optional[Tuple[int, int]] = None,
worker_session_ratio: Optional[float] = None) -> SessionPoolConfig:
"""최적 세션풀 구성 가져오기"""
return session_pool_manager.calculate_optimal_config(
custom_lama_migan_ratio=lama_migan_ratio,
custom_worker_session_ratio=worker_session_ratio
)
def print_config_summary():
"""구성 요약 출력"""
print(session_pool_manager.generate_config_summary())
if __name__ == "__main__":
# 테스트 실행
logging.basicConfig(level=logging.INFO)
print("🔍 GPU 자동 감지 및 최적 구성 계산...")
# 기본 구성
config1 = get_optimal_session_config()
# 4:6 비율 적용
config2 = get_optimal_session_config(lama_migan_ratio=(4, 6), worker_session_ratio=3.0)
# 3:7 비율 적용
config3 = get_optimal_session_config(lama_migan_ratio=(3, 7), worker_session_ratio=3.0)
print_config_summary()

View File

@ -38,6 +38,20 @@ class MaskModule:
# return processed_mask
return processed_mask
# ========== MIGAN 전용: 파일 경로 입력 ==========
def create_masks_migan(self,
image_path: str,
ocr_results: List[Dict],
expansion_size: int = 6,
min_component_area: int = 32) -> np.ndarray:
image = cv2.imread(image_path)
if image is None:
self.logger.log(f"이미지를 읽을 수 없습니다: {image_path}", level=logging.ERROR)
return None
return self.create_masks_migan_np(image, ocr_results,
expansion_size=expansion_size,
min_component_area=min_component_area)
# ========== NEW: ndarray 직접 마스크 ==========
def create_masks_np(
@ -97,6 +111,83 @@ class MaskModule:
processed_mask = self.process_mask(mask, expansion_size, blur_size)
return processed_mask
# ========== NEW: MIGAN 전용 ndarray 마스크 ==========
def create_masks_migan_np(
self,
image: "np.ndarray",
ocr_results: List[Dict],
expansion_size: int = 6,
min_component_area: int = 32,
dilate_iters: int = 1,
enable_closing: bool = True,
closing_kernel: int = 3,
bridge_h_px: int = 0,
bridge_v_px: int = 0
) -> "np.ndarray | None":
"""
MIGAN에 최적화된 마스크 생성:
- 하드 바이너리(0/255) 마스크
- 블러 없음 (경계 페더링은 MIGAN 내부 처리에 위임)
- 소형 노이즈 제거, 보수적 팽창(dilate)
"""
if image is None or image.size == 0:
self.logger.error("ndarray 이미지가 비었습니다.")
return None
h, w = image.shape[:2]
mask = np.zeros((h, w), dtype=np.uint8)
# 폴리곤 확장 후 채우기 (보수적 여유)
for res in ocr_results:
poly = res.get("polygon")
if not poly:
continue
expanded = self.expand_polygon(poly, offset=max(3, expansion_size))
cv2.fillPoly(mask, [expanded], 255)
# 소형 컴포넌트 제거
try:
num, labels, stats, _ = cv2.connectedComponentsWithStats((mask > 0).astype(np.uint8), connectivity=8)
cleaned = np.zeros_like(mask)
for i in range(1, num):
area = stats[i, cv2.CC_STAT_AREA]
if area >= max(16, min_component_area):
cleaned[labels == i] = 255
mask = cleaned
except Exception:
# 연결 성분 계산 실패 시 원본 유지
pass
# 보수적 팽창 (경계 이음새 방지), 블러는 적용하지 않음
if expansion_size > 0:
k = max(3, min(13, (expansion_size if isinstance(expansion_size, int) else 7) | 1)) # 홀수 보장, 상한 13
kernel = np.ones((k, k), np.uint8)
iters = max(1, min(3, int(dilate_iters)))
mask = cv2.dilate(mask, kernel, iterations=iters)
# 경계 미세 구멍 제거(클로징)
if enable_closing:
ck = max(3, min(9, (closing_kernel if isinstance(closing_kernel, int) else 3) | 1))
cker = np.ones((ck, ck), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, cker)
# 인접 텍스트 간 브릿지(선택): 수평/수직 방향으로만 연결 강화
try:
if isinstance(bridge_h_px, (int, str)) and int(bridge_h_px) > 0:
bh = max(5, min(31, int(bridge_h_px) | 1))
hk = cv2.getStructuringElement(cv2.MORPH_RECT, (bh, 3))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, hk)
if isinstance(bridge_v_px, (int, str)) and int(bridge_v_px) > 0:
bv = max(5, min(31, int(bridge_v_px) | 1))
vk = cv2.getStructuringElement(cv2.MORPH_RECT, (3, bv))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, vk)
except Exception:
pass
# 최종 이진화 보장
mask = ((mask > 0) * 255).astype(np.uint8)
return mask
def expand_polygon(self, polygon, offset=15):
poly = Polygon(polygon)
expanded = poly.buffer(offset)

View File

@ -95,6 +95,7 @@ class MIGANInpaintingModule:
'max_image_size': 1600, # 최대 한 변 제한
'output_max_width': 800, # 출력 가로 최대 크기
'enable_output_resize': True, # 출력 리사이즈 활성화
'overwrite_force_margin_px': 0, # 결과 강제 덮어쓰기 마진(px), 0이면 비활성
}
if config:
@ -585,12 +586,35 @@ class MIGANInpaintingModule:
# 8. BGR 변환
result_bgr = cv2.cvtColor(result, cv2.COLOR_RGB2BGR)
# 9. 원본 크기로 복원
if scale_info['scaled']:
result_bgr = self.restore_original_scale(result_bgr, scale_info)
# 10. 출력 크기 조정 (옵션)
# 10. 경계 강제 덮어쓰기(옵션): 잔상 제거용
try:
margin_px = int(effective_config.get('overwrite_force_margin_px', 0) or 0)
except Exception:
margin_px = 0
if margin_px > 0:
try:
bin_mask = (mask_known255 > 0).astype(np.uint8)
k = max(3, min(21, (margin_px * 2 + 1)))
kernel = np.ones((k, k), np.uint8)
force_zone = cv2.dilate(bin_mask, kernel, iterations=1)
force_zone_3 = np.repeat(force_zone[:, :, None], 3, axis=2)
# 원본 스케일과 맞추기
if scale_info['scaled']:
force_zone_3 = cv2.resize(force_zone_3, (result_bgr.shape[1], result_bgr.shape[0]), interpolation=cv2.INTER_NEAREST)
bgr_resized = cv2.resize(bgr, (result_bgr.shape[1], result_bgr.shape[0]), interpolation=cv2.INTER_NEAREST)
else:
bgr_resized = bgr
result_bgr = np.where(force_zone_3 == 1, result_bgr, bgr_resized)
self.logger.log(f"강제 덮어쓰기 적용: margin={margin_px}px", level=logging.DEBUG)
except Exception as _:
pass
# 11. 출력 크기 조정 (옵션)
if effective_config.get('enable_output_resize', True):
max_width = effective_config.get('output_max_width', 800)
result_bgr = self.resize_output_if_needed(result_bgr, max_width)

View File

@ -55,6 +55,8 @@ class ROIInpaintingModule:
'blend_kernel_ratio': 20, # 블렌딩 커널 크기 비율
'max_blend_kernel': 21, # 최대 블렌딩 커널 크기
'min_blend_kernel': 5, # 최소 블렌딩 커널 크기
# 🔥 성능 최적화 설정
'disable_roi_fallback': False, # ROI 폴백 완전 비활성화 (True면 항상 full 전략)
# 🔥 이미지 크기 제한 설정
'max_image_size': 2048, # 최대 이미지 크기 (긴 변 기준)
'enable_size_limit': True, # 크기 제한 활성화
@ -906,31 +908,10 @@ class ROIInpaintingModule:
roi_area_low_threshold = config.get('roi_area_low', 0.30) # 30%
roi_count_threshold = config.get('roi_count_threshold', 3) # 개수
# 🔥 하이브리드 정책 휴리스틱
if H >= memory_high_threshold and (S <= small_image_threshold or (A <= roi_area_low_threshold and N <= roi_count_threshold)):
# 작은 이미지 또는 작은 ROI + 적은 개수 + GPU 여유 → 풀프레임이 빠름
strategy = "full"
reason = f"small_image(S={S:.1f}MP) or small_roi(A={A:.1%}, N={N}) + gpu_plenty(H={H:.0f}MB)"
elif A >= roi_area_high_threshold:
# ROI가 너무 큰 경우 → 풀프레임이 의미있음
strategy = "full"
reason = f"large_roi_coverage(A={A:.1%})"
elif H < memory_low_threshold:
# GPU 메모리 부족 → 안전하게 ROI
strategy = "roi"
reason = f"low_gpu_memory(H={H:.0f}MB)"
elif N >= 2 and total_pixels > 1024 * 1024 and H >= memory_high_threshold:
# 다중 ROI + 큰 이미지 + GPU 여유 → 병렬 전처리
strategy = "roi_parallel"
reason = f"multi_roi(N={N}) + large_image(S={S:.1f}MP) + gpu_plenty(H={H:.0f}MB)"
else:
# 기본: ROI 처리
strategy = "roi"
reason = f"default_roi(A={A:.1%}, N={N}, H={H:.0f}MB)"
# 🚫 ROI 전략 완전 폐기: 작은 이미지에서는 항상 full이 더 빠름
# 성능 측정 결과 1.2초(full) vs 4-5초(roi)로 full이 압도적으로 빠름
strategy = "full"
reason = f"roi_strategy_deprecated(S={S:.1f}MP,A={A:.1%},N={N},H={H:.0f}MB)"
# 🔥 상세 성능 예측 로깅
estimated_roi_overhead = N * 0.02 + 0.03 # 컴포넌트당 20ms + 기본 30ms
@ -1348,16 +1329,68 @@ class ROIInpaintingModule:
return (x1, y1, x2, y2)
def _setup_cudnn_optimization(self):
"""cuDNN 최적화 설정"""
"""🔥 강화된 cuDNN 최적화 설정"""
try:
import torch
if torch.cuda.is_available():
# 🔥 cuDNN 벤치마크 활성화 - 첫 실행에서 최적 알고리즘 찾아서 캐시
torch.backends.cudnn.benchmark = True
torch.backends.cudnn.deterministic = False
self.logger.log("cuDNN 최적화 설정 완료", level=logging.INFO)
# 🔥 메모리 형식 최적화
torch.backends.cudnn.allow_tf32 = True
torch.backends.cuda.matmul.allow_tf32 = True
# 🔥 메모리 할당 전략 최적화
torch.cuda.empty_cache() # 기존 캐시 정리
# 🔥 cuDNN 알고리즘 캐시 예열 (동일 크기 더미 텐서로 미리 탐색)
self._warmup_cudnn_algorithms()
self.logger.log("🔥 강화된 cuDNN 최적화 설정 완료", level=logging.INFO)
except ImportError:
self.logger.log("cuDNN 라이브러리를 찾을 수 없습니다. cuDNN 최적화를 사용할 수 없습니다.", level=logging.WARNING)
def _warmup_cudnn_algorithms(self):
"""🔥 cuDNN 알고리즘 캐시 예열"""
try:
import torch
import torch.nn.functional as F
# 🔥 일반적인 웹툰 크기들로 cuDNN 알고리즘 미리 탐색
common_sizes = [
(1, 3, 640, 640), # 작은 정사각형
(1, 3, 832, 1024), # 웹툰 표준
(1, 3, 1200, 816), # 현재 샘플 크기
(1, 3, 896, 1152), # 웹툰 세로형
]
with torch.no_grad():
for size in common_sizes:
try:
# 더미 텐서 생성
dummy_input = torch.randn(size, device='cuda', dtype=torch.float32)
# 일반적인 연산들로 cuDNN 알고리즘 탐색 트리거
_ = F.conv2d(dummy_input, torch.randn(32, 3, 3, 3, device='cuda'), padding=1)
_ = F.conv2d(dummy_input, torch.randn(64, 3, 5, 5, device='cuda'), padding=2)
_ = F.interpolate(dummy_input, scale_factor=0.5, mode='bilinear')
_ = F.interpolate(dummy_input, scale_factor=2.0, mode='bilinear')
del dummy_input # 즉시 메모리 해제
except Exception as e:
# 개별 크기 실패해도 계속 진행
continue
# 메모리 정리
torch.cuda.empty_cache()
self.logger.log("🔥 cuDNN 알고리즘 캐시 예열 완료", level=logging.INFO)
except Exception as e:
self.logger.log(f"cuDNN 예열 중 오류 (무시): {e}", level=logging.DEBUG)
def record_performance(self, bucket_name: str, processing_time: float, strategy: str):
"""🔥 버킷별 성능 히스토리 기록"""
if bucket_name not in self.bucket_performance_history:
@ -1389,11 +1422,14 @@ class ROIInpaintingModule:
)
def should_fallback_to_roi(self, bucket_name: str, predicted_time: float) -> bool:
"""🔥 성능 히스토리 기반 ROI 폴백 판단"""
if bucket_name not in self.bucket_performance_history:
return False
history = self.bucket_performance_history[bucket_name]
"""🚫 성능 히스토리 기반 ROI 폴백 완전 비활성화"""
# 🔥 성능 히스토리 폴백은 1초대 성능을 4-5초로 악화시키므로 완전 비활성화
self.logger.log(
f"🚫 ROI 폴백 비활성화: {bucket_name} (성능 악화 방지를 위해 full 전략 강제)",
level=logging.INFO
)
return False
# 🔥 조건 1: 평균 시간이 예측치의 4배 이상
if history['avg_time'] > predicted_time * 4:

View File

@ -0,0 +1,297 @@
"""
세션풀 동적 관리 통합 모듈
- 기존 워커 시스템에 동적 세션풀 관리 기능 통합
- 런타임 메모리 모니터링 세션풀 조정
"""
import logging
import threading
import time
from typing import Dict, Any, Optional
from contextlib import contextmanager
from .dynamic_session_pool_manager import (
session_pool_manager,
get_optimal_session_config,
SessionPoolConfig
)
class SessionPoolIntegrator:
"""세션풀 통합 관리자"""
def __init__(self, logger: Optional[logging.Logger] = None):
self.logger = logger or logging.getLogger(__name__)
self._config: Optional[SessionPoolConfig] = None
self._monitoring_thread: Optional[threading.Thread] = None
self._monitoring_active = False
self._session_pools = {}
self._lock = threading.Lock()
def initialize_dynamic_pools(self,
lama_migan_ratio: tuple = (4, 6),
worker_session_ratio: float = 3.0) -> SessionPoolConfig:
"""동적 세션풀 초기화"""
self.logger.info("🚀 동적 세션풀 시스템 초기화 시작...")
try:
# GPU 정보 감지
memory_info = session_pool_manager.detect_gpu_info()
# 최적 구성 계산
config = get_optimal_session_config(
lama_migan_ratio=lama_migan_ratio,
worker_session_ratio=worker_session_ratio
)
self._config = config
# 구성 요약 로깅
self._log_configuration()
# 모니터링 시작
self.start_monitoring()
self.logger.info("✅ 동적 세션풀 시스템 초기화 완료")
return config
except Exception as e:
self.logger.error(f"❌ 동적 세션풀 초기화 실패: {e}")
raise
def _log_configuration(self):
"""구성 정보 로깅"""
if not self._config:
return
config = self._config
memory_info = session_pool_manager._memory_info
self.logger.info("🎯 동적 세션풀 구성:")
self.logger.info(f" GPU: {memory_info.gpu_name} ({memory_info.gpu_tier.value})")
self.logger.info(f" VRAM: {memory_info.total_vram_mb}MB (사용가능: {memory_info.available_vram_mb}MB)")
self.logger.info(f" 세션풀: MIGAN {config.migan_sessions}개, LAMA {config.lama_sessions}개, OCR {config.ocr_sessions}")
self.logger.info(f" 워커: {config.workers}개 (비율 {config.worker_session_ratio:.1f}:1)")
self.logger.info(f" 메모리 사용: {config.total_vram_usage_mb}MB ({config.total_vram_usage_mb/memory_info.total_vram_mb*100:.1f}%)")
self.logger.info(f" LAMA:MIGAN = {config.lama_migan_ratio}")
self.logger.info(f" 예상 동시 클라이언트: {config.expected_concurrent_clients}")
def start_monitoring(self):
"""메모리 모니터링 시작"""
if self._monitoring_active:
return
self._monitoring_active = True
self._monitoring_thread = threading.Thread(
target=self._monitoring_worker,
daemon=True,
name="SessionPoolMonitor"
)
self._monitoring_thread.start()
self.logger.info("📊 메모리 모니터링 시작")
def stop_monitoring(self):
"""메모리 모니터링 중지"""
self._monitoring_active = False
if self._monitoring_thread:
self._monitoring_thread.join(timeout=5)
self.logger.info("📊 메모리 모니터링 중지")
def _monitoring_worker(self):
"""모니터링 워커 스레드"""
while self._monitoring_active:
try:
# 메모리 상태 체크 및 조정
adjusted = session_pool_manager.monitor_and_adjust()
if adjusted:
self.logger.warning("⚠️ 메모리 조정이 수행되었습니다")
# 메모리 상태 로깅
memory_status = session_pool_manager.get_current_memory_status()
if "error" not in memory_status:
self.logger.info(f" 현재 VRAM 사용률: {memory_status['utilization_pct']}%")
self.logger.info(f" 사용량: {memory_status['allocated_mb']}MB / {memory_status['total_mb']}MB")
# 30초 대기
time.sleep(30)
except Exception as e:
self.logger.error(f"❌ 메모리 모니터링 오류: {e}")
time.sleep(60) # 오류 시 더 긴 대기
def get_session_pool_config(self) -> Optional[SessionPoolConfig]:
"""현재 세션풀 구성 반환"""
return self._config
def get_memory_status(self) -> Dict[str, Any]:
"""현재 메모리 상태 반환"""
return session_pool_manager.get_current_memory_status()
def register_session_pool(self, pool_type: str, pool_instance):
"""세션풀 인스턴스 등록"""
with self._lock:
self._session_pools[pool_type] = pool_instance
self.logger.info(f"{pool_type} 세션풀 등록 완료")
def get_session_pool(self, pool_type: str):
"""세션풀 인스턴스 반환"""
with self._lock:
return self._session_pools.get(pool_type)
@contextmanager
def session_context(self, pool_type: str):
"""세션 컨텍스트 매니저"""
pool = self.get_session_pool(pool_type)
if not pool:
raise RuntimeError(f"세션풀 '{pool_type}'이 등록되지 않았습니다")
session = None
try:
# 세션 획득 (구현에 따라 다름)
session = pool.get_session() if hasattr(pool, 'get_session') else pool
yield session
finally:
# 세션 반환 (구현에 따라 다름)
if session and hasattr(pool, 'return_session'):
pool.return_session(session)
def generate_celery_config(self) -> Dict[str, Any]:
"""Celery 설정 생성"""
if not self._config:
raise RuntimeError("세션풀 구성이 초기화되지 않았습니다")
config = self._config
celery_config = {
# 워커 설정
"worker_concurrency": config.workers,
"worker_prefetch_multiplier": 1,
# 세션풀 설정
"session_pools": {
"migan": {
"size": config.migan_sessions,
"timeout": 30,
"retry_attempts": 3
},
"lama": {
"size": config.lama_sessions,
"timeout": 30,
"retry_attempts": 3
},
"ocr": {
"size": config.ocr_sessions,
"timeout": 15,
"retry_attempts": 2
}
},
# 메모리 관리
"memory_management": {
"max_vram_usage_mb": config.total_vram_usage_mb,
"safety_margin_mb": config.safety_margin_mb,
"monitoring_interval": 30,
"gc_threshold": 0.90 # 90% 사용률에서 GC 트리거
},
# 라우팅 전략
"routing": {
"lama_migan_ratio": config.lama_migan_ratio,
"default_method": "migan" if config.migan_sessions >= config.lama_sessions else "lama",
"fallback_method": "lama" if config.migan_sessions >= config.lama_sessions else "migan"
}
}
return celery_config
def print_status(self):
"""현재 상태 출력"""
if not self._config:
print("❌ 세션풀이 초기화되지 않았습니다")
return
config = self._config
memory_info = session_pool_manager._memory_info
memory_status = self.get_memory_status()
print(f"""
🚀 동적 세션풀 상태
🔧 GPU: {memory_info.gpu_name} ({memory_info.gpu_tier.value})
💾 VRAM: {memory_info.total_vram_mb}MB 총용량
📊 현재 사용률: {memory_status.get('utilization_pct', 'N/A')}%
🎯 세션풀 구성:
- MIGAN: {config.migan_sessions} ({config.migan_sessions * 1200}MB)
- LAMA: {config.lama_sessions} ({config.lama_sessions * 500}MB)
- OCR: {config.ocr_sessions} ({config.ocr_sessions * 400}MB)
- 워커: {config.workers}
📈 성능 지표:
- LAMA:MIGAN 비율: {config.lama_migan_ratio}
- 워커:세션 비율: {config.worker_session_ratio:.1f}:1
- 예상 동시 클라이언트: {config.expected_concurrent_clients}
- 메모리 사용률: {config.total_vram_usage_mb/memory_info.total_vram_mb*100:.1f}%
🔄 모니터링: {'활성' if self._monitoring_active else '비활성'}
""")
# 전역 통합 관리자 인스턴스
session_integrator = SessionPoolIntegrator()
def initialize_dynamic_session_pools(lama_migan_ratio: tuple = (4, 6),
worker_session_ratio: float = 3.0,
logger: Optional[logging.Logger] = None) -> SessionPoolConfig:
"""동적 세션풀 초기화 헬퍼 함수"""
if logger:
session_integrator.logger = logger
return session_integrator.initialize_dynamic_pools(
lama_migan_ratio=lama_migan_ratio,
worker_session_ratio=worker_session_ratio
)
def get_celery_config() -> Dict[str, Any]:
"""Celery 설정 반환 헬퍼 함수"""
return session_integrator.generate_celery_config()
def print_session_status():
"""세션풀 상태 출력 헬퍼 함수"""
session_integrator.print_status()
if __name__ == "__main__":
# 테스트 실행
import time
logging.basicConfig(level=logging.INFO)
print("🔍 동적 세션풀 통합 테스트...")
# 4:6 비율로 초기화
config = initialize_dynamic_session_pools(lama_migan_ratio=(4, 6), worker_session_ratio=3.0)
# 상태 출력
print_session_status()
# Celery 설정 생성
celery_config = get_celery_config()
print("\n📋 Celery 설정:")
import json
print(json.dumps(celery_config, indent=2, ensure_ascii=False))
# 짧은 모니터링 테스트
print("\n⏱️ 10초간 모니터링 테스트...")
time.sleep(10)
# 정리
session_integrator.stop_monitoring()
print("✅ 테스트 완료")

View File

@ -79,7 +79,7 @@ class TextRenderingModule:
'dpi': 150, # 고해상도 렌더링
'antialiasing': True,
'subpixel_rendering': True,
'font_hinting': True,
'font_hinting': False,
}
# 🔥 WCAG 대비 비율 설정
@ -470,7 +470,7 @@ class TextRenderingModule:
rel_pos = (position[0] - x1, position[1] - y1)
# 🔥 외곽선 렌더링 (8방향)
outline_width = max(1, int(font_size / 12))
outline_width = max(1, int(font_size / 24))
outline_color = (255, 255, 255) if sum(text_color) < 384 else (0, 0, 0)
for dx in [-outline_width, 0, outline_width]: