ओलमा और क्वेन-3 एमबेडिंग मॉडल का उपयोग करके टेक्स्ट दस्तावेजों को पुनर्अभिषेक - गो भाषा में

आपका प्रश्न

Page content

यह छोटा सा
पुनर्विन्यास Go केode उदाहरण में Ollama को रनिंग (Reranking) करके एम्बेडिंग (embeddings) जनरेट करने का प्रयोग हुआ है
क्वेरी (query) और प्रत्येक कैंडिडेट दस्तावेज़ (candidate document) के लिए,
फिर कोसाइन समानता (cosine similarity) के आधार पर अवरोधकता (descending order) में दर्जीन (sorting) करना है।

हमने पहले भी समान गतिविधि कोशिश की - पुनर्विन्यास (Reranking) में एम्बेडिंग मॉडल परंतु तब Python में था, LLM के साथ अलग थे और लगभग एक वर्ष पहले।

विभिन्न ऊंचाइयों की llama - Ollama के साथ पुनर्विन्यास (Reranking) करता है

मुख्य बातें (TL;DR)

परिणाम बहुत अच्छे दिख रहे हैं, प्रति दस्तावेज़ 0.128 सेकंड की गति
प्रश्न (Question) को एक दस्तावेज़ (doc) के रूप में गिना जाता है।
और संगणना और प्रिंटिंग (Sorting and printing) भी इस सांख्यिकी (stat) के भाग में शामिल हैं।

LLM स्मृति उपभोग (memory consumption): कुछ गीबास (GB) होने पर भी, सड्डा डिस्क (sdd) पर (ollama ls) मॉडल का आकार 3GB से कम है:

dengcao/Qwen3-Embedding-4B:Q5_K_M           7e8c9ad6885b    2.9 GB

GPU VRAM में यह (निश्चयात्मक) अधिक होता है: 5.5GB। (ollama ps)

NAME                                 ID              SIZE  
dengcao/Qwen3-Embedding-4B:Q5_K_M    7e8c9ad6885b    5.5 GB 

अगर आपके पास 8GB GPU है - ठीक होगा।

Ollama के साथ एम्बेडिंग (Embeddings) के साथ पुनर्विन्यास (Reranking) का परीक्षण - उदाहरण आउटपुट

सभी तीन परीक्षण मामलों में, dengcao/Qwen3-Embedding-4B:Q5_K_M Ollama मॉडल का उपयोग करके एम्बेडिंग से पुनर्विन्यास (reranking) करना बहुत अच्छा था!
खुद से देखिए।

हमने 7 फ़ाइलें हैं, जो कुछ पाठ (texts) युक्त हैं, जो उनके नाम से क्या कहती हैं:

  • ai_introduction.txt
  • machine_learning.md
  • qwen3-reranking-models.md
  • ollama-parallelism.md
  • ollama-reranking-models.md
  • programming_basics.txt
  • setup.log

परीक्षण चलाएं:

पुनर्विन्यास (Reranking) परीक्षण: क्या artificial intelligence है और machine learning कैसे काम करता है?

./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 0.899s (avg: 0.128s per document)

Ollama के साथ पुनर्विन्यास (Reranking) कैसे करते हैं?

./rnk example_query3.txt example_docs/

Using embedding model: dengcao/Qwen3-Embedding-4B:Q5_K_M  
Ollama base URL: http://localhost:11434  
Processing query file: example_query3.txt, target directory: example_docs/  
Query: How can we do the reranking of the document with ollama?  
Found 7 documents  
Extracting query embedding...  
Processing documents...

=== RANKING BY SIMILARITY ===
1. example_docs/ollama-reranking-models.md (Score: 0.552)  
2. example_docs/ollama-parallelism.md (Score: 0.525)  
3. example_docs/qwen3-reranking-models.md (Score: 0.524)  
4. example_docs/ai_introduction.txt (Score: 0.369)  
5. example_docs/machine_learning.md (Score: 0.346)  
6. example_docs/programming_basics.txt (Score: 0.316)  
7. example_docs/setup.log (Score: 0.279)

Processed 7 documents in 0.882s (avg: 0.126s per document)

Ollama के साथ पुनर्विन्यास (Reranking) का दूसरा परीक्षण

./rnk example_query2.txt example_docs/

Using embedding model: dengcao/Qwen3-Embedding-4B:Q5_K_M  
Ollama base URL: http://localhost:11434  
Processing query file: example_query2.txt, target directory: example_docs/  
Query: How ollama handles parallel requests?  
Found 7 documents  
Extracting query embedding...  
Processing documents...

=== RANKING BY SIMILARITY ===
1. example_docs/ollama-parallelism.md (Score: 0.557)  
2. example_docs/qwen3-reranking-models.md (Score: 0.532)  
3. example_docs/ollama-reranking-models.md (Score: 0.498)  
4. example_docs/ai_introduction.txt (Score: 0.366)  
5. example_docs/machine_learning.md (Score: 0.332)  
6. example_docs/programming_basics.txt (Score: 0.307)  
7. example_docs/setup.log (Score: 0.257)

Processed 7 documents in 0.858s (avg: 0.123s per document)

Go स्रोत कोड

इसे एक फ़ोल्डर में रखिए और इस प्रकार संकलित कीजिए:

go build -o rnk

किसी भी मनोरुचि (entertaining) या व्यापारिक (commercial) प्रयोग में इसे उपयोग कर सकते हैं।
या फिर GitHub पर अपलोड करना भी चाहिए - MIT लाइसेन्स (license)।

main.go

package main

import (
	"fmt"
	"log"
	"os"
	"sort"
	"time"

	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "rnk [query-file] [target-directory]",
	Short: "RAG निर्माण प्रणाली Ollama के साथ",
	Long:  "एक सरल RAG प्रणाली जो Ollama का उपयोग करके एम्बेडिंग (embeddings) निकालती है और दस्तावेज़ों को पुनर्विन्यास (Reranking) करती है",
	Args:  cobra.ExactArgs(2),
	Run:   runRnk,
}

var (
	embeddingModel string
	ollamaBaseURL  string
)

func init() {
	rootCmd.Flags().StringVarP(&embeddingModel, "model", "m", "dengcao/Qwen3-Embedding-4B:Q5_K_M", "उपयोग किए जाने वाला एम्बेडिंग मॉडल")
	rootCmd.Flags().StringVarP(&ollamaBaseURL, "url", "u", "http://localhost:11434", "Ollama का base URL")
}

func main() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func runRnk(cmd *cobra.Command, args []string) {
	queryFile := args[0]
	targetDir := args[1]

	startTime := time.Now()

	fmt.Printf("Using embedding model: %s\n", embeddingModel)
	fmt.Printf("Ollama base URL: %s\n", ollamaBaseURL)
	fmt.Printf("Processing query file: %s, target directory: %s\n", queryFile, targetDir)

	// Query को फ़ाइल से पढ़ें
	query, err := readQueryFromFile(queryFile)
	if err != nil {
		log.Fatalf("Error reading query file: %v", err)
	}
	fmt.Printf("Query: %s\n", query)

	// target directory में सभी टेक्स्ट फ़ाइलों को पाया
	documents, err := findTextFiles(targetDir)
	if err != nil {
		log.Fatalf("Error finding text files: %v", err)
	}
	fmt.Printf("Found %d documents\n", len(documents))

	// Query के एम्बेडिंग (embeddings) को निकालें
	fmt.Println("Extracting query embedding...")
	queryEmbedding, err := getEmbedding(query, embeddingModel, ollamaBaseURL)
	if err != nil {
		log.Fatalf("Error getting query embedding: %v", err)
	}

	// दस्तावेज़ों की प्रक्रिया
	fmt.Println("Processing documents...")
	validDocs := make([]Document, 0)

	for _, doc := range documents {
		embedding, err := getEmbedding(doc.Content, embeddingModel, ollamaBaseURL)
		if err != nil {
			fmt.Printf("Warning: Failed to get embedding for %s: %v\n", doc.Path, err)
			continue
		}

		similarity := cosineSimilarity(queryEmbedding, embedding)
		doc.Score = similarity
		validDocs = append(validDocs, doc)
	}

	if len(validDocs) == 0 {
		log.Fatalf("No documents could be processed successfully")
	}

	// समानता (similarity) अंक पर आधारित दर्जीन (sorting) करें
	sort.Slice(validDocs, func(i, j int) bool {
		return validDocs[i].Score > validDocs[j].Score
	})

	// परिणामों को प्रदर्शित करें
	fmt.Println("\n=== RANKING BY SIMILARITY ===")
	for i, doc := range validDocs {
		fmt.Printf("%d. %s (Score: %.3f)\n", i+1, doc.Path, doc.Score)
	}

	totalTime := time.Since(startTime)
	avgTimePerDoc := totalTime / time.Duration(len(validDocs))

	fmt.Printf("\nProcessed %d documents in %.3fs (avg: %.3fs per document)\n",
		len(validDocs), totalTime.Seconds(), avgTimePerDoc.Seconds())
}

documents.go

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

func readQueryFromFile(filename string) (string, error) {
	content, err := os.ReadFile(filename)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(content)), nil
}

func findTextFiles(dir string) ([]Document, error) {
	var documents []Document

	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if !info.IsDir() && isTextFile(path) {
			content, err := os.ReadFile(path)
			if err != nil {
				fmt.Printf("Warning: Could not read file %s: %v\n", path, err)
				return nil
			}

			documents = append(documents, Document{
				Path:    path,
				Content: string(content),
			})
		}

		return nil
	})

	return documents, err
}

func isTextFile(filename string) bool {
	ext := strings.ToLower(filepath.Ext(filename))
	textExts := []string{".txt", ".md", ".rst", ".csv", ".json", ".xml", ".html", ".htm", ".log"}
	for _, textExt := range textExts {
		if ext == textExt {
			return true
		}
	}
	return false
}

embeddings.go

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func getEmbedding(text string, model string, ollamaBaseURL string) ([]float64, error) {
	req := OllamaEmbeddingRequest{
		Model:  model,
		Prompt: text,
	}

	jsonData, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}

	resp, err := http.Post(ollamaBaseURL+"/api/embeddings", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("ollama API error: %s", string(body))
	}

	var embeddingResp OllamaEmbeddingResponse
	if err := json.NewDecoder(resp.Body).Decode(&embeddingResp); err != nil {
		return nil, err
	}

	return embeddingResp.Embedding, nil
}

similarity.go

package main

func cosineSimilarity(a, b []float64) float64 {
	if len(a) != len(b) {
		return 0
	}

	var dotProduct, normA, normB float64

	for i := range a {
		dotProduct += a[i] * b[i]
		normA += a[i] * a[i]
		normB += b[i] * b[i]
	}

	if normA == 0 || normB == 0 {
		return 0
	}

	return dotProduct / (sqrt(normA) * sqrt(normB))
}

func sqrt(x float64) float64 {
	if x == 0 {
		return 0
	}
	z := x
	for i := 0; i < 10; i++ {
		z = (z + x/z) / 2
	}
	return z
}

types.go

package main

// OllamaEmbeddingRequest represents the request payload for Ollama embedding API  
type OllamaEmbeddingRequest struct {  
	Model  string `json:"model"`  
	Prompt string `json:"prompt"`  
}

// OllamaEmbeddingResponse represents the response from Ollama embedding API  
type OllamaEmbeddingResponse struct {  
	Embedding []float64 `json:"embedding"`  
}

// Document represents a document with its metadata  
type Document struct {  
	Path    string  
	Content string  
	Score   float64  
}