Field Log · Entry
Embedding Geometry: 유사도·정규화·Pooling·Hubness (2/14)
이번 글의 결론
- L2-normalized vector에서는 cosine 순위와 inner product 순위가 같지만, 정규화하지 않으면 norm이 relevance signal 또는 원치 않는 bias로 작동합니다.
- Pooling은 구현 세부가 아니라 token 정보를 한 vector로 압축하는 학습 가능한 bottleneck입니다. Model이 학습한 공식 pooling을 따라야 합니다.
- T-SNE 그림이 예쁘다고 retrieval이 좋은 것은 아닙니다. Geometry 진단은 nearest-neighbor metric·positive alignment·uniformity·hubness와 연결합니다.
- Anisotropy와 hubness는 관련 있지만 같은 현상은 아닙니다. 중심화·whitening 같은 후처리는 held-out task와 index에서 검증합니다.
- Dimension을 줄이거나 quantize할 때 vector reconstruction error보다 top-k 보존율과 downstream quality가 더 중요합니다.
앞 글에서 embedding을 task가 요구한 관계를 좌표에 압축한 표현이라고 정의했습니다. 이제 그 좌표에서 “가깝다”를 계산하는 법을 정확히 만듭니다.
1. 세 가지 기본 유사도
Query vector (q), document vector (d)가 있다고 합시다.
Inner Product
dot(q, d) = q · d = Σ_i q_i d_i
방향과 크기(norm)가 모두 영향을 줍니다.
Cosine Similarity
cos(q, d) = (q · d) / (||q||₂ ||d||₂)
두 vector 사이 각도만 비교하며 범위는 보통 -1에서 1입니다.
Euclidean Distance
L2(q, d) = ||q - d||₂
작을수록 가깝습니다.
2. L2 Normalization 뒤에는 순위가 같아진다
(\hat q=q/||q||), (\hat d=d/||d||)라면:
dot(q̂, d̂) = cos(q, d)
||q̂ - d̂||²
= ||q̂||² + ||d̂||² - 2q̂·d̂
= 2 - 2cos(q, d)
따라서 normalized vector에서 dot product를 내림차순 정렬하는 것과 L2 distance를 오름차순 정렬하는 것은 같은 순위를 냅니다.
하지만 query만 정규화하거나 document만 정규화하면 이 등가성은 깨집니다.
3. Norm은 정보인가 Bias인가
정규화하지 않은 dot product는 다음처럼 분해됩니다.
q · d = ||q|| ||d|| cos(θ)
Document norm이 큰 이유가 model 학습상 confidence나 salience라면 유용할 수 있습니다. 반대로 length, frequent pattern, language, formatting 때문에 norm이 커졌다면 irrelevant document가 반복적으로 상위에 나타날 수 있습니다.
확인할 histogram:
norm by:
relevant / irrelevant
document length
language
source
template
duplicate group
공식 model이 dot product를 전제로 학습했다면 무조건 normalize하는 것도 잘못입니다. Training score와 serving score를 맞추는 것이 우선입니다.
4. Query·Corpus Mean Centering
Corpus vector 평균을 (\mu)라고 합시다.
μ = (1/N) Σ_i d_i
centered(d) = d - μ
많은 vector가 공통 방향에 몰리면 그 방향이 모든 similarity에 영향을 줄 수 있습니다. Centering은 공통 성분을 제거하지만 corpus snapshot에 의존합니다.
주의점:
- 새 corpus 분포에서 평균이 바뀜
- query에도 같은 transform을 적용해야 함
- incremental update 때 transform version 필요
- 원래 model의 norm signal을 제거할 수 있음
후처리도 model artifact의 일부입니다.
5. Anisotropy
Isotropic space라면 방향이 구면에 비교적 고르게 퍼집니다. Anisotropic space에서는 vector가 좁은 cone이나 일부 주성분 방향에 몰립니다.
isotropic: ↖ ↑ ↗ → ↘ ↓ ↙ ←
anisotropic: ↗ ↗ ↑ ↗ ↑
문제는 unrelated pair도 높은 cosine을 가져 score range가 좁아질 수 있다는 것입니다.
진단:
- random-pair cosine distribution
- covariance eigenvalue spectrum
- effective rank
- average cosine to corpus centroid
- positive와 negative similarity separation
단, anisotropy 자체를 낮추는 것이 항상 task metric을 올리지는 않습니다. Task에 유용한 dominant direction까지 지울 수 있습니다.
6. Alignment와 Uniformity
Contrastive representation 연구는 normalized hypersphere에서 두 성질을 구분합니다.
Alignment
Positive pair가 가까운가?
E ||f(x) - f(x⁺)||²
Uniformity
전체 representation이 구면에 충분히 퍼지는가?
log E exp(-t ||f(x) - f(y)||²)
Positive만 강하게 당기면 모든 vector가 한 점으로 collapse할 수 있습니다. Negative와 normalization은 space를 펼치는 역할을 합니다. 다음 글에서 InfoNCE와 연결합니다.
7. Hubness
Hub는 많은 query의 nearest-neighbor에 비정상적으로 자주 등장하는 corpus item입니다.
k-occurrence(d)
= number of queries for which d appears in top-k
긴 boilerplate 문서, 일반적인 문구, 특정 언어 vector가 hub가 될 수 있습니다.
진단 table:
| document_id | top-10 출현 수 | 실제 relevant 수 | 길이 | template |
|---|---|---|---|---|
| d-17 | 1,842 | 11 | 1,024 | generic policy footer |
| d-42 | 311 | 205 | 288 | product guide |
Top-k 출현 분포의 skewness, maximum occurrence, hub document의 precision을 봅니다.
Anisotropy는 vector 분포의 방향 집중이고 hubness는 nearest-neighbor graph의 출현 불균형입니다. 2026년 cross-lingual 연구처럼 둘을 통계적으로 분리해서 보는 흐름도 있습니다.
8. Pooling은 어떤 정보를 남기는가
Transformer가 token state (h_1…h_T)를 만들었다고 합시다.
Mean Pooling
Padding을 제외한 token 평균입니다.
z = Σ_i mask_i h_i / Σ_i mask_i
분산된 정보를 모으지만 긴 입력의 작은 핵심 신호를 희석할 수 있습니다.
CLS Pooling
특별 [CLS] token의 hidden state를 사용합니다.
z = h_CLS
Pretraining/fine-tuning에서 이 token이 global representation 역할을 배우지 않았다면 좋은 embedding이 아닐 수 있습니다.
Last-token / EOS Pooling
Decoder-only LLM embedding에서 마지막 token이 앞 token을 모두 볼 수 있다는 점을 이용합니다.
z = h_EOS
Causal attention에서는 앞 token이 뒤 내용을 볼 수 없으므로 mean pooling의 각 token 정보가 비대칭입니다. Echo embedding은 입력을 반복해 두 번째 구간의 token이 전체 첫 구간을 보게 하는 아이디어를 제안했습니다. LLM2Vec·NV-Embed 계열은 bidirectional attention으로 바꾸는 접근을 사용합니다.
Learned Attention Pooling
학습된 query/latent가 token을 attention해 vector를 만듭니다. NV-Embed는 latent attention layer가 mean·last-token보다 낫다고 보고했습니다. 하지만 다른 checkpoint에 그 pooling head만 붙여 같은 효과를 기대할 수는 없습니다.
9. Masked Mean Pooling 구현
import torch
import torch.nn.functional as F
def mean_pool(last_hidden_state, attention_mask):
mask = attention_mask.unsqueeze(-1).to(last_hidden_state.dtype)
summed = (last_hidden_state * mask).sum(dim=1)
count = mask.sum(dim=1).clamp_min(1e-9)
return summed / count
embeddings = mean_pool(outputs.last_hidden_state, attention_mask)
embeddings = F.normalize(embeddings, p=2, dim=1)
Special token 포함 여부도 official implementation과 맞춥니다. Padding token까지 평균하면 길이에 따라 embedding이 변합니다.
10. Truncation은 Geometry를 바꾼다
긴 입력을 max_length=512로 자르면 단지 일부 text가 사라지는 것이 아닙니다. Pooling에 들어오는 token 집합이 달라져 vector 전체가 이동합니다.
측정:
cos(embed(full), embed(truncated))
retrieval rank of gold as length grows
answer-span retained rate
Model card의 최대 context가 8K여도 8K 문서를 single vector로 잘 표현한다는 뜻은 아닙니다. 최대 허용 길이와 effective retrieval length를 구분합니다.
11. Dimension과 정보 밀도
차원 (d)가 커지면 표현 capacity가 늘 수 있지만:
- vector 저장 공간 증가
- memory bandwidth 증가
- exact similarity 연산 증가
- HNSW graph·PQ 설정 영향
- high-dimensional neighbor search 난이도 증가
Float32 기준 raw vector 저장량:
storage ≈ number_of_vectors × dimension × 4 bytes
10,000,000 × 1024 × 4
≈ 40.96 GB (index overhead 제외)
고차원이 자동으로 더 좋은 것은 아닙니다. Matryoshka-trained model은 앞부분 차원에 coarse-to-fine 정보를 배치해 잘라 쓸 수 있지만, 일반 vector를 임의로 앞 256차원만 자르는 것과 다릅니다.
12. PCA·Whitening과 MRL을 혼동하지 않는다
| 방법 | 학습 시 설계 | 변환이 corpus에 의존 | 임의 prefix 절단 |
|---|---|---|---|
| PCA | 아니어도 가능 | 예 | 불가 |
| Whitening | 아니어도 가능 | 예 | 불가 |
| Random projection | 불필요 | 보통 아니오 | 불가 |
| Matryoshka | 필요 | 아니오 | 가능하도록 학습 |
WhiteningBERT 계열은 일부 조건에서 BERT sentence representation과 retrieval을 개선했지만, modern task-trained embedding에도 항상 개선된다는 법은 없습니다.
13. Visualization의 함정
T-SNE·UMAP은 local structure를 2D로 투영합니다. Parameter와 random seed에 따라 cluster 모양이 달라질 수 있습니다.
좋은 사용:
- label 오류·duplicate·language island 탐색
- model A/B의 동일 sample 이동 비교
- hub·outlier 후보 찾기
나쁜 결론:
"2D plot에서 class가 나뉘었다"
→ "고차원 retrieval이 좋다" (성립하지 않음)
정량 nearest-neighbor 평가와 함께 사용합니다.
14. Geometry Diagnostic Notebook
geometry_report:
model_revision: "..."
prompt_revision: query-v2/document-v2
pooling: mean
normalize: true
dimension: 1024
samples: 50000
metrics:
norm:
p05: 1.0
p50: 1.0
p95: 1.0
random_pair_cosine:
mean: 0.04
std: 0.08
positive_cosine:
mean: 0.71
hard_negative_cosine:
mean: 0.62
effective_rank: 311
top10_hub_max_occurrence: 1842
숫자의 절대 기준보다 model A/B가 같은 held-out corpus에서 어떻게 달라지는지 봅니다.
15. 실전 체크리스트
- Model이 기대하는 cosine·dot·L2를 확인했다.
- Query와 document 정규화가 동일한 contract를 따른다.
- Official pooling과 special-token 처리를 재현했다.
- Norm이 length·language·source와 상관되는지 확인했다.
- Random·positive·hard-negative similarity 분포를 비교했다.
- Hub document와 boilerplate를 audit했다.
- Truncation 전후 vector·gold rank 변화를 측정했다.
- 차원 축소는 top-k 보존과 downstream metric으로 검증했다.
- 후처리 transform과 corpus statistic을 versioning한다.
- Visualization만으로 품질 결론을 내리지 않는다.
스스로 확인하기
- Normalized vector에서 cosine, dot product, L2가 같은 순위를 만드는 이유는 무엇인가?
- Document norm이 relevance가 아닌 bias를 나타낼 수 있는 예는 무엇인가?
- Anisotropy와 hubness의 차이는 무엇인가?
- Decoder-only model에서 last-token pooling이 mean pooling보다 자연스러울 수 있는 이유는 무엇인가?
- MRL model의 prefix truncation과 일반 embedding의 차원 slicing은 왜 다른가?
다음 글에서는 positive를 당기고 negative를 미는 InfoNCE를 temperature, batch size, gradient 관점에서 해부합니다.
참고자료
- Understanding Contrastive Representation Learning through Alignment and Uniformity
- SimCSE: Simple Contrastive Learning of Sentence Embeddings
- WhiteningBERT: An Easy Unsupervised Sentence Embedding Approach
- Repetition Improves Language Model Embeddings
- NV-Embed: Improved Techniques for Training LLMs as Generalist Embedding Models
- Hubness Reduction Improves Sentence-BERT Semantic Spaces