본문으로 건너뛰기

© 2026 Molayo

GitHub요약2026. 06. 17. 11:57

Secure-Offline-RAG-System

요약

데이터 프라이버시와 보안에 특화된 오프라인 RAG 시스템 솔루션입니다. 하이브리드 검색과 Docling을 활용한 고품질 텍스트 추출을 통해 효율적인 문서 처리 및 검색 성능을 제공합니다.

핵심 포인트

  • BM25와 FAISS를 결합한 하이브리드 검색 방식 채택
  • Docling을 활용한 고품질 Markdown 파싱 및 서식 보존
  • Llamafile 통합을 통한 간편한 오프라인 배포 및 추론
  • 캐싱 시스템과 BGE Reranker를 통한 성능 최적화

최소한의 계산 오버헤드로 다양한 콘텐츠 유형을 효율적으로 처리하도록 설계된 검색 증강 생성 (Retrieval-Augmented Generation (RAG)) 시스템입니다.

이 솔루션은 UnderstandTech에서 주최한 Secure RAG Challenge에서 1위를 차지했습니다!

자세한 내용은 다음과 같습니다:

  • 🌟 공식 경진대회 저장소 (Official Competition Repository) - 모든 결선 진출자의 솔루션이 포함되어 있습니다.
  • 📢 공식 결과 발표 (Official Results Announcement) - 경진대회 결과 및 세부 사항이 담긴 LinkedIn 게시물입니다.

이번 챌린지는 데이터 프라이버시, 보안 및 오픈 소스 기술에 중점을 둔 안전한 오프라인 RAG 시스템 구축에 초점을 맞추었습니다.

  • 개요 (Overview)
  • 시스템 요구 사항 (System Requirements)
  • 시스템 아키텍처 세부 사항 (System Architecture Details)
  • 주요 기능 (Key Features)
  • 설치 가이드 (Installation Guide)
  • 사용 가이드 (Usage Guide)
  • 지원되는 파일 유형 (Supported File Types)
  • 설정 (Configuration)
  • 성능 최적화 (Performance Optimizations)
  • 프로젝트 구조 (Project Structure)
  • 의존성 및 라이선스 (Dependencies and Licenses)
  • 라이선스 (License)
  • 저자 (Authors)

이 시스템은 다음과 같은 핵심 구성 요소로 RAG 파이프라인을 구현합니다:

전처리 단계 (Preprocessing Stage):-
Langchain Loaders와 Docling을 사용하여 여러 파일 유형을 처리합니다.
특히 Office 문서는 먼저 PDF 형식으로 변환됩니다.
Docling은 PDF를 Markdown 형식으로 파싱합니다.
주요 장점: 탁월한 텍스트 추출 품질 및 서식 보존

  • 텍스트는 최적화된 청크 (chunks)로 분할됩니다.

이중 인코딩 시스템 (Dual Encoding System):
밀집 인코딩 (Dense Encoding): Nomic Embed가 의미론적 임베딩 (semantic embeddings)을 생성합니다.
희소 인코딩 (Sparse Encoding): 키워드 매칭을 위해 TF-IDF를 사용하는 BM25를 사용합니다.

  • 파일 콘텐츠, 분할된 후의 청크, 그리고 임베딩은 효과적인 재사용을 위해 캐싱됩니다.

저장 및 검색 (Storage & Retrieval):-

  • 밀집 임베딩을 위한 FAISS 벡터 데이터베이스

  • 희소 표현을 위한 TF-IDF 인덱스

쿼리 처리 (Query Processing):-

  • FAISS와 BM25 간의 결합된 검색 후 상위 K (Top K) 문서가 반환됩니다.

  • BGE Reranker가 상위 K 청크를 재순위화 (rerank) 합니다.

  • 상위 N (N < K) 문서가 쿼리와 함께 LLM으로 전송됩니다.

생성 단계 (Generation Stage):
Llamafile 통합 (Llamafile Integration):-

  • 간편한 배포 및 사용
  • 우수한 CPU/GPU 성능
  • 리소스 최적화를 위한 유연한 GPU 레이어 제어
  • 빠른 추론 속도

테스트된 구성:

  • Ubuntu 22.04

  • 32GB RAM

  • 8GB VRAM (RTX 3070 Laptop)

  • Intel Core i7 (16 CPU cores)

  • CUDA 버전: 12.4

  • 드라이버 버전: 550.120

  • 다중 문서 처리 (텍스트, 코드, 기술 문서)

  • BM25와 벡터 검색 (vector search)을 결합한 하이브리드 검색 (Hybrid retrieval)

  • 성능 최적화를 위한 고급 캐싱 시스템 (Advanced caching system)

  • 자동 메모리 관리를 포함한 GPU 가속 임베딩 (GPU-accelerated embeddings)

  • 설정 가능한 처리 파이프라인 (Configurable processing pipeline)

  • 스레드 안전 (Thread-safe) LLM 연산

  • 진행 상황 추적 및 포괄적인 로깅 (Logging)

  • Streamlit을 통한 웹 인터페이스

  • 통합 문서 로딩 인터페이스

  • 다양한 콘텐츠 유형을 위한 특화된 핸들러

  • 효율적인 청킹 (Chunking) 및 전처리

  • 지능형 캐싱 시스템

  • 키워드 기반 검색을 위한 BM25

  • 의미론적 검색 (Semantic search)을 위한 FAISS 벡터 저장소

  • 설정 가능한 가중치를 가진 하이브리드 검색

  • 문맥 인식 응답 생성 (Context-aware response formulation)

  • 쿼리 확장 (Query expansion) 기능 (
    성능 저하로 인해 구현되었으나 사용되지 않음) - 스레드 안전 (Thread-safe) LLM 핸들링

  • 구조화된 응답 포맷팅

  • 헤더 기반 분할을 적용한 Markdown

  • 변환 기능이 강화된 PDF

  • 사용자 정의 컬럼 처리가 가능한 CSV

  • 테이블 추출 기능이 포함된 HTML

특화된 파싱 (Parsing)을 지원하는 언어:

  • Python

  • JavaScript/TypeScript

  • Java

  • C#

  • C++

  • Go

  • Rust

  • 기타 등등...

  • 자동 목차 (TOC) 감지

  • 헤더 계층 구조 보존

  • 출처 표기 (Source attribution)

  • 메타데이터 강화

# 패키지 목록을 업데이트하고 LibreOffice를 설치합니다
sudo apt update
sudo apt install libreoffice
...
- (중요: VRAM이 8GB 이하인 경우 CUDA OOM(Out of Memory)을 방지하기 위해, 아래 "사용 가이드"의 "2. 시스템 초기화" 단계 이후에만 LLM 서버를 시작하십시오)

-ngl 12

GPU로 오프로드(offload)할 모델 레이어의 수를 나타냅니다. 더 나은 성능을 위해 사용 가능한 VRAM이 더 많다면 이 값을 높이고, 그렇지 않다면 낮추십시오. 이 파라미터를 지정하지 않으면 모델은 GPU VRAM 대신 RAM에 로드됩니다.

# llamafile 다운로드 및 설정
wget https://huggingface.co/Mozilla/Mistral-Nemo-Instruct-2407-llamafile/resolve/main/Mistral-Nemo-Instruct-2407.Q5_K_M.llamafile
chmod +x Mistral-Nemo-Instruct-2407.Q5_K_M.llamafile
...

config/init_config.yml에서 데이터 경로를 설정하십시오.

:
document_paths에서

files 또는 URLS에 대한 경로를 지정하십시오.

URL을 제공하는 경우, 시스템이 웹 페이지의 Table Of Content (목차)를 자동으로 탐색하고 웹 페이지에서 정보를 추출한다는 점에 유의하십시오. test_data에는 제출(submission) 파일을 생성하기 위해 test.csv 파일의 경로를 제공해야 합니다. 또한 제출 파일을 저장할 위치를 나타내기 위해 test_output을 제공해야 합니다.

files:
document_paths:
- "path/to/your/documents"
...

python init_cache_data.py

이 명령은 시스템을 초기화합니다. 이 단계가 끝나면 문서의 내용, 분할된 청크 (chunks), 그리고 임베딩 (embeddings)이 config/init_config.yml에 지정된 폴더 (기본값: cache/)에 저장됩니다. 이 전략을 사용하면 검색 (retrieval)을 위해 매번 시스템 데이터를 다시 생성할 필요가 없습니다. 작업을 분리해야 하는 경우 (예를 들어, 하나는 코드용 캐시로, 다른 하나는 텍스트 문서용 캐시로 사용), 새로운 cache_dir 경로를 제공할 수 있습니다.

paths:
cache_dir: "./cache"

python generate_submission_csv.py

이 명령은 config/init_config.ymltest_output: 내용을 읽으며, 파일이 이미 존재하는 경우 답변 생성을 재개합니다. 그렇지 않으면 새로운 제출 파일을 생성합니다.

Streamlit 웹 인터페이스 (Web Interface)

streamlit run streamlit_app.py

  • 이 명령을 실행하면 사용자가 RAG 시스템과 상호작용할 수 있으며, 모델이 답변을 생성하는 데 사용한 컨텍스트 (context)를 확인할 수 있습니다.
    참고: 출력 형식이 아직 완벽하게 정돈되지 않았습니다. 답변을 표시하는 코드는 업데이트가 필요합니다.
    RAG Pipeline Architecture

Jupyter Notebook

  • inference_notebook.ipynb를 열고 실행하십시오.

명령줄 인터페이스 (Command Line Interface)

python process_single_query.py --query "여기에 쿼리를 입력하세요"

.txt

(일반 텍스트).md

(마크다운).pdf

(PDF 문서).docx

,.doc

(Word 문서).ppt

,.pptx

(PowerPoint 프레젠테이션).xlsx

,.xls

(Excel 스프레드시트).odt

(OpenDocument 텍스트).csv

(쉼표로 구분된 값).json

(JSON 파일).html

,.htm

(HTML 파일).eml

.msg

.py

(Python).js

,.jsx

(JavaScript).ts

,.tsx

(TypeScript).java

(Java).cpp

,.c

(C/C++).cs

(C#).go

(Go).rs

(Rust)

.ipynb

효율적인 캐싱 (Efficient Caching)- 자동 캐싱

  • 콘텐츠 유형 기반 선택적 캐싱
  • 캐시 키를 위한 MD5 해싱

GPU 메모리 (GPU Memory)- 자동 CUDA 메모리 정리

  • 임베딩을 위한 배치 처리
  • 장치 인식 작업(Device-aware operations)

병렬 처리 (Parallel Processing)- 다중 프로세스 문서 로딩

  • 스레드 기반 LLM 연산
  • 설정 가능한 스레드 개수

청킹 전략 (Chunking Strategies)- 적응형 청크 크기

  • 콘텐츠 인식 분할(Content-aware splitting)
  • 중복 최적화(Overlap optimization)

벡터 저장소 (Vector Storage)- 효율적인 유사도 검색을 위한 FAISS

  • 압축된 임베딩 저장

문서 저장소 (Document Storage)- 디스크 기반 저장

  • 가능한 경우 지연 로딩(Lazy loading)
trustii_rag_project/
├── config/ # 설정 파일
├── data/ # 데이터 저장소
...
패키지/도구 (Package/Tool)라이선스 (License)사용법 (Usage)
LangChainMIT핵심 RAG 기능 및 임베딩
...
시스템은 두 가지 주요 설정 파일을 사용합니다:

init_config.yml
: 시스템 초기화 및 핵심 매개변수 제어process_config.yaml
: 쿼리 처리 및 검색 설정 제어

logging:
level: "INFO"
show_progress: true
...
파라미터 (Parameter)설명 (Description)권장 값 (Suggested Values)비고 (Notes)
level로깅 상세 수준 (Logging verbosity)"DEBUG", "INFO", "WARNING", "ERROR"개발 시에는 "DEBUG", 운영 환경에서는 "INFO" 사용
show_progress진행 바 표시 (Display progress bars)true/false헤드리스 (headless) 환경에서는 비활성화
hide_http_requestsHTTP 로그 억제 (Suppress HTTP logs)true/false더 깔끔한 로그를 위해 활성화
file_logging파일로 로깅 (Log to files)true/false운영 환경에서는 활성화 상태 유지
console_logging콘솔로 로깅 (Log to console)true/false운영 환경에서는 비활성화 가능
model:
embedding_model_hf: "nomic-ai/nomic-embed-text-v1.5"
rerank_model: "BAAI/bge-reranker-v2-m3"
...
파라미터 (Parameter)설명 (Description)권장 값 (Suggested Values)튜닝 비고 (Tuning Notes)
embedding_model_hfHugging Face 임베딩 모델 (Hugging Face embedding model)"nomic-ai/nomic-embed-text-v1.5", "BAAI/bge-base-en-v1.5"정확도와 속도 요구 사항에 따라 선택
rerank_model결과 재순위화 모델 (Model for reranking results)"BAAI/bge-reranker-v2-m3", "cross-encoder/ms-marco-MiniLM-L-4-v2"모델이 클수록 더 정확하지만 속도는 느림
device_rerank연산 장치 (Computing device)"cuda", "cpu"GPU를 사용할 수 없는 경우 "cpu" 사용
ingestion:
ignore_columns: None #["Query"]

csv 파일의 데이터 인제스션 (ingestion) 과정에서 특정 컬럼을 건너뛰려면 ignore_columns를 설정하세요.

processing:
TOC_text: "Table of Contents"
headers_to_split_on:
...
매개변수 (Parameter)설명 (Description)기본값 (Default)튜닝 권장 사항 (Tuning Recommendations)
chunk_size텍스트 청크 (text chunks)의 크기2000- 기술 문서의 경우 증가 (3000-5000) - QA 스타일 콘텐츠의 경우 감소 (600-1000) - 문맥 (context)과 관련성 (relevance) 사이의 균형 조절
chunk_overlap청크 간의 중첩 (overlap)200- chunk_size의 20-25% 권장 - 복잡한 문서의 경우 증가 - 단순하고 구조화된 콘텐츠의 경우 감소
batch_size_embeddings임베딩 (embedding) 생성 시 배치 크기 (batch size)32- GPU 메모리가 더 많을 경우 증가 (64-128) - CPU 처리의 경우 감소 (8-16)
batch_size_reranking재순위화 (reranking) 시 배치 크기 (batch size)8- GPU 메모리에 따라 조정
OMP_NUM_THREADS병렬 처리 (parallel processing)를 위한 스레드 (thread) 수15- (CPU 코어 수 - 1)로 설정 - 공유 시스템의 경우 낮게 설정
paths:
cache_dir: "./cache"
data_dir: "./data"
...

이번 챌린지에서는 다음 4가지 정보 소스의 조합을 테스트했습니다:

data/raw/742762880-Matter-1-3-Core-Specification.pdf
: Matter 사양 (specification) 버전 1.3.

data/raw/data.txt
: train.csv 내 Response 컬럼의 행(rows).

data/raw/matter_specification.pdf
: Matter 사양 (specification) 버전 1.0.

https://project-chip.github.io/connectedhomeip-doc/
: Matter 사양 (specification)의 GitHub 문서.

최종적으로 data/raw/742762880-Matter-1-3-Core-Specification.pdfdata/raw/data.txt가 제출에 사용되었습니다.

retrieval:
llamafile_server_base_url: "http://localhost:8081"
send_nb_chunks_to_llm: 3
...
파라미터 (Parameter)설명 (Description)기본값 (Default)튜닝 권장 사항 (Tuning Recommendations)
send_nb_chunks_to_llmLLM으로 전송할 청크 (chunks) 수2- 복잡한 질의의 경우 증가 (7-10) - 단순한 질의의 경우 감소 (3-4) - 컨텍스트 (context)와 속도 사이의 균형 조절
use_bm25BM25 검색 활성화 여부true- 키워드 중심의 질의 시 활성화 - 의미론적 (semantic) 질의 시 비활성화
bm25_weightBM25와 벡터 검색 (vector search) 간의 가중치0.2- 기술적 콘텐츠의 경우 증가 (0.6-0.8) - 대화형 콘텐츠의 경우 감소 (0.2-0.4)
top_k초기 결과 수100- 다양한 콘텐츠를 위해 증가 (150-200) - 집중된 도메인을 위해 감소 (50-75)
use_reranking결과 재순위화 (reranking) 활성화 여부true- 정확도를 위해 활성화 - 속도를 위해 비활성화
use_query_expansion질의 확장 (query expansion) 활성화 여부false- 모호한 질의의 경우 활성화 - 구체적인 질의의 경우 비활성화
  • LLM의 출력은 선택된 프롬프트 (prompt)의 영향을 받습니다.
  • 이번 경연에서 사용된 프롬프트는 다음과 같습니다:
prompt = ChatPromptTemplate.from_template("""
You are an efficient Q&A assistant that respond to user queries based on provided context.
Based on the following information, please provide a clear, accurate, and comprehensive answer to the question.
...

참고: train.csv의 답변들은 간결하며 일반적으로 참조 (references)가 부족합니다. 반면, Understand.Tech에서 Matter model이 제공하는 baseline은 인용 (citations)을 포함한 상세한 응답을 제공합니다. 이로 인해 딜레마가 발생했습니다: 퍼블릭 리더보드 (public leaderboard)의 정답 (ground truth)에 맞춰 간결한 답변을 생성해야 할까요, 아니면 Matter model처럼 포괄적인 응답을 생성해야 할까요? 저는 최종적으로 참조를 포함하지 않는 절충안을 선택했습니다. 생성된 응답에 인용 (citations)을 포함하려면, 사용자는 프롬프트 지침인 6. Don't mention the source of the information6. Mention the sources (sections, tables, figures, etc.) where possible.로 교체하기만 하면 됩니다.

제한된 RAM (16GB 이하):-

  • chunk_size를 500으로 감소

  • batch_size_embeddings 설정

  • batch_size_reranking을 16으로 설정

  • 필요 시 use_reranking 비활성화 (4로 설정)

고용량 RAM (32GB 이상):-

  • chunk_size를 1000-1500으로 증가
  • batch_size_embeddings를 설정

AI 자동 생성 콘텐츠

본 콘텐츠는 GitHub AI Tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0