How Hugging Face Inference Endpoints, Jobs, and Buckets Power Search on Papers with Code Hugging Face has built a hybrid search system for Papers with Code that combines PostgreSQL full-text search with pgvector dense embeddings, using reciprocal rank fusion (RRF) to merge results. The system maintains embeddings for more than 110,000 papers from arXiv and Daily Papers, powered by Hugging Face Jobs for offline corpus embedding, Storage Buckets for durable handoff, and Inference Endpoints for low-latency live queries. This architecture enables fast, accurate search for AI research, including fuzzy and navigational queries. Feature Extraction • 0.6B • Updated • 7.04M • 1.17k How Hugging Face Inference Endpoints, Jobs, and Buckets Power Search on Papers with Code Update on GitHub https://github.com/huggingface/blog/blob/main/pwc-search.md revival https://www.reddit.com/r/MachineLearning/comments/1tgmwqr/reviving paperswithcode by hugging face p/ of Papers with Code https://paperswithcode.co see also the announcement tweet https://x.com/NielsRogge/status/2056366395605078252 . Its goal is to make open AI research accessible and digestible, so that people can easily find the artifacts related to a paper, find state-of-the-art SOTA across the various domains of AI, share interesting research and build on top of each other's work. In other words, its goal is to power the wave of research that leads to the next Transformer https://paperswithcode.co/paper/1706.03762 . Of course, making AI research accessible requires a powerful search engine, so that humans and agents can quickly find relevant and related work, either through the website or the pwc search CLI command https://github.com/huggingface/pwc-cli , which agents can use via the Skill https://github.com/huggingface/pwc-cli/blob/main/standalone cli/SKILL.md . It's important to note that searching for research is not quite the same as searching for regular text. A useful paper search engine should find an exact title or arXiv identifier, but it should also understand a query such as “small language models for code generation” even when those words do not appear together in a paper. It needs to recognize that “the original BERT paper” is a navigational request, tolerate an incomplete title or typos, and still respond quickly when a model service is cold or temporarily unavailable. For Papers with Code https://paperswithcode.co , we built this as a hybrid search system. This is also based on our prior experience at ML6 http://ml6.eu/ , where we developed RAG https://paperswithcode.co/paper/2005.11401 -based systems for clients. It turned out that hybrid search typically outperforms keyword- and vector-based search systems, as it combines the best of both worlds see also this blog https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/azure-ai-search-outperforming-vector-search-with-hybrid-retrieval-and-reranking/3929167 for more info . Keyword search finds exact mentions, whereas vector search finds more fuzzy, semantically similar terms. Note that rerankers https://www.pinecone.io/learn/series/rag/rerankers/ also called cross-encoders can further improve the results, although they also come with additional overhead and latency. Papers with Code relies on a PostgreSQL database, hence its full-text search capabilities provide a fast lexical baseline. For dense embeddings, pgvector https://github.com/pgvector/pgvector is used to add semantic recall, and the reciprocal rank fusion RRF https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion algorithm combines the two. Three Hugging Face services are used for the dense embeddings: Hugging Face Jobs https://huggingface.co/docs/hub/jobs gives us burstable GPU compute for embedding the paper corpus. Hugging Face Storage Buckets https://huggingface.co/docs/hub/storage-buckets provides the durable handoff between our database, experiments, and Jobs. Hugging Face Inference Endpoints https://huggingface.co/docs/inference-endpoints/index serves low-latency embeddings for live queries and incremental updates. Today, the system maintains embeddings for more than 110,000 current papers sourced from arXiv https://arxiv.org/ and Daily Papers https://hf.co/papers . This post explains the architecture, the design decisions behind it, and the lessons we learned while taking it to production. TL;DR We deliberately split search into an offline corpus build and an online search service: The expensive, throughput-oriented work runs as Jobs. Durable artifacts live in a Bucket. Only the small query-embedding step sits on the request path, behind a protected Inference Endpoint, to power the online search. If that endpoint is cold, busy, or unhealthy, search immediately falls back to full-text retrieval. This separation makes the system both powerful and fast. Start with a strict embedding contract Embedding pipelines often fail in subtle ways: a model revision changes, query and document prompts are mixed up, vectors are truncated differently, or an updated abstract no longer matches its stored vector. We avoid this by treating the embedding format as a versioned API. Every paper is encoded as: normalized title + "\n\n" + normalized abstract For each vector generation, we record: - the model repository and exact revision; - the output dimension; - the input-format version; - whether the input is a query or a document; - the normalization method; - a content hash for the source title and abstract. Our production generation uses Qwen/Qwen3-Embedding-0.6B https://huggingface.co/Qwen/Qwen3-Embedding-0.6B , pinned to an exact revision, with 256-dimensional L2-normalized vectors. Note that newer embedding models like Qwen3 allow for 2 new features: - one can specify a dynamic embedding size , which allows to trade-off quality with speed/storage costs. Qwen models call this "MRL" which is short for Matryoshka Representation Learning https://paperswithcode.co/paper/2205.13147 . You can learn all about it here https://huggingface.co/blog/matryoshka . We chose an embedding size of 256 to make the search fast. - one can provide an instruction prompt . Qwen embedding models support a document prompt which we use to embed the papers and live searches use their query prompt to embed the user query . This contract follows an embedding from export, through GPU inference, into PostgreSQL, and finally into online retrieval. Jobs turn a database snapshot into a vector corpus Full-corpus embedding is a classic batch workload. It needs a GPU for a relatively short period, benefits from high throughput, and should not consume resources between runs. Hugging Face Jobs https://huggingface.co/docs/huggingface hub/guides/jobs fits that shape well: a Job is defined by a command, a hardware flavor https://huggingface.co/docs/hub/main/en/jobs-pricing pricing , and optionally a Docker image, and can run uv https://docs.astral.sh/uv/ scripts with their dependencies declared inline. Our corpus build starts by exporting the latest version of every paper from a repeatable-read PostgreSQL snapshot. The exporter streams rows rather than loading the catalog into memory, writes bounded JSONL shards, and creates a manifest containing row counts and SHA-256 checksums. We sync that immutable run directory to a private Storage Bucket https://huggingface.co/docs/hub/storage-buckets and mount the Bucket directly using hf-mount https://github.com/huggingface/hf-mount into an l4x1 Job an NVIDIA L4 GPU, which has 24GB of VRAM . From the worker's perspective it is simply a filesystem: hf jobs uv run \ --flavor l4x1 \ --timeout 6h \ --volume hf://buckets/OWNER/pwc-paper-embeddings:/bucket \ embed papers job.py \ --input /bucket/runs/RUN ID/input \ --output /bucket/runs/RUN ID/output \ --model Qwen/Qwen3-Embedding-0.6B \ --revision MODEL REVISION \ --dimensions 256 \ --allow-matryoshka The worker: - verifies the input manifest and every shard checksum; - loads the pinned model revision; - sorts texts by length to reduce padding; - calls encode document in batches as noted in the model card https://huggingface.co/Qwen/Qwen3-Embedding-0.6B ; - reduces the batch size automatically if the GPU runs out of memory; - truncates the Matryoshka representation https://huggingface.co/blog/matryoshka to 256 dimensions and normalizes it; - writes float16 Parquet shards atomically; and - records throughput, package versions, hardware, peak VRAM, row counts, and output checksums. Each completed shard has its own marker, so a restarted Job can skip verified work. This is useful for a large corpus: retrying should just resume work rather than overwriting existing embeddings. In our 5,000-paper pilot, the Qwen Job encoded about 75 papers per second at 1024 dimensions on an L4 GPU. The same pass could be deterministically materialized at 512 and 256 dimensions, so we could compare the storage and retrieval trade-offs without paying for more inference. Buckets are the connective tissue Storage Buckets https://huggingface.co/docs/hub/storage-buckets are mutable, S3-like object storage on the Hub, optimized for AI workloads. They can be accessed through hf://buckets/... paths and mounted https://github.com/huggingface/hf-mount read-write in Jobs without building a separate storage integration. For us, the Bucket is more than a place to put vectors. It is the boundary between three systems with different lifecycles: - the production database exports source records; - ephemeral Jobs consume those records and produce vectors; - the importer validates the results before touching the search index. We organize artifacts under immutable run prefixes: runs/