273 lines
6.8 KiB
Markdown
273 lines
6.8 KiB
Markdown
# 이미지 번역 워커 시스템
|
|
|
|
이 워커 시스템은 Redis와 Celery를 사용하여 이미지 번역 작업을 분산 처리합니다.
|
|
메인 서버의 Redis에 연결하여 `translate_me` 요청을 처리하고, `ImageProcessor`의 `process_single_image` 메서드를 실행합니다.
|
|
|
|
## 시스템 구조
|
|
|
|
```
|
|
메인서버 (FastAPI + Redis + Flower + Celery Client)
|
|
↓ (Redis Queue)
|
|
워커서버 (Celery Worker + ImageProcessor + Redis Client)
|
|
```
|
|
|
|
**워커 역할**: 작업 수행만 담당 (Redis 서버, Flower 모니터링은 메인서버에서 운영)
|
|
|
|
## 필요한 환경
|
|
|
|
- Python 3.8+
|
|
- **메인서버**: Redis 서버, Flower 대시보드 (이미 구축됨)
|
|
- **워커서버**: Celery 워커, Redis 클라이언트
|
|
- CUDA 지원 GPU (선택사항, 성능 향상)
|
|
|
|
## 설치 및 설정
|
|
|
|
### 1. 워커 전용 의존성 설치
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
**주요 패키지**:
|
|
- `celery`: 워커 프로세스 실행
|
|
- `redis`: Redis 서버 연결용 클라이언트
|
|
- ~~`flower`: 메인서버에서만 필요 (워커에는 불필요)~~
|
|
|
|
### 2. 환경 변수 설정
|
|
|
|
```bash
|
|
# Redis 서버 주소 (메인서버 주소)
|
|
export REDIS_URL="redis://메인서버IP:6379/0"
|
|
|
|
# 메인 서버 주소
|
|
export MAIN_SERVER_HOST="메인서버IP"
|
|
|
|
# 워커 식별명 (선택사항)
|
|
export WORKER_NAME="worker-AGX-$$"
|
|
|
|
# 동시 처리 수 (선택사항)
|
|
export CONCURRENCY="2"
|
|
```
|
|
|
|
## 워커 실행 방법
|
|
|
|
### 방법 1: 자동 시작 스크립트 사용
|
|
|
|
```bash
|
|
# Docker 모드로 실행
|
|
WORKER_MODE=docker ./start_worker.sh
|
|
|
|
# 로컬 모드로 실행
|
|
WORKER_MODE=local ./start_worker.sh
|
|
|
|
# 원격 모드로 실행 (다른 서버에서)
|
|
WORKER_MODE=remote REDIS_URL=redis://메인서버IP:6379/0 ./start_worker.sh
|
|
```
|
|
|
|
### 방법 2: 직접 실행
|
|
|
|
```bash
|
|
# Python으로 직접 실행
|
|
python worker.py --concurrency 2 --redis-url redis://메인서버IP:6379/0
|
|
|
|
# Docker Compose로 실행
|
|
docker-compose up -d
|
|
```
|
|
|
|
### 방법 3: Docker로 실행
|
|
|
|
```bash
|
|
# Docker 이미지 빌드
|
|
docker build -t image-worker .
|
|
|
|
# Docker 컨테이너 실행
|
|
docker run -d \
|
|
-e REDIS_URL=redis://메인서버IP:6379/0 \
|
|
-e MAIN_SERVER_HOST=메인서버IP \
|
|
-v ./modules:/worker/modules \
|
|
-v ./models:/worker/models \
|
|
image-worker
|
|
```
|
|
|
|
## 사용 가능한 작업 (Tasks)
|
|
|
|
### 1. translate_me_task
|
|
- **용도**: 전체 이미지 번역 처리 (OCR → 번역 → 인페인팅 → 텍스트 렌더링)
|
|
- **큐**: `translate`
|
|
- **파라미터**:
|
|
```python
|
|
{
|
|
'image_data': 'base64_encoded_image', # 또는 image_path 사용
|
|
'image_path': '/path/to/image.jpg', # 또는 image_data 사용
|
|
'toggle_states': {
|
|
'ocr': True,
|
|
'watermark_text': '번역완료'
|
|
},
|
|
'unwanted_texts': {
|
|
'광고': '이미지삭제',
|
|
'홍보': '공지'
|
|
},
|
|
'index': 0,
|
|
'file_prefix': 'test'
|
|
}
|
|
```
|
|
|
|
### 2. ocr_task
|
|
- **용도**: OCR만 수행
|
|
- **큐**: `ocr`
|
|
- **파라미터**:
|
|
```python
|
|
{
|
|
'image_data': 'base64_encoded_image', # 또는 image_path 사용
|
|
'image_path': '/path/to/image.jpg' # 또는 image_data 사용
|
|
}
|
|
```
|
|
|
|
### 3. inpaint_task
|
|
- **용도**: 인페인팅만 수행
|
|
- **큐**: `inpaint`
|
|
|
|
## 테스트 방법
|
|
|
|
### 1. 워커 상태 확인
|
|
|
|
```bash
|
|
python test_worker_client.py --test-type status
|
|
```
|
|
|
|
### 2. OCR 테스트
|
|
|
|
```bash
|
|
python test_worker_client.py --image sample.jpg --test-type ocr
|
|
```
|
|
|
|
### 3. 번역 테스트
|
|
|
|
```bash
|
|
python test_worker_client.py --image sample.jpg --test-type translate
|
|
```
|
|
|
|
### 4. 전체 테스트
|
|
|
|
```bash
|
|
python test_worker_client.py --image sample.jpg --test-type all
|
|
```
|
|
|
|
## 메인서버에서 워커 호출 예제
|
|
|
|
```python
|
|
from celery import Celery
|
|
import base64
|
|
|
|
# Celery 클라이언트 설정
|
|
celery_app = Celery(
|
|
"main_server",
|
|
broker="redis://localhost:6379/0",
|
|
backend="redis://localhost:6379/0"
|
|
)
|
|
|
|
# 이미지를 base64로 인코딩
|
|
with open("image.jpg", "rb") as f:
|
|
image_data = base64.b64encode(f.read()).decode('utf-8')
|
|
|
|
# translate_me 작업 요청
|
|
result = celery_app.send_task(
|
|
'worker.translate_me_task',
|
|
kwargs={
|
|
'image_data': image_data,
|
|
'toggle_states': {
|
|
'ocr': True,
|
|
'watermark_text': '번역완료'
|
|
},
|
|
'unwanted_texts': {
|
|
'광고': '이미지삭제'
|
|
},
|
|
'index': 0
|
|
}
|
|
)
|
|
|
|
# 결과 대기
|
|
task_result = result.get(timeout=300)
|
|
print(f"상태: {task_result['status']}")
|
|
print(f"워커: {task_result['worker_name']}")
|
|
|
|
# 결과 이미지 저장
|
|
if task_result.get('output_image'):
|
|
with open("result.png", "wb") as f:
|
|
f.write(base64.b64decode(task_result['output_image']))
|
|
```
|
|
|
|
## 모니터링
|
|
|
|
### Flower 대시보드 사용 (메인서버에서만)
|
|
**중요**: Flower는 메인서버에서만 실행합니다. 워커에서는 설치/실행할 필요가 없습니다.
|
|
|
|
```bash
|
|
# 메인서버에서만 실행
|
|
flower --broker=redis://localhost:6379/0 --port=5555
|
|
```
|
|
|
|
브라우저에서 `http://메인서버IP:5555`로 접속하여 워커 상태 확인
|
|
|
|
### 명령행으로 상태 확인 (워커서버에서도 가능)
|
|
|
|
```bash
|
|
# 활성 워커 목록
|
|
celery -A worker inspect active
|
|
|
|
# 등록된 작업 목록
|
|
celery -A worker inspect registered
|
|
|
|
# 통계 정보
|
|
celery -A worker inspect stats
|
|
```
|
|
|
|
## 문제 해결
|
|
|
|
### 1. 워커가 연결되지 않는 경우
|
|
- Redis 서버가 실행 중인지 확인
|
|
- 방화벽 설정 확인 (Redis 포트 6379)
|
|
- REDIS_URL 환경 변수 확인
|
|
|
|
### 2. 작업이 실행되지 않는 경우
|
|
- 워커가 정상적으로 시작되었는지 로그 확인
|
|
- 큐 이름이 올바른지 확인
|
|
- ImageProcessor 의존성 모듈들이 설치되었는지 확인
|
|
|
|
### 3. 메모리 부족 오류
|
|
- CONCURRENCY 값을 낮춤 (1 또는 2)
|
|
- Docker의 메모리 제한 확인
|
|
|
|
### 4. GPU 관련 오류
|
|
- CUDA 드라이버 설치 확인
|
|
- requirements.txt의 GPU 패키지들 설치 확인
|
|
|
|
## 로그 확인
|
|
|
|
```bash
|
|
# Docker 로그 확인
|
|
docker-compose logs -f worker
|
|
|
|
# 로컬 실행 시 로그는 터미널에 출력됨
|
|
```
|
|
|
|
## 성능 최적화
|
|
|
|
1. **동시 처리 수 조정**: `--concurrency` 옵션으로 CPU/GPU 리소스에 맞게 조정
|
|
2. **메모리 사용량 모니터링**: 이미지 크기에 따라 메모리 사용량 증가
|
|
3. **네트워크 최적화**: 메인서버와 워커서버 간 네트워크 지연 최소화
|
|
4. **Redis 설정 최적화**: Redis 메모리 및 연결 수 설정 조정
|
|
|
|
## 패키지 역할 정리
|
|
|
|
### 메인서버에 필요한 패키지
|
|
- `redis`: Redis 서버
|
|
- `flower`: 워커 모니터링 대시보드
|
|
- `celery`: 작업 전송용 클라이언트
|
|
|
|
### 워커서버에 필요한 패키지
|
|
- `celery`: 워커 프로세스 실행
|
|
- `redis`: Redis 연결용 클라이언트
|
|
- `ImageProcessor` 관련 의존성들
|
|
|
|
**결론**: 워커는 단순히 작업을 받아서 처리하는 역할만 하므로, Redis 서버나 Flower 대시보드를 별도로 실행할 필요가 없습니다. |