Przestawianie kolejności dokumentów za pomocą Ollama i modelu Qwen3 Reranker - w języku Go
Wdrażanie RAG? Oto kilka fragmentów kodu w Go - 2...
Ponieważ standardowy Ollama nie ma bezpośredniego interfejsu API do ponownego rangowania, musisz zaimplementować ponowne rangowanie przy użyciu Qwen3 Reranker w GO generując embeddingi dla par zapytań i dokumentów oraz oceniając je.
Tydzień temu zrobiłem trochę ponownego rangowania dokumentów tekstowych z użyciem Ollama i modelu Qwen3 Embedding - w Go.
Dzisiaj spróbuję niektórych modeli Qwen3 Reranker.
Jest dość duża liczba nowych modeli Qwen3 Embedding & Reranker na Ollama dostępnych, używam średniego - dengcao/Qwen3-Reranker-4B:Q5_K_M
Uruchomienie testu: TL;DR
Działa, i dość szybko, nie jest to bardzo standardowy sposób, ale nadal:
$ ./rnk ./example_query.txt ./example_docs
Używany model embedding: dengcao/Qwen3-Embedding-4B:Q5_K_M
Podstawowy adres URL Ollama: http://localhost:11434
Przetwarzanie pliku zapytania: ./example_query.txt, katalog docelowy: ./example_docs
Zapytanie: Co to jest sztuczna inteligencja i jak działa uczenie maszynowe?
Znaleziono 7 dokumentów
Wyodrębnianie embeddingu zapytania...
Przetwarzanie dokumentów...
=== RANGOWANIE NA PODSTAWIE PODOBIEŃSTWA ===
1. example_docs/ai_introduction.txt (Wynik: 0,451)
2. example_docs/machine_learning.md (Wynik: 0,388)
3. example_docs/qwen3-reranking-models.md (Wynik: 0,354)
4. example_docs/ollama-parallelism.md (Wynik: 0,338)
5. example_docs/ollama-reranking-models.md (Wynik: 0,318)
6. example_docs/programming_basics.txt (Wynik: 0,296)
7. example_docs/setup.log (Wynik: 0,282)
Przetworzono 7 dokumentów w 2,023s (średnio: 0,289s na dokument)
Ponowne rangowanie dokumentów przy użyciu modelu rerankera...
Implementowanie ponownego rangowania przy użyciu podejścia cross-encoder z `dengcao/Qwen3-Reranker-4B:Q5_K_M`
=== RANGOWANIE Z UŻYCIEM RERANKERA ===
1. example_docs/ai_introduction.txt (Wynik: 0,343)
2. example_docs/machine_learning.md (Wynik: 0,340)
3. example_docs/programming_basics.txt (Wynik: 0,320)
4. example_docs/setup.log (Wynik: 0,313)
5. example_docs/ollama-parallelism.md (Wynik: 0,313)
6. example_docs/qwen3-reranking-models.md (Wynik: 0,312)
7. example_docs/ollama-reranking-models.md (Wynik: 0,306)
Przetworzono 7 dokumentów w 1,984s (średnio: 0,283s na dokument)
Kod w Go do wywoływania Ollama przez rerankera
Weź większość kodu z wpisu ponowne rangowanie dokumentów tekstowych z użyciem Ollama i modelu embedding...
i dodaj te fragmenty:
Na końcu funkcji runRnk():
startTime = time.Now()
// ponowne rangowanie przy użyciu modelu rerankera
fmt.Println("Ponowne rangowanie dokumentów przy użyciu modelu rerankera...")
// 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("Błąd ponownego rangowania dokumentów: %v", err)
}
fmt.Println("\n=== RANGOWANIE Z UŻYCIEM RERANKERA ===")
for i, doc := range rerankedDocs {
fmt.Printf("%d. %s (Wynik: %.3f)\n", i+1, doc.Path, doc.Score)
}
totalTime = time.Since(startTime)
avgTimePerDoc = totalTime / time.Duration(len(rerankedDocs))
fmt.Printf("\nPrzetworzono %d dokumentów w %.3fs (średnio: %.3fs na dokument)\n",
len(rerankedDocs), totalTime.Seconds(), avgTimePerDoc.Seconds())
Następnie dodaj kilka dodatkowych funkcji:
func rerankDocuments(validDocs []Document, query, rerankingModel, ollamaBaseURL string) ([]Document, error) {
// Ponieważ standardowy Ollama nie ma bezpośredniego interfejsu API do ponownego rangowania, zaimplementujemy
// ponowne rangowanie generując embeddingi dla par zapytań i dokumentów oraz oceniając je
fmt.Println("Implementowanie ponownego rangowania przy użyciu podejścia cross-encoder z", rerankingModel)
rerankedDocs := make([]Document, len(validDocs))
copy(rerankedDocs, validDocs)
for i, doc := range validDocs {
// Utwórz wskazówkę do ponownego rangowania łącząc zapytanie i dokument
rerankPrompt := fmt.Sprintf("Zapytanie: %s\n\nDokument: %s\n\nZnaczenie:", query, doc.Content)
// Pobierz embedding dla łącznej wskazówki
embedding, err := getEmbedding(rerankPrompt, rerankingModel, ollamaBaseURL)
if err != nil {
fmt.Printf("Ostrzeżenie: Nie udało się uzyskać embeddingu do ponownego rangowania dla dokumentu %d: %v\n", i, err)
// Ustawienie neutralnego wyniku jako domyślne
rerankedDocs[i].Score = 0.5
continue
}
// Użyj wielkości embeddingu jako wyniku znaczenia
// (To uproszczone podejście - w praktyce użyłbyś wytrenowanego rerankera)
score := calculateRelevanceScore(embedding)
rerankedDocs[i].Score = score
// fmt.Printf("Dokument %d ponownie zrangaowany z wynikiem: %.4f\n", i, score)
}
// Posortuj dokumenty według wyniku ponownego rangowania (malejąco)
sort.Slice(rerankedDocs, func(i, j int) bool {
return rerankedDocs[i].Score > rerankedDocs[j].Score
})
return rerankedDocs, nil
}
func calculateRelevanceScore(embedding []float64) float64 {
// Proste ocenianie oparte na wielkości embeddingu i dodatnich wartościach
var sumPositive, sumTotal float64
for _, val := range embedding {
sumTotal += val * val
if val > 0 {
sumPositive += val
}
}
if sumTotal == 0 {
return 0
}
// Normalizacja i połączenie wielkości z dodatnim biasem
magnitude := math.Sqrt(sumTotal) / float64(len(embedding))
positiveRatio := sumPositive / float64(len(embedding))
return (magnitude + positiveRatio) / 2
}
Nie zapomnij zaimportować trochę matematyki
import (
"math"
)
Teraz skompilujmy to
go build -o rnk
i teraz uruchommy ten prosty prototyp technologii RAG rerankera
./rnk ./example_query.txt ./example_docs
Przydatne linki
- Ponowne rangowanie dokumentów tekstowych z użyciem Ollama i modelu Qwen3 Embedding - w Go
- Modeli Qwen3 Embedding & Reranker na Ollama: Stan technologii
- Szybki przewodnik po Ollama
- Zainstaluj i skonfiguruj lokalizację modeli Ollama
- Jak Ollama obsługuje żądania równoległe
- Test: Jak Ollama wykorzystuje wydajność procesora Intel i efektywne jądra