In che modo la ricerca HNSW sacrifica memoria per ottenere il richiamo in un database vettoriale locale?

Eva Wong è la Technical Writer e smanettatrice residente di ZimaSpace. Una geek da sempre con una passione per homelab e software open-source, si specializza nel tradurre concetti tecnici complessi in guide accessibili e pratiche. Eva crede che l'auto-ospitare debba essere divertente, non intimidatorio. Attraverso i suoi tutorial, dà potere alla comunità di demistificare le configurazioni hardware, dalla costruzione del loro primo NAS al dominio dei container Docker.

HNSW scambia memoria con il richiamo memorizzando un grafo navigabile di vicini, la cui connettività e ampiezza di ricerca determinano quanto a fondo le query esplorano i vettori vicini.

Un database vettoriale locale può contenere embedding di documenti domestici, testo OCR, metadati fotografici, manuali, trascrizioni e record applicativi. La ricerca a forza bruta confronta la query con ogni vettore, mentre HNSW cerca di raggiungere lo stesso vicinato utile attraversando un grafo a livelli. Questa scorciatoia è veloce perché il database memorizza in anticipo una struttura aggiuntiva del grafo, e la sua accuratezza dipende da quanto è connesso il grafo e da quanti candidati una query può esplorare.

HNSW aggiunge un grafo di prossimità a livelli attorno ai vettori memorizzati

Ogni vettore diventa un nodo collegato a vicini selezionati. Un piccolo sottoinsieme di nodi compare anche nei livelli superiori, creando percorsi a lunga distanza che aiutano la ricerca a spostarsi rapidamente verso la regione in cui è probabile che si trovino i vettori più vicini.

Un grafo di prossimità multilivello fornisce a HNSW percorsi generali nei livelli superiori e una navigazione dei vicini progressivamente più dettagliata verso la parte inferiore della gerarchia.

Questi archi memorizzati costituiscono il primo compromesso in termini di memoria. A differenza di un array piatto di vettori, l’indice conserva una topologia che deve rimanere disponibile durante l’attraversamento.

La gerarchia riduce la quantità della raccolta visitata da una query normale, ma è approssimata: il percorso può non raggiungere un vero vicino quando il grafo o il budget di ricerca non espongono il percorso corretto.

Il parametro M utilizza più memoria del grafo per creare più percorsi

Le implementazioni HNSW espongono un parametro di connettività comunemente chiamato `m` o `M`. Aumentarlo consente ai nodi di mantenere più collegamenti ai vicini, creando percorsi alternativi attraverso le aree dense o irregolari dello spazio vettoriale.

Un valore m di HNSW più alto memorizza più connessioni ai vicini per nodo, migliorando in genere le opzioni di navigazione e il richiamo, ma aumentando la memoria del grafo e il lavoro di costruzione.

L’aumento della memoria deriva dagli archi del grafo e dalle strutture di indice associate, non dal fatto che i valori degli embedding originali diventino più grandi. Con milioni di vettori, pochi collegamenti aggiuntivi per nodo si accumulano nell’intera raccolta. Ridurre `m` può rendere più gestibile un server domestico con memoria limitata, ma un grafo eccessivamente rado offre alla ricerca meno modi per aggirare i vicoli ciechi locali e può ridurre il richiamo.

Ef Construction utilizza più lavoro di costruzione per migliorare il grafo stesso

La qualità del grafo viene influenzata anche durante l’inserimento dei vettori. `ef_construct` controlla quanto è ampio il vicinato di candidati esaminato dal costruttore prima di scegliere i collegamenti per un nuovo nodo.

Utilizzare efConstruction come parametro per la qualità della costruzione consente alla costruzione dell’indice di esaminare un vicinato di candidati più ampio prima di scegliere gli archi, migliorando la qualità del grafo al costo di un maggiore lavoro durante la costruzione.

Questo costo viene sostenuto durante la costruzione o la ricostruzione, anziché a ogni query. Per un corpus privato che cambia lentamente, dedicare più tempo alla costruzione può essere accettabile se migliora la qualità della ricerca senza aumentare permanentemente la precisione dei vettori.

Tuttavia, il lavoro di costruzione non può compensare indefinitamente un grafo gravemente sottodimensionato. `m`, l’ampiezza della costruzione, la distribuzione dei dati e la cronologia degli inserimenti interagiscono tra loro.

Ef Search utilizza lavoro durante la query anziché memoria permanente del grafo

Durante la query, HNSW mantiene una frontiera di candidati ed esplora i nodi promettenti del grafo. Un parametro comunemente chiamato `ef`, `ef_search` o `hnsw_ef` controlla quanti candidati rimangono sotto esame durante l’attraversamento.

Aumentare l’ampiezza dell’esplorazione della query consente a una richiesta di esaminare più candidati del grafo prima di stabilire i risultati più vicini, aumentando generalmente il richiamo ma anche la latenza della query.

A differenza di `m`, un valore `ef` di query più alto non richiede che ogni nodo memorizzato conservi più archi permanenti. Il suo costo principale si manifesta in ulteriori calcoli delle distanze, accessi alla memoria e latenza per quella richiesta. Questa distinzione offre a un server domestico due manopole diverse: la connettività del grafo determina l’impronta permanente dell’indice, mentre l’ampiezza della query può essere aumentata solo per le ricerche difficili che giustificano il lavoro aggiuntivo.

La compressione dei vettori non elimina il costo del grafo HNSW

La quantizzazione degli embedding può rendere ogni vettore memorizzato molto più piccolo, ma HNSW ha comunque bisogno delle relazioni tra i vicini. L’indice complessivo contiene quindi almeno due componenti principali in termini di memoria: i dati dei vettori e la topologia del grafo.

Anche quando i valori dei vettori sono compressi, la quantizzazione non riduce i collegamenti del grafo; HNSW ha comunque bisogno della topologia, degli ID e delle strutture correlate attorno a quei vettori.

Per questo, un rapporto di compressione dei vettori pari a 4× o superiore non produce automaticamente una riduzione equivalente della memoria complessiva di HNSW. Restano gli archi del grafo, gli ID degli oggetti, i metadati, l’overhead dell’allocatore e le cache.

Su un piccolo server domestico, misura l’intero insieme residente della raccolta invece di stimare la RAM basandoti soltanto sulle dimensioni dei vettori.

Il richiamo deve essere misurato rispetto ai vicini esatti, non dedotto dalle impostazioni

Valori più alti di `m` ed `ef` spostano generalmente il sistema verso un richiamo migliore, ma nessun valore dei parametri garantisce un’accuratezza fissa per ogni modello di embedding, dimensione del corpus o distribuzione dei documenti.

Il costo della memoria dei grafi HNSW in più raccolte RAG si somma quando diverse raccolte private rimangono attive insieme a modelli locali, indici dei metadati, cache e altri servizi del server domestico.

Crea un insieme rappresentativo di query e confronta i risultati approssimati con una scansione esatta su un campione gestibile. Tieni traccia di richiamo, latenza, RAM dell’indice, tempo di costruzione e impatto delle richieste concorrenti. Il compromesso pratico di HNSW non è quindi “più RAM equivale sempre a una ricerca migliore”. Consiste nello scegliere una connettività del grafo e un’ampiezza di esplorazione delle query sufficienti a raggiungere il richiamo misurato senza sottrarre risorse al resto dello stack di IA domestica.

Hub Tecnologico e AI

Altro da leggere

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.