Files
gott/Plans/SENTENCEPIECE_TOKENIZER.md
T
MelekiandClaude Opus 4.6 3f2baa1639 feat: AutoContext-Suche grundlegend verbessern + Embedding-Debug-Tool
Hybrid-Suche (Vektor + FTS5-Keyword), Recency-Boost, Query-Erweiterung
(letzte 2-3 User-Messages), Chunk-Overlapping, FullText-Speicherung,
konfigurierbares Embedding-Modell/MaxSeqLen, deduplizierter AutoContext-
Code (Streaming + CLI shared), Admin-Diagnose-Seite mit Re-Embed-Funktion.
Threshold von 0.45 auf 0.35 gesenkt (Hybrid-Suche ist präziser).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 08:50:41 +02:00

4.0 KiB
Raw Blame History

Plan: SentencePiece-Tokenizer-Support für multilinguales Embedding-Modell

Ziel

paraphrase-multilingual-MiniLM-L12-v2 als alternatives Embedding-Modell ermöglichen, indem der EmbeddingService neben WordPiece (BERT) auch SentencePiece (XLM-RoBERTa) Tokenizer unterstützt.

Hintergrund

  • Aktuell: all-MiniLM-L6-v2 (BERT, WordPiece, vocab.txt, 384 Dims)
  • Ziel-Modell: paraphrase-multilingual-MiniLM-L12-v2 (XLM-RoBERTa, SentencePiece, sentencepiece.bpe.model, 384 Dims)
  • Problem: Unser Tokenizer ist hardcoded auf WordPiece – Special Tokens ([CLS]/[SEP]), token_type_ids, vocab.txt

Unterschiede zwischen den Tokenizern

Aspekt WordPiece (BERT) SentencePiece (XLM-R)
Vocab-Datei vocab.txt sentencepiece.bpe.model
Special Tokens [CLS]=101, [SEP]=102, [PAD]=0 <s>=0, </s>=2, <pad>=1
token_type_ids Required (alle 0) Nicht verwendet
Subword-Prefix ## ▁ (U+2581)
Vocab-Groesse ~30.522 ~250.002

Schritte

Schritt 1: NuGet-Paket hinzufuegen

  • Microsoft.ML.Tokenizers.SentencePieceBpe oder SentencePieceSharp evaluieren
  • Kriterien: .NET 10 Kompatibilitaet, kein native-Dependency-Problem auf Linux, Lizenz
  • Paket zu gott.csproj hinzufuegen

Schritt 2: Tokenizer-Abstraktion in EmbeddingService.cs

  • Interface oder Strategie-Pattern: ITextTokenizer mit Methode Tokenize(string text, int maxLen) -> (long[] inputIds, long[] attentionMask, long[]? tokenTypeIds)
  • WordPieceTokenizer – bestehende Logik extrahieren (Zeilen 127-161)
  • SentencePieceTokenizer – neue Implementierung
  • Constructor-Logik: Wenn vocab.txt existiert -> WordPiece; wenn sentencepiece.bpe.model existiert -> SentencePiece
  • Property TokenizerType fuer Debug/Logging

Schritt 3: ONNX-Session Input anpassen

  • WordPiece: 3 Inputs (input_ids, attention_mask, token_type_ids)
  • SentencePiece: 2 Inputs (input_ids, attention_mask) – kein token_type_ids
  • GenerateEmbedding() muss dynamisch die richtigen Inputs erstellen basierend auf Tokenizer-Typ
  • ONNX Input-Names aus dem Modell lesen statt hardcoded (robuster)

Schritt 4: Special Token IDs konfigurierbar machen

  • [CLS]/[SEP] IDs vs. <s>/</s> IDs
  • Am besten aus special_tokens_map.json oder tokenizer_config.json lesen, falls vorhanden
  • Fallback: Hardcoded Mapping pro Tokenizer-Typ

Schritt 5: Modell-Dateien bereitstellen

  • Von HuggingFace herunterladen:
    • model.onnx (ONNX-Export des Modells)
    • sentencepiece.bpe.model
  • Ablegen in data/models/paraphrase-multilingual-MiniLM-L12-v2/
  • Server-Setting EmbeddingModelDir auf den neuen Ordner setzen

Schritt 6: Re-Embed-Kompatibilitaet

  • Dimensionen sind identisch (384) -> Keine DB-Schema-Aenderung noetig
  • Re-Embed-Endpoint muss weiterhin funktionieren
  • Beim Modell-Wechsel: Alle Embeddings muessen neu berechnet werden (altes Modell-Vektoren sind inkompatibel mit neuem Modell)
  • Warnung im Admin-UI wenn Modell gewechselt wurde aber Re-Embed noch nicht gelaufen ist

Schritt 7: Tests & Verifikation

  • Embedding-Debug-Page nutzen: Gleiche Queries mit altem vs. neuem Modell vergleichen
  • Testcases:
    • Deutsche Query -> deutsche Messages ("weisst du was zum thema autocontext")
    • Englische Query -> englische Messages ("skills")
    • Gemischt -> gemischte Messages ("otter karten")
    • Pruefen ob Scores sich verbessern (besonders fuer deutsche Queries)

Betroffene Dateien

  1. gott.csproj – NuGet-Paket
  2. Services/EmbeddingService.cs – Tokenizer-Abstraktion, SentencePiece-Support
  3. wwwroot/js/embedding-debug.js – ggf. Anzeige des aktiven Modells/Tokenizers

Risiken

  • SentencePiece NuGet auf Linux: Native Dependencies koennten Probleme machen -> vorher testen
  • Re-Embed Dauer: 14k Messages mit 256 Tokens -> je nach CPU 5-30 Minuten
  • Dimensionen-Mismatch: Falls ein zukuenftiges Modell andere Dims hat -> DB-Migration noetig (aktuell nicht, beide 384)

Aufwand

  • Geschaetzt: ~2-3 Stunden Implementierung
  • Groesster Block: Tokenizer-Abstraktion sauber bauen