Reranking des documents avec Ollama et le modèle Qwen3 Reranker - en Go
Mise en œuvre de RAG ? Voici quelques extraits de code en Go - 2...
Comme Ollama standard ne dispose pas d’API de rerank directe, vous devrez implémenter le reranking avec Qwen3 Reranker en GO en générant des embeddings pour les paires de requêtes et de documents et en les notant.
La semaine dernière, j’ai fait un peu de Reranking de documents textuels avec Ollama et Qwen3 Embedding model - en Go.
Aujourd’hui, je vais essayer certains modèles Qwen3 Reranker.
Il existe un ensemble assez important de nouveaux Qwen3 Embedding & Reranker Models sur Ollama disponibles, j’utilise medium - dengcao/Qwen3-Reranker-4B:Q5_K_M
Le test Run: TL;DR
Ça marche, et assez rapide, pas très standard, mais tout de même :
$ ./rnk ./example_query.txt ./example_docs
Using embedding model: dengcao/Qwen3-Embedding-4B:Q5_K_M
Ollama base URL: http://localhost:11434
Processing query file: ./example_query.txt, target directory: ./example_docs
Query: What is artificial intelligence and how does machine learning work?
Found 7 documents
Extracting query embedding...
Processing documents...
=== RANKING BY SIMILARITY ===
1. example_docs/ai_introduction.txt (Score: 0.451)
2. example_docs/machine_learning.md (Score: 0.388)
3. example_docs/qwen3-reranking-models.md (Score: 0.354)
4. example_docs/ollama-parallelism.md (Score: 0.338)
5. example_docs/ollama-reranking-models.md (Score: 0.318)
6. example_docs/programming_basics.txt (Score: 0.296)
7. example_docs/setup.log (Score: 0.282)
Processed 7 documents in 2.023s (avg: 0.289s per document)
Reranking documents with reranker model...
Implementing reranking using cross-encoder approach with dengcao/Qwen3-Reranker-4B:Q5_K_M
=== RANKING WITH RERANKER ===
1. example_docs/ai_introduction.txt (Score: 0.343)
2. example_docs/machine_learning.md (Score: 0.340)
3. example_docs/programming_basics.txt (Score: 0.320)
4. example_docs/setup.log (Score: 0.313)
5. example_docs/ollama-parallelism.md (Score: 0.313)
6. example_docs/qwen3-reranking-models.md (Score: 0.312)
7. example_docs/ollama-reranking-models.md (Score: 0.306)
Processed 7 documents in 1.984s (avg: 0.283s per document)
Code de reranker en Go pour appeler Ollama
Prendre la plupart du code de l’article Reranking text documents with Ollama using Embedding...
et ajouter ces éléments :
À la fin de la fonction runRnk() :
startTime = time.Now()
// rerank using reranking model
fmt.Println("Reranking documents with reranker model...")
// 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("Error reranking documents: %v", err)
}
fmt.Println("\n=== RANKING WITH RERANKER ===")
for i, doc := range rerankedDocs {
fmt.Printf("%d. %s (Score: %.3f)\n", i+1, doc.Path, doc.Score)
}
totalTime = time.Since(startTime)
avgTimePerDoc = totalTime / time.Duration(len(rerankedDocs))
fmt.Printf("\nProcessed %d documents in %.3fs (avg: %.3fs per document)\n",
len(rerankedDocs), totalTime.Seconds(), avgTimePerDoc.Seconds())
Ensuite, ajouter quelques fonctions supplémentaires :
func rerankDocuments(validDocs []Document, query, rerankingModel, ollamaBaseURL string) ([]Document, error) {
// Comme Ollama standard ne dispose pas d'API de rerank directe, nous allons implémenter
// le reranking en générant des embeddings pour les paires de requêtes et de documents et en les notant
fmt.Println("Implementing reranking using cross-encoder approach with", rerankingModel)
rerankedDocs := make([]Document, len(validDocs))
copy(rerankedDocs, validDocs)
for i, doc := range validDocs {
// Créer un prompt pour le reranking en combinant la requête et le document
rerankPrompt := fmt.Sprintf("Query: %s\n\nDocument: %s\n\nRelevance:", query, doc.Content)
// Obtenir l'embedding pour le prompt combiné
embedding, err := getEmbedding(rerankPrompt, rerankingModel, ollamaBaseURL)
if err != nil {
fmt.Printf("Warning: Failed to get rerank embedding for document %d: %v\n", i, err)
// Fallback à une note neutre
rerankedDocs[i].Score = 0.5
continue
}
// Utiliser la magnitude de l'embedding comme note de pertinence
// (C'est une approche simplifiée - en pratique, vous utiliseriez un reranker entraîné)
score := calculateRelevanceScore(embedding)
rerankedDocs[i].Score = score
// fmt.Printf("Document %d reranked with score: %.4f\n", i, score)
}
// Trier les documents par note de reranking (décroissante)
sort.Slice(rerankedDocs, func(i, j int) bool {
return rerankedDocs[i].Score > rerankedDocs[j].Score
})
return rerankedDocs, nil
}
func calculateRelevanceScore(embedding []float64) float64 {
// Scoring simple basé sur la magnitude de l'embedding et les valeurs positives
var sumPositive, sumTotal float64
for _, val := range embedding {
sumTotal += val * val
if val > 0 {
sumPositive += val
}
}
if sumTotal == 0 {
return 0
}
// Normaliser et combiner la magnitude avec un biais positif
magnitude := math.Sqrt(sumTotal) / float64(len(embedding))
positiveRatio := sumPositive / float64(len(embedding))
return (magnitude + positiveRatio) / 2
}
N’oubliez pas d’importer un peu de math
import (
"math"
)
Maintenant, compilons-le
go build -o rnk
et maintenant, exécutons ce prototype simple de RAG reranker
./rnk ./example_query.txt ./example_docs
Liens utiles
- Reranking de documents textuels avec Ollama et Qwen3 Embedding model - en Go
- Qwen3 Embedding & Reranker Models sur Ollama: Performance d’avant-garde
- Feuille de rappel Ollama
- Installer et configurer l’emplacement des modèles Ollama
- Comment Ollama gère les requêtes parallèles
- Test : Comment Ollama utilise les performances du processeur Intel et les cœurs efficaces