💡 핵심 인사이트 HNSW(Hierarchical Navigable Small World)는 "다층 그래프(Multi-layer Graph) 구조를 이용해 벡터 공간에서 가까운 이웃을 계층적으로 탐색하는" 대표적인 ANN(Approximate Nearest Neighbor) 알고리즘입니다. 상위 레이어에서는 **대략적인 위치**를 빠르게 파악하고, 하위 레이어로 점진적으로 내려가며 (세밀하게 탐색) 합니다. 이 "_ Hierarchical_" 구조 덕분에 **수천 차원의 벡터에서도 수십 밀리초 내에 정확한 유사 이웃을 발견**할 수 있습니다. Milvus, Weaviate, Qdrant 등 **주요 벡터 데이터베이스의 기본 인덱싱 알고리즘**으로 사용됩니다.


Ⅰ. HNSW의 탄생: NSW의 한계를 극복

HNSW은 NSW(Navigable Small World) 알고리즘에서 영감을 받았습니다.

[NSW의 문제점]

NSW는 단일 레이어의 그래프입니다.
- 가까운 노드를 순차적으로 탐색
- 시작 위치에 따라 탐색 경로가 크게 달라질 수 있음
- 전역적 최적값을 보장하기 어려움

NSW 그래프 예시:
      ●────────────────●
     /                  \
    ●───────●────────────●
    |       |           /
    |       |          /
    ●───────●─────────●

    문제: 시작점이 "좌측 상단"이면
          "우측 하단"의 노드를 못 찾을 수 있음

HNSW의 해결책:

  • 다층 레이어 도입 → 상위 레이어에서 넓은 범위 탐색, 하위 레이어에서 세밀한 탐색
  • 점진적 세분화 (Progressive Refinement)
  • O(log N) 시간 복잡도 달성

Ⅱ. HNSW의 구조: 다층 그래프

[HNSW 다층 구조]

┌─────────────────────────────────────────────────────────────────┐
│                       HNSW 다층 구조                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Layer 3 (최상위):                                              │
│       ●━━━━━━━━━━━━━━━━━━━━━━━━━●                               │
│       │                         │                               │
│       │   (검색 시작 시 랜덤 엔트리 포인트에서 시작)               │
│       │   전역적으로 가장 가까운 클러스터 발견                      │
│       │                                                       │
│  Layer 2:                                                      │
│       ●━━━●━━━●━━━●━━━●━━━●━━━●━━━●━━━●━━━●━━━●               │
│       │                                                           │
│       │   (발견된 클러스터 내 하위 레이어로 이동)                    │
│       │                                                           │
│  Layer 1:                                                      │
│       ●━●━●━●━●━●━●━●━●━●━●━●━●━●━●━●━●━●━●━●               │
│       │                                                           │
│       │   (더 세밀한 지역 탐색)                                    │
│       │                                                           │
│  Layer 0:                                                      │
│  ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●         │
│       │                                                           │
│       │   (가장 세밀한 레벨, 모든 벡터가 이 레벨에 존재)             │
│       │   ef 파라미터만큼 탐색하여最近的 이웃 도출                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

각 레이어의 역할:

  • Layer 3, 2 (상위): (전역적으로) (가장 가까운) (노드를) (빠르게) (발견)
  • Layer 1 (중간): (지역적) (세분화)
  • Layer 0 (최하위): (가장 세밀한) (탐색, (ef) (파라미터) (만큼) (탐색) (_))

HNSW의 검색은 greedy traversal 방식으로 이루어집니다.

[HNSW 탐색 과정]

입력: 쿼리 벡터 q, 파라미터 ef (탐색 범위)

1. 최상위 레이어에서 시작 (엔트리 포인트)
   - 랜덤하게 선택된 노드에서 시작
   - 또는 사전에 지정된 엔트리 포인트

2. 현재 레이어에서 q와 가장 가까운 노드 탐색
   while (현재 레이어에서 개선 가능한 이웃이 있으면):
       가장 가까운 이웃 = ef개의 후보 중 q와 거리 가장 가까운 노드
       if (가장 가까운 이웃 != 현재 노드):
           현재 노드 = 가장 가까운 이웃
       else:
           break

3. 더 하위 레이어가 있으면:
   - 현재 노드에서 하위 레이어로 이동
   - 2번 과정 반복

4. 최하위 레이어에서 ef개의最近的 이웃 반환

시간 복잡도:

탐색 시간 = Σ(1/M)^i  (i = 0부터 레이어 수-1)
          ≈ 1 / (1 - 1/M)  (상수)

→ O(log N)  (N = 전체 벡터 수)

Ⅳ. HNSW 파라미터와 성능 조절

# HNSWlib (Python) 예시
import hnswlib

# 인덱스 초기화
dim = 1536  # 벡터 차원
max_elements = 1000000  # 벡터 수

index = hnswlib.Index(space='cosine', dim=dim)
index.init_index(max_elements=max_elements, ef_construction=200, M=16)

# 벡터 추가
index.add_items(vectors, ids=range(len(vectors)))

# 검색
index.set_ef(100)  # 검색 시 탐색 범위
labels, distances = index.knn_query(query_vectors, k=10)

핵심 파라미터:

┌─────────────────────────────────────────────────────────────────┐
│                    HNSW 파라미터 설명                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  M (Maximum connections per node):                              │
│  - 각 노드가 상위 레이어에서 가질 수 있는 최대 연결 수              │
│  - 기본값: 16                                                   │
│  - ↑ M: 정확도↑, 메모리↑, 빌드 시간↑                              │
│  - ↓ M: 정확도↓, 메모리↓, 빌드 시간↓                              │
│                                                                 │
│  efConstruction (Build time search breadth):                     │
│  - 인덱스 빌드 시 각 레이어에서 탐색할 후보 수                       │
│  - 기본값: 200                                                   │
│  - ↑ efConstruction: 정확도↑, 빌드 시간↑                           │
│  - ↓ efConstruction: 정확도↓, 빌드 시간↓                          │
│                                                                 │
│  efSearch (Query time search breadth):                           │
│  - 검색 시 최하위 레이어에서 탐색할 후보 수                          │
│  - 기본값: M과 efConstruction에 따라 결정                          │
│  - ↑ efSearch: 정확도↑, 검색 시간↑                                │
│  - ↓ efSearch: 정확도↓, 검색 시간↓                                │
│                                                                 │
│  권장 조합:                                                      │
│  - 빠른 응답 (추천 시스템): M=8, efConstruction=100, ef=50        │
│  - 균형: M=16, efConstruction=200, ef=100                        │
│  - 고정확도 (RAG): M=32, efConstruction=400, ef=200             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Ⅴ. HNSW의 메모리 관리와 📢 비유

메모리 사용량:

# 메모리估算
# 대략: (M * 2 * bytes_per_float + overhead) * num_vectors

# 예시:
M = 16
dim = 1536
num_vectors = 10_000_000
bytes_per_float = 4

memory_per_vector = M * 2 * dim * bytes_per_float  # 양방향 연결
memory = memory_per_vector * num_vectors
# = 16 * 2 * 1536 * 4 * 10,000,000
# = 약 2.5 GB

메모리 최적화 기법:

  • _PQ (Product Quantization): 벡터를 저차원으로 압축하여 메모리 절감
  • 자연적 계층 활용: 자주アクセス되는データを上層에配置

📢 섹션 요약 비유: HNSW는 **"대형 도시에서 가장近い 맛집을 찾는 것에 비유"**할 수 있습니다. (전체) (도시간) (道路) (네트워크) (에서) ('가장 가까운 맛집') () (찾는) (것은) (거의) (불가능) (합니다) () (KNN의) (수백만) (계산) (문제) ()。(HNSW는) (지도를) (3단계) (계층으로) (나누어) (探します: (1단계) (_ Province/시_) (단위) (에서) (검색) () (2단계) (区/군) (단위) (에서) (검색) () (3단계) (개별) (맛집) (에서) (세밀한) (비교) () (거의) (정확한) (최 가까운) (맛집) () () () (안에) (발견) (하는) () () (같습니다) ())。(다만) (가끔) (_ Province_) (단계) (에서) (잘못된) () () (선택) (하면) (최종) (결과가) (100%) (정확하지) (않을) () (있는) (것처럼) (HNSW도) (근사값) () (반환하는) (것을) (감안) (해야) (합니다) ())。