diff --git a/test1/dynamic_worker_test.py b/test1/dynamic_worker_test.py new file mode 100644 index 0000000..1a802af --- /dev/null +++ b/test1/dynamic_worker_test.py @@ -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() + diff --git a/test1/log.log b/test1/log.log new file mode 100644 index 0000000..c327763 --- /dev/null +++ b/test1/log.log @@ -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::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::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::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 \ No newline at end of file diff --git a/test1/translated_result.png b/test1/translated_result.png index bc8b5f7..fc1e103 100644 Binary files a/test1/translated_result.png and b/test1/translated_result.png differ diff --git a/test1/worker_test.py b/test1/worker_test.py index 108e829..b008b37 100644 --- a/test1/worker_test.py +++ b/test1/worker_test.py @@ -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): diff --git a/worker/celery_worker.py b/worker/celery_worker.py index f4f17a4..d4a8c3e 100644 --- a/worker/celery_worker.py +++ b/worker/celery_worker.py @@ -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) diff --git a/worker/dynamic_session_pool_manager.py b/worker/dynamic_session_pool_manager.py new file mode 100644 index 0000000..467ea79 --- /dev/null +++ b/worker/dynamic_session_pool_manager.py @@ -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() + diff --git a/worker/mask_module_for_paddle.py b/worker/mask_module_for_paddle.py index c20ca06..c236e8f 100644 --- a/worker/mask_module_for_paddle.py +++ b/worker/mask_module_for_paddle.py @@ -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) diff --git a/worker/migan_inpainting_module.py b/worker/migan_inpainting_module.py index 8aedda7..af9c580 100644 --- a/worker/migan_inpainting_module.py +++ b/worker/migan_inpainting_module.py @@ -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) diff --git a/worker/roi_inpainting_module.py b/worker/roi_inpainting_module.py index 5acc449..945345b 100644 --- a/worker/roi_inpainting_module.py +++ b/worker/roi_inpainting_module.py @@ -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: diff --git a/worker/session_pool_integration.py b/worker/session_pool_integration.py new file mode 100644 index 0000000..7601d1d --- /dev/null +++ b/worker/session_pool_integration.py @@ -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("✅ 테스트 완료") + diff --git a/worker/text_rendering_module.py b/worker/text_rendering_module.py index a4c8858..657312e 100644 --- a/worker/text_rendering_module.py +++ b/worker/text_rendering_module.py @@ -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]: