Переранжирование документов с использованием Ollama и модели Qwen3 Reranker - на языке Go
Реализуете RAG? Вот несколько фрагментов кода на Go - 2...
Поскольку стандартный Ollama не имеет прямого API для переупорядочивания, вам нужно реализовать переупорядочивание с использованием Qwen3 Reranker на GO, генерируя векторы представлений для пар запрос-документ и оценивая их.
На прошлой неделе я немного переупорядочил текстовые документы с использованием Ollama и Qwen3 Embedding model - на Go.
Сегодня попробую некоторые модели Qwen3 Reranker.
Доступно довольно большое количество новых Qwen3 Embedding & Reranker Models на Ollama, я использую среднюю - dengcao/Qwen3-Reranker-4B:Q5_K_M
Тестовый запуск: TL;DR
Это работает, и довольно быстро, не очень стандартный способ, но всё равно:
$ ./rnk ./example_query.txt ./example_docs
Используется модель векторного представления: dengcao/Qwen3-Embedding-4B:Q5_K_M
Базовый URL Ollama: http://localhost:11434
Обработка файла запроса: ./example_query.txt, целевая директория: ./example_docs
Запрос: Что такое искусственный интеллект и как работает машинное обучение?
Найдено 7 документов
Извлечение вектора запроса...
Обработка документов...
=== УПОРЯДОЧЕНИЕ ПО ПОДОБИЮ ===
1. example_docs/ai_introduction.txt (Оценка: 0.451)
2. example_docs/machine_learning.md (Оценка: 0.388)
3. example_docs/qwen3-reranking-models.md (Оценка: 0.354)
4. example_docs/ollama-parallelism.md (Оценка: 0.338)
5. example_docs/ollama-reranking-models.md (Оценка: 0.318)
6. example_docs/programming_basics.txt (Оценка: 0.296)
7. example_docs/setup.log (Оценка: 0.282)
Обработано 7 документов за 2.023с (в среднем: 0.289с на документ)
Переупорядочивание документов с использованием модели переупорядочивания...
Реализация переупорядочивания с использованием подхода cross-encoder с dengcao/Qwen3-Reranker-4B:Q5_K_M
=== УПОРЯДОЧЕНИЕ С ИСПОЛЬЗОВАНИЕМ МОДЕЛИ ПЕРЕУПОРЯДОЧИВАНИЯ ===
1. example_docs/ai_introduction.txt (Оценка: 0.343)
2. example_docs/machine_learning.md (Оценка: 0.340)
3. example_docs/programming_basics.txt (Оценка: 0.320)
4. example_docs/setup.log (Оценка: 0.313)
5. example_docs/ollama-parallelism.md (Оценка: 0.313)
6. example_docs/qwen3-reranking-models.md (Оценка: 0.312)
7. example_docs/ollama-reranking-models.md (Оценка: 0.306)
Обработано 7 документов за 1.984с (в среднем: 0.283с на документ)
Код модели переупорядочивания на Go для вызова Ollama
Беру большую часть кода из поста Reranking text documents with Ollama using Embedding...
и добавляю эти фрагменты:
В конце функции runRnk():
startTime = time.Now()
// переупорядочивание с использованием модели переупорядочивания
fmt.Println("Переупорядочивание документов с использованием модели переупорядочивания...")
// 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("Ошибка переупорядочивания документов: %v", err)
}
fmt.Println("\n=== УПОРЯДОЧЕНИЕ С ИСПОЛЬЗОВАНИЕМ МОДЕЛИ ПЕРЕУПОРЯДОЧИВАНИЯ ===")
for i, doc := range rerankedDocs {
fmt.Printf("%d. %s (Оценка: %.3f)\n", i+1, doc.Path, doc.Score)
}
totalTime = time.Since(startTime)
avgTimePerDoc = totalTime / time.Duration(len(rerankedDocs))
fmt.Printf("\nОбработано %d документов за %.3fs (в среднем: %.3fs на документ)\n",
len(rerankedDocs), totalTime.Seconds(), avgTimePerDoc.Seconds())
Затем добавить несколько дополнительных функций:
func rerankDocuments(validDocs []Document, query, rerankingModel, ollamaBaseURL string) ([]Document, error) {
// Поскольку стандартный Ollama не имеет прямого API для переупорядочивания, мы реализуем
// переупорядочивание, генерируя векторы представлений для пар запрос-документ и оценивая их
fmt.Println("Реализация переупорядочивания с использованием подхода cross-encoder с", rerankingModel)
rerankedDocs := make([]Document, len(validDocs))
copy(rerankedDocs, validDocs)
for i, doc := range validDocs {
// Создание промпта для переупорядочивания, объединяющего запрос и документ
rerankPrompt := fmt.Sprintf("Query: %s\n\nDocument: %s\n\nRelevance:", query, doc.Content)
// Получение вектора представления для объединенного промпта
embedding, err := getEmbedding(rerankPrompt, rerankingModel, ollamaBaseURL)
if err != nil {
fmt.Printf("Предупреждение: Не удалось получить вектор переупорядочивания для документа %d: %v\n", i, err)
// Заглушка с нейтральной оценкой
rerankedDocs[i].Score = 0.5
continue
}
// Использование величины вектора представления в качестве оценки релевантности
// (Это упрощённый подход - на практике вы бы использовали обученную модель переупорядочивания)
score := calculateRelevanceScore(embedding)
rerankedDocs[i].Score = score
// fmt.Printf("Документ %d переупорядочен с оценкой: %.4f\n", i, score)
}
// Сортировка документов по оценке переупорядочивания (по убыванию)
sort.Slice(rerankedDocs, func(i, j int) bool {
return rerankedDocs[i].Score > rerankedDocs[j].Score
})
return rerankedDocs, nil
}
func calculateRelevanceScore(embedding []float64) float64 {
// Простая оценка на основе величины вектора и положительных значений
var sumPositive, sumTotal float64
for _, val := range embedding {
sumTotal += val * val
if val > 0 {
sumPositive += val
}
}
if sumTotal == 0 {
return 0
}
// Нормализация и комбинация величины с смещением в сторону положительных значений
magnitude := math.Sqrt(sumTotal) / float64(len(embedding))
positiveRatio := sumPositive / float64(len(embedding))
return (magnitude + positiveRatio) / 2
}
Не забудьте импортировать немного math
import (
"math"
)
Теперь соберите его
go build -o rnk
и теперь запустите этот простой прототип RAG-модели переупорядочивания
./rnk ./example_query.txt ./example_docs
Полезные ссылки
- Переупорядочивание текстовых документов с использованием Ollama и Qwen3 Embedding model - на Go
- Qwen3 Embedding & Reranker Models на Ollama: Состояние искусства в производительности
- Справочник Ollama
- Установка и настройка расположения моделей Ollama
- Как Ollama обрабатывает параллельные запросы
- Тест: Как Ollama использует производительность ядра Intel CPU и эффективные ядра