Riordinare i documenti con Ollama e modello Qwen3 Reranker - in Go
L'implementazione di RAG? Ecco alcuni frammenti di codice in Go - 2...
Poiché l’Ollama standard non dispone di un’API di reranking diretta, sarà necessario implementare reranking utilizzando Qwen3 Reranker in GO generando gli embedding per le coppie query-documento e valutandoli.
La settimana scorsa ho fatto un po’ di Reranking di documenti testuali con Ollama e Qwen3 Embedding model - in Go.
Oggi proverò alcuni modelli Qwen3 Reranker.
Esiste un insieme abbastanza ampio di nuovi Qwen3 Embedding & Reranker Models su Ollama disponibili, ne uso uno medio - dengcao/Qwen3-Reranker-4B:Q5_K_M
Esecuzione del test: TL;DR
Funziona, e piuttosto veloce, non è un modo molto standard, ma comunque:
$ ./rnk ./example_query.txt ./example_docs
Utilizzo del modello di embedding: dengcao/Qwen3-Embedding-4B:Q5_K_M
URL base di Ollama: http://localhost:11434
Elaborazione del file query: ./example_query.txt, cartella target: ./example_docs
Query: Cosa è l'intelligenza artificiale e come funziona l'apprendimento automatico?
Trovati 7 documenti
Estrazione dell'embedding della query...
Elaborazione dei documenti...
=== RANKING PER SIMILARITÀ ===
1. example_docs/ai_introduction.txt (Punteggio: 0.451)
2. example_docs/machine_learning.md (Punteggio: 0.388)
3. example_docs/qwen3-reranking-models.md (Punteggio: 0.354)
4. example_docs/ollama-parallelism.md (Punteggio: 0.338)
5. example_docs/ollama-reranking-models.md (Punteggio: 0.318)
6. example_docs/programming_basics.txt (Punteggio: 0.296)
7. example_docs/setup.log (Punteggio: 0.282)
Elaborati 7 documenti in 2.023s (media: 0.289s per documento)
Reranking dei documenti con modello reranker...
Implementazione del reranking utilizzando un approccio cross-encoder con dengcao/Qwen3-Reranker-4B:Q5_K_M
=== RANKING CON RERANKER ===
1. example_docs/ai_introduction.txt (Punteggio: 0.343)
2. example_docs/machine_learning.md (Punteggio: 0.340)
3. example_docs/programming_basics.txt (Punteggio: 0.320)
4. example_docs/setup.log (Punteggio: 0.313)
5. example_docs/ollama-parallelism.md (Punteggio: 0.313)
6. example_docs/qwen3-reranking-models.md (Punteggio: 0.312)
7. example_docs/ollama-reranking-models.md (Punteggio: 0.306)
Elaborati 7 documenti in 1.984s (media: 0.283s per documento)
Codice in Go per chiamare Ollama
Prendere gran parte del codice dal post Reranking di documenti testuali con Ollama utilizzando Embedding...
e aggiungere questi elementi:
Alla fine della funzione runRnk():
startTime = time.Now()
// rerank utilizzando il modello reranker
fmt.Println("Reranking dei documenti con modello reranker...")
// rerankingModel := "dengcao/Qwen3-Reranker-0.6B:F16"
rerankingModel := "dengcao/Qwen3-Reranker-4B:Q5_K_M"
rerankedDocs, err := rerankDocuments(validDocs, query, rerankingModel, ollamaBaseURL)
if err != nil {
log.Fatalf("Errore nel reranking dei documenti: %v", err)
}
fmt.Println("\n=== RANKING CON RERANKER ===")
for i, doc := range rerankedDocs {
fmt.Printf("%d. %s (Punteggio: %.3f)\n", i+1, doc.Path, doc.Score)
}
totalTime = time.Since(startTime)
avgTimePerDoc = totalTime / time.Duration(len(rerankedDocs))
fmt.Printf("\nElaborati %d documenti in %.3fs (media: %.3fs per documento)\n",
len(rerankedDocs), totalTime.Seconds(), avgTimePerDoc.Seconds())
Poi aggiungere un paio di funzioni aggiuntive:
func rerankDocuments(validDocs []Document, query, rerankingModel, ollamaBaseURL string) ([]Document, error) {
// Poiché l'Ollama standard non dispone di un'API di reranking diretta, implementeremo
// il reranking generando gli embedding per le coppie query-documento e valutandoli
fmt.Println("Implementazione del reranking utilizzando un approccio cross-encoder con", rerankingModel)
rerankedDocs := make([]Document, len(validDocs))
copy(rerankedDocs, validDocs)
for i, doc := range validDocs {
// Creare un prompt per il reranking combinando query e documento
rerankPrompt := fmt.Sprintf("Query: %s\n\nDocumento: %s\n\nRilevanza:", query, doc.Content)
// Ottenere l'embedding per il prompt combinato
embedding, err := getEmbedding(rerankPrompt, rerankingModel, ollamaBaseURL)
if err != nil {
fmt.Printf("Avviso: Impossibile ottenere l'embedding per il reranking del documento %d: %v\n", i, err)
// Valore di fallback per un punteggio neutrale
rerankedDocs[i].Score = 0.5
continue
}
// Utilizzare la magnitudo dell'embedding come punteggio di rilevanza
// (Questo è un approccio semplificato - in pratica si utilizzerebbe un reranker addestrato)
score := calculateRelevanceScore(embedding)
rerankedDocs[i].Score = score
// fmt.Printf("Documento %d reranked con punteggio: %.4f\n", i, score)
}
// Ordinare i documenti per punteggio di reranking (decrescente)
sort.Slice(rerankedDocs, func(i, j int) bool {
return rerankedDocs[i].Score > rerankedDocs[j].Score
})
return rerankedDocs, nil
}
func calculateRelevanceScore(embedding []float64) float64 {
// Punteggio semplice basato sulla magnitudo dell'embedding e sui valori positivi
var sumPositive, sumTotal float64
for _, val := range embedding {
sumTotal += val * val
if val > 0 {
sumPositive += val
}
}
if sumTotal == 0 {
return 0
}
// Normalizzazione e combinazione della magnitudo con un bias positivo
magnitude := math.Sqrt(sumTotal) / float64(len(embedding))
positiveRatio := sumPositive / float64(len(embedding))
return (magnitude + positiveRatio) / 2
}
Non dimenticare di importare un po’ di math
import (
"math"
)
Ora compiliamo
go build -o rnk
e ora eseguiamo questo semplice prototipo di RAG reranker
./rnk ./example_query.txt ./example_docs
Link utili
- Reranking di documenti testuali con Ollama e Qwen3 Embedding model - in Go
- Qwen3 Embedding & Reranker Models su Ollama: Prestazioni all’avanguardia
- Ollama cheatsheet
- Installazione e configurazione della posizione dei modelli Ollama
- Come Ollama gestisce le richieste parallele
- Test: Come Ollama utilizza le prestazioni del processore Intel e i core efficienti