AI 시스템

RAG 문서 전처리 파이프라인 설계 — AWS Batch + GPU Spot으로 비동기 문서 변환 구축하기

AWS Batch와 GPU Spot Instance를 활용한 비동기 문서 전처리 파이프라인 설계, 카테고리별 파이프라인 분리, 콜백 패턴 기반 상태 추적을 구현한 경험을 정리한다.

Table of Contents

RAG 챗봇을 구축할 때 문서 전처리는 검색 품질을 좌우한다. 단순 텍스트 PDF는 몇 초면 처리되지만 테이블과 이미지가 포함된 마케팅 자료는 GPU가 필요하고 수십 분이 걸린다. 이 처리 시간 편차를 AWS Batch + GPU Spot Instance로 해결한 비동기 파이프라인 설계를 정리한다.

문제 정의

RAG 시스템에서 처리해야 할 문서는 두 종류로 나뉜다.

  • 단순 문서: 제품 사양서, FAQ (PDF/XLSX) → Lambda로 5~30초 처리 가능
  • 복잡 문서: 마케팅 자료, 테이블/이미지 포함 PDF → GPU 필요 (VLM 기반 추출)

Lambda는 5~30초, Batch+GPU는 1~60분이다. 처리 시간 편차가 크고 각 문서의 전처리 상태를 추적해야 하는 것도 과제였다.

솔루션: 카테고리별 파이프라인 선택

DB의 pipeline_config에 카테고리별 처리 전략을 저장한다.

public enum PreprocessType {
    LAMBDA,  // 단순 문서
    BATCH    // 복잡 문서 (GPU 필요)
}
카테고리타입프로세서소요시간비용
product_specsLAMBDALambda 함수5-30초~$0.001/문서
faqLAMBDALambda 함수5-30초~$0.001/문서
marketingBATCHAWS Batch + GPU Spot1-60분~$0.05/문서

파이프라인 엔드포인트는 DB에 저장되며 하드코딩하지 않는다.

pipeline_config:
  preprocess_type: BATCH
  preprocess_endpoint: /preprocessing/marketing
  embedding_endpoint: /embedding/create
  supported_extensions: ["pdf", "docx", "xlsx", "pptx"]
  max_collections: 5
  delete_after_days: 60

AWS Batch + GPU 아키텍처

시퀀스 흐름

---
config:
  theme: base
  themeVariables:
    primaryColor: "#e0f2fe"
    primaryTextColor: "#0c4a6e"
    primaryBorderColor: "#38bdf8"
    lineColor: "#94a3b8"
    fontSize: "14px"
---
graph TB
    A["Admin UI\nPOST /preprocessing"] --> B["AWS Batch\nJob 제출 + 환경변수 전달"]
    B --> C["GPU Spot Instance\nVLM 컨테이너"]
    C --> D["S3 Input → 변환 → S3 Output\n원본 다운로드 → 마크다운 업로드"]
    D --> E["HTTP POST Callback\n→ Admin Backend"]
    E --> F["DB 업데이트\nstatus: PREPROCESSED"]

    style A fill:#fef3c7,stroke:#f59e0b,color:#78350f
    style B fill:#e0f2fe,stroke:#38bdf8,color:#0c4a6e
    style C fill:#e0f2fe,stroke:#38bdf8,color:#0c4a6e
    style D fill:#e0f2fe,stroke:#38bdf8,color:#0c4a6e
    style E fill:#f3e8ff,stroke:#a855f7,color:#581c87
    style F fill:#f0fdf4,stroke:#22c55e,color:#14532d

환경변수 매핑

API 요청 필드를 컨테이너 환경변수로 전달한다는 뜻이다.

API 필드환경변수설명
versionIdVERSION_ID버전 식별자
documentIdDOCUMENT_ID문서 식별자
fileS3UrlINPUT_BUCKET + INPUT_KEY입력 파일 위치
callbackUrlCALLBACK_URL완료 알림 URL

환경변수를 선택한 이유는 컨테이너 격리다. GPU 컨테이너가 Admin API의 스키마를 알 필요가 없다.

S3 경로 규칙

Input:  s3://{input-bucket}/{categoryName}/v{version}/{uuid}.{ext}
Output: s3://{output-bucket}/{categoryName}/v{version}/{uuid}.md

예시:
Input:  s3://doc-input/FAQ/v1/abc-123.xlsx
Output: s3://doc-output/FAQ/v1/abc-123.md

Callback 패턴

성공 응답

POST http://admin/api/v1/callback/preprocess
{
  "versionId": "ver-001",
  "documentId": "doc-001",
  "status": "SUCCESS",
  "textS3Url": "s3://output-bucket/FAQ/v1/uuid.md",
  "errorMessage": null,
  "processedAt": "2026-01-30T02:35:34Z"
}

실패 응답

{
  "versionId": "ver-001",
  "documentId": "doc-001",
  "status": "FAILED",
  "textS3Url": null,
  "errorMessage": "Timeout after 3600s",
  "processedAt": "2026-01-30T02:35:34Z"
}

Polling 대신 Callback을 선택한 이유

  1. API 호출 절감: 폴링처럼 N초마다 호출하지 않는다.
  2. 즉시 알림: 폴링 간격 지연이 없다.
  3. 무상태 처리: GPU 컨테이너가 연결 유지를 할 필요가 없다.
  4. 타임아웃 처리: 3600초 제한이 있고 GPU는 타임아웃을 FAILED로 보고한다.

전체 파이프라인

업로드 → 전처리 → 임베딩 → 배포

---
config:
  theme: base
  themeVariables:
    primaryColor: "#e0f2fe"
    primaryTextColor: "#0c4a6e"
    primaryBorderColor: "#38bdf8"
    lineColor: "#94a3b8"
    fontSize: "14px"
---
graph LR
    A["Upload\n파일 → S3\nUPLOADED"] --> B["Preprocess\nLambda/Batch → 마크다운\nPREPROCESSED"]
    B --> C["Embed\n벡터 청크 생성\nCOMPLETE"]
    C --> D["Deploy\n별칭 전환\ntest/prod"]

    style A fill:#fef3c7,stroke:#f59e0b,color:#78350f
    style B fill:#e0f2fe,stroke:#38bdf8,color:#0c4a6e
    style C fill:#e0f2fe,stroke:#38bdf8,color:#0c4a6e
    style D fill:#f0fdf4,stroke:#22c55e,color:#14532d

Embedding 적용 로직

관리자가 “임베딩 적용”을 클릭할 시 다음을 수행한다.

  1. 모든 비완료 문서 조회
  2. 삭제 표시된 문서: Milvus 청크 + S3 + DB 삭제
  3. UPLOADED 문서: 전처리 먼저 트리거
  4. PREPROCESSED 문서: 임베딩 서비스로 전송
  5. 수정된 문서: 기존 청크 삭제 후 새 청크 삽입

GPU Spot Instance 전략

  • 비용을 60~91% 절감한다.
  • VLM 기반 문서 변환은 GPU가 필수다 (테이블/이미지 추출용).
  • Spot 중단 시 AWS Batch가 자동으로 다른 인스턴스에서 재시도한다.
  • 최대 재시도 3회. 타임아웃은 문서당 3600초다.

운영 시 주의할 점

  1. DB에 파이프라인 설정 저장: 새 카테고리 추가 = DB 입력이면 충분하다. 코드 배포는 불필요하다.
  2. Callback 검증: 업데이트 전 versionId + documentId 일치를 확인한다.
  3. 멱등성: 같은 callback이 두 번 도착해도 불일치가 없어야 한다.
  4. 오류 세분화: “Timeout after 3600s”가 일반적 “FAILED”보다 유용하다.
  5. S3 경로 규칙: Category/version/uuid 패턴으로 충돌을 방지하고 정리를 용이하게 한다.

참고

  • #rag
  • #aws-batch
  • #document-processing
  • #callback-pattern
  • #async-pipeline