제6부 생성형 AI 플랫폼
6.9 RAG I — Retriever·임베딩·벡터DB
6.9.1 이 장에서 배우는 것 / 선수 지식
6.1에서 "지식은 파인튜닝이 아니라 RAG로"라 했다. 최신·사실·사내 지식은 가중치에 굳히면 갱신이 어렵고 환각을 안 준다 — 대신 검색해서 문맥으로 주입한다. 이 장은 그 RAG(Retrieval-Augmented Generation)의 검색(retrieval) 절반 — 임베딩·청킹·벡터DB·리랭킹 — 을 판다. 전체 파이프라인·생성·평가는 6.10.
핵심 통찰: RAG의 품질은 "검색이 정답 근거를 가져오느냐"에 달렸다. 아무리 좋은 LLM도 검색이 잘못된 문맥을 주면 엉뚱하게 답한다(garbage in). 그래서 검색은 2단계 — 빠른 임베딩+ANN 검색으로 후보를 넓게 건지고(recall), 리랭킹으로 정밀하게 추린다(precision). 그리고 청킹·임베딩 모델·인덱스 파라미터가 그 품질을 좌우한다.
배우는 것:
- RAG의 동기 — 파인튜닝 대비 지식 갱신·환각 감소·출처 인용·비용.
- 임베딩 — 텍스트의 의미 벡터, 유사도 검색, 임베딩 모델(NeMo Retriever 임베딩 NIM).
- 청킹 — 문서를 검색 단위로 분할, 청크 크기·오버랩의 트레이드오프.
- 벡터DB·ANN — 임베딩 저장·근사 최근접 탐색(HNSW·IVF), GPU 가속(cuVS), 왜 exact가 아니라 ANN인가.
- 2단계 검색 — bi-encoder(임베딩·recall) → cross-encoder(리랭킹·precision).
- 하이브리드 검색 — dense(의미) + sparse(키워드)로 recall 보완.
선수 지식: 6.1(지식=RAG·라이프사이클), 6.7(임베딩·리랭킹 NIM), 6.2(청킹은 데이터 처리와 유사), 1.9(HBM — 벡터 검색). 전체 파이프라인·평가는 6.10, 가드레일은 6.11. 환경은 NIM·벡터DB.
정직: NeMo Retriever의 구성요소(임베딩·리랭킹 모델·커넥터)와 벡터DB·가속 라이브러리(cuVS/RAFT 등)는 버전·생태계 의존이다. RAG·임베딩·ANN의 원리는 안정적이고 도구는 풍부하다(LangChain·LlamaIndex·여러 벡터DB) — 이 장은 원리·트레이드오프를 가르치고 도구는 중립적으로. 모든 수치는 환경 의존 개략값.
6.9.2 RAG는 왜 — 검색으로 지식을 준다
파인튜닝으로 지식을 주면 가중치에 굳혀 갱신마다 재학습해야 하고, 환각이 줄지 않으며, 출처가 없다(6.1). RAG로 지식을 주면(위 흐름) 다음 이점이 있다:
- 지식 갱신: 인덱스만 갱신(재학습 X)
- 환각 감소: 실제 문서를 근거로(없으면 "모른다")
- 출처 인용: 어느 문서에서 왔는지 제시 → 신뢰·검증
- 비용: 학습보다 비용이 낮고 빠름
RAG 전체 구조(이 장 = 검색, 6.10 = 생성·평가):
검색 절반(임베딩·ANN 검색·리랭킹)이 이 장이고, LLM 생성은 6.10이다.
핵심: RAG는 "지식을 모델 밖에 두고 필요할 때 가져오는" 구조다. 모델은 추론·언어 능력을, 지식은 검색 가능한 외부 저장소를 맡는다. 검색이 좋은 근거를 가져오는 것이 RAG 품질의 전제 — 그래서 이 장(검색)이 중요하다.
6.9.3 임베딩 — 의미를 벡터로
임베딩(embedding) 은 텍스트를 고차원 벡터로 바꾼다. 의미가 비슷한 텍스트는 벡터 공간에서 가깝다.
| 텍스트 | 임베딩 | 관계 |
|---|---|---|
| "환불 절차" | [0.21, -0.05, ..., 0.13] (예: 768·1024차원 벡터) | 기준 |
| "어떻게 돈을 돌려받나" | 비슷한 벡터(의미 유사) | 가까움 |
| "오늘 날씨" | 먼 벡터 | 무관 |
검색 = 질의 벡터의 '최근접 이웃'을 벡터DB에서 찾기(유사도 = 코사인·내적).
- 임베딩 모델: 텍스트 → 벡터. 검색 특화 임베딩 모델(retrieval embedding)을 쓴다. NeMo Retriever 임베딩 NIM(6.7)이 GPU 가속으로 대량 임베딩.
- 유사도: 코사인 유사도(또는 정규화 후 내적). 가까울수록 관련.
- 차원·모델 선택: 차원↑ = 표현력↑·저장/검색 비용↑. 모델은 도메인·언어·성능으로(검색 벤치로 평가).
함정: 질의 임베딩과 문서 임베딩은 같은 모델·같은 방식이어야 한다(6.2 토크나이저 일관성과 동형). 다른 모델로 임베딩하면 같은 공간이 아니라 검색이 망가진다. 일부 모델은 질의/문서에 다른 프리픽스를 쓴다(asymmetric) — 모델 규약을 따른다.
6.9.4 청킹 — 검색 단위 만들기
문서 전체를 임베딩하면 너무 크고 부정확하다. 청킹으로 검색 가능한 단위로 분할한다.
청크 크기 트레이드오프:
| 청크 크기 | 효과 |
|---|---|
| 너무 작음(예 1문장) | 문맥 부족 → 검색은 정밀하나 답에 필요한 주변 정보 누락 |
| 너무 큼(예 1페이지) | 한 청크에 여러 주제 → 임베딩이 '흐려짐'(평균화), 무관 내용 섞임 |
| 적당(문단·수백 토큰) | 의미 단위 보존 + 정밀 |
오버랩: 청크 경계에서 문맥이 잘리지 않게 일부 겹친다. 의미 기반 청킹: 문장·섹션 경계로 자연스럽게(고정 길이보다 나을 수 있음).
청킹 결정:
- 크기: 보통 수백 토큰(문단 단위). 도메인·문서 구조로 조정. 표·코드는 별도 처리.
- 오버랩: 인접 청크가 일부 겹쳐 경계 정보 손실 방지(예 10~20%).
- 메타데이터: 청크에 출처·섹션·날짜를 붙여 필터링·인용에 활용.
- 구조 인지: 마크다운 헤더·표·코드 블록을 존중하는 청킹이 단순 고정 길이보다 나을 때 많음.
견해: 청킹은 RAG 품질의 숨은 결정자다 — 부적절한 청킹(너무 크거나 작거나 주제가 섞임)은 좋은 임베딩·LLM으로도 못 살린다. 문서 구조를 존중하고(헤더·문단), 적당한 크기+오버랩, 메타데이터를 붙인다. 청킹 전략을 검색 평가(6.10)로 검증한다.
6.9.5 벡터DB·ANN — 스케일 검색
수백만~수십억 청크에서 질의 최근접을 찾으려면 전수 비교(exact)는 비현실적이다. 벡터DB는 ANN(근사 최근접 탐색) 으로 빠르게 찾는다.
| 방식 | 동작 | 특징 |
|---|---|---|
| exact NN | 질의 벡터를 모든 청크 벡터와 비교 → O(N) | 수십억이면 너무 느림 |
| ANN · HNSW(그래프) | 계층 그래프를 따라 탐색 | 빠르고 정확, 메모리↑ |
| ANN · IVF(클러스터) | 벡터를 클러스터로 나눠 가까운 클러스터만 탐색 | 근사 |
| ANN · PQ(양자화) | 벡터를 압축 | 메모리·속도↑(정확도 약간↓) |
ANN(근사)은 인덱스 구조로 '거의 최근접'을 빠르게 찾는다(약간의 정확도 희생). → recall(정확한 최근접을 얼마나 찾나) vs 속도/메모리의 트레이드오프.
- GPU 가속: 대규모 벡터 검색·인덱스 구축을 GPU로(cuVS/RAFT 계열). 임베딩 생성(임베딩 NIM)도 GPU. 웹/엔터프라이즈 스케일에서 결정적.
- 벡터DB 선택: 여러 제품(오픈소스·매니지드)이 ANN·필터·확장을 제공. NeMo Retriever가 커넥터로 연결.
- 메타데이터 필터: 벡터 검색 + 메타데이터 조건(날짜·부서·권한)으로 범위 제한.
- recall vs 속도: ANN 파라미터(HNSW의 ef, IVF의 nprobe)로 조절 — recall↑면 느림·메모리↑.
핵심: 벡터 검색은 exact가 아니라 ANN이다(스케일). recall(놓치지 않기)과 속도/메모리의 균형을 파라미터로 설정하고, GPU로 가속한다. 너무 낮은 recall은 정답 청크를 놓쳐 RAG가 실패하므로, recall을 평가(6.10)로 확인.
6.9.6 2단계 검색 — 임베딩 + 리랭킹
임베딩 검색(bi-encoder)은 빠르지만 정밀도가 한계다. 2단계로 recall과 precision을 모두 확보한다.
| 단계 | 동작 | 장 | 단 |
|---|---|---|---|
| 1단계 — bi-encoder(임베딩 검색, recall) | 질의·문서를 '각각' 임베딩해 벡터 유사도 → ANN으로 top-k(예 100) 빠르게 | 빠름(문서 임베딩 미리 계산) | 질의-문서 상호작용을 못 봐 정밀도 한계 |
| 2단계 — cross-encoder(리랭킹, precision) | 질의와 각 후보 문서를 '함께' 모델에 넣어 관련도 점수 → top-k를 재정렬해 top-n(예 5) | 질의-문서 상호작용을 직접 봐 정밀 | 느림(후보마다 모델 추론) → top-k에만 적용 |
- 왜 2단계: bi-encoder는 빠르나 거칠고(독립 임베딩), cross-encoder는 정밀하나 느림(쌍마다 추론). 빠른 1단계로 후보를 좁히고, 고비용 2단계를 소수에만 → 둘의 장점.
- NeMo Retriever: 임베딩 NIM(1단계) + 리랭킹 NIM(2단계)을 GPU 가속으로 제공.
- top-k·top-n 튜닝: 1단계 k(recall 충분히), 2단계 n(LLM 문맥에 들어갈 만큼).
견해: 리랭킹은 RAG 정밀도의 큰 레버다. 임베딩만으로는 top-5가 부정확할 수 있는데, 리랭킹이 실제로 관련된 문서를 상위로 올린다. 비용은 top-k에만 적용해 관리. 정밀도가 중요하면(법률·의료) 리랭킹을 거의 항상 쓴다.
6.9.7 하이브리드 검색 — dense + sparse
임베딩(dense)은 의미를 잘 잡지만 정확한 키워드·희귀어·코드·ID에 약할 수 있다. sparse(키워드, BM25류) 와 결합한다.
| 방식 | 특징 |
|---|---|
| dense(임베딩) | 의미 유사("환불"↔"돈 돌려받기") 잘 잡음, 정확 키워드 약 |
| sparse(BM25) | 정확 키워드·희귀어·코드·제품ID 잘 잡음, 의미 일반화 약 |
| 하이브리드 | 둘의 결과를 결합(가중합·RRF) → recall 보완 |
특히 도메인 용어·정확 매칭이 중요한 경우 하이브리드가 dense 단독보다 낫다.
- 결합 방식: 점수 가중합, RRF(Reciprocal Rank Fusion) 등.
- 언제: 도메인 전문 용어·제품명·코드·정확 매칭이 중요하면 하이브리드. 일반 의미 검색은 dense로 충분할 때도.
6.9.8 중간 점검 (체크포인트)
- [ ] RAG가 파인튜닝 대비 지식 갱신·환각 감소·출처 인용에서 나은 이유를 안다(6.1).
- [ ] 임베딩(의미 벡터·유사도)과 질의-문서 임베딩 일관성의 필요를 설명한다.
- [ ] 청킹 크기·오버랩·구조 인지의 트레이드오프와 RAG 품질에의 영향을 안다.
- [ ] 벡터DB·ANN(HNSW/IVF/PQ)이 exact 대신 쓰이는 이유와 recall vs 속도 트레이드오프를 안다.
- [ ] 2단계 검색(bi-encoder recall → cross-encoder rerank precision)의 구조·이유를 설명한다.
- [ ] 하이브리드(dense+sparse)가 언제 필요한지 안다.
증상→의심: 관련 문서를 못 찾음(recall 낮음) → ANN 파라미터·청킹·임베딩 모델·하이브리드. 찾은 top-5가 부정확 → 리랭킹 없음 → cross-encoder 추가. 정확 키워드·코드 검색 실패 → dense만 → 하이브리드. 검색이 느림 → exact NN 또는 ANN 미가속 → GPU·ANN 튜닝. 질의 임베딩이 문서와 안 맞음 → 다른 모델·프리픽스 → 일관성. 인덱스가 오래됨 → 문서 갱신 미반영 → 재인덱싱(6.10 운영).
6.9.9 트레이드오프·대안
검색 구성 선택.
| 결정 | 트레이드오프 |
|---|---|
| 청크 작게/크게 | 정밀·문맥부족 vs 문맥·흐려짐 |
| 임베딩 차원·모델 | 표현력↑·비용↑ vs 경량·정밀도↓ |
| ANN recall vs 속도 | 정확↑·느림·메모리↑ vs 빠름·놓침 |
| 리랭킹 on/off | 정밀↑·비용↑(top-k 추론) vs 빠름·정밀도↓ |
| dense vs 하이브리드 | 의미 vs 의미+키워드(recall↑·복잡) |
| GPU 가속 | 스케일·속도 vs 인프라 |
견해: 기본 레시피 — 적당한 청크(문단·오버랩) + 검색 임베딩 + ANN(recall 충분히) + 리랭킹(정밀). 도메인 용어·정확 매칭이 중요하면 하이브리드 추가. 각 선택을 검색 평가(recall@k·정밀도, 6.10)로 검증하며 튜닝한다. 정밀도가 critical(법률·의료)이면 리랭킹·하이브리드를 적극, 일반 FAQ면 단순 dense+ANN로 시작.
비엔비디아 정직: RAG·임베딩·ANN·리랭킹은 공개 연구·풍부한 생태계다(LangChain·LlamaIndex·Haystack, 다수 벡터DB·임베딩 모델). NeMo Retriever의 강점은 GPU 가속 임베딩·리랭킹 NIM·대규모 검색(cuVS)·NIM 통합이다. 도구는 교체할 수 있으니 원리(청킹·임베딩 일관성·2단계·recall vs precision) 를 이해하는 것이 본질. 임베딩·리랭킹 모델 품질은 도메인 데이터로 평가.
6.9.10 흔한 함정
- 청킹을 대충. 너무 크거나 작거나 주제가 섞인 청크는 좋은 임베딩·LLM으로도 못 살림. 구조 존중·적당 크기·오버랩·메타데이터.
- 질의-문서 임베딩 불일치. 다른 모델·프리픽스로 임베딩하면 같은 공간이 아니라 검색 붕괴. 동일 모델·규약.
- 리랭킹 생략. 임베딩 top-5가 부정확한데 그대로 LLM에 → 잘못된 근거. cross-encoder 리랭킹으로 정밀.
- recall 무시(ANN 과도 축소). 속도만 좇아 recall이 낮으면 정답 청크를 놓쳐 RAG 실패. recall을 평가로 확인.
- dense만으로 정확 매칭. 제품ID·코드·희귀어는 dense가 약함 → 하이브리드(sparse).
- 인덱스 staleness. 문서가 바뀌었는데 재인덱싱 안 하면 옛 정보 → 갱신 파이프라인(6.10).
- exact NN을 스케일에서. 수백만+에서 전수 비교는 비현실 → ANN·GPU.
- 검색 평가 없이 튜닝. 청크·임베딩·ANN·리랭킹을 recall@k·정밀도로 측정 안 하면 추측 → 6.10 평가.
6.9.11 연습문제
연습 1 (왜 RAG). 사내 정책 Q&A를 파인튜닝 대신 RAG로 하는 이유 넷을 들고, RAG 검색이 나쁘면 좋은 LLM으로도 왜 실패하는지 설명하라.
정답
이유: ① 지식 갱신 — 정책이 바뀌면 인덱스만 갱신(재학습 불필요), 파인튜닝은 매번 재학습. ② 환각 감소 — 실제 문서를 근거로 답하고 없으면 "모른다"; 파인튜닝은 지식을 굳혀 환각을 안 줄임. ③ 출처 인용 — 어느 문서에서 왔는지 제시해 신뢰·검증 가능. ④ 비용 — 검색이 학습보다 비용이 낮고 빠름. 검색이 나쁘면: RAG는 "검색된 문맥을 근거로 생성"하므로, 검색이 엉뚱하거나 무관한 청크를 주면 LLM은 그 잘못된 근거로 답한다(garbage in, garbage out) — 정답 문서가 인덱스에 있어도 검색이 못 건지면 LLM은 그것을 못 봄. 그래서 RAG 품질은 LLM이 아니라 검색이 정답 근거를 가져오느냐에 1차로 달렸다. 좋은 LLM은 좋은 검색 위에서만 빛난다.
연습 2 (청킹). 긴 기술 매뉴얼을 RAG에 넣는다. (a) 청크가 너무 작을 때와 너무 클 때 각각의 문제, (b) 좋은 청킹 전략, (c) RAG 품질에 미치는 영향.
정답
(a) 너무 작음(1문장): 검색은 정밀하나 답에 필요한 주변 문맥이 잘려 청크만으로 답을 못 만듦(예: 절차의 한 단계만 검색되고 전후 없음). 너무 큼(1페이지): 한 청크에 여러 주제가 섞여 임베딩이 평균화되어 흐려지고(특정 질의와의 유사도 약화), 무관한 내용이 문맥에 섞여 LLM을 혼란. (b) 전략: 문서 구조 존중(헤더·섹션·문단 경계로), 적당 크기(수백 토큰), 오버랩(경계 정보 손실 방지 10~20%), 표·코드는 별도, 메타데이터(섹션·출처) 부착. (c) 영향: 청킹은 검색 단위를 정하므로 recall·정밀도·답 완결성을 직접 좌우 — 부적절한 청킹은 좋은 임베딩·리랭킹·LLM으로도 못 살림. 청킹 전략을 검색 평가(6.10)로 검증.
연습 3 (ANN). 1천만 청크 벡터DB에서 (a) exact NN이 비현실적인 이유, (b) ANN(HNSW/IVF)이 어떻게 빠르게 하나, (c) recall을 너무 낮추면 무슨 일이?
정답
(a) exact NN은 질의 벡터를 모든 1천만 청크와 비교(O(N))해야 해 질의마다 막대한 연산 — 저지연 검색이 불가능, 스케일 안 됨. (b) ANN은 인덱스 구조로 후보를 좁힘: HNSW는 계층 그래프를 따라 가까운 이웃으로 점프하며 탐색(전수 비교 없이 빠르게 근접), IVF는 벡터를 클러스터로 나눠 질의와 가까운 클러스터만 탐색(nprobe개). PQ는 벡터를 압축해 메모리·속도↑. 약간의 정확도(정확한 최근접을 가끔 놓침)를 내주고 속도·스케일을 얻음. GPU(cuVS)로 더 가속. (c) recall을 너무 낮추면(ANN 파라미터 과도 축소): 질의의 실제로 관련된 청크를 놓쳐(검색 결과에 정답이 없음) → 정답 문서가 인덱스에 있어도 RAG가 못 찾아 실패·환각. 그래서 recall@k를 평가로 확인하며 속도와 균형. 너무 낮은 recall은 빠르지만 쓸모없다.
연습 4 (2단계). bi-encoder 임베딩 검색만으로 top-5가 부정확하다. (a) bi-encoder의 한계, (b) cross-encoder 리랭킹이 어떻게 개선하나, (c) 왜 리랭킹을 1단계가 아니라 2단계로?
정답
(a) bi-encoder 한계: 질의와 문서를 각각 독립적으로 임베딩해 벡터 유사도만 봄 → 질의-문서 간 세밀한 상호작용(특정 단어가 특정 문맥에서 얼마나 관련)을 반영하지 못해 정밀도에 한계. 빠른 대신 거침. (b) cross-encoder 리랭킹: 질의와 후보 문서를 함께 한 모델에 넣어(둘의 상호작용을 직접 어텐션) 관련도 점수를 매김 → 훨씬 정밀하게 top-k를 재정렬 → 실제로 관련된 문서가 top-n에 올라옴. (c) cross-encoder는 쌍마다 모델 추론이라 느림 — 전체 1천만 문서에 적용하면 비현실적. 그래서 빠른 bi-encoder(ANN)로 top-100을 먼저 좁히고(recall), 고비용 cross-encoder를 그 100개에만(precision) 적용. 1단계 recall + 2단계 precision으로 둘의 장점을 결합. 리랭킹을 1단계로 쓰면 비용 폭발.
연습 5 (하이브리드). 코드·제품ID·전문 용어가 많은 기술 지원 RAG에서 dense 임베딩만으로 정확 검색이 안 된다. (a) 원인, (b) 하이브리드 검색이 어떻게 돕나, (c) 트레이드오프.
정답
(a) 원인: dense 임베딩은 의미 유사를 잘 잡지만 정확한 토큰 매칭에 약함 — 제품ID(예: "ABC-123"), 코드 심볼, 희귀 전문 용어는 의미 공간에서 흐려져 정확히 매칭 못 할 수 있음(비슷한 다른 ID와 혼동). (b) 하이브리드: dense(의미) + sparse(BM25류 키워드) 를 결합 — sparse는 정확한 토큰·희귀어·ID를 정확 매칭하고, dense는 의미 일반화를 담당. 두 결과를 가중합·RRF로 융합 → "환불 방법"(의미)과 "ABC-123"(정확 키워드) 둘 다 잘 검색. (c) 트레이드오프: recall·정확도↑이지만 복잡도↑(두 인덱스·융합 로직·가중치 튜닝), 약간의 비용. 일반 의미 검색만이면 dense로 충분하나, 정확 매칭·도메인 용어가 중요하면 하이브리드가 큰 차이. 가중치·융합은 검색 평가로 튜닝.
6.9.12 요약 · 다음 장
- RAG는 지식을 모델 밖 검색 가능한 저장소에 두고 질의 시 검색해 문맥으로 주입 — 파인튜닝 대비 지식 갱신·환각 감소·출처 인용에서 낫다(6.1). 품질은 검색이 정답 근거를 가져오느냐에 1차로 달렸다.
- 임베딩(의미 벡터·유사도)으로 검색하되 질의-문서 임베딩 일관성이 필수. 청킹(구조 존중·적당 크기·오버랩·메타데이터)이 검색 단위를 정하는 숨은 결정자.
- 벡터DB는 ANN(HNSW/IVF/PQ)으로 스케일 검색 — recall vs 속도/메모리 트레이드오프, GPU 가속(cuVS). 너무 낮은 recall은 정답을 놓친다.
- 2단계 검색: 빠른 bi-encoder(임베딩·recall) → 정밀한 cross-encoder(리랭킹·precision), 리랭킹은 top-k에만. 하이브리드(dense+sparse)는 정확 키워드·용어에.
- 정직: NeMo Retriever 구성·벡터DB는 생태계 의존(도구 중립), 임베딩·리랭킹 품질은 도메인 평가, 모든 선택은 검색 평가(6.10)로 검증.
다음 장: 6.10 RAG II — 파이프라인·평가. 이 장의 검색을 생성과 연결한 엔드투엔드 RAG(검색→문맥 구성→프롬프트→생성→인용)와, RAG의 핵심 난제인 평가(검색 품질·답 충실성·환각·근거성)를 판다. 검색을 아무리 잘해도 평가 없이는 개선할 수 없다 — RAG 품질을 측정·개선하는 법을 본다.