Hugging Face Inference Endpoints, Jobs, 그리고 Buckets가 Papers with Code의 검색 기능을
요약
본 글은 Papers with Code의 강력한 논문 검색 기능을 구현한 아키텍처를 설명합니다. 오프라인 코퍼스 구축, 온라인 하이브리드 검색 서비스, 그리고 Inference Endpoint를 분리하여 시스템의 안정성과 속도를 확보했습니다. 또한, 임베딩 파이프라인 실패 방지를 위해 버전 관리되는 API와 상세 메타데이터 기록을 강조합니다.
핵심 포인트
- 검색 기능을 오프라인 코퍼스 구축과 온라인 검색으로 분리하여 성능 및 안정성 확보
- 임베딩 형식은 'normalized title + abstract'로 표준화하고, 모든 벡터 생성 과정을 추적 관리
- Qwen/Qwen3-Embedding 모델을 사용하며, 동적 임베딩 크기(MRL)와 명령어 프롬프트 기능을 활용함
- 시스템의 안정성을 위해 Inference Endpoint 실패 시 전체 텍스트 검색으로 폴백하는 구조를 채택
물론, AI 연구를 접근 가능하게 만들려면 강력한 검색 엔진이 필요합니다. 그래야 사람이든 에이전트든 웹사이트나 Skill을 통해 에이전트가 사용할 수 있는 pwc search CLI 명령어를 통해 관련성 있고 연관된 작업을 빠르게 찾을 수 있기 때문입니다.
연구를 검색하는 것은 일반 텍스트를 검색하는 것과는 조금 다릅니다. 유용한 논문 검색 엔진은 정확한 제목이나 arXiv 식별자를 찾아야 하지만,
오늘날 시스템은 arXiv와 Daily Papers에서 가져온 110,000개 이상의 현재 논문에 대한 임베딩을 유지합니다. 이 글에서는 해당 아키텍처, 그 배경에 있는 설계 결정, 그리고 이를 프로덕션 환경으로 구현하면서 배운 교훈들을 설명합니다.
저희는 검색 기능을 오프라인 코퍼스 구축과 온라인 검색 서비스로 의도적으로 분리했습니다:

비용이 많이 들고 처리량(throughput) 중심의 작업은 Jobs로 실행됩니다. 영구적인 아티팩트는 Bucket에 보관됩니다. 요청 경로상에는 작은 쿼리 임베딩 단계만 보호된 Inference Endpoint 뒤에 위치하여 온라인 검색을 구동합니다. 만약 해당 엔드포인트가 콜드하거나, 바쁘거나, 건강하지 않으면, 검색은 즉시 전체 텍스트 검색으로 폴백(fallback)됩니다. 이러한 분리는 시스템을 강력하면서도 빠르게 만듭니다.
임베딩 파이프라인은 종종 미묘한 방식으로 실패합니다: 모델 개정판이 바뀌거나, 쿼리와 문서 프롬프트가 뒤섞이거나, 벡터가 다르게 잘리거나, 업데이트된 초록이 저장된 벡터와 더 이상 일치하지 않는 경우가 있습니다.
저희는 임베딩 형식을 버전 관리되는 API로 취급함으로써 이를 방지합니다. 모든 논문은 다음 형식으로 인코딩됩니다:
normalized title + "\n\n" + normalized abstract
각 벡터 생성마다 저희는 다음 사항들을 기록합니다:
- 모델 레포지토리와 정확한 개정판;
- 출력 차원(output dimension);
- 입력 형식 버전(input-format version);
- 입력이 쿼리인지 문서인지 여부;
- 정규화 방법(normalization method);
- 소스 제목과 초록에 대한 콘텐츠 해시(content hash).
저희의 프로덕션 생성은 정확한 개정판으로 고정된 Qwen/Qwen3-Embedding-0.6B를 사용하며, 256차원의 L2 정규화 벡터를 사용합니다. 저희는 임베딩 모델을 비교하는 표준 벤치마크인 MTEB 리더보드(leaderboard)의 도움을 받아 이 모델을 선택했습니다. 참고로 Qwen3와 같은 새로운 임베딩 모델은 2가지 새로운 기능을 허용합니다:
- **동적 임베딩 크기(dynamic embedding size)**를 지정할 수 있어 품질과 속도/저장 비용 간의 균형을 맞출 수 있습니다. Qwen 모델은 이를 'MRL'이라고 부르며, 이는 Matryoshka Representation Learning의 약자입니다. 자세한 내용은 여기에서 확인할 수 있습니다. 저희는 검색 속도를 높이기 위해 임베딩 크기를 256으로 선택했습니다. - **명령어 프롬프트(instruction prompt)**를 제공할 수 있습니다. Qwen 임베딩 모델은 논문을 임베드하는 데 사용되는
document프롬프트와 사용자 질의를 임베드하는 라이브 검색에 사용하는query프롬프트를 지원합니다.
이 과정은 임베딩 내보내기(embedding from export)를 거쳐 GPU 추론을 통해 PostgreSQL로, 그리고 최종적으로 온라인 검색으로 이어집니다.
전체 코퍼스 임베딩(Full-corpus embedding)은 전형적인 배치 작업 부하입니다. 비교적 짧은 시간 동안 GPU가 필요하며, 높은 처리량(high throughput)의 이점을 누릴 수 있고, 실행 간에 리소스를 소모해서는 안 됩니다. Hugging Face Jobs는 이러한 형태에 잘 맞습니다: Job은 명령어, 하드웨어 유형(hardware flavor), 그리고 선택적으로 Docker 이미지를 지정하여 정의되며, 인라인으로 의존성을 선언한 uv 스크립트를 실행할 수 있습니다.
저희 코퍼스 빌드는 반복 가능하게 읽을 수 있는 PostgreSQL 스냅샷에서 모든 논문의 최신 버전을 내보내는 것부터 시작합니다. 이 익스포터는 카탈로그를 메모리에 로드하는 대신 행(row) 단위로 스트리밍하고, 경계가 지정된 JSONL 샤드를 작성하며, 행 개수와 SHA-256 체크섬을 포함하는 매니페스트를 생성합니다.
저희는 이 불변의 실행 디렉터리를 비공개 스토리지 버킷(Storage Bucket)으로 동기화하고, 해당 버킷을 직접 (hf-mount를 사용하여) l4x1 Job에 마운트합니다 (NVIDIA L4 GPU이며 24GB VRAM을 가집니다). 작업자(worker)의 관점에서는 단순히 파일 시스템일 뿐입니다:
hf jobs uv run \
--flavor l4x1 \
--timeout 6h \
...
작업자는 다음 작업을 수행합니다:
- 입력 매니페스트와 모든 샤드 체크섬을 확인합니다;
- 지정된 모델 버전을 로드합니다;
- 패딩(padding)을 줄이기 위해 텍스트를 길이별로 정렬합니다;
encode_document를 호출합니다.
배치(batches) 단위로 (모델 카드에 언급된 바와 같이); - GPU 메모리가 부족하면 배치 크기를 자동으로 줄입니다; - Matryoshka 표현을 256 차원으로 자르고 정규화합니다; - float16 Parquet 샤드를 원자적으로 작성하며; - 처리량(throughput), 패키지 버전, 하드웨어, 최대 VRAM, 행 수, 출력 체크섬을 기록합니다.
완료된 각 샤드는 자체 마커를 가지므로, 재시작된 Job은 검증된 작업을 건너뛸 수 있습니다. 이는 대규모 코퍼스에 유용합니다: 재시도할 때 기존 임베딩을 덮어쓰기보다는 작업이 중단된 지점부터 다시 시작해야 합니다.
5,000편의 논문을 대상으로 한 파일럿에서 Qwen Job은 L4 GPU를 사용하여 1024 차원에서 초당 약 75편의 논문을 인코딩했습니다. 동일한 작업을 512차원 및 256차원에서 결정론적으로 구현할 수 있었으므로, 추가적인 추론 비용을 지불하지 않고도 저장소와 검색 간의 트레이드오프를 비교할 수 있었습니다.
Storage Buckets는 Hub 상에 있는 가변적(mutable) S3 유사 객체 스토리지로, AI 워크로드에 최적화되어 있습니다. 이들은 hf://buckets/... 경로를 통해 접근할 수 있으며, 별도의 스토리지 통합을 구축하지 않고도 Job 내에서 읽기-쓰기로 마운트 할 수 있습니다.
저희에게 Bucket은 단순히 벡터를 저장하는 장소 그 이상입니다. 그것은 서로 다른 라이프사이클을 가진 세 시스템 사이의 경계이기 때문입니다:
- 프로덕션 데이터베이스가 소스 레코드를 내보냅니다;
- 일시적인(ephemeral) Job이 해당 레코드를 소비하여 벡터를 생성합니다;
- 임포터가 검색 인덱스에 적용하기 전에 결과를 검증합니다.
저희는 불변한 실행 접두사(immutable run prefixes) 아래에 아티팩트를 구성합니다:
runs/<run-id>/
├── input/
│ ├── manifest.json
...
Bucket 자체는 의도적으로 가변적이기 때문에, 불변성은 애플리케이션 수준의 규칙입니다: run ID는 절대 덮어쓰지 않으며, 모든 아티팩트는 매니페스트와 체크섬에 의해 보호됩니다.
이것은 저희에게 몇 가지 유용한 속성을 제공합니다:
재현성 (Reproducibility): 데이터베이스 생성 과정을 정확한 코퍼스 스냅샷, 모델 리비전, 그리고 아티팩트 세트로 추적할 수 있습니다.안전한 재시도 (Safe retries): 작업(Jobs)은 동일한 실행 접두사(run prefix)에서 완료된 샤드부터 재개될 수 있습니다.저렴한 실험 (Cheap experiments): 여러 모델이나 차원(dimensions)이 하나의 검증된 입력 스냅샷을 재사용할 수 있습니다.제어된 배포 (Controlled rollout): 생성을 가져오는 것이 즉시 활성화되지는 않습니다. 먼저 커버리지를 검증하고 인덱스를 구축합니다.간단한 롤백 (Simple rollback): 이전 생성과 그 아티팩트는 새로운 것이 안정적임이 입증될 때까지 사용 가능하게 유지됩니다.
임포터가 스키마, 체크섬, 차원, 정규화, 고유 논문 ID, 그리고 현재 콘텐츠 해시를 재확인한 후에야 벡터들을 PostgreSQL에 로드합니다. 그런 다음 새로운 생성을 위한 별도의 HNSW 인덱스를 구축하고, 모든 적격한 현재 논문을 커버할 때만 원자적으로(atomically) 활성화 상태로 표시합니다 (HNSW는 빠른 벡터 검색을 가능하게 하는 그래프 기반 알고리즘입니다).
배치 임베딩은 검색의 문서 측면을 해결합니다. 사용자 쿼리는 여전히 동일한 모델 계약(model contract)을 사용하여 요청 시점에 임베딩되어야 합니다.
저희는 고정된 모델을 Text Embeddings Inference (TEI) 기반의 인증된 추론 엔드포인트(Inference Endpoint)로 배포합니다. 이 엔드포인트는 쿼리 텍스트를 받아 모델의 query 프롬프트를 사용하여 정규화된 256차원 벡터를 반환합니다. vLLM이나 SGLang을 여기서 활용할 수도 있다는 점에 유의하십시오.

그러면 API가 활성화된 pgvector 생성에 대해 코사인 거리 검색(cosine-distance search)을 수행합니다:
SELECT paper_id,
embedding <=> CAST(:query_vector AS halfvec(256)) AS distance
FROM paper_embeddings
...
HNSW 인덱스는 이 조회를 빠르게 유지합니다. 5,000개 논문 규모의 파일럿 테스트에서, 256차원 Qwen 인덱스는 정확한 검색 대비 Recall@20에서 0.9955를 달성했으며, HNSW 조회 지연 시간은 p50 기준 1.31ms, p95 기준 2.21ms였습니다. 이 테이블과 인덱스는 1024차원 버전의 저장 공간 중 약 27%만을 사용하면서도 테스트에서 본질적으로 동일한 ANN 리콜을 유지했습니다.
엔드포인트는 최대 1개의 복제본(replica)으로 구성되며 유휴 상태일 때는 0까지 확장할 수 있습니다. 이는 비용 절감에 매우 유용합니다. 사용량이 없을 때 지불하는 비용이 없다는 의미이기 때문입니다. 하지만 이 점은 콜드 스타트(cold starts)를 예외적인 이벤트로 취급하기보다는 애플리케이션 설계의 일부로 포함해야 함을 의미하기도 합니다. 엔드포인트가 준비되고 트래픽을 처리하는 데 시간이 걸리기 때문입니다.
따라서 저희 쿼리 클라이언트는 의도적으로 엄격한 동작 방식을 갖추고 있습니다:
- 1초의 프로덕션 타임아웃(production timeout);
- 비차단 동시성 제한(non-blocking concurrency limit);
- 응답 차원, 유한성 및 노름(norm) 검증;
- 쿼리 기반의 짧은 캐시 및 임베딩 생성;
- 반복적인 실패 후 회로 차단기(circuit breaker);
- 로그에 원본 쿼리 텍스트를 남기지 않고 정규화된 지문(fingerprint)만 기록.
엔드포인트가 확장 중이거나, 타임아웃되거나, 잘못된 벡터를 반환하거나, 동시성을 사용할 수 없는 경우, 저희는 즉시 의미론적 브랜치(semantic branch) 처리를 건너뜁니다. 사용자는 신뢰할 수 없는 의존성(dependency)을 기다리는 대신 여전히 어휘적 검색 결과를 받게 됩니다.
Inference Endpoints는 매우 안정적으로 작동하며, 주요 분석 지표를 빠르게 확인할 수 있는 멋진 대시보드도 포함하고 있습니다.

모든 쿼리에 대해, 어휘적 브랜치는 가중치 기반의 PostgreSQL 전체 텍스트 검색을 사용하여 최대 50개의 후보를 검색합니다. 의미론적 브랜치는 pgvector에서 최대 50개의 후보를 검색합니다.
저희는 가중치 역순위 결합(weighted reciprocal rank fusion, RRF)을 사용하여 이들의 순위를 결합합니다:
RRF는 두 가지 다른 규모의 시스템에서 나온 점수(score)가 아닌 순위(rank)를 결합하기 때문에 간단하고 견고합니다. 기본적으로 논문이 어휘적 브랜치와 의미론적 브랜치 모두에 의해 높은 순위로 평가되면, 하이브리드 검색에서도 높은 순위를 차지할 가능성이 더 높습니다. 현재 저희는 동일한 브랜치 가중치를 사용하며 (k=60)을 적용합니다 (k는 RRF 알고리즘의 초매개변수(hyperparameter)인
• 정확한 제목과 arXiv ID는 상단에 유지됩니다.;
• 방법론 분류(method taxonomy)는 “원조 BERT 논문”과 같은 탐색 검색을 인식합니다.;
• 불완전한 제목이나 경계가 있는 철자 오류에는 보수적인 트라이그램 후보를 사용하며;
• 모호한 퍼지 매치(fuzzy match)의 경우 잘못된 결과를 강제하기보다는 포기하는 것이 좋습니다.
참고: 하이브리드 검색이 항상 최선의 선택은 아니므로, 저렴하고 빠른 기준선으로 키워드 검색부터 시작하는 것이 권장되며, 검색 품질에 합리적인 향상을 제공한다고 판단될 때만 시맨틱 및/또는 하이브리드 검색을 추가해야 합니다. Qwen3-Reranker와 같은 모델을 사용하여 키워드/시맨틱/하이브리드 검색 후 재순위 지정기(reranker)를 추가함으로써 검색을 더욱 개선할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Hugging Face Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기