사단법인 한국인공지능연구소에서 진행하는 오픈랩 프로그램이 7기로 참여했고, 어찌어찌 NLP 분야의 팀에서 활동을 하게 되었다. 여기서 BERT 공부를 다 끝내면 한 번 읽어보라고 논문을 추천받은 게 바로 Sentence-BERT이다.
논문 내용은 생각보다... 별 게 없어보이는데, 또 나름 유의미한 것들이다. 한 번 살펴보자.
이 논문을 읽기 위해 최소한 준비해야 할 것(뇌피셜)
- 읽어봐야 하는 논문: BERT
- 알아야 할 개념: Embeddings, Siamese Network, Triplet Network
주의! 본 포스팅은 논문을 번역하거나 자세하게 설명하는 것이 아닌, 주요한 부분들을 집어 제 나름대로의 이해를 바탕으로 서술한 것입니다. 이 포스팅은 논문 이해에 도움이 될 순 있어도 논문의 모든 것을 담지 않았으니, 반드시 원문을 함께 읽으시길 바랍니다.
https://arxiv.org/pdf/1908.10084.pdf
Introduction
- 우리는 Sentence-BERT를 소개한다.
- siamse 네트워크과 triplet 네트워크를 활용한 BERT의 변형 버전이다.
- semantically meaningful sentence embeddings를 구할 수 있다.
- 기존의 BERT에 적용할 수 없던 NLP tasks(large-scale semantic similarity comparison, clustering, and information retrieval via semantic search 등...)도 SBERT를 통해 적용 가능하다.
- pair regression task의 경우, 10,000개의 문장 집합에서 가능한 pair 조합은 49,995,000개로, V100에서 BERT로 추론시 65시간이 걸린다.
- clustering이나 semantic search에서 흔한 방법론이 문장을 벡터 공간으로 mapping하여 의미적으로 유사한 것이 공간상 가깝도록 하는 것인데, 최근 연구자들은 각각의 문장을 BERT로 포워딩해 평균하거나, CLS 토큰의 값을 이용해왔다. 그러나 이런 방법들은 GloVe 임베딩에 평균을 취하는 것보다 별로다.
- 이러한 이슈들을 해결하고자 SBERT를 개발했다.
- siamese 네트워크는 입력 문장에 대한 고정 크기의 벡터 출력을 가능케 한다.
- cosine similarity, manhatten/euclidean distance 같은 유사도 측정 방법으로부터 의미적으로 유사한 문장을 찾을 수 있다.
- 이러한 유사도 측정 방법들은 현대의 하드웨어에서 아주 효율적으로 구동되어 SBERT는 semantic smilarity search나 clustering같은 목적으로 쓰일 수 있다.
- BERT는 10,000개의 문장 집합에서 유사한 문장 pair를 찾는 데 걸리는 시간이 65시간인 반면, SBERT의 출력인 fixed-size vector 10,000개에서 유사한 문장 pair를 찾는 작업은 5초로 줄어들었다. 코사인 유사도는 0.01초가 걸린다.
이하 생략...
풀어 얘기하자면, BERT는 [SEP] 토큰으로 연결된 두 문장을 모델에 넣어 CLS 토큰에 대한 출력값으로 두 문장의 유사성을 찾는다. 문제는 두 문장의 유사성을 알기 위해서 모든 문장 pair를 모델에 넣어야 한다는 것이다. 즉, 10,000개의 문장이 있다면 한 문장이 BERT 네트워크를 9,999번 거친다. 매우 비효율적인 일이다. 반면 SBERT는 10,000개의 문장을 모두 고정 크기의 벡터로 변환하여 저장하고, 이 벡터들 사이에서 유사도를 구해 argmax한다는 느낌이다. 한 문장에 모델을 한 번 거치므로 그 효율성의 차이가 매우 크다고 할 수 있겠다.
Related Work
BERT
2018년에 제안된 pretrained transformer network인 BERT는 여러 NLP tasks(QA, 문장 분류, sentence-pair regression 등)에서 SOTA 퍼포먼스를 달성했다. sentence-pair regression에서 입력은 [SEP] 토큰으로 구분된 연속된 두 문장이다. Multi-head attention이 12/24층으로 적용되었고, 그 출력은 단순한 regression 레이어로 넘어가 최종적으로 label을 출력한다. 이러한 BERT는 Semantic Textual Semilarity (STS) 벤치마크에서 SOTA를 달성했다. 2019년에 제안된 RoBERTa는 작은 pre-training 전략의 적용만으로 BERT를 향상시켰다.
BERT의 큰 단점은 독립적인 문장 임베딩이 계산될 수 없어 단일 문장에 대한 임베딩을 구하기 어렵다는 것이다. 그래서 average word embeddings와 유사하게 단일 문장을 BERT에 넣어 평균을 취해 고정 크기 벡터를 얻거나, 단순히 CLS 토큰의 결과를 이용하는 방법들이 사용되어 왔다. 그러나 이러한 방법들이 유용한 문장 임베딩인지는 아직 연구되지 않았다.
Sentence Embeddings
문장 임베딩은 오래동안 연구되어 왔다. 주변 문장을 예측하기 위해 encoder-decoder 구조를 이용한 Skip-Thought, siamse BiLSTM의 출력에 max pooling을 적용한 InferSent 등이 있다.
InferSent는 Skip-Thought와 같은 비지도 방법을 뛰어넘는다는 연구가 있다.
문장 임베딩이 학습된 task가 그 임베딩 퀄리티에 큰 영향을 미친다는 연구도 있고, SNLI 데이터셋이 문장 임베딩을 학습하기에 적합하다는 연구도 있다.
siamese DAN과 siamese transformer 네트워크를 이용해 Reddit의 대화를 학습한 연구도 있으며, 이는 STS 벤치마크에서 좋은 결과를 내었다.
BERT의 cross-encoder의 런타임 처리시간에 대해 설명하고 어텐션 메커니즘을 이용하여 $m$개의 문맥 벡터와 미리 계산된 후보 임베딩에서 어떤 score를 계산해내는 방법을 제안한 연구가 있다(poly-encoder).
poly-encoder는 큰 데이터셋에서 가장 점수가 큰 문장을 찾는 데에 효율이 높지만, score function이 비대칭적이고 점수계산에 $O(n^2)$의 복잡도를 요구하는 clusterin 같은 task에서는 처리 시간이 상당히 크다는 단점이 있다.
기존 연구들은 random weight initialization으로 학습을 시작했지만, 이 논문에서는 pre-trained BERT/RoBERTa를 fine-tuning해 좋은 문장 임베딩을 얻을 것이다. 이는 학습 시간을 매우 낮추는데, SBERT는 학습하는 데 20분이 걸리지 않으면서 다른 문장 임베딩보다 좋은 결과를 내었다.
Model
SBERT는 BERT/RoBERTa(이후 편한 표기를 위해 RoBERTa는 생략)의 output에 pooling 연산을 추가했다. 여기서 pooling 전략이 3가지가 있는데, 1) CLS 토큰의 결과를 사용 2) 모든 output 벡터를 평균하여 사용 3) output 벡터의 max-over-time을 계산해 사용. 기본 설정 전략은 MEAN이다.
BERT를 fine-tuning하기 위해서 siamese/triplet network를 추가했다. 이를 이용해 가중치를 조정하여 문장 임베딩이 semantically meaningful하고 코사인 유사도로 계산될 수 있도록 하였다.
모델 구조는 학습 데이터에 따라 다르다. 아래의 경우에 따라 모델 구조와 목적 함수를 달리 설계하였다.
Classification Objective Function
두 문장 임베딩 $u$와 $v$를 그 차이 $|u-v|$와 concat해 $3n$ 차원의 텐서를 만들고, 이를 가중치 $W_t\in\mathbb R^{3n\times k}$에 곱한다. 이를 softmax함수에 넣으면 $k$개 label에 대한 분류 작업이 가능해진다. loss는 cross-entropy로 설정했다.
$$
o=\text{softmax}(W_t(u, v, |u-v|))
$$
Regerssion Objective Function
두 문장 임베딩 $u$와 $v$의 코사인 유사도가 계산된다. MSE를 loss로 사용했다.
Triplet Objective Function
anchor/positive/negative 문장 $a, p, n$에 대해 triplet loss는 모델이 $a$와 $p$ 사이 거리가 $a$와 $n$사이 거리보다 작게 하도록 학습시킨다. loss는 아래와 같다.
$$
max(||s_a-s_p||-||s_a-s_n||+\epsilon, 0)
$$
$s_x$는 문장 $x$의 임베딩이고, $||\cdot||$은 거리고, $\epsilon$은 margin이다. margin은 $s_p$가 $s_n$보다 최소한 $\epsilon$만큼 $s_a$에 가깝도록 하는 장치이다. 이 논문에서는 Euclidean 거리를 단위로 $\epsilon=1$로 설정했다.
Trainig Deatil은 생략
Evaluation - Sematic Textual Similarity
STS task의 기존 SOTA들은 문장 임베딩들을 유사도 점수에 복잡한 regression function을 이용해 mapping하는 방법을 써왔다. 이런 regression finction들은 pair-wise(pair를 입력받음)하기에 문장 집합이 커지면 조합적 폭발(조합의 개수가 $_nC_2$이므로 $n$이 커질수록 폭발)이 발생했고, 모델이 scalable하지 못했다.
SBERT는 단순한 코사인 유사도를 사용해 두 문장 임베딩을 비교한다. negative Manhatten/nagative Euclidean 거리 역시 유사도 측정으로 사용했다. 다만 코사인 유사도와 비슷한 결과를 보였다.
Unsupervised STS
특정 STS 학습 데이터셋을 사용하지 않고 SBERT의 성능을 측정했다.
사용한 데이터셋은 STS tasks 2012 - 2016, STS benchmark, SICK-Relatedness이다. 이 데이터셋들은 문장 pairs들의 의미적 유사성을 label로 0점부터 5점까지 제공한다.
사람이 측정한 상관관계는 별로이므로, 문장 임베딩의 코사인 유사도와 gold label 사이의 Spearman 랭크를 계산했다. 이 부분은 무슨 얘기를 하는지 아직 잘 모르겠다.
그 결과는 아래와 같다.
보다시피 BERT의 output을 그대로 쓰는 건 성능이 별로다. Avg. BERT embeddings는 평균 성능이 54.81이며, BERT CLS-vector는 29.19이다. InferSent - GloVe보다 못한 걸 알 수 있다.
제안된 siamese 네트워크 구조와 fine-tuning 메커니즘을 InferSent나 Universal Sentence Encoder를 유의미하게 앞서는 결과를 내었다. SBERT가 좋은 성적을 내지 못한 유일한 데이터셋은 SICK-R이다.
Universal Sentence Encoder는 뉴스, QA 페이지, 토론 포럼처럼 SICK-R 벤치마킹에 적합한 데이터셋에 학습되었다. 반면 SBERT는 위키피디아와 NLI 데이터에만 학습되었다.
SRoBERTa는 성능이 좋긴 한데, SBERT에 비해 큰 차이를 보이진 않았다.
Supervised STS
STS benchmark (STSb)에서 제공되는 데이터셋을 이용했다. regression objective functnio을 사용해 SBERT를 fine-tuning했고, 추론 시에는 코사인 유사도를 사용했다.
STSb에만 학습한 것과, NLI에 학습한 후 STSb에 fine-tuning하는 것으로 두 가지 옵션을 비교했다. 후자의 경우가 미세하게 더 좋은 성능을 보이는 것이 관찰됐고, 이런 two-step approach는 특히나 BERT cross-encoder에 큰 영향을 미쳤다. BERT와 RoBERTa 사이에는 큰 차이가 없었다.
이하는 각종 데이터셋에 대해 여러 전략으로 학습하여 평가한 내용이므로, 전부 생략하고 넘어가겠다.
Evaluation - SentEval
SentEval은 문장 임베딩이 logistic regression classifier에 입력으로 사용되고, logistic regression classifier는 여러 task에 학습된다.
SBERT 문장 임베딩의 목적은 전이 학습을 위함이 아니다. 여기서는 BERT를 전부 업데이트하기보다 fine-tuning하는 것이 더 적합할 것으로 생각되지만, SentEval은 여러 task에 대해 SBERT의 문장 임베딩의 퀄리티에 영향을 줄 수 있다.
SentEval에는 MR/CR/SUBJ/MPQA/SST/TREC/MRPC로 7개의 transfer tasks가 있다.
여차저차 좋은 결과를 내었다. 자세한 사항은 원문 참조.
Ablation Study
처음 얘기했던 pooling 전략 3가지 MEAN, MAX, CLS를 비교한다. 또한 classification objective function의 경우 concat할 대상들을 달리할 수 있는데, 이 역시 비교한다.
classification인지 regression인지는 데이터셋에 따라 다른데, classification의 경우 SBERT를 SNLI와 Multi-NLI 데이터셋으로 학습했다. regression의 경우 STSb로 학습했다.
classification objective function을 학습할 때에는 pooling 전략의 차이는 큰 영향을 미치지 않았다. 반면 concat에서 어떤 걸 concat하느냐에 따라 성능 차이가 컸다. InferSent나 Universal Sentence Encoder는 $u*v$를 추가했는데, SBERT에서는 이를 추가하면 오히려 성능이 감소했다.
가장 중요한 요소는 두 임베딩의 차이인 $|u-v|$이다. 이는 두 임베딩 사이의 거리를 보여주는 것이므로, 비슷한 벡터는 가깝게, 비슷하지 않은 벡터는 멀게 하도록 도와준다.
regression objective function을 학습할 때에는 pooling 전략이 큰 영향을 미치는 걸 발견했다. MAX 전략이 MEAN, CLS 전략보다 좋지 못한 결과를 보였다. 이는 InferSent의 BiLSTM이 MEAN 대신 MAX를 전략을 취하도록 하는 게 더 좋다는 연구결과에 상반된다.
Computational Efficiency
문장 임베딩은 아주 많은 문장들을 계산해야 하므로, 높은 컴퓨팅 속도를 요구한다. 여기서는 SBERT를 Avg GloVe 임베딩과 InferSent, Universal Sentence Encoder에 비교한다.
데이터셋은 STSb를 사용했다.
Avg GloVe 임베딩은 numpy와 python 기본 for loop로 계산하였고, InferSent는 PyTorch로 하였다. USE는 TensorFlow Hub의 버전을 이용했다. SBERT는 PyTorch에 기반한다.
향상된 문장 임베딩 컴퓨팅을 위해 스마트한 배치 전략을 사용했다. 문장 길이가 유사한 것들끼리 모아 grouping을 하고, 그 미니 배치 안에서 길이가 가장 긴 문장을 기준으로 패딩한다. 이 전략은 불필요한 패딩 토큰을 줄여 처리 시간을 상당히 줄여준다.
결과는 아래와 같다.
Conclusion
이 논문에서 저자들은 BERT가 코사인 유사도와 같은 일반적인 유사도 측정 방법론에 적절하지 못하게 mapping한다는 것을 보였다. 이는 Avg GloVe 임베딩의 성능보다 낮았다.
이러한 단점을 극복하기 위해 SBERT를 제안했고, SBERT는 siamese/triplet 네트워크를 통해 BERT를 fine-tuning한다. SOTA 임베딩 방법들에 비해 상당한 성능 향상이 있었다.
BERT를 RoBERTa로 바꿨을 때에는 유의미한 성능 향상이 있지는 않았다.
SBERT는 연산 성능이 효율적이다. 10,000개의 문장을 클러스터링하려면 약 5천만 개의 조합을 계산해야 하므로 BERT에서 아주 오랜 시간이 걸린다. 반면 SBERT를 통해 미리 임베딩을 구해 두면 클러스터링 작업을 5초 이내로 줄일 수 있었다.
SBERT의 구체적인 내용과 documentation은 공식 레퍼런스 사이트에서 찾아볼 수 있다.