검색
← 모듈 로드맵

오픈 도메인 질의응답을 위한 밀집 문단 검색 (DPR)

논문 · 준전문가 · Vladimir Karpukhin 외 7명 · 2020 · arXiv

원제 · Dense Passage Retrieval for Open-Domain Question Answering

질문 · 문단을 BERT 두 개로 벡터화해 내적으로 찾는 검색기로 BM25를 앞선 논문

먼저 알아야 할 것

BERTBM25 · TF-IDF내적 · 소프트맥스문장 임베딩음의 로그 가능도

다루는 내용

DPR은 질문 인코더와 문단 인코더(각각 BERT-base)로 768차원 벡터를 만들고 내적으로 위키백과 2,100만 문단을 검색합니다. 추가 사전학습 없이 질문-문단 쌍과 배치 내 음성 예시, BM25 어려운 음성 예시 1개로 학습해 상위 20개 검색 정확도에서 BM25를 9~19%p 앞섰습니다. 이를 쓴 QA 시스템은 NQ에서 EM 41.5로 ORQA · REALM을 넘었고, 이후 RAG의 기본 검색기가 됐습니다.

초록

저자가 쓴 초록을 옮긴 것입니다.

오픈 도메인 질의응답은 후보 문맥을 고르는 효율적인 문단 검색에 의존하며, 여기서는 TF-IDF나 BM25 같은 전통적인 희소 벡터 공간 모델이 사실상 표준입니다. 이 연구에서는 검색을 밀집 표현만으로도 실용적으로 구현할 수 있음을 보입니다. 이때 임베딩은 단순한 듀얼 인코더 구조로 적은 수의 질문과 문단에서 학습합니다. 여러 오픈 도메인 QA 데이터셋에서 평가한 결과, 우리의 밀집 검색기는 상위 20개 문단 검색 정확도 기준으로 강력한 Lucene-BM25 시스템을 9%~19%p 큰 차이로 앞섰고, 이를 쓴 전체 QA 시스템이 여러 오픈 도메인 QA 벤치마크에서 새로운 최고 성능을 세우는 데 기여했습니다.

해설

오픈 도메인 질의응답을 위한 밀집 문단 검색 (DPR)

질문과 문단을 각각 BERT로 벡터 하나씩 만들고 내적으로 찾는, 단순한 두 인코더 검색기로 키워드 검색(BM25)을 크게 앞선 논문입니다. 별도 사전학습 없이 질문-문단 쌍과 '배치 안 음성 예시' 요령만으로 해냈고, 이후 RAG의 기본 검색기가 됐습니다.

항목내용
원제Dense Passage Retrieval for Open-Domain Question Answering
저자Vladimir Karpukhin 외 7명 (Facebook AI · 워싱턴대 · 프린스턴대)
발표2020 · EMNLP 2020 · arXiv 2004.04906
트랙 · 수준RAG·검색 · 중급
먼저 알면 좋은 것BERT, 내적 · 소프트맥스, TF-IDF · BM25 키워드 검색, 문장 임베딩(Sentence-BERT), 음의 로그 가능도

들어가기 전에

이 해설은 아래 내용을 안다고 보고 씁니다. 처음이라면 먼저 읽고 오면 수식과 손계산을 훨씬 쉽게 따라올 수 있습니다.

한눈에 보기

  • 키워드 검색(BM25)이 왜 '악당'과 'villain' 같은 말 바꿈에 약한지, 밀집 벡터가 이를 어떻게 메우는지 알게 됩니다.
  • 질문 인코더 · 문단 인코더 두 개로 이루어진 듀얼 인코더(dual-encoder) 검색기의 구조와 학습 손실을 이해합니다.
  • 한 배치 안의 다른 질문 정답을 음성 예시로 재활용하는 배치 내 음성 예시(in-batch negatives) 가 왜 싸고 강력한지 손계산으로 확인합니다.
  • 검색이 좋아지면 최종 답 정확도도 실제로 올라가는지, 논문 수치로 판단할 수 있게 됩니다.

초록 (번역)

오픈 도메인 질의응답은 후보 문맥을 고르는 효율적인 문단 검색에 의존하며, 여기서는 TF-IDF나 BM25 같은 전통적인 희소 벡터 공간 모델이 사실상 표준입니다. 이 연구에서는 검색을 밀집 표현만으로도 실용적으로 구현할 수 있음을 보입니다. 이때 임베딩은 단순한 듀얼 인코더 구조로 적은 수의 질문과 문단에서 학습합니다. 여러 오픈 도메인 QA 데이터셋에서 평가한 결과, 우리의 밀집 검색기는 상위 20개 문단 검색 정확도 기준으로 강력한 Lucene-BM25 시스템을 9%~19%p 큰 차이로 앞섰고, 이를 쓴 전체 QA 시스템이 여러 오픈 도메인 QA 벤치마크에서 새로운 최고 성능을 세우는 데 기여했습니다.

무엇을 풀었나

오픈 도메인 질의응답(open-domain QA)은 위키백과처럼 거대한 문서 모음에서 사실형 질문의 답을 찾는 과제입니다. 보통 두 단계로 풉니다. ① 검색기(retriever) 가 답이 있을 법한 문단 몇 개를 고르고, ② 독해기(reader) 가 그 문단을 꼼꼼히 읽어 답 구간을 뽑습니다. 논문은 이 방식에서 검색이 약하면 성능이 크게 무너진다고 지적합니다(예: SQuAD에서 정답 문단을 줄 때 80% 넘던 정확도가, 직접 검색하면 40% 아래로 떨어진 사례).

당시 검색의 표준은 TF-IDF · BM25 같은 희소(sparse) 검색 이었습니다. 질문과 문단에 같은 단어가 얼마나 겹치는지를 셉니다. 빠르고 튼튼하지만 말 바꿈에 약합니다. 논문의 예로 "반지의 제왕의 bad guy는 누구인가?"라는 질문의 답은 "villain 사우론을 연기한…" 문장에 있는데, 'bad guy'와 'villain'은 겹치는 글자가 없습니다.

뜻으로 찾는 밀집(dense) 검색 은 이 문제를 풀 수 있지만, "좋은 밀집 벡터를 만들려면 라벨된 질문-문단 쌍이 아주 많이 필요하다"는 것이 통념이었습니다. 직전 연구 ORQA는 복잡한 추가 사전학습(역 클로즈 과제, ICT)으로 처음 BM25를 넘었지만, 계산이 비싸고 문단 인코더는 질문-답 쌍으로 미세조정하지 않는다는 약점이 있었습니다.

이 논문의 질문은 단순합니다. 추가 사전학습 없이, 질문-문단 쌍만으로 더 좋은 밀집 검색기를 학습할 수 있는가?

핵심 아이디어

mermaid
flowchart LR
  W[위키백과 2,100만 문단] --> EP[문단 인코더 E_P]
  EP --> IDX[(FAISS 벡터 색인)]
  Q[질문] --> EQ[질문 인코더 E_Q]
  EQ --> S[내적으로 상위 k개 검색]
  IDX --> S
  S --> R[독해기 BERT: 문단 고르기 + 답 구간 뽑기]
  R --> A[답]

1. 듀얼 인코더와 내적 유사도

직관. 도서관 사서 두 명이 있다고 해 봅시다. 한 사람은 미리 모든 책에 '내용 좌표'를 붙여 두고, 다른 사람은 손님의 질문을 같은 좌표계에 찍습니다. 좌표가 가까운 책을 꺼내면 됩니다.

단계별 설명.

  1. 위키백과 문서를 100단어씩 끊어 문단(passage) 21,015,324개를 만듭니다. 문단 앞에는 문서 제목을 붙입니다.
  2. 문단 인코더 EPE_P(BERT-base)로 모든 문단을 768차원 벡터로 바꿔 FAISS 색인에 미리 넣습니다.
  3. 질문이 오면 별도의 질문 인코더 EQE_Q(또 하나의 BERT-base)로 벡터를 만듭니다.
  4. 질문 벡터와 내적이 가장 큰 문단 kk개(보통 20~100개)를 꺼냅니다.

수식.

sim(q,p)=EQ(q)⊤EP(p)\mathrm{sim}(q, p) = E_Q(q)^\top E_P(p)
기호뜻
qq, pp질문, 문단
EQ(⋅)E_Q(\cdot), EP(⋅)E_P(\cdot)질문 · 문단 인코더. 각각 BERT의 [CLS] 출력을 씀, 차원 d=768d = 768
⊤^\top전치. a⊤ba^\top b는 두 벡터의 내적

숫자로 해 보기 (설명용 예시, 논문 수치 아님). 3차원으로 줄여 생각해 봅시다. 질문 벡터가 (1,2,0)(1, 2, 0), 문단 A가 (2,1,0)(2, 1, 0), 문단 B가 (0,0,3)(0, 0, 3)이면 내적은 A가 1⋅2+2⋅1+0=41 \cdot 2 + 2 \cdot 1 + 0 = 4, B가 00입니다. A를 먼저 꺼냅니다.

왜 내적인가. 문단 벡터를 미리 계산해 두려면 유사도 함수가 '질문 쪽 계산'과 '문단 쪽 계산'으로 쪼개져야 합니다. 두 문장을 함께 넣는 교차 어텐션은 더 정교하지만 쪼갤 수 없어 2천만 문단 검색에는 못 씁니다. 논문은 코사인 · 유클리드(L2) 거리도 비교했는데 L2는 내적과 비슷했고 둘 다 코사인보다 나았습니다. 그래서 가장 단순한 내적을 골랐습니다.

왜 인코더를 두 개로 나눴나. 질문은 짧고 의문형이고, 문단은 길고 서술형입니다. 성격이 다른 두 입력을 각자 맞는 방식으로 읽도록 서로 독립된 BERT 두 개를 씁니다. (SBERT는 가중치를 공유하는 하나의 인코더였다는 점과 대비됩니다.)

2. 학습 손실: 정답 문단의 확률을 높인다

직관. 객관식 문제에서 정답 보기 하나와 오답 보기 여러 개를 주고 "정답을 고를 확률"을 높이도록 연습시키는 것과 같습니다.

단계별 설명.

  1. 학습 예시 하나는 질문 qiq_i, 정답 문단 pi+p_i^+, 오답 문단 nn개 pi,1−,…,pi,n−p_{i,1}^-, \dots, p_{i,n}^-로 이루어집니다.
  2. 질문과 각 문단의 내적 점수를 구합니다.
  3. 소프트맥스로 '정답 문단이 뽑힐 확률'을 만들고, 그 음의 로그를 손실로 줄입니다.

수식.

L=−log⁡esim(qi,pi+)esim(qi,pi+)+∑j=1nesim(qi,pi,j−)L = -\log \frac{e^{\mathrm{sim}(q_i, p_i^+)}}{e^{\mathrm{sim}(q_i, p_i^+)} + \sum_{j=1}^{n} e^{\mathrm{sim}(q_i, p_{i,j}^-)}}
기호뜻
pi+p_i^+질문 qiq_i의 정답(양성) 문단
pi,j−p_{i,j}^-jj번째 오답(음성) 문단
exe^{x}지수 함수. 점수를 양수로 바꾸고 큰 점수를 더 키움
분수 전체정답 문단이 뽑힐 확률(소프트맥스)
−log⁡-\log확률이 1에 가까울수록 0에 가까워지는 벌점

숫자로 해 보기 (설명용). 정답 점수 2, 오답 두 개 점수 0과 1이라고 합시다. e2≈7.39e^2 \approx 7.39, e0=1e^0 = 1, e1≈2.72e^1 \approx 2.72이므로 정답 확률은 7.39/11.11≈0.677.39 / 11.11 \approx 0.67, 손실은 −log⁡0.67≈0.40-\log 0.67 \approx 0.40입니다. 학습은 정답 점수를 올리고 오답 점수를 내려 이 값을 0 쪽으로 밉니다.

어떤 오답을 쓰나. 정답은 데이터에 있지만, 오답은 2천만 문단 중에서 골라야 합니다. 논문은 세 종류를 비교했습니다.

  • 무작위(Random): 아무 문단
  • BM25: 질문 단어와 많이 겹치지만 답은 없는 문단 — 헷갈리기 쉬운 '어려운 음성 예시(hard negative)'
  • 골드(Gold): 학습 세트의 다른 질문의 정답 문단

3. 배치 내 음성 예시: 계산을 재활용하는 요령

직관. 반 학생 BB명이 각자 자기 답안지를 냈을 때, 다른 학생들의 답안지를 '내 문제의 오답 보기'로 그대로 쓰는 것입니다. 오답을 새로 만들 필요가 없습니다.

단계별 설명.

  1. 한 배치에 질문 BB개와 각 질문의 정답 문단 BB개가 있습니다.
  2. 질문 벡터를 쌓은 행렬 QQ와 문단 벡터를 쌓은 행렬 PP를 만듭니다(각각 B×dB \times d).
  3. S=QP⊤S = QP^\top 한 번의 행렬 곱으로 B×BB \times B 점수표를 얻습니다.
  4. 대각선 (i,i)(i, i)는 정답, 나머지는 모두 오답입니다. 질문마다 오답이 B−1B - 1개 생깁니다.

수식.

S=QP⊤∈RB×B,Sij=sim(qi,pj)S = Q P^\top \in \mathbb{R}^{B \times B}, \qquad S_{ij} = \mathrm{sim}(q_i, p_j)

숫자로 해 보기 (설명용). B=3B = 3이고 점수표가 아래와 같다면, 1번 질문 줄 (3,1,0)(3, 1, 0)에서 정답은 첫 칸입니다. 소프트맥스를 줄마다 적용해 대각선 칸의 확률을 높이면 됩니다.

문단 1문단 2문단 3
질문 1310
질문 2021
질문 3104

문단 3개를 한 번씩 인코딩했을 뿐인데 질문-문단 쌍 B2=9B^2 = 9개를 학습에 씁니다.

왜 효과가 컸나. 논문의 NQ 개발 세트 실험에서 같은 '골드 음성 7개' 조건이라도, 배치 안에서 가져오면 상위 5개 정확도가 51.1이었습니다(배치 밖에서 따로 뽑을 때는 무작위 47.0 · BM25 50.0 · 골드 42.6). 배치를 키울수록 오답 수가 늘어 정확도가 꾸준히 올랐고(골드 음성 31개 52.1 → 127개 55.8), 배치 128에 BM25 어려운 음성 문단 1개 를 더한 설정이 가장 좋았습니다(상위 5개 65.8). BM25 음성을 2개로 늘려도 더 좋아지지 않았습니다.

4. 학습 설정과 하이브리드 (논문 기준)

  • 배치 128, 질문마다 BM25 음성 문단 1개 추가, Adam 학습률 10−510^{-5}, 선형 스케줄 + 워밍업, 드롭아웃 0.1
  • 큰 데이터셋(NQ · TriviaQA · SQuAD)은 최대 40에폭, 작은 데이터셋(TREC · WQ)은 100에폭
  • BM25 + DPR 결합: 두 방법으로 각각 상위 2,000개를 뽑아 합친 뒤 BM25(q,p)+λ⋅sim(q,p)\mathrm{BM25}(q, p) + \lambda \cdot \mathrm{sim}(q, p)로 다시 순위를 매깁니다(λ=1.1\lambda = 1.1, 개발 세트로 정함).

5. 독해기 (참고)

검색된 상위 kk개 문단에서 BERT 독해기가 ① 각 문단이 뽑힐 확률과 ② 답 구간의 시작 · 끝 확률을 냅니다. 가장 점수가 높은 문단에서 가장 좋은 구간을 답으로 고릅니다. 독해기는 두 문장을 함께 보는 교차 어텐션을 쓰므로, 후보가 적을 때만 쓸 수 있는 '정밀 재순위 장치' 역할도 합니다.

결과

문단 검색 정확도 (테스트 세트, 상위 20개 안에 답이 든 문단이 있는 비율 %, 여러 데이터셋으로 함께 학습한 DPR)

데이터셋BM25DPRBM25 + DPR
Natural Questions59.179.478.0
TriviaQA66.978.879.9
WebQuestions55.075.074.7
CuratedTREC70.989.188.5
SQuAD68.851.666.2
  • NQ 하나로만 학습한 DPR도 상위 20개 78.4로 BM25(59.1)를 크게 앞섰고, 상위 5개에서는 65.2 대 42.9였습니다. 상위 kk가 작을수록 격차가 큽니다.
  • SQuAD만 예외 였습니다. 문단을 보고 질문을 써서 단어가 많이 겹치고(BM25에 유리), 위키백과 문서 500여 개에서만 모은 치우친 데이터라는 것이 논문의 설명입니다.
  • 적은 데이터로도 됩니다: 학습 예시 1,000개만 써도 BM25를 넘었습니다.
  • 다른 데이터셋으로 옮겨도: NQ로만 학습해 WQ · TREC에 바로 쓰면 상위 20개 69.9 / 86.3으로, 그 데이터로 학습한 최고 모델(75.0 / 89.1)보다 3~5점 낮지만 BM25(55.0 / 70.9)보다는 훨씬 좋았습니다.

최종 QA 정확도 (완전 일치 EM %)

시스템NQTriviaQA
ORQA33.345.0
REALM (Wiki)39.2—
BM25 + 독해기 (이 논문)32.652.4
DPR + 독해기 (이 논문)41.556.8
  • 5개 중 4개 데이터셋에서 이전 최고 기록을 1~12%p 앞섰습니다. 추가 사전학습을 쓴 ORQA · REALM보다 NQ · TriviaQA에서 높았습니다.
  • 검색기와 독해기를 함께 학습하는 방식을 따로 시험했더니 NQ에서 39.8로, 따로 학습한 41.5보다 낮았습니다.

속도와 비용

  • 검색: FAISS(HNSW) 메모리 색인으로 초당 질문 995.0개(질문마다 상위 100개). BM25/Lucene은 CPU 스레드당 초당 23.7개.
  • 색인 구축은 비쌉니다: 2,100만 문단 임베딩에 GPU 8개로 약 8.8시간, FAISS 색인 구축에 서버 한 대로 8.5시간. Lucene 역색인은 약 30분.

왜 중요한가 · 이후 영향

  • "밀집 검색이 키워드 검색을 대체할 수 있다"를 처음 설득력 있게 보였습니다. 복잡한 사전학습 없이 표준 BERT와 올바른 학습 요령만으로 충분하다는 결론이 실무 도입의 문을 열었습니다.
  • RAG의 기본 검색기가 됐습니다. 같은 연구진의 RAG, 그리고 Fusion-in-Decoder가 DPR을 검색기로 썼습니다. 오늘날 벡터 DB에 문서를 넣고 질문으로 찾는 구성이 그대로 이 구조입니다.
  • 배치 내 음성 예시 + 어려운 음성 예시 는 이후 임베딩 학습(Contriever 등)의 기본 재료가 됐습니다.

한계 · 주의할 점

  • 드문 고유명사에 약합니다. 논문 부록 예시에서 "Thoros of Myr" 같은 핵심 구절은 BM25가 찾고 DPR은 놓쳤습니다. 실무에서 BM25와 섞는 하이브리드 검색이 쓰이는 이유입니다.
  • 라벨된 질문-문단 쌍이 필요합니다. 1,000개면 BM25를 넘지만, 새 분야로 옮길수록 성능이 떨어집니다. 라벨 없이 학습하는 방향은 Contriever가 다룹니다.
  • 색인 비용: 문서가 바뀌면 다시 임베딩해야 하고, 구축 시간이 역색인보다 훨씬 깁니다.
  • 문단 하나를 벡터 하나로 압축 하므로, 긴 문단 속 세부 단어 정보가 사라질 수 있습니다. 토큰마다 벡터를 남기는 ColBERT가 이 지점을 공략합니다.

스스로 점검

  1. 배치 크기가 128이고 BM25 음성 문단을 하나씩 더하면, 질문 하나가 보는 오답 문단은 몇 개인가요?

    다른 질문의 정답 127개와 배치 안 BM25 음성 128개(모든 질문이 공유)로 255개입니다. 논문 표의 '127+128'이 이 뜻입니다.

  2. 왜 교차 어텐션 모델을 검색기로 쓰지 않나요?

    질문과 문단을 함께 넣어야 점수가 나와 문단 벡터를 미리 계산할 수 없기 때문입니다. 2천만 문단마다 매번 돌려야 하므로 검색 단계에서는 못 쓰고, 후보가 적은 독해 단계에서만 씁니다.

  3. SQuAD에서 DPR이 BM25보다 못했던 이유는?

    질문을 문단을 보고 써서 단어가 많이 겹치고(키워드 검색에 유리), 문서 500여 개에서만 모은 치우친 데이터라서입니다.

용어 정리

용어쉬운 뜻
오픈 도메인 질의응답(open-domain QA)정답 문단을 주지 않고, 거대한 문서 모음에서 직접 찾아 답하는 과제
희소 검색(sparse retrieval)단어가 겹치는 정도로 찾는 검색. TF-IDF · BM25
밀집 검색(dense retrieval)문장을 짧은 실수 벡터로 바꿔 뜻이 가까운 것을 찾는 검색
듀얼 인코더(dual-encoder)질문 · 문단을 각자 다른 인코더로 벡터화하고 벡터끼리 비교하는 구조
음성 예시(negative)학습 때 '이건 정답이 아니다'로 보여 주는 문단
어려운 음성 예시(hard negative)정답처럼 보이지만 답이 없는 헷갈리는 문단
배치 내 음성 예시(in-batch negatives)같은 배치의 다른 질문 정답을 내 질문의 오답으로 재활용하는 요령
FAISS대량 벡터에서 가장 가까운 것을 빠르게 찾는 오픈소스 라이브러리
상위 kk 정확도(top-k accuracy)검색 결과 상위 kk개 안에 답이 든 문단이 있는 질문의 비율
완전 일치(EM)모델 답이 정답과 글자 그대로 같은 비율

이어서 읽을 것

다음에 볼 것

이 글을 이해했다면 이어서 보면 좋은 항목입니다.

출처

AI 원리부터 이해하기 · RAG·검색 모듈

RAG·검색 모듈 학습

이 글은 RAG·검색 모듈의 학습 자료입니다. 전체 21개 자료 중 3번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

arXiv (논문별 상이)

arXiv 2004.04906