Der Beitrag erläutert, wie sich multimodale Embedding- und Reranker-Modelle mit Sentence Transformers trainieren und finetunen lassen, und nutzt dafür Visual Document Retrieval (VDR) als durchgehendes Beispiel. Dabei wird Qwen/Qwen3-VL-Embedding-2B auf die Aufgabe angepasst, zu einer Textanfrage passende Dokumentseiten als Bilder zu finden, also inklusive Layout, Tabellen und Diagrammen.
Als zentrales Ergebnis nennt der Beitrag für das finetunte Modell tomaarsen/Qwen3-VL-Embedding-2B-vdr auf den eigenen Evaluationsdaten ein NDCG@10 von 0,947 gegenüber 0,888 für das Basismodell. Laut Beitrag übertrifft das Modell damit die getesteten bestehenden VDR-Modelle, darunter auch Modelle mit bis zu vierfacher Größe. Nach einem Training über eine Epoche wird für den Evaluationssatz mit 300 Queries und 1.500 Korpusdokumenten bei Cosine Similarity ein NDCG@10 von 0,947 angegeben.
Der Text begründet das Finetuning damit, dass allgemeine multimodale Embedding-Modelle zwar auf viele Sprachen und Aufgaben ausgelegt sind, dadurch aber nicht zwingend für eine konkrete Aufgabe optimal sind. Für VDR müsse ein Modell Dokumentlayouts, Diagramme, Tabellen und Text gemeinsam erfassen, was sich von anderen Bild-Text-Aufgaben unterscheide. Durch domänenspezifisches Finetuning sollen diese Muster besser gelernt werden.
Die Trainingspipeline entspricht laut Beitrag weitgehend dem textbasierten Training mit Sentence Transformers. Verwendet werden dieselben Komponenten: Modell, Datensatz, Loss Function, optionale Training Arguments, optionaler Evaluator und der Trainer. Der Unterschied besteht vor allem darin, dass Datensätze zusätzlich Bilder oder andere Modalitäten enthalten und der Prozessor des Modells die Vorverarbeitung der Bilder automatisch übernimmt.
Für das Beispiel wird ein bestehendes multimodales Embedding-Modell finetunt. Gezeigt wird Qwen/Qwen3-VL-Embedding-2B mit model_kwargs für Attention-Implementierung und numerische Präzision sowie processor_kwargs für Bildauflösungsgrenzen. Höhere max_pixels-Werte erhalten mehr Details, erhöhen aber den Speicherbedarf. Alternativ lässt sich laut Beitrag auch von einem Vision-Language-Model-Checkpoint wie Qwen/Qwen3-VL-2B ausgehen, wobei Sentence Transformers Architektur, Modalitäten, Forward-Methode und Pooling möglichst automatisch erkennt. Falls nötig, kann die Konfiguration in sentence_bert_config.json nachträglich angepasst werden.
Ergänzend beschreibt der Beitrag einen alternativen Aufbau mit dem Router-Modul. Dabei werden getrennte Encoder für Modalitäten wie Text und Bild kombiniert, etwa ein Text-Encoder auf Basis von all-MiniLM-L6-v2 und ein Bild-Encoder auf Basis von SigLIP. Da die Embedding-Räume solcher getrennten Encoder anfangs nicht ausgerichtet sind, ist Training notwendig, um sinnvolle cross-modale Ähnlichkeiten zu erhalten. Eine zusätzliche Dense-Projektion hilft dabei, verschiedene Encoder in einen gemeinsamen Raum abzubilden.
Als Trainingsdaten dient der Datensatz tomaarsen/llamaindex-vdr-en-train-preprocessed, eine vorverarbeitete englische Teilmenge von llamaindex/vdr-multilingual-train. Der Ursprungssatz umfasst laut Beitrag etwa 500.000 mehrsprachige Query-Bild-Beispiele aus öffentlich zugänglichen Internet-PDFs; die Queries wurden synthetisch mit VLMs wie gemini-1.5-pro und Qwen2-VL-72B erzeugt. Die vorverarbeitete Variante filtert auf 53.512 englische Beispiele und löst 4 von 16 ID-basierten Hard Negatives pro Beispiel in tatsächliche Dokument-Screenshots auf.
Für das Training wird die train-Konfiguration mit den ersten 10.000 Beispielen verwendet, für die Evaluation die nächsten 300 Beispiele aus eval. Im Training werden die Spalten query, image und negative_0 ausgewählt, also Tripel aus Anchor, Positivbeispiel und einem Hard Negative. Der Beitrag weist darauf hin, dass zusätzliche Hard Negatives das Trainingssignal vermutlich verbessern würden, aber auch Speicherbedarf und Trainingszeit erhöhen; im Beispiel bleibt es deshalb bei einem Negativbeispiel pro Query. Für die Evaluation werden dagegen alle vier Hard Negatives pro Query behalten, um den Retrieval-Korpus schwieriger zu machen.
Wie beim textbasierten Training muss das Datenformat zur gewählten Loss Function passen. Falls eine Loss Function ein Label verlangt, muss der Datensatz eine Spalte label oder score enthalten; alle übrigen Spalten gelten als Inputs. Bei multimodalen Datensätzen können diese Inputs Text, Bild, Audio, Video oder multimodale Dictionaries enthalten. Die Vorverarbeitung übernimmt der Data Collator automatisch über model.preprocess(), sodass weder manuelle Tokenisierung noch manuelle Bildverarbeitung nötig ist.
Für das Retrieval-Training verwendet der Beitrag CachedMultipleNegativesRankingLoss. Diese Loss Function arbeitet mit Query-Positiv-Paaren und optional zusätzlichen Hard-Negative-Spalten. Während des Trainings wird die Ähnlichkeit zwischen Query und Positivbeispiel erhöht und die Ähnlichkeit zu Negativbeispielen verringert. Negative stammen dabei sowohl explizit aus den Hard-Negative-Spalten als auch aus In-Batch-Negatives, also den Positiv- und Negativbeispielen anderer Samples im selben Batch. Mehr Negative pro Query stärken laut Beitrag das Trainingssignal, weshalb größere Batch-Größen die Trainingsqualität direkt verbessern können.
Die verwendete gecachte Variante nutzt Gradient Caching, um große effektive Batch-Größen auch bei begrenztem GPU-Speicher praktikabel zu machen. Für große multimodale Modelle wird mini_batch_size=1 empfohlen, um Out-of-Memory-Fehler in den gecachten Forward-Pässen zu vermeiden, ohne auf die Vorteile großer effektiver Batch-Größen zu verzichten.
Zusätzlich wird die Basis-Loss mit MatryoshkaLoss kombiniert. Dadurch soll das Modell Embeddings erzeugen, die auch bei Trunkierung auf kleinere Dimensionen brauchbar bleiben. Im Beispiel werden die Dimensionen 2048, 1536, 1024, 512, 256, 128 und 64 trainiert. Der Beitrag bezeichnet das als besonders nützlich für multimodale Modelle mit großen Embeddings, da bei der späteren Nutzung kleinere Embeddings schnellere Suche bei geringem Qualitätsverlust ermöglichen sollen.
Für das Beispiel-Finetuning werden unter anderem eine Epoche, eine Lernrate von 2e-5, ein warmup_ratio von 0,1, bf16=True und BatchSamplers.NO_DUPLICATES gesetzt. bfloat16 wird gegenüber float16 wegen besserer numerischer Stabilität bevorzugt. Das Sampling ohne Duplikate soll bei MultipleNegativesRankingLoss und der gecachten Variante sicherstellen, dass In-Batch-Negatives tatsächlich verschiedene Samples sind. Evaluation, Speichern und Logging werden jeweils in Abständen von 10 Prozent einer Epoche ausgeführt.
Zur Auswertung kommt der InformationRetrievalEvaluator zum Einsatz, der Metriken wie NDCG@10, MAP und Recall@k berechnet. Im Beispiel bestehen die Queries aus Text, der Korpus aus Bildern. Zusätzlich zu den positiven Dokument-Screenshots werden vier Hard Negatives pro Query mit versetzten IDs in den Korpus aufgenommen. Die Zuordnung relevanter Dokumente erfolgt über gleiche Indizes von Query und positivem Dokument. Für die Evaluation des großen VLM wird batch_size=1 verwendet, um Speicherprobleme zu vermeiden.
Der eigentliche Trainingsablauf mit SentenceTransformerTrainer bleibt laut Beitrag fast identisch zu einem textbasierten Skript. Unterschiede ergeben sich vor allem beim Laden des Modells mit model_kwargs und processor_kwargs, bei der Loss Function mit CachedMultipleNegativesRankingLoss und mini_batch_size=1 sowie beim Evaluator, der Text-Queries gegen einen Bild-Korpus prüft. Datensatzladen, Training Arguments und Trainer verhalten sich ansonsten gleich.
Für die Ergebnisse wird neben der Verbesserung von 0,888 auf 0,947 auch die Wirkung des Matryoshka-Trainings beschrieben. Bei Embeddings mit voller Größe von 2048 Dimensionen wird ein Peak von 0,948 genannt; bei 512 Dimensionen liege das Modell noch innerhalb von 0,3 Prozent des Peaks, und bei 64 Dimensionen würden noch mehr als 92 Prozent des Peak-Werts erhalten bleiben. Der Abstand zwischen 1024 und 2048 Dimensionen sei mit 0,946 gegenüber 0,948 klein, weshalb das gespeicherte Modell standardmäßig mit truncate_dim=1024 konfiguriert wurde. Dadurch erzeugt SentenceTransformer("tomaarsen/Qwen3-VL-Embedding-2B-vdr") standardmäßig 1024-dimensionale Embeddings; andere Dimensionen lassen sich beim Laden überschreiben.
Der Beitrag beschreibt außerdem das Finetuning multimodaler Cross Encoder für Reranking. Dafür werden dieselbe Trainingsinfrastruktur, aber CrossEncoderTrainer und Cross-Encoder-spezifische Loss Functions verwendet. Gezeigt wird ein vereinfachtes Beispiel auf Basis eines Doodles-Trainingsskripts, in dem ein Reranker Bilder und Bildunterschriften auf Übereinstimmung prüft.
Als mögliche Architekturen für multimodale Reranker nennt der Text zum einen Any-to-Any + LogitScore, bei dem das multimodale Sprachmodell ein Token erzeugt und daraus die Log-Odds für „1“ gegenüber „0“ berechnet werden. Zum anderen wird Feature Extraction + Pooling + Dense genannt, bei dem nur das multimodale Basismodell genutzt wird, der Hidden State des letzten Tokens extrahiert und über eine Dense-Schicht in einen Score projiziert wird. In den verlinkten Skripten wird das Training in zwei Richtungen aufgeteilt, also Bild-zu-Text und Text-zu-Bild, jeweils mit richtungsspezifischen Prompts und zufällig gesampelten Negativbeispielen für ein ausbalanciertes Verhältnis von Treffern und Nicht-Treffern.
Abschließend verweist der Beitrag auf mehrere multimodale Trainingsbeispiele im Sentence-Transformers-Repository, darunter das Visual-Document-Retrieval-Skript aus dem Beitrag selbst sowie Beispiele für multimodale Reranker mit LogitScore und mit Feature Extraction. Zusätzlich werden weiterführende Seiten zu Training, Loss Functions, Datensätzen, API-Referenz und verwandten Themen wie Matryoshka Embeddings, statischen Embeddings, Quantisierung und dem zugrunde liegenden LlamaIndex-VDR-Datensatz genannt.
