본문 바로가기
Programming/AI&ML

[RAG] 건강정보 pdf 를 학습하여 RAG 서비스를 구현 준비와 절차

by BitSense 2025. 3. 19.

구축 기반 조건 및 서비스 내용

건강/영양 정보 PDF(수십 페이지)를 기반으로 1일 추천 영양정보 및 영양별 건강정보를 제공하는 RAG 기반 웹서비스를 구축
업데이트 주기는 1회성이고 비주기로 약간 추가 가능
적합한 기술 스택과 배포 환경을 추천
RAG 모델을 운영할 cafe24 호스팅 서버 스펙
대안으로 PC에서 운영할 경우의 가능성도 함께 고려.

웹서비스 구성

프론트엔드

영양정보를 제공하는 웹 애플리케이션의 프론트엔드는 SPA(Single Page Application) 프레임워크를 사용하는 것이 적합합니다. ReactVue.js와 같은 프레임워크가 대표적이며, 풍부한 생태계와 컴포넌트 재사용성을 제공하기 때문에 대화형 UI 구현에 유리합니다. 특히 React는 전 세계적으로 널리 사용되는 프론트엔드 라이브러리로 커뮤니티 지원이 풍부하고, 필요에 따라 Next.js 같은 프레임워크로 확장해 SSR/정적 배포도 가능해 유연합니다. Vue 역시 러닝커브가 낮고 직관적인 모델-뷰 바인딩을 제공하므로, 팀의 숙련도와 선호도에 따라 선택하면 됩니다. 두 경우 모두, 백엔드의 API와 통신하여 영양 정보를 질의하고 결과를 표시하는 구조로 구현합니다.

백엔드 (API 서버)

Python 기반 웹 프레임워크 중에서는 FastAPI를 사용하는 것이 권장됩니다. FastAPI는 비동기 I/O 지원과 높은 성능으로 API 서버 개발에 최적화되어 있으며, 경량 프레임워크인 Flask보다 속도가 빠르고 Django보다 설정이 간편합니다 (Comparison of FastAPI with Django and Flask - GeeksforGeeks). 예를 들어, FastAPI는 Uvicorn 같은 ASGI 서버와 함께 사용하여 고성능 비동기 엔진을 활용할 수 있고, Pydantic 기반의 데이터 모델링으로 입력 검증도 손쉽습니다. Flask는 소규모 프로젝트에는 적합하지만 대규모 확장이나 비동기 처리 측면에서 한계가 있고, Django는 풀스택 기능(ORM, Admin 등)을 제공하지만 비교적 무거워서 REST API만 필요한 RAG 서비스에는 과할 수 있습니다 (Comparison of FastAPI with Django and Flask - GeeksforGeeks). 따라서 빠른 응답과 확장성이 중요한 본 서비스에는 FastAPI가 잘 어울립니다. FastAPI는 또한 Swagger/OpenAPI 문서 자동생성 기능이 있어 API 인터페이스 관리에도 편리합니다.

백엔드는 RESTful API 혹은 GraphQL API 형태로 프론트엔드와 통신합니다. 프론트엔드에서 사용자의 질의를 보내면 백엔드가 벡터 DB를 조회하고, LLM을 통해 생성된 응답을 반환하는 흐름으로, 이러한 비즈니스 로직은 Python 코드로 구현합니다. Python은 풍부한 데이터 처리 라이브러리와 AI 생태계를 갖추고 있어 이러한 RAG 서비스를 구현하기에 적합합니다.

 

벡터 데이터베이스

PDF에서 추출한 영양 정보를 임베딩 벡터로 저장하고 유사도 검색을 하기 위해 **벡터 데이터베이스(Vector DB)**를 도입합니다. 벡터 DB는 임베딩된 고차원 벡터를 효율적으로 저장/검색하기 위한 전문 DB로, 질의 시 입력 문장의 벡터와 가장 유사한 컨텍스트를 빠르게 찾아줍니다 (Faiss vs. Pinecone: Ideal Vector Database Comparison). 후보로 제시된 솔루션별 특징은 다음과 같습니다:

  • Pinecone – 클라우드 완전관리형 벡터 DB 서비스입니다. 인덱스 생성부터 스케일 아웃까지 모두 관리형으로 제공되어 복잡한 인프라 걱정 없이 몇 줄의 API 호출만으로 통합할 수 있습니다 (Faiss vs. Pinecone: Ideal Vector Database Comparison). 대규모 데이터에 대해 예측 가능한 성능과 확장성을 제공하며, 텍스트 임베딩 등 자연어 처리 용도에 최적화된 플랫폼입니다 (Faiss vs. Pinecone: Ideal Vector Database Comparison) (Faiss vs. Pinecone: Ideal Vector Database Comparison). 예컨대 Pinecone는 대량의 벡터 데이터에도 일관된 검색 성능을 보이며, 서버 운영이나 파티셔닝 등을 신경쓰지 않아도 되므로 개발 편의성이 높습니다. 반면 SaaS이므로 벤더 종속비용을 고려해야 합니다 (How to choose a vector database: Pinecone, Weaviate, MongoDB Atlas, SemaDB - DEV Community) (무료 규모 이상으로 확장 시 유료 과금). 메타데이터는 벡터와 함께 저장 가능하나, Pinecone는 구조화된 문서 데이터를 통째로 저장하기보다는 벡터+메타 정보 위주로 취급합니다 (How to choose a vector database: Pinecone, Weaviate, MongoDB Atlas, SemaDB - DEV Community).
  • Weaviate – 오픈소스 벡터 DB로 자체 서버에 설치하여 운용할 수 있으며, 필요에 따라 Weaviate Cloud와 같은 클라우드 관리형 옵션도 제공합니다. Weaviate는 GraphQL 기반의 풍부한 쿼리 인터페이스를 제공하고 스키마를 통해 벡터와 함께 메타데이터 필드를 저장/검색할 수 있는 장점이 있습니다. 오픈소스이기 때문에 벤더 락인 위험이 적고 로컬 설치 시 인터넷 없이도 동작합니다 (How to choose a vector database: Pinecone, Weaviate, MongoDB Atlas, SemaDB - DEV Community). 단일 바이너리로 실행 가능해 설치가 비교적 간단하며, on-premise 환경에서 사용하기에 적합합니다 (How to choose a vector database: Pinecone, Weaviate, MongoDB Atlas, SemaDB - DEV Community). 다만 Docker로 배포하거나 Java로 구동되는 등의 초기 세팅이 필요하고, 운영 중 업그레이드나 유지보수는 직접 해야 합니다. 소규모 서비스라면 단일 노드로 충분하나, 데이터가 커지면 클러스터 구성도 가능하여 유연성도 갖추고 있습니다.
  • FAISS – Facebook AI Research가 만든 벡터 검색 라이브러리입니다. 엄밀히 말하면 완전한 DB 서버보다는 Python/C++ 라이브러리로, 대용량 벡터에 대한 근사 최근접 탐색(ANN)을 매우 빠르게 수행할 수 있습니다. 성능 측면에서 뛰어난 알고리즘들을 제공하여 메모리 내에서 유사도 검색을 효율적으로 수행하며, 수백만 개 이상의 벡터도 거리 기반으로 빠르게 검색 가능합니다 (Faiss vs. Pinecone: Ideal Vector Database Comparison). 그러나 저장소/서버 기능이 내장되어 있지 않아서, 이를 사용하면 애플리케이션 코드 내에 벡터 색인 객체를 관리해야 하고 데이터의 지속성(persistence)이나 동시접근 제어 등을 직접 구현해야 합니다 (Faiss vs. Pinecone: Ideal Vector Database Comparison). 기술적으로 자유도가 높지만 활용을 위해선 전문 지식이 좀 더 요구되며 (Faiss vs. Pinecone: Ideal Vector Database Comparison), 데이터 업데이트 시 인덱스를 재구성하거나 별도의 처리 과정을 거쳐야 할 수도 있습니다. 작은 규모에서는 파이썬 서버 메모리에 FAISS 인덱스를 올려두고 쓰는 방식도 고려할 수 있지만, 운영/배포의 편의성을 생각하면 완전한 DB솔루션(Pinecone/Weaviate 등)을 사용하는 편이 낫습니다.

이외에도 Milvus, Qdrant, Chroma 등의 벡터 DB 솔루션이 존재합니다. Milvus는 분산형 벡터DB(클라우드 네이티브)로 성능이 우수하고, Qdrant는 러스트로 구현된 오픈소스 벡터DB, Chroma는 파이썬에서 손쉽게 쓸 수 있는 임베딩DB 등 각각 장단이 있습니다. 그러나 질문에 언급된 범위 내에서는 상기 Pinecone, Weaviate, FAISS 조합으로도 충분합니다. 권장 전략은 초기에는 구현과 관리가 간편한 Pinecone으로 시작해 보고, 추후 비용 문제나 데이터 통제 이슈가 발생하면 Weaviate로 마이그레이션하는 것입니다. Pinecone은 API 구조가 단순해 개발 속도를 높여주고 (Faiss vs. Pinecone: Ideal Vector Database Comparison), Weaviate는 자체 운영 시 데이터 주권을 확보할 수 있습니다 (Considerations for RAG systems in product and service development). 데이터 양이 매우 적고 시스템 복잡성을 최소화하고 싶다면, 아예 벡터DB 없이 파이썬 딕셔너리에 임베딩을 넣고 FAISS로 검색하는 방법도 있지만, 향후 확장성과 유지보수를 고려하면 전문 벡터DB 사용이 바람직합니다.

 

자연어 처리 모델 및 RAG 구성

Retrieval-Augmented Generation (RAG) 파이프라인을 구현하기 위해서는 두 가지 핵심 요소가 필요합니다: 임베딩 생성기(벡터화 도구)와 언어 생성 모델(LLM). 또한 이를 연결하고 질의 응답 체계를 구축하는 프레임워크가 필요합니다.

  • 임베딩 모델: PDF에서 추출한 문서 텍스트를 벡터로 변환하기 위해 사용됩니다. OpenAI의 text-embedding-ada-002 모델(API)을 사용하면 손쉽게 1536차원의 임베딩을 얻을 수 있고, 다국어에 대한 성능도 우수합니다. 대안으로 SentenceTransformers(예: all-MiniLM 등)와 같은 오픈소스 임베딩 모델을 쓸 수도 있습니다. 임베딩 모델 선택은 성능 vs. 비용 트레이드오프인데, OpenAI 임베딩은 품질이 높지만 API 비용이 발생하고 인터넷 호출이 필요하며, 로컬 모델은 초기 비용 없이도 구동 가능하지만 성능이 다소 떨어질 수 있습니다. 한국어 문서의 경우 KoSentenceBERT 등의 공개모델이나 코히어(cohere) API 등의 옵션도 있지만, OpenAI 모델들이 한국어 이해도 역시 뛰어난 것으로 알려져 있습니다.
  • LLM (생성 모델): 사용자 질의와 벡터DB에서 조회한 문맥을 조합하여 최종 답변을 생성합니다. 가장 손쉬운 방법은 OpenAI의 GPT-3.5 혹은 GPT-4 API를 사용하는 것입니다. OpenAI API를 쓰면 별도의 모델 호스팅 없이도 최첨단 언어모델의 성능을 활용할 수 있고, 프롬프트에 전달한 컨텍스트를 바탕으로 상당히 정확한 답변을 생성해줍니다. GPT-4는 높은 정확도와 창의성을 보여주지만 응답 시간이 다소 길고 비용이 높으므로, 예산과 필요에 따라 GPT-3.5 Turbo를 사용해도 충분할 수 있습니다. 대안으로 자체 호스팅 LLM을 고려할 수 있습니다. 예를 들어 Llama 2 13B와 같은 오픈소스 모델을 GPU 서버에 올려서 사용하는 방식인데, 이 경우 모델 로딩에만 수십 GB의 RAM/VRAM이 필요하며 (Llama2-13B는 대략 12GB 이상의 GPU 메모리를 요구함 (Run Llama 2 70B on Your GPU with ExLlamaV2)) 성능/응답시간이 OpenAI 대비 떨어질 수 있습니다. 일반 PC급 GPU로는 7B13B 모델까지 구동이 현실적이며, 대규모 30B70B 모델은 A100 같은 고성능 GPU가 필요합니다. **따라서 운영 초기에는 OpenAI 등 API 기반 접근이 현실적이며, 추후 데이터가 민감하거나 API 비용을 절감해야 할 상황이 되면 자체 LLM 도입을 검토하는 전략이 좋습니다.
  • RAG 프레임워크: 벡터DB와 LLM을 효과적으로 결합하기 위해 LangChain이나 LlamaIndex (기존 이름: GPT Index) 같은 고수준의 라이브러리를 활용할 수 있습니다. LangChain은 LLM 어플리케이션 개발을 위한 모듈 집합을 제공하여, 프롬프트 템플릿, 체인 로직, 메모리, 도구 사용 등을 체계적으로 관리해줍니다 (LangChain - Pinecone Docs). 핵심 철학은 데이터 인지 애플리케이션을 쉽게 만드는 것으로, 외부 데이터 소스와 상호작용하며 LLM을 활용하는 체인을 구축하기 용이합니다 (LangChain - Pinecone Docs). 예를 들어 LangChain을 Pinecone와 통합하면, 질의응답, 챗봇, 에이전트 등에 벡터DB 기반 지식을 추가로 부여할 수 있어 LLM의 활용도를 크게 높일 수 있습니다 (LangChain - Pinecone Docs). 한편 LlamaIndex는 RAG에 특화된 프레임워크로, 문서 데이터를 LLM에 연결하는 엔드투엔드 파이프라인 구축에 유용합니다 (LlamaIndex - Pinecone Docs). LlamaIndex는 데이터 로딩/전처리, 인덱싱, 질의 시 컨텍스트 구성까지의 과정을 고수준으로 지원하며, 자체적으로 간단한 벡터 저장소 기능도 포함하고 있습니다 (World's Most Accurate RAG? Langchain/Pinecone, LlamaIndex and EyeLevel Duke it Out). 두 프레임워크 모두 Python에서 사용 가능하고, 본 프로젝트의 PDF기반 질의응답에 필요한 문서 로더, 텍스트 분할, 임베딩 생성, 벡터검색, LLM 호출 등의 기능을 제공하므로 개발 생산성을 높여줍니다. 예를 들어 LangChain에는 PDF를 불러오는 DocumentLoader와 텍스트 chunk를 만드는 TextSplitter, 그리고 Pinecone같은 벡터DB에 임베딩을 넣고 질의시 검색하는 Retriever체계가 이미 구현되어 있습니다 (Build a PDF ingestion and Question/Answering system | ️ LangChain). 이러한 도구들을 활용하면 RAG 파이프라인을 비교적 적은 코드로 구축할 수 있습니다.
정리하면: 프론트엔드는 React 기반 SPA로 구현하고, 백엔드는 FastAPI로 구성된 Python API 서버를 구축합니다. 백엔드는 PDF에서 추출된 텍스트 조각과 임베딩을 벡터DB에 저장해두고, 질의 시 유사도 검색을 통해 관련 정보를 찾아 LLM 프롬프트에 첨부하여 OpenAI GPT 모델(API)로 답변 생성하는 구조가 됩니다 (LangChain - Pinecone Docs). 이 전체 흐름을 LangChain이나 LlamaIndex 같은 라이브러리로 관리하면 편리하며, 초기에는 클라우드 기반의 Pinecone+OpenAI 조합으로 구현하고, 필요 시 Weaviate나 자체 LLM으로 대체하는 확장성을 열어두는 것이 바람직합니다.

서버 및 배포 환경

자체 서버 vs 클라우드 서버

클라우드 서버를 사용하는 것이 대부분의 경우 최적의 선택입니다. AWS, Azure, GCP에서는 가상머신(예: EC2)이나 컨테이너 서비스를 통해 손쉽게 서버를 프로비저닝할 수 있고, 필요에 따라 스펙을 조정하거나 Auto Scaling으로 탄력적 확장을 할 수 있습니다. 초기 투자비용 없이 사용한 만큼 과금되므로 경제적이며, 하드웨어 관리나 데이터센터 운용에 대한 부담이 없습니다 (Considerations for RAG systems in product and service development). 예를 들어 AWS EC2에 Ubuntu 서버를 올리고 FastAPI 백엔드를 배포하면, 네트워크 설정이나 로드밸런싱, 모니터링 도구(CloudWatch 등)도 AWS에서 지원받을 수 있어 운영이 수월합니다. **반면 자체 물리 서버(on-premise)**를 운용하는 것은 데이터가 민감한 경우 등에 고려할 수 있습니다. 온프레미스 환경에서는 데이터가 모두 사내에 저장되므로 외부 유출 위험을 줄이고 보안 통제가 수월하며, 클라우드 정책에 좌우되지 않는 자유도가 있습니다 (Considerations for RAG systems in product and service development). 예컨대 의료/금융처럼 내부 규제가 엄격한 데이터일수록 직접 서버를 두고 관리하는 편이 안심될 수 있습니다. 하지만 그 대가로 초기 하드웨어 마련 비용과 서버실 인프라, 그리고 상시 운영 인력이 필요하고, 물리적 한계 내에서만 확장이 가능하다는 제약이 있습니다 (Considerations for RAG systems in product and service development).

요약하면, 특별한 사유가 없다면 클라우드에 백엔드와 벡터DB를 배포하는 것이 효율적입니다. AWS, Azure, GCP 모두 Python 웹서비스와 벡터DB 워크로드에 익숙한 플랫폼입니다. 예를 들어 AWS에서는 EC2에 FastAPI를 띄우고, 필요하면 AWS SageMaker나 Bedrock 서비스를 통해 관리형 Vector DB나 LLM API를 활용하는 식으로 아키텍처를 구성할 수 있습니다. Azure도 유사하게 Azure App Service나 VM, 그리고 Azure Cognitive Search 등을 활용해 RAG 파이프라인을 구축할 수 있고, GCP에서는 Vertex AI나 Cloud Run, Dataproc 등의 서비스를 조합할 수 있습니다. 하이브리드로 일부 구성(예: 벡터DB)은 SaaS(Pinecone)를 쓰고, 나머지는 자체 서버를 쓰는 식으로 혼합할 수도 있습니다. 다만 SaaS/API를 활용하면 편리한 대신 해당 서비스의 SLA와 비용 구조, 그리고 데이터 주권 이슈를 검토해야 합니다 (Considerations for RAG systems in product and service development).

참고: 온프레미스로 RAG 시스템을 구축할 경우, Weaviate 같은 오픈소스 벡터DB와 vLLM, Ollama 같은 로컬 LLM 실행 환경을 이용해 완전히 자체 인프라 내에 구성할 수도 있습니다 (Considerations for RAG systems in product and service development). 이는 데이터가 절대 외부로 나가면 안 될 때 고려할 옵션이며, 운영 복잡도가 높습니다.

 

RAG 서버 스펙 및 구성

CPU 및 RAM: RAG 서비스의 자원 요구사항은 사용되는 모델 종류에 따라 크게 달라집니다. OpenAI API를 통해 임베딩 생성과 답변 생성을 모두 처리한다면, 우리 서버에서는 주로 네트워크 I/O와 벡터DB 쿼리만 담당하므로 과도한 스펙이 필요하지 않습니다. 일반적인 웹 서버 수준인 24 vCPU에 48GB RAM 정도면 수백~수천 명대의 동시 접속자까지도 처리 가능할 것입니다. FastAPI 자체는 경량이므로 CPU 1개로도 동작하지만, 임베딩 벡터 유사도 계산 등 약간의 행렬연산이 있고, 또 여유로운 동시성 처리를 위해 vCPU 2개 이상을 권장합니다. 메모리는 벡터DB에 로딩한 임베딩 데이터 양에 비례하여 필요합니다. 예를 들어 1만 개 임베딩(1536차원)이라면 수십 MB 수준에 불과하지만, 100만 개 이상으로 늘면 수 GB 메모리가 필요할 수 있습니다. Pinecone 같은 서비스는 자체 인덱싱을 관리하므로 우리 서버 메모리에 부담이 없지만, FAISS를 메모리 내 사용한다면 프로세스 메모리를 충분히 할당해야 합니다.

GPU 필요 여부: 외부 LLM API들을 활용하는 경우 GPU는 필수가 아닙니다. 모든 모델 추론이 OpenAI 등의 클라우드에서 이뤄지므로, 우리 서버는 GPU 없이도 충분하며, 오히려 CPU 코어 수나 네트워크 대역폭이 중요합니다. 하지만 사용자가 자체 LLM 모델을 호스팅하기로 한다면 상황이 달라집니다. 대형 언어모델은 수십억~수천억 개의 매개변수를 가지고 있어 CPU만으로는 실시간 응답을 하기 어렵고, 전용 GPU 가속이 필요합니다. 예컨대 Llama-2 13B 모델을 실시간 추론하려면 약 12GB 이상의 VRAM을 가진 GPU가 요구되며 (Run Llama 2 70B on Your GPU with ExLlamaV2), 7B 모델은 약 8GB 내외, 30B 모델은 20GB 이상, 70B 모델은 40GB 이상을 필요로 합니다. 따라서 적어도 NVIDIA **RTX 3090 (24GB)**급이나 A10G, A100 (40GB) 같은 데이터센터 GPU가 있어야 원활한 서비스가 가능합니다. GPU 메모리가 부족한 경우 4bit/8bit 양자화된 모델이나 FlashAttention 같은 최적화 기법을 활용해야 하지만, 응답 속도가 다소 희생될 수 있습니다. 정리하면, RAG 구성에서 OpenAI, Pinecone 등의 클라우드 컴포넌트에 의존하면 CPU 서버로 충분하나, 모든 것을 직접 운영하려면 고사양 GPU 머신이 필요합니다. 초기에는 전자의 접근으로 개발하고 추후 트래픽 증가나 모델 전환이 있을 때 서버 스펙을 조정하는 탄력적 운영이 바람직합니다.

스토리지: 영양정보 PDF 등의 데이터 파일이나 벡터DB의 스토리지도 고려해야 합니다. Pinecone 같은 서비스는 저장을 맡아주지만, 직접 Weaviate/Milvus 등을 운영하면 데이터 저장소로 SSD 용량이 필요합니다. 수십 페이지 PDF의 텍스트와 임베딩은 용량이 크지 않지만, 추후 데이터가 누적될 것을 대비해 수십 GB 이상의 여유 스토리지를 확보하면 좋습니다. 또한 검색 성능을 위해 고속 SSD 사용이 권장됩니다.

네트워크: OpenAI API나 외부 서비스 호출 시 지연을 최소화하려면 서버의 네트워크 안정성과 속도도 중요합니다. 클라우드 VM이라면 보통 1Gbps 이상의 내부망/인터넷망이 제공되므로 크게 문제되지 않으나, 온프레미스 PC에서 운영한다면 업로드 대역폭을 확인해야 합니다. 또한 SSL 인증서 적용 등 보안 설정도 빠뜨리지 말아야 합니다.

 

로컬 PC에서 운영하는 경우

서비스를 개인 PC에서 직접 돌리는 것은 권장되는 프로덕션 구성은 아니지만, 예산이나 개발 편의상 고려할 수 있습니다. 로컬 PC에서 FastAPI 서버와 벡터DB를 띄우고 포트를 포워딩하거나 ngrok과 같은 터널링 서비스를 사용하면 외부 접속도 가능은 합니다. 그러나 다음 사항들을 유의해야 합니다:

  • 스펙 요구사항: PC에 충분한 자원이 있는지 확인해야 합니다. 예를 들어 OpenAI API 기반으로만 구동한다 해도, 동시 요청을 처리하려면 멀티스레딩/비동기로 동작할 CPU 코어 여유가 필요합니다. 쿼드코어 이상의 CPU와 16GB 정도의 RAM을 갖춘 PC라면 소규모 사용자 상대에는 견딜 수 있습니다. 하지만 자체 LLM을 돌릴 경우 앞서 언급한대로 고성능 GPU가 필수이며, 일반 데스크탑에는 RTX 4090(24GB) 같은 GPU를 장착해야 13B~30B 모델의 원활한 추론이 가능합니다. PC에 그런 GPU가 없다면 7B 이하 소형 모델이나 양자화모델로 성능을 타협해야 합니다.
  • 운영체제 및 환경: Windows 환경에서도 FastAPI나 LangChain를 구동할 수 있지만, 대개 Linux에서의 운영이 더 안정적이고 권장됩니다. PC에 WSL이나 Docker를 활용해 Linux 환경을 구성하면 배포 환경과 최대한 비슷하게 맞출 수 있습니다. 예를 들어 Docker로 FastAPI 컨테이너를 만들면 개발-PC와 클라우드 사이에 환경 차이를 줄여서 이식성이 높아집니다.
  • 24시간 가동의 어려움: PC는 개발용으로 적합하지만, 서버급 안정성을 보장하기 어렵습니다. 예기치 않은 재부팅이나 인터넷 회선 문제가 있을 수 있고, 전원이나 하드웨어 고장 시 대응이 늦어질 수 있습니다. 또한 가정용 인터넷은 고정 IP가 없거나 포트가 차단된 경우도 있어 외부 서비스로 운용하기엔 한계가 있습니다. 따라서 PC 운영은 어디까지나 테스트나 PoC 단계에서만 활용하고, 실제 서비스 출시 시에는 클라우드나 전문 호스팅을 이용하는 것이 좋습니다.
  • 보안: PC에서 직접 서비스를 노출하면 방화벽 설정, OS 보안패치 등을 사용자가 모두 책임져야 합니다. 클라우드 서버에서는 기본 방화벽/VPC 설정을 제공해주지만, PC는 곧바로 공인망에 노출되기 때문에 SSH 접속 보안, API 엔드포인트 보안에 각별히 신경써야 합니다.

결론적으로, 개발 단계에서는 로컬에서도 충분히 실행 가능하나, 상용 환경에서는 가급적 안정된 클라우드 VM이나 매니지드 서비스를 활용해 운영하고, 개발용 PC는 백업/테스트 용도로 활용하는 것을 권장합니다.

 

Cafe24 호스팅 서버 옵션

국내 호스팅 업체인 Cafe24에서 본 서비스를 운영하는 것도 가능하나, 몇 가지 고려사항이 있습니다:

  • 공유 웹호스팅의 한계: Cafe24의 일반적인 웹호스팅 상품은 PHP, JSP, Node.js 등 특정 언어 실행 환경을 제공하지만, Python 실행은 CGI 방식으로만 제한적으로 지원합니다 (국내에 파이썬 호스팅 하는 곳 있으면 알려주세요. > 파이썬 게시판 만들기). 즉 Python으로 작성된 스크립트를 Apache CGI 모듈을 통해 호출하는 정도만 가능하고, 상시 구동되는 FastAPI/Django 서버 프로세스를 띄우는 것은 불가능합니다. 실제로 Cafe24 호스팅센터 측 답변에서도 “웹호스팅에서는 파이썬을 직접 실행하는 방식이 아닌 CGI 형태로 이용 가능”하다고 명시하고 있습니다 (국내에 파이썬 호스팅 하는 곳 있으면 알려주세요. > 파이썬 게시판 만들기). 이러한 환경에서는 오늘날 요구되는 상시 접속 API 서버나 소켓 연결 등을 구현하기 어려우므로, 공유호스팅만으로는 RAG 웹서비스를 운영하기 어렵습니다.
  • 가상서버 호스팅 (VPS): Cafe24는 웹호스팅 외에 서버 호스팅 상품군으로 가상서버호스팅을 제공하고 있습니다. 이는 AWS Lightsail과 유사하게 가상 머신 하나를 임대하는 형태로, 사용자가 루트 권한으로 OS부터 설정을 자유롭게 할 수 있습니다. 따라서 이 옵션을 선택하면 사실상 일반 클라우드 VM을 사용하는 것과 같은 환경을 얻을 수 있습니다. Ubuntu 등의 리눅스를 설치하고 Python, FastAPI, Django 등을 직접 세팅하면 되므로, FastAPI나 Django 지원에 제약이 없습니다. 한 블로그 후기에서는 Cafe24 가상서버호스팅 신청 시 SSD 리눅스 서버를 선택하고, 용도에 따라 “일반형으로도 괜찮고 좀 여유 있게 쓰려면 비즈니스 상품을 선택”할 수 있다고 안내하고 있습니다 (cafe24 가상서버호스팅 신청하고 서버 셋팅과 파이썬 장고 설치하기). 즉 **일반형(VPS)**은 소규모로, **비즈니스형(VPS)**은 CPU/RAM 여유가 있는 플랜으로 구분되며, 예산과 필요에 맞게 고르면 됩니다. 가상서버를 신청하면 공인 IP가 할당되고 root 비밀번호가 주어져 사용자가 SSH로 접속해 서버를 운용하게 됩니다 (cafe24 가상서버호스팅 신청하고 서버 셋팅과 파이썬 장고 설치하기). 이 환경에서는 FastAPI를 Uvicorn+Nginx로 데몬 실행하거나, Docker로 원하는 애플리케이션을 띄우는 등 자유도가 매우 높습니다. 또한 벡터DB도 자체 설치 가능해서, 예를 들어 Weaviate Docker 컨테이너를 올리거나, pip로 FAISS를 설치하여 Python 프로세스 내에서 사용하거나, 필요하면 Pinecone API도 호출할 수 있습니다.
  • 스펙과 비용: Cafe24 VPS의 사양은 선택한 요금제에 따라 다르지만, 대체로 vCPU 24개, RAM 48GB 수준부터 옵션이 있습니다 (정확한 사양은 상품 페이지 참고). 이는 AWS 등의 VM과 유사한 성능이므로, 앞서 언급한 권장 사양에 맞춰 비즈니스형 VPS를 선택하면 무난합니다. 다만 GPU 옵션은 지원되지 않으므로 Cafe24에서는 자체 LLM을 돌릴 수는 없습니다. GPU가 꼭 필요하면, Naver Cloud Platform의 GPU 서버나 해외 GCP/AWS의 GPU 인스턴스를 사용하는 편이 현실적입니다. Cafe24 VPS 비용은 해당 사양의 해외 클라우드와 비교해 큰 차이는 없지만, 트래픽은 무제한 제공 등의 이점이 있을 수 있습니다. (단, 무제한이라고 해서 매우 높은 트래픽을 지속 유발하면 제재가 있을 수 있으므로 약관을 확인해야 합니다.)
  • 호환성과 기술지원: Cafe24는 개발 언어별 호스팅으로 Tomcat JSP, Node.js 전용 호스팅 등을 제공하는데, Python 전용 호스팅은 별도로 없으므로 VPS 사용이 사실상 유일한 방법입니다. VPS를 쓰면 OS 단계부터 전부 직접 관리해야 하므로, 초기 설정에 익숙하지 않다면 시간과 노력이 들어갈 수 있습니다. (예: UFW 방화벽 설정, 시스템 패키지 업데이트, 가상환경 구성 등). 다행히 Cafe24 측에서도 VPS 사용법에 관한 가이드 문서와 고객센터 지원이 있으니 참고하면 됩니다. FastAPI, Django 모두 VPS 환경에서 문제없이 동작하며, MariaDB/MySQL 등 데이터베이스도 원한다면 직접 구축하거나, 필요 시 Cafe24의 DB 호스팅 상품과 연동할 수도 있습니다. 요약하면, Cafe24에서는 “가상서버호스팅 + 사용자 직접 환경구축” 조합으로 본 서비스를 운영하게 됩니다.
  • 벡터DB와 AI 실행: 벡터DB인 Weaviate를 Cafe24 VPS에 도커로 띄우는 것은 가능하나, 메모리 사용량 등 리소스 모니터링을 잘 해야 합니다. FAISS를 사용하는 경우 Python 프로세스 메모리에 임베딩을 올리므로 VPS의 RAM 범위 내에서 사용 가능합니다. Pinecone API 사용은 외부 인터넷 호출이므로 문제없으며, Cafe24는 특별한 아웃바운드 차단을 하지 않으므로 OpenAI API 통신도 가능합니다. 다만 Cafe24의 네트워크가 해외 API 호출 시 약간 지연이 있을 수 있으므로 (국내 IDC → 해외 OpenAI 서버 왕복), 응답 속도 최적화를 위해 서울 리전에 있는 Azure OpenAI나 Naver HyperCLOVA 등의 대안을 고려할 수도 있습니다.
정리: Cafe24에서 운영하려면, 공유호스팅은 피하고 **가상서버호스팅(VPS)**을 이용해야 합니다. 해당 VPS에 Ubuntu 등을 설치한 뒤 FastAPI 서버, 벡터DB 등을 직접 셋업하게 됩니다. FastAPI나 Django 모두 구동 가능하며, Python 패키지 설치나 포트개방 등의 제약은 없습니다. 성능은 선택한 VPS 스펙에 따르고, GPU는 사용할 수 없으므로 LLM은 API 방식으로 쓰는 구성이 현실적입니다. 초기 진입장벽은 있지만, 한 번 환경을 갖추고 나면 Cafe24 VPS도 일반 클라우드 서버와 다를 바 없이 운용할 수 있습니다. 만약 운영 중에 트래픽이 폭증하면 Cafe24 단독 서버 호스팅이나 클라우드 호스팅(카페24 클라우드)으로 이전하는 방안도 있습니다. 그러나 카페24 클라우드 역시 결국 VPS의 일종이므로, 필요시 AWS 등으로 옮기는 것도 고려해볼 수 있습니다.

추가로, 카페24는 도메인 관리SSL 신청도 지원하므로, 도메인이 있다면 Cafe24에 연결해놓고 VPS로 포워딩하거나, VPS에 직접 SSL 인증서를 설치해 서비스를 운영하면 됩니다.

 

데이터 처리 및 업데이트 방식

PDF 데이터 벡터DB 삽입 (인덱싱 파이프라인)

건강 정보 PDF 문서를 RAG에 활용하려면 먼저 해당 PDF의 내용을 구조화하여 벡터DB에 저장해야 합니다. 일반적인 절차는 다음과 같습니다 (Design and Develop a RAG Solution - Azure Architecture Center | Microsoft Learn):

  1. 텍스트 추출: PDF로부터 텍스트를 추출합니다. Python의 PyMuPDF(fitz), pdfminer.six 또는 PyPDF2 등 라이브러리를 사용해 페이지 단위로 문자열을 얻을 수 있습니다. LangChain의 PyPDFLoader 같은 도구를 쓰면 여러 페이지를 바로 Document 객체로 불러올 수도 있습니다 (Build a PDF ingestion and Question/Answering system | ️ LangChain). 추출한 텍스트는 보통 페이지별로 나누어지며, 표나 그림 설명이 섞여 있을 경우 전처리가 필요할 수 있습니다.
  2. 청크 분할: 추출한 텍스트를 적당한 크기로 Chunking합니다. 한 페이지가 매우 길거나 여러 개념을 담고 있을 수 있으므로, 의미 단위로 잘라주는 과정입니다 (Design and Develop a RAG Solution - Azure Architecture Center | Microsoft Learn). 예를 들어 영양소 정보라면 항목별로, 또는 한 두 문단 단위로 청크를 만들 수 있습니다. 보통 한 청크당 수백자~수천자 정도로 하는데, 이는 나중에 LLM에 투입할 프롬프트 최대 길이에 맞춘 것입니다. LangChain의 CharacterTextSplitter 혹은 RecursiveTextSplitter 등을 활용하면 문장 단위를 유지하면서 지정한 크기 내로 청크를 나눠줍니다. 이 때 각 청크에는 원문 PDF의 페이지 번호나 섹션 제목 같은 메타데이터를 함께 보관해 두면 좋습니다 (출처 근거 제공용). Azure RAG 가이드에서도 문서를 잘게 나누고, 각 조각에 메타데이터(예: 제목, 요약, 키워드)를 추가하는 청크 enrich 과정이 중요하다고 언급합니다 (Design and Develop a RAG Solution - Azure Architecture Center | Microsoft Learn). 이러한 메타데이터는 추후 사용자 질문에 출처를 달거나 필터링 질의를 할 때 유용합니다.
  3. 벡터 임베딩 생성: 각 청크 텍스트에 대해 임베딩 벡터를 계산합니다. OpenAI의 Embedding API를 사용한다면 추출한 텍스트 조각을 API에 보내 1536차원 벡터를 받아오면 되고, 로컬에서 Huggingface 모델을 쓴다면 해당 모델을 로드해서 벡터화를 합니다. 임베딩 결과와 함께 청크를 식별할 수 있는 키(예: 문서ID+페이지번호 조합)와 메타데이터를 준비합니다. 이렇게 생성된 임베딩은 향후 유사도 검색의 기본 단위가 됩니다. 임베딩 생성 과정은 문서 추가/갱신 시마다 다시 수행되어야 하므로, 배치 작업으로 처리하는 것이 일반적입니다.
  4. 벡터DB에 적재 (Indexing): 앞 단계에서 얻은 (벡터, 메타데이터) 쌍들을 벡터 데이터베이스에 저장합니다. Pinecone의 경우 index.upsert() 메소드를 통해 여러 개의 벡터를 한꺼번에 업sert할 수 있습니다. 새로운 문서 청크에 대해서는 고유한 ID를 부여해 upsert하면 기존 레코드에 영향 없이 추가됩니다 (Incremental Upsert - Support - Pinecone Community). 만약 동일한 ID로 upsert하면 해당 벡터와 메타데이터가 업데이트되어 레코드 갱신도 구현할 수 있습니다 (Pinecone Vector Upsert - Matillion Docs). Weaviate를 쓴다면 REST API나 Python 클라이언트로 batch 객체를 생성해 벡터를 저장할 수 있고, 내부적으로 HNSW 등의 인덱스를 갱신합니다. FAISS를 사용한다면 메모리상의 index 객체에 add 함수를 호출해 벡터를 추가하고, 필요 시 디스크에 serialize해 저장합니다. 주요 고려사항은 벡터DB가 실시간으로 인덱스에 추가를 허용하는지 여부인데, Pinecone이나 Weaviate 등은 온라인 인서트/업데이트를 지원하며, 약간의 반영 지연 후 바로 쿼리에 검색 가능합니다.

위 과정이 완료되면 PDF의 내용이 벡터화되어 DB에 저장되며, 질의응답 시에는 이 벡터 인덱스를 질의에 대한 임베딩으로 검색하여 관련 청크를 획득하게 됩니다. 이렇게 사전 구축된 벡터 인덱스는 RAG 시스템의 지식 베이스로 작동합니다. LlamaIndex 등 프레임워크를 쓰면 이러한 일련의 과정을 더 자동화할 수 있습니다. 예컨대 LlamaIndex에서는 문서를 넣으면 내부적으로 벡터스토어 인덱싱까지 해주는 모듈이 있어서 개발자가 개별 단계를 세부적으로 코딩하지 않아도 됩니다.

 

데이터 업데이트 주기 및 절차

건강 정보는 정기적으로 업데이트될 수 있으므로, 벡터DB의 데이터도 주기적으로 최신화해야 합니다. 운영 상 고려사항은 다음과 같습니다:

  • 업데이트 주기: PDF가 새로 발행되거나 개정판이 나오면 즉시 해당 파일을 처리하여 인덱스를 갱신하는 것이 이상적입니다. 현실적으로는 개정 주기에 맞춰 (예: 월간, 분기별) 파이프라인을 재실행하면 됩니다. 스크립트를 만들어 신규 PDF 경로를 입력하면 위의 추출→임베딩→업서트 과정을 수행하도록 해두고, 이를 크론(cron) 작업으로 등록해 정기 배치로 돌릴 수 있습니다. 또는 관리자 인터페이스에서 "데이터 업데이트" 버튼을 만들어 수동 트리거할 수도 있습니다. 데이터 양이 많지 않다면 전체 재처리도 부담이 크지 않으므로, 매번 모든 PDF를 다시 임베딩해 덮어쓰는 방법도 가능합니다. 벡터DB가 업데이트를 효율적으로 지원하므로, 변경된 부분만 골라 업데이트하거나 통째로 다시 넣거나 구현 선택의 자유도가 높습니다 (Incremental Upsert - Support - Pinecone Community).
  • 증분 업데이트: 새로 추가된 PDF라면 기존 인덱스에 추가 삽입만 하면 되지만, 기존 PDF의 내용이 일부 교체된 경우 기존 벡터의 삭제 또는 갱신도 필요합니다. Pinecone의 경우 특정 ID로 vector를 upsert하면 내용을 덮어쓰게 되므로 이를 이용해 갱신하고, 삭제가 필요하면 delete API로 해당 ID를 제거할 수 있습니다. Weaviate도 객체 삭제 기능이 있습니다. FAISS는 부분 삭제가 복잡한 편이라 보통 변경분 반영을 위해 인덱스를 새로 구축하는 경우가 많습니다. 만약 자주 갱신되는 데이터라면, 문서별 네임스페이스를 구분해 관리하면 편리합니다 (예: Pinecone의 namespace 기능으로 버전별 인덱스를 분리해두고 최신 namespace만 질의에 사용).
  • 자동화 파이프라인: 데이터 소스가 업데이트될 때 이를 자동으로 처리하려면, ETL 파이프라인이나 서버 사이드의 스케줄러를 활용합니다. 예를 들어 Apache Airflow나 Prefect 같은 워크플로우 툴을 쓰면 새로운 PDF 발생 시 잡을 실행시켜 벡터DB 갱신까지 자동화할 수 있습니다. 간단한 대안으로 Github Actions CI를 이용해 주기적으로 스크립트를 실행하거나, Linux 서버 cron + Shell 조합으로 구현할 수도 있습니다. 중요한 것은 업데이트 과정에서 일관성을 유지하는 것입니다. 업데이트 도중 질의가 들어올 수 있으므로, 가능하면 트랜잭션하게 처리하거나, 업데이트 완료 전에 새 벡터를 잠시 쿼리에 포함시키지 않는 등의 설계가 필요할 수 있습니다. 소규모 서비스에서는 큰 문제는 아니지만, 대규모 벡터DB에서는 인덱스 교체 전략(예: 새로운 인덱스 빌드 후 엔드포인트 스왑)을 사용하기도 합니다.
  • 모니터링 및 검증: 주기적 업데이트 시 잘못된 데이터가 들어가거나 임베딩 단계에서 오류가 발생할 수 있으므로, 로그를 모니터링하고 예외를 처리해야 합니다. 예를 들어 임베딩 API 호출 실패 시 재시도 로직, PDF 파싱 실패 시 해당 파일을 스킵하고 알림 보내기 등의 대책이 필요합니다. 또한 업데이트가 끝나면 몇 가지 샘플 질문을 통해 새로운 내용이 반영되었는지 테스트하면 품질 유지에 도움이 됩니다.

효율적인 운영 방안: 데이터를 지속적으로 활용하려면 중복 처리 방지와 불필요한 재계산 최소화가 중요합니다. 예를 들어 동일한 PDF에 변화가 거의 없다면 이전 임베딩을 재사용하고 변경된 부분만 새로 임베딩하도록 최적화하면 자원 낭비를 줄일 수 있습니다. 또한 임베딩 생성 비용(API 비용)이 누적될 수 있으므로, 임베딩 결과를 어디엔가 캐싱/저장해두고 (예: 파일이나 DB에), 동일한 문서에 대해 반복 임베딩하지 않도록 관리합니다. Pinecone 등의 벡터DB는 자체가 영구 저장소 역할을 하므로, 일단 upsert한 벡터는 다시 생성할 필요 없이 그대로 남아 있습니다.

마지막으로, 서비스 운영 시 프롬프트 구성이나 모델 튜닝도 계속 개선해야 합니다. RAG의 정확도는 적절한 컨텍스트 제공과 모델의 활용에 달려 있으므로, 벡터 검색 결과 중 상위 N개를 얼마나 포함할지, 프롬프트에 출처를 어떻게 배치할지 등을 실험하며 조정합니다. LangChain의 체인이나 LlamaIndex의 query engine 설정을 변경하면서 답변의 품질과 신뢰도 평가를 정기적으로 실시하는 것이 좋습니다. 필요하면 중요 키워드에 대해서는 벡터 검색 외에 키워드 필터링(예: "비타민 C" 등 특정 토픽만 검색)이나 재랭킹 단계를 추가하여 정확도를 높일 수도 있습니다.

이상의 방안을 종합하면, 건강정보 PDF에 기반한 RAG 웹서비스 구축 시 React + FastAPI + 벡터DB + OpenAI API 조합이 현재로서는 개발 생산성과 응답 품질 면에서 최적입니다. 클라우드 환경에서 작은 인스턴스로 시작해도 되고, Cafe24 VPS같이 손쉽게 접근 가능한 호스팅을 활용할 수도 있습니다. 핵심은 벡터DB를 통한 신뢰할 만한 정보조회LLM의 자연어 생성을 매끄럽게 통합하는 것이며, 이를 위해 언급된 기술 스택과 배포 전략을 상황에 맞게 선택하면 될 것입니다. 실제 운영 단계에서는 성능 모니터링(APM 도구 도입 등), 예외 상황 대비(모델 API 장애 시 fallback 답변 등)도 준비하여 안정적이고 효율적인 서비스가 되도록 합니다. (Faiss vs. Pinecone: Ideal Vector Database Comparison) (LangChain - Pinecone Docs)

반응형