📌 들어가며1. BERT의 치명적인 약점1.1 BERT는 왜 문장 유사도 계산이 느릴까?1.2 기존 해결책의 한계2. Sentence-BERT의 핵심 아이디어2.1 Siamese Network로 문제 해결2.2 어떻게 학습시킬까? 세 가지 목적 함수3. Pooling 전략도 중요하다4. 실험 결과는 얼마나 좋아졌을까?4.1 속도 개선이 압도적이다4.2 성능도 크게 향상됐다5. 다양한 활용: Transfer Learning5.1 SentEval에서도 검증5.2 Wikipedia Sections Distinction6. 아쉬운 점도 있다7. 배운 점과 생각8. 마치며
📌 들어가며
BERT를 처음 접했을 때 정말 놀라웠다.
"이 모델 하나면 모든 NLP 문제를 해결할 수 있겠다"고 생각했다. 하지만 막상 실무에서 사용하려고 보니 치명적인 문제가 하나 있었다. 바로 문장 간 유사도를 빠르게 계산하는 것이 거의 불가능하다는 점이었다.
예를 들어 1만 개의 문장 중에서 가장 비슷한 문장 쌍을 찾으려면 BERT로는 무려 65시간이 걸린다.
Sentence-BERT 논문을 읽으면서 "아, 이 문제를 이렇게 해결할 수 있구나!"라는 깨달음을 얻었다. 오늘은 이 논문을 같이 살펴보려고 한다.
1. BERT의 치명적인 약점
1.1 BERT는 왜 문장 유사도 계산이 느릴까?
BERT는 기본적으로 Cross-Encoder 방식으로 작동한다. 트랜스포머에 대한 지식은 아래의 링크를 참고하여 공부하면 큰 도움이 되어 임베드 해두었다.
YouTubeAttention/Transformer 시각화로 설명

Attention/Transformer 시각화로 설명
[Powered by Vrew] 이 영상의 자막은 Vrew를 통해 생성/편집되었습니다. 이 영상은 Attention과 Transformer 시리즈 영상을 종합한 영상입니다. 영상에는 3Blue1Brown의 open source 라이브러리 manim을 사용하였습니다. 본 영상 소스를 만든 코드는 https://github.com/CodingVillainKor/manim-kor 에서 확인할 수 있습니다. 00:00 1 Attention의 원리 12:00 2 Positional Encoding과 Self-attention 18:36 3 Transformer의 학습방식, Masking #어텐션 #트랜스포머 #딥러닝
두 문장 A와 B의 유사도를 계산하려면, 두 문장을
[SEP] 토큰으로 연결해서 BERT에 넣어야 한다. 그러면 BERT가 두 문장을 동시에 보면서 관계를 파악한다. 문제는 여기서 발생한다.만약 1만 개의 문장에서 가장 비슷한 쌍을 찾으려면, 가능한 모든 조합(n×(n-1)/2)을 계산해야 한다. 즉, 약 5천만 번의 BERT 추론이 필요하다는 뜻이다.
논문에 따르면 이 작업이 V100 GPU로 약 65시간 걸린다고 한다…
실시간 검색 시스템이나 클러스터링 같은 작업에서는 절대 쓸 수 없는 속도다.
1.2 기존 해결책의 한계
그럼 다른 방법은 없었을까?
사람들이 시도한 방법은 크게 두 가지였다:
- BERT 출력층을 평균내기 (BERT embeddings)
- [CLS] 토큰 사용하기 (CLS-token output)
하지만 논문 저자들이 실험해보니, 이 방법들은 평균 GloVe 임베딩보다도 성능이 더 나빴다고 한다.
왜일까? BERT는 애초에 문장 간 관계를 비교하도록 학습됐지, 독립적인 문장 벡터를 만들도록 학습되지 않았기 때문이다.
2. Sentence-BERT의 핵심 아이디어
2.1 Siamese Network로 문제 해결
Sentence-BERT(SBERT)의 해결책은 의외로 간단했다.
BERT의 구조는 그대로 쓰되, 학습 방식만 바꾸는 것이었다.
저자는 Siamese Network 구조를 도입했다. 쉽게 말하면 같은 BERT를 두 번 사용하는 것이다.
- 문장 A를 BERT에 넣고 → pooling → 벡터 u
- 문장 B를 같은 BERT에 넣고 → pooling → 벡터 v
- u와 v를 비교해서 학습
이렇게 하면 각 문장을 독립적인 벡터로 변환할 수 있다. 그리고 한번 벡터로 바꿔놓으면, 나중에는 벡터끼리만 비교하면 되니까 엄청나게 빠르다.
2.2 어떻게 학습시킬까? 세 가지 목적 함수
논문에서는 데이터 특성에 따라 세 가지 학습 방법을 제시했다.
① Classification Objective (분류 목적 함수)
두 문장 벡터 u, v를 받아서 [u, v, |u-v|]를 만들고 softmax로 레이블을 예측한다.
SNLI 같은 자연어 추론 데이터셋(entailment, contradiction, neutral)에 적합하다.
② Regression Objective (회귀 목적 함수)
두 문장 벡터의 코사인 유사도를 직접 예측한다.
STS 벤치마크 같이 유사도 점수가 있는 데이터에 쓴다.
③ Triplet Objective (삼중 손실)
Anchor 문장 a, Positive 문장 p, Negative 문장 n을 사용한다.
목표는 a와 p의 거리를 a와 n의 거리보다 가깝게 만드는 것이다
3. Pooling 전략도 중요하다
BERT 출력을 하나의 벡터로 만드는 방법도 여러 가지를 실험했다.
- MEAN: 모든 토큰 벡터의 평균
- MAX: 각 차원별 최댓값
- CLS: [CLS] 토큰 출력만 사용
논문 저자들의 필기를 보니, MEAN 방식이 기본(default)이라고 적혀 있었다.
실험 결과를 보면, 분류 태스크에서는 pooling 전략의 영향이 크지 않았지만, 회귀 태스크에서는 MAX 전략이 의외로 성능이 많이 떨어졌다고 한다.
4. 실험 결과는 얼마나 좋아졌을까?
4.1 속도 개선이 압도적이다
논문의 가장 인상적인 부분은 속도 향상이었다.
- BERT: 1만 문장에서 유사 쌍 찾기 → 65시간
- SBERT: 같은 작업 → 약 5초
무려 13,000배 이상 빨라진 것이다.
어떻게 이게 가능할까? SBERT는 각 문장을 한 번씩만 인코딩하면 되기 때문이다. 1만 개 문장을 벡터로 바꾸는 데 5초 정도 걸리고, 코사인 유사도 계산은 0.01초도 안 걸린다.
4.2 성능도 크게 향상됐다
STS(Semantic Textual Similarity) 벤치마크에서:
- Avg. GloVe embeddings: 61.32
- Avg. BERT embeddings: 54.81 (더 나쁨!)
- InferSent: 68.03
- Universal Sentence Encoder: 74.92
- SBERT-NLI-large: 79.23 🔥
SBERT는 기존 SOTA(InferSent, Universal Sentence Encoder)를 크게 뛰어넘었다.
특히 7개의 STS 태스크 중 6개에서 압도적인 성능을 보였다. 유일하게 Universal Sentence Encoder보다 낮았던 데이터셋은 SICK-R인데, 이건 Universal Sentence Encoder가 여러 데이터셋으로 학습했기 때문인 것 같다.
5. 다양한 활용: Transfer Learning
5.1 SentEval에서도 검증
SentEval은 문장 임베딩의 품질을 평가하는 유명한 툴킷이다.
감성 분석, 주관성 예측 등 7가지 태스크로 구성되어 있다. SBERT는 여기서도 평균 87.69점을 받아 InferSent(85.10)와 Universal Sentence Encoder(85.59)를 넘어섰다.
흥미로운 점은 감성 분석 태스크에서 특히 성능이 좋았다는 것이다. SBERT가 문장의 감정 정보도 잘 포착한다는 의미다.
5.2 Wikipedia Sections Distinction
더 재밌는 실험도 있었다.
Wikipedia의 같은 article 내 section들은 주제가 비슷하고, 다른 article의 section들은 주제가 다르다. 이걸 구분할 수 있는지 테스트한 것이다.
SBERT는 이 태스크에서도 0.8078의 정확도를 보였다.
6. 아쉬운 점도 있다
완벽해 보이는 SBERT도 한계는 있다.
논문에서 RoBERTa를 써서 성능을 더 높이려 했지만(SRoBERTa), 큰 차이가 없었다고 한다. 저자들도 "minor difference"라고 표현했다.
또한 TREC 데이터셋(질문 유형 분류)에서는 Universal Sentence Encoder가 더 좋았다. 아무래도 질문-답변 형식의 데이터로 학습된 Universal Sentence Encoder가 이런 태스크에 더 적합했던 것 같다.
7. 배운 점과 생각
이 논문을 읽으면서 몇 가지를 깨달았다.
첫째, "더 큰 모델이 항상 답은 아니다"라는 것이다.
BERT는 분명 강력한 모델이다. 하지만 작업의 특성에 맞지 않으면 오히려 독이 될 수 있다. SBERT는 BERT의 구조를 바꾸지 않고도, 학습 방식만 바꿔서 새로운 태스크에 적용 가능하게 만들었다.
둘째, 속도와 성능의 트레이드오프를 영리하게 해결할 수 있다는 점이다.
보통은 속도를 높이면 성능이 떨어진다고 생각하기 쉽다. 하지만 SBERT는 속도도 13,000배 빨라지고, 성능도 올렸다. 이게 가능했던 건 문제의 본질을 정확히 파악했기 때문이다.
셋째, 기본기의 중요성이다.
Siamese Network, Triplet Loss 같은 개념은 이미 오래전부터 있던 기법이다. 저자들은 이걸 BERT에 적용하는 센스를 발휘한 것이다. 결국 최신 논문을 따라가는 것도 중요하지만, 기본적인 머신러닝 기법들을 탄탄히 아는 게 더 중요하다는 생각이 들었다.
8. 마치며
Sentence-BERT는 BERT의 약점을 정확히 짚어내고, 실용적인 해결책을 제시한 논문이다.
지금도 많은 실무 프로젝트에서 SBERT가 쓰이고 있다. 검색 엔진, 추천 시스템, 문서 클러스터링 등 문장 유사도가 필요한 곳이라면 어디든지 활용 가능하다.
나도 다음 프로젝트에서 문장 유사도 계산이 필요하면 SBERT를 꼭 써봐야겠다. 😊
앞으로도 이런 실용적이면서도 아이디어가 좋은 논문들을 계속 읽어봐야겠다.
[필기한 논문 자료 첨부]
![[Paper Review] BERT가 문장을 이해하지 못한다고? Sentence-BERT로 풀어낸 문제](/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fattachment%253Aead1f888-9ec6-4476-b4da-a8d1c140bfe8%253A%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2026-01-05_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_8.22.05.png%3Ftable%3Dblock%26id%3D2dfe642e-de97-80f7-b576-e6e681b71434%26cache%3Dv2&w=1920&q=75)