국문과 유목민

[일일리포트] Day 69 (Scaling Up & Linking) 본문

IT 견문록/2022_부스트캠프 AITech 3기(100일)

[일일리포트] Day 69 (Scaling Up & Linking)

논곰 2022. 4. 27. 22:53

해당 일일리포트에서는 네이버 커넥트에서 진행하는 '부스트캠프 AI Tech 3기'에서 배운 내용을 다루고 있습니다. 저작권 이슈 때문에 관련 자료를 올릴 수는 없기에 핵심 이론과 코드를 요약해서 올리고 있기에 내용이 부족할 수 있습니다.

▶ Today I Learned (핵심 요약 정리)

Passage Retrieval and Similarity Search

DenseEmbedding을 활용한 Retrieval을 보면, Passage와 Query를 각각 임베딩한 후 Query로부터 거리가 가까운 순서대로 Passage에 순위를 매김으로써 검색을 진행했다. 이때, 유사도를 계산할 때, neighbors nearest search보다 Inner Product가 더 많이 사용된다. 즉, 가장 거리가 가까운 벡터를 찾겠다고 하면 Maximum Inner Product Search(MIPS)를 한다고 생각하면 된다.
MIPS는 주어진 질문(Query) 벡터 q에 대해 Passage 벡터v들 중 가장 질문과 관련된 벡터를 찾는 과정이다. 여기서 관련성은 내적이 가장 큰 것을 기준으로 한다. brute-force(exhaustive) search는 저장해둔 모든 Sparse/Dense 임베딩에 대해 일일히 내적값을 계산해 가장 값은 큰 Passage를 추출하게 된다. 하지만 실제 검색해야할 데이터는 수십 억, 조 단위까지 커질 수 있기 때문에 이 경우 더이상 모든 문서 임베딩을 일일히 보면서 검색할 수 없게 된다.

Tradeoff

우리는 유사도 기반 검색을 하기 위해서는 여러 Tradeoff를 고려해야 한다. 속도와 재현율의 관계에 대해 생각해야 하고, 코퍼스의 크기가 커질수록 탐색 공간이 커져 검색이 어려워지는 부분과 그로 인해 Memory Space가 많이 요구되는 경우도 고려해야 한다.
1) Search Speed: 쿼리 당 유사한 벡터 k개를 찾는데 얼마나 걸리는지? 가지고 있는 벡터량이 클수록 더 오래 걸림 [Pruning]
2) Memoey Usage: 벡터를 사용할 때 어디서? RAM에 모두 올린다면 빠르지만, 많은 용량을 요구한다. 디스크에서 불러와야 하면 속도가 느려짐 [Compression]
3) Accuracy: brute-force검색 결과와 얼마나 비슷한지? 속도를 증가시키려면 정확도를 희생해야하는 경우가 많음 [Exhaustive search]

Tradeoff of Similarity Search

Appoximating Similiarity Search

Compression - Scalar Quntization (SQ)

Vector를 압축해 하나의 Vector가 더 적은 용량을 차지하게 함으로써 메모리 효율을 올리는 방법이다. 4-byte floating point를 1-byte unsigned integer로 압축 가능한데, 실제 inner product에는 1-byte만으로 충분하기 때문에 성능 차이가 크지 않다고 한다.


Pruning - Inverted File(IVF)

Search Space를 줄임으로써 Search 속도를 개선하는 방법이다. Clustering+Inverted file을 활용해 Search를 진행한다. Search과정은 다음과 같이 진행된다. 우선, 주어진 query vector에 대해 근접한 centroid 벡터를 찾는다. 그리고 찾은 Cluter의 Inverted list 내 vector들에 대해 Search를 수행한다. 이렇게 함으로써 속도를 비약적으로 향상시킬 수 있다고 한다.
1) Clutering: 전체 vector space를 k개의 cluster로 나눈다. (k-means clustering 방법론이 제일 많이 사용됨)
2) Inverted file(IVF): 각 cluter의 centroid id와 해당 cluter의 vector들이 연결되어있는 형태

Clutering + Inverted index

FAISS

Facebook에서 만든 Similarity Search의 효율성을 위해 만들어진 라이브러리이다. Large scale에 사용이 가능하고 파이썬으로도 활용가능하다. FAISS는 인덱싱 부분에서 도움을 준다.
1) Train index and map vectors: train을 통해 IVF와 SQ8이 정해지면 그때 add 하게 된다. 따라서 클러스터 학습과 클러스터 추가 단계로 나줘진다.
2) Search based on FAISS index: nprobe를 활용해 몇 개의 가장 가까운 cluter를 방문해 search할 것인지 결정하게 된다.

Train index and map vectors

Scaling up wirh FAISS

FAISS를 활용해 Scaling up할 수 있는 방법들에 대해서 간단하게만 소개하고 넘어가겠다.

  • brute-force로 모든 벡터와 쿼리를 비교하는 가장 단순한 인덱스 만들기
  • IVF with FAISS: Quantization을 하기 위해서 Pruning은 IVF로 찾을 수 있다. 빠른 검색이 가능하며, 클러스터 내에서는 여전히 전체 벡터와 거리 비교 (Flat)
  • IVF-PQ with FAISS: Clustering, 벡터 압축 기법 (PQ) 활용해서, 전체 벡터를 저장하지 않고 압축된 벡터만을 저장해 메모리 사용량을 줄일 수 있음
  • Using GPU with FAISS: GPU의 빠른 연산 속도를 활용할 수 있다.( 거리 계산을 위한 행렬곱 등에서 유리)또한, Exhaustive SEarch를 빠르게 할 수 있지만 GPU 메모리 제한이나 다른 라이브러리를 사용하기 어려운 경우가 많다.

Linking MRC and Retrieval

앞서 MRC와 Retrieval Task에 대해서 살펴봤다. MRC는 지문이 주어진 상황에서 질의응답을 할 수 있는 Task이고 Retrieval은 코퍼스에서 검색을 통해 해당하는 문서를 가져오는 Task이다. 추가적으로 이번에 프로젝트를 진행하게 될ODQA는 지문이 따로 주어지지 않은 상태에서 방대한 World Knowledge에 기반해서 질의응답을 하는 Task이다. 요즘 Modern search engines들의 경우 연관문서 뿐만 아니라 질문의 답을 같이 제공하는 Task가 바로 ODQA이다.


ODQA에서 가장 많이 사용되는 Retrieval-Reader 접근 방식을 살펴 보면, 데이터베이스에서 관련있는 문서를 검색(search)하는 Retriever검색된 문서에서 질문에 해당하는 답을 찾아내는 Reader가 존재한다.

Retrieval-Reader Approch

접근방식

  입력 출력
Retriever 문서셋, 질문 관련성 높은 문서
Reader Retrieved된 문서, 질문 답변

학습단계

Retriever Sparse Retrieval[TF-IDF, BM25(학습 필요없음)], Dense Retrieval(학습 필요)
Reader SQuAD와 같은 MRC 데이터셋, 학습 데이터를 추가하기 위해 *Distant supervision 활용

*Distant Supervision: 질문-답변만 있는 데이터셋에서 MRC 학습데이터를 만드는 것

ODQA과정을 간단하게 다음과 같이 정리할 수 있을 것 같다.

  1. Retriever가 질문과 가장 관련성 높은 5개 문서 출력
  2. Reader는 5개 문서를 읽고 답변 예측
  3. Reader가 예측한 답변 중 가장 score가 높은 것을 최종 답으로 사용

Issues & Recent Approaches

ODQA Task에 대한 이슈와 최근 접근방식에 대해서 간단히 정리해보도록 하겠다. (보충 필요)

  • Different granularities of text at indexing time: 위키피디아에서 각 Passage의 단위를 문서, 단락, 또는 문장으로 정의할 지 정해야 한다. 이를 위해 Retrieval 단계에서 몇 개의 문서를 넘길지 정해야 한다. Granularity에 따라 k가 다를 수밖에 없다. 따라서 k가 튜닝의 기준이 될 수 있다.
  • Single-passage training vs Multi-passage training: 지금까지는 k 개의 passages 들을 Reader이 각각 확인하고 특정 answer span에 대한 예측 점수를 나타냈다. 그리고 이 중 가장 높은 점수를 가진 answer span 을 고르도록 하는 Single Passage 방법을 사용했다. 하지만 해당 방법은 각 retrieved passages 들에 대한 직접적인 비교라고 볼 수 없다. 따라서 Retrieved Passages 전체를 하나의 passage로 취급하고, Reader 모델이 그 안에서 asnwer span하나를 찾도록 하는 방법인 Multi-passage방법이 등장하게 됐다. 단, 문서가 너무 길어지므로 GPU에 더 많은 메모리를 할당해야 하고, 처리해야하는 연산량이 많아지게 된다.
  • Importance of each passage: Retriever 모델에서 추출된 top-k passage들의 retrieval score를 reader모델에 전달한다. 그리고 최종 answer를 고를 때 passage retriever 스코어까지 같이 고려하는 방법으로, 해당 방법을 사용하면 성능이 더 올라가는 경우가 있다.
Importance of each passage

▶ Review (생각)

오늘로 강의 정리까지 다 끝냈고, 내일부터 프로젝트를 본격적으로 시작하게 될 것 같다. 사실 오늘부터 제대로 진행하려고 했는데 후반 과제에서 시간이 조금 막혔고, 오늘 마스터 클래스와 멘토링도 있어서 시간이 좀 부족했다. 과제의 경우 베이스라인 코드와 연관된 부분이 있어서 대충 넘어가면 안 되겠다는 생각이 들어서 조금 더 붙잡고 있다보니 시간이 좀 더 소요됐던 것 같다.
이번에 FAISS와 Linking 강의를 정리하면서 프로젝트에서 어떠한 실험을 해보면 좋을 지 대충 윤곽이 잡힌 것 같다. 위 접근방식과 학습단계 부분을 고려해서, Retrieval에서는 BM-25나 Reader에서는 다양한 MRC 데이터셋으로 학습된 모델들을 다뤄보면 좋을 것 같다는 생각이 들었다. 추가적으로 월-화 간단하게 베이스라인 코드를 보고 돌려본 결과 어떤 파라미터를 튜닝하면 좋을지에 대한 부분도 공부할 필요가 있다고 생각했다. 기존 batch나 lr, epoch 이외에 새로 튜닝해볼만한 부분이 꽤 많이 생긴 것 같아서 논문 등을 참고해 볼 계획이다.
추가적으로 오늘 멘토링 시간에 멘토님께서 실험 기록을 하는 부분에 대해서 말씀을 해주셨다. 실험을 기록함에 있어서 왜 이 실험을 했는 지에 대한 가설과 실험 결과를 통해 얻고자 하는 점, 실제 실험 결과에 대한 분석 등에 대해서 적어야 한다고 하셨다. 말씀해주신 부분은 기존에 생각하고 있던 부분이었지만, 이전 프로젝트에서 팀 전체적으로 잘 안지켜서 좀 아쉬웠던 부분이었다. 그래서 이번 기회에 팀원들과 같이 해보자고 할 수 있을 것 같아 멘토님께 감사했다.
내일부터 프로젝트를 진행할 것 같은데, 이번에 새로 마일스톤도 추가했으니까 양식을 잘 지켜서 남들에게 보여준다는 의미로 잘 정리해봐야겠다.