Self-Knowledge Distillation?
먼저 Knowledge Distillation(지식 증류)부터
원래 Knowledge Distillation은 두 모델 사이에서 일어나는 과정임:
Teacher 모델 (크고 똑똑함)
│
│ "이 문서와 이 쿼리의 관련도는 0.85야" ← teacher의 판단
│
▼
Student 모델 (작고 가벼움)
→ "아, 0.85에 가깝게 학습해야겠구나"
큰 모델의 지식을 작은 모델에 “증류(distill)“해서 옮기는 것. 소주 증류할 때 원액에서 핵심만 뽑아내는 것과 같은 원리임.
Self-Knowledge Distillation: 자기 자신이 teacher
BGE-M3는 teacher 모델이 따로 없음. 자기 자신의 여러 출력을 합쳐서 teacher를 만듦.
BGE-M3는 하나의 모델인데 출력이 세 개임:
입력: "asyncio에서 에러 발생" ↔ "gather에 sync 함수 넘기면 TypeError"
BGE-M3 모델 (하나의 모델)
│
├─ Dense 출력: "이 두 문장의 관련도는 0.72야"
│ (의미적으로 비슷한지 판단)
│
├─ Sparse 출력: "이 두 문장의 관련도는 0.65야"
│ (키워드가 얼마나 겹치는지 판단)
│
└─ Multi-vec 출력: "이 두 문장의 관련도는 0.80이야"
(토큰별 세밀한 매칭으로 판단)
세 가지가 각각 다른 관점에서 관련도를 판단 중. 여기서 핵심 아이디어가 도출됨:
“세 명의 심사위원이 각자 점수를 줬으면, 그 평균이 한 명보다 더 정확하지 않을까?”
Teacher Signal (종합 점수) = Dense(0.72) + Sparse(0.65) + Multi-vec(0.80)
─────────────────────────────────────────────
3
= 0.723 (대략)
이 종합 점수가 "정답"이 됨
그 다음, 이 종합 점수를 목표로 삼아 각 개별 출력을 다시 학습시킴:
[학습 과정]
종합 점수: 0.723 ← "이게 정답"
│
├─→ Dense(0.72): "난 0.72인데 0.723에 맞춰야지" → 약간 올림
├─→ Sparse(0.65): "난 0.65인데 0.723에 맞춰야지" → 좀 더 올림
└─→ Multi-vec(0.80): "난 0.80인데 0.723에 맞춰야지" → 약간 내림
이 과정을 반복하면:
[학습 전]
Dense: 0.72 | Sparse: 0.65 | Multi-vec: 0.80
(각자 따로 놀고 있음)
[학습 후: 서로를 강화]
Dense: 0.78 | Sparse: 0.76 | Multi-vec: 0.82
(서로의 판단을 참고해서 각자 더 정확해짐)
특히 Sparse가 가장 큰 수혜자. 원래 키워드 매칭만으로는 의미를 못 잡지만, Dense와 Multi-vec이 “이 두 문장은 의미적으로 관련 있다”고 알려주니까, Sparse도 그걸 반영해서 키워드 가중치를 더 잘 조절하게 됨. 논문에서도 self-knowledge distillation이 특히 sparse retrieval과 multi-vector retrieval의 성능을 크게 향상시켰다고 명시 Hugging Face.
비유로 정리
[일반 BM25]
국어 선생님 혼자 채점 → 국어 관점에서만 판단
[일반 Dense]
수학 선생님 혼자 채점 → 수학 관점에서만 판단
[BGE-M3 Self-Knowledge Distillation]
국어+수학+영어 선생님이 각자 채점한 후
→ 세 점수를 평균 내서 "종합 정답"을 만들고
→ 각 선생님이 그 종합 정답에 맞춰서 자기 채점 기준을 보정
→ 결과: 국어 선생님도 수학적 논리를, 수학 선생님도 언어적 맥락을 반영하게 됨
그래서 BGE-M3의 sparse가 단순 BM25보다 강한 것.
sparse 검색이 키워드 검색을 대체 가능한 이유
같은 토큰이 양쪽에 다 있을 때만 값이 나오고, 한쪽이라도 0이면 기여하지 않음. 결국 “같은 키워드가 있으면 점수가 올라간다”는 것이고, 키워드 매칭과 본질적으로 동일함.
그러면 BM25와 뭐가 다른지?
문서: "파이썬 비동기 처리에서 문제 발생"
쿼리: "asyncio 에러"
[BM25]
"asyncio" 있나? → ❌ 없음 → 점수 0
"에러" 있나? → ❌ 없음 ("문제"는 있지만 "에러"는 없음) → 점수 0
최종: 0점 (매칭 실패) ❌
[BGE-M3 sparse]
모델이 문맥을 이해하고 가중치를 줌:
"비동기" → Transformer가 "이건 async 관련이다"라고 학습했기 때문에
async 관련 토큰에도 약간의 가중치를 부여할 수 있음
"문제" → "에러"와 비슷한 맥락이라는 걸 학습에서 배움
최종: 낮지만 0은 아닌 점수 (약한 매칭) ⚠️
이게 앞서 말한 Self-Knowledge Distillation의 효과임. Dense(의미 검색)가 “비동기 = asyncio”라는 걸 알고 있으니까, 학습 과정에서 sparse 쪽도 그 정보를 간접적으로 흡수한 것. 그래서 BGE-M3 sparse가 순수 BM25보다 성능이 높음.
다만 어차피 하이브리드 검색을 사용할 것이므로, 키워드 검색은 정확한 키워드를 가져오는 역할만 수행하면 됨.
핵심 연구: IBM Blended RAG
IBM 연구에서 BM25, dense vector, BM25 + dense, dense + sparse vector, BM25 + dense + sparse vector 조합을 비교한 결과, 세 가지를 다 쓰는 three-way retrieval이 최적이라는 결론이 나옴 Infiniflow.
[IBM 연구 결과, nDCG 기준]
Dense only ████████░░ (기본)
Dense + Sparse █████████░ (약간 개선)
Dense + BM25 ██████████ (큰 개선)
Dense + Sparse + BM25 ██████████▌ (최고 성능)
왜 Sparse vector가 BM25를 대체 못 하는지
sparse vector는 3만 차원으로 모든 키워드를 커버할 수 없고, 다국어 상황에서는 더 심함. 또한 구문 검색(phrase query)에서 심각한 정보 손실이 발생함. 이런 작업은 full-text search(BM25)로 처리해야 함 Infiniflow.
구체적으로 보면:
문제 1. 토크나이저가 다르다
검색어: "run_in_executor"
[BM25: 단어 단위]
→ "run_in_executor" 통째로 매칭
→ 문서에 "run_in_executor"가 있으면 100% 매칭 ✅
[SPLADE/BGE-M3 sparse: subword 단위]
→ ["run", "_", "in", "_", "ex", "ecu", "tor"]으로 쪼개짐
→ "executor"가 포함된 다른 문서도 부분 매칭 ⚠️
→ "run_in_executor" 자체의 정확 매칭은 보장되지 않음
Qdrant 팀 자체도 이 문제를 인정함. SPLADE 같은 학습된 sparse 모델은 transformer 토크나이저를 쓰는데, 이 토크나이저가 retrieval 용도로 설계된 게 아니라는 것 Qdrant.
문제 2. 학습 데이터 편향
SPLADE 같은 learned sparse 모델의 transformer 토크나이저는 영어 자연어용으로 만들어진 것. 제품 코드, 정책 번호 같은 특수 식별자를 처리하도록 설계된 게 아님 Minimalistinnovation.
내 지식 DB에 들어갈 QLoRA, pgvector, astream_events, ContextVar 같은 기술 용어가 정확히 이 케이스에 해당함.
문제 3. 용어 확장이 양날의 검
“study”라는 키워드를 BM25로 변환하면 딱 하나의 non-zero 값만 생기지만, SPLADE로 변환하면 “learn”, “research”, “investigate” 등 유사 단어에도 non-zero 값이 생김 Medium.
이 용어 확장(term expansion)이 일반 검색에서는 장점이지만, 지금 유스케이스에서는:
쿼리: "QLoRA"
[BM25]
→ "QLoRA"만 찾음 → 정확 ✅
[Sparse vector (SPLADE/BGE-M3)]
→ "QLoRA" + "LoRA" + "adapter" + "quantize" 등에도 가중치 부여
→ "LoRA" 문서도 점수가 높게 나옴 → 노이즈 ⚠️
“QLoRA”를 검색했는데 “LoRA” 문서가 같이 나오는 건 Dense의 역할. 키워드 검색까지 이러면 정확한 매칭을 하는 곳이 아무 데도 없어짐.