Field Log · Entry

Embedding 압축과 ANN 서빙: Dimension부터 Re-index까지 (12/14)

원본 embedding을 차원 축소와 양자화한 뒤 exact, HNSW, IVF-PQ, disk index로 나누어 품질과 메모리, 지연시간을 비교하는 서빙 지도

이번 글의 결론

  • Production 품질은 encoder 하나가 아니라 representation × dimension × dtype/code × index × search parameter의 조합입니다.
  • 차원 절단은 MRL로 학습됐는지 확인해야 합니다. 임의의 embedding 뒷부분을 자르는 것은 일반적인 압축법이 아닙니다.
  • Quantization loss와 ANN loss를 한 번에 측정하지 않습니다. fp32 exact → compressed exact → compressed ANN 순서로 원인을 분해합니다.
  • HNSW의 M·efConstruction·efSearch, IVF의 nlist·nprobe, PQ code 크기는 품질·memory·latency를 바꾸는 실험 변수입니다.
  • Model 또는 dimension이 바뀌면 기존 vector와 섞지 말고 shadow index를 만들며, dual-read·canary·rollback이 가능한 version contract를 둡니다.

앞 글에서 model quality를 공정하게 읽는 법을 배웠습니다. 이제 exact matrix에 있던 vector를 실제 traffic과 corpus 규모에 맞춥니다.


1. 먼저 용량을 계산한다

Dense vector의 raw storage는 단순합니다.

raw bytes = number_of_vectors × dimension × bytes_per_element

1억 개, 1,024차원이라면:

표현원소당 byteRaw vector만의 크기
float324약 409.6 GB
float162약 204.8 GB
int81약 102.4 GB
binary1 bit약 12.8 GB

여기에 ID, metadata, graph edge, posting list, allocator overhead, replica가 더해집니다. HNSW index가 raw vector size와 같다고 가정하면 capacity plan이 틀립니다.

2. 다섯 층을 분리한다

encoder weights
  → full embedding z ∈ R^d
  → dimension policy d'
  → numeric representation / code
  → ANN index structure
  → search-time parameters

각 층의 질문:

품질 질문운영 질문
Modelrelevant item을 가깝게 두는가encode throughput·memory
Dimension정보가 prefix에 보존되는가vector bytes·dot-product cost
Quantizationscore ordering을 얼마나 보존하는가memory bandwidth·SIMD
Indexexact neighbor를 얼마나 찾는가build time·RAM·disk
Searchtarget recall을 어떤 비용으로 달성하는가p95·p99·QPS

한 번에 모두 바꾸면 regression 원인을 찾을 수 없습니다.

3. Matryoshka Representation Learning, MRL

MRL은 큰 vector의 앞쪽 prefix도 유용한 representation이 되도록 여러 차원에서 loss를 겁니다.

z = [z1, z2, ..., z1024]

loss = w128 L(z[:128])
     + w256 L(z[:256])
     + w512 L(z[:512])
     + w1024 L(z[:1024])

이렇게 학습된 model은 같은 checkpoint에서 128·256·512·1,024차원을 선택하는 quality–cost knob를 제공합니다.

중요한 제한

MRL을 적용하지 않은 model의 앞 256차원이 특별히 중요하다는 보장은 없습니다. 다음 세 방식은 구분해야 합니다.

방식학습 필요성질
임의 prefix truncation없음일반적으로 안전하지 않음
PCA/projectioncorpus fit새 좌표축·projection artifact
MRL prefixmulti-dim objective학습된 nested representation

Model card가 지원하는 dimension과 normalization 순서를 따릅니다.

4. Dimension Sweep

dimensions = [128, 256, 512, 768, 1024]

for each dimension:
  1. query/document vector truncate
  2. model contract에 따라 normalize
  3. fp32 exact retrieval
  4. relevance metric + latency + bytes 측정

보고 표:

DimExact Recall@50nDCG@10bytes/vector(fp16)query dot time
128256
256512
5121,024
1,0242,048

전체 평균뿐 아니라 entity, 숫자, 부정, 긴 문서, cross-lingual slice를 확인합니다. 낮은 차원에서 드문 세부 정보가 먼저 사라질 수 있습니다.

5. 2D Matryoshka 관점

2D Matryoshka 계열은 network depth와 embedding dimension을 함께 elastic하게 쓰려는 방향입니다.

compute axis: transformer layers 6 / 12 / 24
vector axis:  dimension       128 / 256 / 768

아이디어는 traffic에 따라 encoder compute와 vector cost를 동시에 조절하는 것입니다. 하지만 모든 조합이 같은 checkpoint에서 안전한 것은 아니며, 학습 recipe가 지원한 exit와 dimension만 평가해야 합니다.

6. Scalar Quantization

float16 / bfloat16

실수 범위를 유지하면서 byte를 절반으로 줄입니다. CPU index가 실제로 해당 dtype 계산을 효율적으로 지원하는지 확인합니다. 저장 dtype과 accumulation dtype도 구분합니다.

int8

각 값 또는 vector/block의 scale을 사용해 8-bit integer로 매핑합니다.

q_i = round(z_i / scale) + zero_point
z_i ≈ scale × (q_i - zero_point)

Symmetric normalized embedding에서는 대칭 scale이 자연스러울 수 있지만, 최적 policy는 vector distribution과 engine에 달려 있습니다.

Binary

부호 등을 1 bit로 바꿔 Hamming distance를 사용할 수 있습니다. memory와 coarse filtering은 크게 좋아지지만 score resolution 손실이 큽니다.

실용적인 방식은 binary로 후보를 넓게 찾고 원본 또는 int8 vector로 rescore하는 cascade입니다.

7. Product Quantization, PQ

PQ는 vector를 여러 subvector로 나누고 각 부분을 codebook centroid ID로 바꿉니다.

z = [z^(1), z^(2), ..., z^(m)]
each subvector → nearest centroid ID
stored code = [c1, c2, ..., cm]

Query와 centroid 사이의 distance table을 미리 계산해 compressed code를 빠르게 비교합니다.

주요 변수:

  • subquantizer 수 m
  • subvector당 bit 수
  • codebook training sample
  • residual PQ 여부
  • OPQ 같은 rotation 사용 여부
  • original vector를 rerank용으로 보존할지

PQ codebook을 다른 model version의 vector에 재사용하면 distribution mismatch가 생길 수 있습니다.

8. 압축 손실을 Exact에서 먼저 잰다

Stage A  fp32 full-dim exact
Stage B  fp32 reduced-dim exact
Stage C  quantized reduced-dim exact / exhaustive code scan
Stage D  same compressed representation + ANN

측정값:

dimension loss  = metric(A) - metric(B)
quantization loss = metric(B) - metric(C)
ANN loss        = metric(C) - metric(D)

Code scan이 true exact floating search와 같다는 의미는 아닙니다. 여기서 exact는 해당 compressed representation의 모든 corpus item을 빠짐없이 비교했다는 뜻입니다.

9. HNSW

HNSW는 가까운 vector를 edge로 연결한 다층 proximity graph를 탐색합니다.

upper sparse layers → 멀리 이동
lower dense layer   → 근방 정밀 탐색

대표 parameter:

Parameter커지면 보통비용
Mgraph connectivity·recall 증가RAM·build 증가
efConstructiongraph quality 증가build time 증가
efSearchsearch recall 증가query latency 증가

장점:

  • 높은 recall–latency 성능
  • search-time efSearch 조절
  • 비교적 자연스러운 incremental insertion

주의:

  • graph edge memory가 큼
  • delete/update와 compaction 정책 필요
  • filter가 graph traversal을 막을 수 있음
  • replica마다 build order가 달라 미세한 결과 차이가 날 수 있음

10. IVF와 IVF-PQ

IVF는 corpus를 coarse centroid의 posting list로 나눕니다.

offline:
  vectors → nearest coarse centroid → inverted list

online:
  query → nearest nprobe centroids → scan their lists
Parameter의미trade-off
nlistcoarse partition 수너무 작으면 scan 증가, 너무 크면 training·빈 list 문제
nprobequery가 방문할 list 수recall 증가 ↔ latency 증가
PQ codelist 안 vector 압축memory 감소 ↔ quantization loss

대규모 batch·GPU 환경에서 매력적일 수 있지만, corpus size와 hardware에 맞춘 centroid training이 필요합니다.

11. DiskANN 계열

RAM에 전체 vector·graph를 올리기 어려울 때 SSD 접근을 고려한 graph index가 필요합니다. DiskANN 연구는 billion-scale nearest-neighbor search에서 memory가 제한된 machine과 SSD를 활용하는 설계를 제안했습니다.

운영에서 확인할 것:

  • warm/cold cache latency
  • random read pattern과 SSD IOPS
  • compressed vector를 RAM에 둘지
  • graph와 full vector의 배치
  • index build·merge 시간
  • node failure와 replica recovery

Disk 기반이라는 label만으로 저렴하다고 결론 내리지 않습니다. Tail latency와 SSD endurance가 비용의 일부입니다.

12. Filtered ANN

실제 검색은 tenant, ACL, language, date, category filter를 동반합니다.

vector top-k AND tenant_id = A AND access_level <= user

방법:

방식문제
ANN 후 post-filter살아남는 결과가 k보다 적을 수 있음
filter 후 brute-force선택도가 낮으면 느림
filter-aware traversalengine 종속·index 복잡도
partition별 index작은 shard·운영 수 증가

Filter selectivity별 recall·latency를 측정합니다. 전체 corpus benchmark만으로 multi-tenant traffic을 대표할 수 없습니다.

13. Pareto Frontier를 만든다

한 개 composite score보다 지배 관계가 분명합니다.

Configuration A dominates B if:
  quality_A >= quality_B
  latency_A <= latency_B
  memory_A  <= memory_B
and at least one is strictly better.

실험 grid 예:

dimensions: [256, 512, 1024]
representations: [fp16, int8, pq_64x8]
indexes:
  flat: [{}]
  hnsw:
    - {M: 16, efConstruction: 128, efSearch: 64}
    - {M: 32, efConstruction: 256, efSearch: 128}
  ivfpq:
    - {nlist: 4096, nprobe: 16, code: pq_64x8}
    - {nlist: 4096, nprobe: 64, code: pq_64x8}

모든 조합을 무작정 실행하지 말고 Stage B/C에서 품질이 낮은 dimension·code를 먼저 제거합니다.

14. Target Recall에서 System을 비교한다

HNSW가 2ms, IVF가 1ms 같은 비교는 recall이 다르면 의미가 약합니다.

1. 각 index의 search parameter sweep
2. ANN recall@10 = 0.95가 되는 점을 interpolation
3. 같은 target recall에서 p50/p95/QPS/RAM 비교
4. qrel metric도 함께 확인

두 개의 recall을 계속 구분합니다.

neighbor preservation: ANN top-k vs exact top-k
task relevance:        retrieved top-k vs qrel

15. End-to-end Latency Budget

T_total = T_queue
        + T_query_encode
        + T_network
        + T_ANN
        + T_metadata_fetch
        + T_rerank
        + T_context_pack

Vector search만 microbenchmark해 전체 SLA를 주장하지 않습니다. Query encoder가 7B이고 ANN이 2ms라면 병목은 model입니다.

측정 조건:

  • batch 1과 concurrent load
  • warm/cold cache
  • corpus size와 filter selectivity
  • hardware·thread·NUMA
  • network hop
  • top-k와 returned metadata size
  • p50·p95·p99

16. Index Identity Contract

index_manifest:
  index_id: policies-ko-v12
  corpus_snapshot: docs-2026-07-01
  chunker_revision: heading-v3
  model_id: org/model
  model_revision: abc123
  query_prompt_revision: qprompt-v4
  document_prompt_revision: dprompt-v3
  pooling: mean
  normalization: l2
  dimension: 512
  vector_dtype: int8
  quantizer_revision: int8-calib-v2
  similarity: inner_product
  ann:
    type: hnsw
    M: 32
    efConstruction: 256
  build_code_commit: def456
  document_count: 9843210
  checksums:
    id_map: "..."
    vectors: "..."

Query encoder contract가 이 manifest와 다르면 request를 거절하거나 명시된 compatible route로 보냅니다.

17. 왜 Vector를 섞으면 안 되는가

Model A와 B가 모두 768차원이어도 좌표계가 다릅니다.

dot(embed_A(query), embed_B(document))
  has no learned compatibility guarantee

같은 model이라도 다음 변경은 full re-embedding 후보입니다.

  • model revision
  • document instruction/prefix
  • pooling
  • normalization
  • dimension
  • quantizer/codebook
  • tokenizer·truncation contract

일부 embedding converter 연구가 좌표계 변환을 학습하지만, 별도 학습·평가 없이 migration shortcut으로 가정하지 않습니다.

18. 안전한 Re-index

current index v11 ────────────── serves traffic

new corpus snapshot
  → encode with contract v12
  → build shadow index v12
  → integrity + exact/ANN eval
  → dual-read shadow comparison
  → 1% canary → 10% → 50% → 100%
  → keep v11 for rollback window

Gate:

  • document count·ID coverage 일치
  • duplicate/missing vector 0 또는 허용 budget 이하
  • sample embedding deterministic check
  • exact relevance regression 없음
  • target ANN recall 달성
  • p95·p99와 error rate budget 충족
  • tenant ACL leakage test 통과
  • rollback pointer 검증

19. Incremental Update

Append-only 문서와 수정·삭제는 다르게 다룹니다.

insert: new document vector + metadata
update: tombstone old ID + insert new version
delete: authorization 즉시 차단 + async physical compaction

보안상 삭제 요청은 graph compaction을 기다려서는 안 됩니다. Query path의 metadata/ACL 층에서 즉시 보이지 않게 한 뒤 물리 삭제를 확인합니다.

Contextual embedding은 한 chunk 수정이 주변 vector 재계산을 요구할 수 있으므로 긴 문서 편의 update scope를 manifest에 포함합니다.

20. 운영 Metric

Quality

  • exact relevance Recall/nDCG
  • ANN neighbor recall
  • compressed score/rank correlation
  • critical slice regression

Performance

  • query encode p50/p95
  • ANN p50/p95/p99
  • QPS at target recall
  • index build·load time
  • re-embedding documents/s

Capacity

  • bytes/vector
  • index bytes/vector
  • RAM·VRAM·disk
  • replicas와 recovery time

Correctness

  • missing/duplicate ID
  • stale document rate
  • ACL post-filter shortfall
  • query/index contract mismatch

21. 선택 가이드

상황첫 실험
수십만 vector, 충분한 RAMfp16/fp32 flat exact baseline
수백만~수천만, high recallHNSW dimension·efSearch sweep
대규모 GPU batch searchIVF/IVF-PQ sweep
수억~수십억, RAM 제약PQ·disk-aware graph 검토
mobile/offlinesmall encoder+MRL+int8/binary cascade
강한 metadata filterfilter-aware engine/partition 실험
multi-vector documentcoarse single-vector → late-interaction cascade

이 표는 출발점이며 corpus 분포와 update pattern이 최종 선택을 바꿉니다.

22. Checklist

  • Raw vector·graph·metadata·replica 용량을 계산했다.
  • MRL 지원 차원만 prefix truncation했다.
  • Full-dim, reduced-dim, quantized, ANN을 단계별 비교했다.
  • ANN recall과 relevance recall을 모두 냈다.
  • 같은 target recall에서 latency·QPS를 비교했다.
  • Filter selectivity와 concurrent load를 재현했다.
  • Model·prompt·pooling·dimension·codebook을 index identity로 묶었다.
  • 새 version은 shadow index와 dual-read로 검증했다.
  • 삭제·ACL이 compaction 전에도 즉시 적용된다.
  • Rollback 가능한 이전 index를 보존했다.

스스로 확인하기

  1. MRL이 아닌 model의 vector prefix를 임의로 자르면 안 되는 이유는 무엇인가?
  2. fp32 exact → compressed exact → compressed ANN 순서가 분리하는 세 손실은 무엇인가?
  3. HNSW의 efSearch를 올렸을 때 기대되는 품질과 비용 변화는 무엇인가?
  4. 서로 같은 dimension인 model A query vector와 model B document vector를 섞을 수 없는 이유는 무엇인가?
  5. Re-index 과정에서 dual-read와 rollback window가 필요한 이유는 무엇인가?

다음 글에서는 LLM backbone, data distillation, small model, contextual·reasoning·multimodal embedding과 평가·보안까지 2024–2026 연구 흐름을 연결합니다.

참고자료