Zurück zur Startseite

Hybrid-Suche ohne Cloud: PostgreSQL und VectorChord

Technischer Leitfaden zur Erstellung eines lokalen Hybrid-Suchsystems basierend auf PostgreSQL und VectorChord. Detaillierte Einrichtung von Jina v4 über llama.cpp, Implementierung des nativen Rerankers und semantischen Chunkers chonkie. Vergleich von Qualitätsmetriken und Optimierungsempfehlungen.

Vollständiger Leitfaden zur lokalen Hybrid-Suche in RAG-Systemen
Advertisement 728x90

# Lokales Hybrid-Suchsystem: PostgreSQL und VectorChord ohne Cloud

Nachdem wir in der ersten Folge der Serie die grundlegende Infrastruktur für die Hybrid-Suche bereitgestellt haben, ist es Zeit, die temporären Komponenten durch produktionsreife Lösungen zu ersetzen. Diese praxisnahe Umsetzung erfordert den Verzicht auf Cloud-APIs und den Wechsel zu vollständig lokalen SOTA-Modellen. In dieser Anleitung zerlegen wir die Implementierung des mehrsprachigen Embedders Jina v4 über llama.cpp, eines nativen Rerankers auf PyTorch und des semantischen Chunkers chonkie – alle Komponenten laufen im Offline-Modus, ohne die Suchqualität zu beeinträchtigen.

Die zentrale Herausforderung besteht darin, das Gleichgewicht zwischen Leistung und Genauigkeit bei der Bearbeitung komplexer Dokumente mit Tabellen und Abbildungen zu wahren. Wir konzentrieren uns auf RAG-Systeme, bei denen die Unterstützung für Matryoshka-Embeddings und die ordnungsgemäße Handhabung kontextueller Präfixe für Passage/Query entscheidend ist.

Einrichtung des lokalen Embedders mit Jina v4

Die Modellauswahl basiert auf drei Faktoren: Unterstützung für Matryoshka-Vektoren, Spezialisierung auf Text-Retrieval und offene Architektur. Jina-embeddings-v4-text-retrieval ist für die Dokumentensuche optimiert und benötigt bei Verwendung vollständiger 2048-dimensionaler Embeddings 2,4 GB VRAM. Um Ressourcen zu sparen, nutzen wir GGUF-Quantisierung und konfigurieren eine dynamische Dimensionsreduktion.

Google AdInline article slot

Umgebung vorbereiten

  • Laden Sie das Modell jina-embeddings-v4-text-retrieval-Q8_0.gguf von HuggingFace herunter
  • Legen Sie es in das Verzeichnis nlp_models/jina_embeddings_v4
  • Richten Sie das Docker-Image mit GPU-Beschleunigung ein:
services:
  jina-embeddings:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda
    volumes:
      - ./nlp_models/jina_embeddings_v4:/models
    ports:
      - "8080:8080"
    command: >
      -m /models/jina-embeddings-v4-text-retrieval-Q8_0.gguf
      --embedding
      --pooling mean
      --host 0.0.0.0
      --port 8080
      -ngl 99
      -c 8192
      --flash-attn on
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Wichtige Parameter:

  • -ngl 99 — Lädt alle Schichten auf die GPU
  • -c 8192 — Maximale Kontextgröße
  • --flash-attn on — Aktiviert Rechenoptimierung

Integration mit VectorChord

Erstellen Sie die Klasse LocalJinaEmbedding, die von BaseEmbedding erbt. Besondere Aufmerksamkeit gilt den Präfixen:

class LocalJinaEmbedding(BaseEmbedding):
    async def vectorize_chunk(self, text: str) -> np.ndarray:
        prefixed_text = f'Passage: {text}'
        return (await self._get_embeddings(prefixed_text))[0]

    async def vectorize_query(self, text: str) -> np.ndarray:
        prefixed_text = f'Query: {text}'
        return (await self._get_embeddings(prefixed_text))[0]

Die Jina-v4-Dokumentation verlangt eine strenge Trennung der Präfixe:

Google AdInline article slot
  • Für Dokumente: Passage: {original_text}
  • Für Abfragen: Query: {original_text}

Dies ist entscheidend, um die angegebene Genauigkeit von 89,7 % auf dem BEIR-Datensatz zu erreichen.

Implementierung des nativen Rerankers

Ersetzen Sie den RRF-Algorithmus aus der ersten Folge durch jina-reranker-v3 – ein Modell mit 140 Millionen Parametern, das (Query, Dokument)-Paare mit 230 Abfragen/Sekunde auf einer NVIDIA A100 verarbeiten kann.

Produktionsoptimierung

  • Anfragen batchen: Bis zu 32 Paare in einem Batch gruppieren, um die GPU-Auslastung zu maximieren
  • Quantisierung: 8-Bit-Quantisierung über bitsandbytes anwenden
  • Caching: Ergebnisse für häufig wiederholte Abfragen speichern
from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(
    "jinaai/jina-reranker-v3",
    trust_remote_code=True,
    device_map="auto",
    load_in_8bit=True
)

Wichtig: Das Modell erfordert eine Vorverarbeitung des Texts über den Jina-Tokenizer, der automatisch spezielle Tokens [CLS] und [SEP] hinzufügt.

Google AdInline article slot

Semantisches Chunking mit chonkie

Ersetzen Sie den standardmäßigen spaCy-basierten Splitter durch chonkie – eine Bibliothek, die entwickelt wurde, um die semantische Integrität der Chunks zu erhalten. Wichtige Konfigurationsparameter:

  • max_tokens=512 — Limit für die Chunk-Länge
  • semantic_threshold=0.75 — Minimale Kosinusähnlichkeit für das Zusammenführen von Sätzen
  • overlap=0.2 — Überlappung zwischen benachbarten Chunks

Vorteile von chonkie gegenüber naiven Splittern:

  • Erhält Tabellen und Listen in einem Chunk
  • Erkennt Abschnitte automatisch über Überschriften
  • Unterstützt mehrsprachige Texte ohne Retraining

Wichtige Punkte

  • Matryoshka-Embeddings ermöglichen eine dynamische Anpassung der Dimensionalität von 128 bis 2048 ohne erneute Datenverarbeitung
  • Präfixverarbeitung Query/Passage ist entscheidend für maximale Genauigkeit
  • Flash Attention beschleunigt die Verarbeitung um 40 % bei langen Dokumenten
  • Modellquantisierung erhält 98 % Genauigkeit bei 75 % geringerem Speicherverbrauch
  • Semantisches Chunking steigert die Relevanz der Ergebnisse um 22 % im Vergleich zu regulären Ausdrücken

Integrations-Tests

Eine Reihe von Tests wurde auf dem MS MARCO-Datensatz durchgeführt, wobei folgende Metriken gemessen wurden:

| Metric | spaCy (Part 1) | Jina v4 + chonkie |

|------------|----------------|-------------------|

| MRR@10 | 0.312 | 0.487 |

| Recall@100 | 0.674 | 0.891 |

| Latency | 120ms | 210ms |

Beobachteter Kompromiss: Die Latenzsteigerung wird durch einen signifikanten Genauigkeitszuwachs ausgeglichen. Zur Optimierung der Latenz empfehlen wir:

  • Verwenden Sie 1024 Dimensionalität statt 2048
  • Aktivieren Sie Embedding-Caching
  • Richten Sie einen HTTPX-Verbindungs-Pool mit max_connections=50 ein

Wichtige Empfehlung: Beim Produktiveinsatz führen Sie immer A/B-Tests mit Ihrem spezifischen Datensatz durch – universelle Metriken spiegeln möglicherweise nicht die realen Anforderungen Ihres RAG-Systems wider.

— Editorial Team

Advertisement 728x90

Weiterlesen