FAISS + FastAPI 기반으로 이미지를 업로드/임베딩/검색까지 처리하는 엔드-투-엔드 파이프라인입니다. 로컬에서 CLI로 데이터를 준비하고, 동일한 코드베이스로 API 서버를 띄워 유사도 검색을 제공할 수 있습니다.
- 필수 요구 사항
- Python 3.11+
uv또는pip- GCP 서비스 계정(JSON)과 GCS 버킷
- 의존성 설치
uv pip install -e '.[cli]' # 또는 pip install -e '.[cli]'
- 환경 변수 작성
루트에
.env를 생성하고 아래 템플릿을 채워주세요.
필요한 최소 값과 자주 쓰는 옵션을 묶어 두었습니다. 값은 실제 환경에 맞게 수정하세요.
# 인덱스/메타데이터 저장용 GCS 버킷
INDEX_BUCKET=my-image-index-bucket
INDEX_PREFIX=prod # 생략 가능
INDEX_MANIFEST=manifest.json
INDEX_POLL_INTERVAL_SEC=60
LOG_LEVEL=INFO
# DB 메타데이터 사용 시
DATABASE_URL=postgresql+psycopg://user:pass@host:5432/dbname
DB_POOL_MIN_SIZE=1
DB_POOL_MAX_SIZE=10
# Vertex AI 임베딩
GOOGLE_GENAI_USE_VERTEXAI=true
GCP_PROJECT_ID=my-project
GCP_REGION=us-central1
GENERATIVE_MODEL=multimodalembedding@001
GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service-account.json
# CLI 업로드 경로
IMAGE_UPLOAD_PREFIX=images
METADATA_PREFIX=metadataCLI는 모두 python -m src.cli.<module> 형태로 실행하는 것이 가장 간단합니다.
python -m src.cli.upload_images \
--image-dir images/sample \
--version 20250201_000000 \
--upload-metadata- JPG/PNG/WEBP 파일을 GCS 버킷에 저장하고 JSONL 메타데이터를
tmp/image_metadata_<version>.jsonl로 생성합니다. --upload-metadata를 사용하면 JSONL도 자동으로 GCS에 업로드됩니다.
python -m src.cli.upsert_images \
--metadata tmp/image_metadata_20250201_000000.jsonl \
--table images \
--chunk-size 500- JSONL을 읽어서
id,img_url을 기준으로 UPSERT합니다. DATABASE_URL이.env에 있어야 하고, 필요한 경우chunk-size를 조절하면 됩니다.
python -m src.cli.build_image_index \
--metadata tmp/image_metadata_20250201_000000.jsonl \
--version 20250201_000000 \
--staging-dir build \
--nprobe 16- Vertex AI 멀티모달 임베딩으로 벡터를 생성하고 FAISS IVF-Flat 인덱스를 만듭니다.
- 완성된
index_v<version>.faiss,id_map_v<version>.json,manifest.json은 자동으로 GCS로 업로드되어 API가 읽을 수 있습니다. - 진행 중에 중단되면
build/embeddings_progress_v<version>.jsonl로 이어서 재시도합니다.
인덱스와 DB가 준비되었다면 FastAPI 서버를 띄워 검색 API를 사용할 수 있습니다.
python -m uvicorn src.app:app --host 0.0.0.0 --port 8000 --reload- 기동 시
manifest.json을 읽어 최신 인덱스를 메모리에 로드합니다. - 백그라운드에서 매니페스트를 주기적으로 확인해 새로운 버전이 있으면 핫스왑합니다.
GET /health: 인덱스 로드 상태, 현재 버전, 마지막 업데이트 시간을 확인POST /search응답에는 인덱스 버전, id, score, (DB 연동 시) 메타데이터가 포함됩니다.{ "query": "sunset beach", "top_k": 10 }
src/
├── api/ # FastAPI 라우터 (search, health 등)
├── app.py # FastAPI 엔트리포인트 및 lifespan
├── cli/ # upload_images, upsert_images, build_image_index
├── core/ # 설정, 인덱스 로더/홀더, 매니페스트 폴러
├── infra/ # 데이터베이스 풀 등 인프라 유틸
├── models/ # Pydantic 모델
└── utils/ # GCS 스토리지, 체크섬 등 공용 유틸