Die richtige Passform finden: Embedding-Erstellung für AI Retrieval (RAG) in Zilliz Cloud Pipelines von OSS, VoyageAI und OpenAI
Dieser Beitrag wurde von Christy Bergman und Jiang Chen verfasst.
Willkommen zu unserem Blogbeitrag über Embedding-Modelle, die auf KI-Retrieval Augmented Generation (RAG)-Anwendungen zugeschnitten sind. Folgendes werden wir behandeln:
Einführung, wie Embedding-Modelle in RAG (generative KI mit Retrieval) verwendet werden
Einführung in SBERT, den gängigsten Typ von Embedding-Modell
MTEB-Leaderboard von Embedding-Modellen und wie man es nutzt
Sechs Embedding-Modelle, die automatisch in Zilliz Cloud Pipelines enthalten sind
Erklärung jedes Modells und Tipps zur Auswahl des besten Embedding-Modells für Ihre Anforderungen
Legen wir los!
Fügen Sie Ihre Daten mit RAG zur KI hinzu: Wie Embedding-Modelle + LLMs verwendet werden
Retrieval Augmented Generation (RAG) hat sich als bevorzugter Ansatz für Frage-Antwort-Bots etabliert. Aufgrund des in allen Modellen inhärenten Stichtags für das Wissens-Training fehlt ihnen jedoch möglicherweise das Bewusstsein für aktuelle Daten. Die meisten Produktionsanwendungsfälle ergänzen ihre Modelle mit spezifischem Wissen, um diese Lücke zu schließen.
Stecken Ihre KI-Antworten in der Vergangenheit fest? Haben Sie genug von Bots, die nur wissen, worauf sie trainiert wurden?
RAG bietet eine Lösung, indem es Ihre Daten in das Wissen der KI integriert. Dieses Muster verwendet Embedding-Modelle und Large Language Models (LLMs). So funktioniert es:
Datenvorbereitung mit einem Embedding-Modell: Starten Sie RAG, indem Sie ein Embedding-Modell verwenden, um Vektor-Embeddings von Textabschnitten aus ALLEN Ihren Dokumenten zu erzeugen. Dies wird IHR Vektorraum, der IHR Domänenwissen repräsentiert, wobei jede Information als Vektor dargestellt wird.
Indexierung und Suche mit demselben Embedding-Modell: Computer können schnell Vektorsuchen ausführen, sobald Ihr Wissen in Vektoren kodiert ist. Das Organisieren der Vektoren in Datenstrukturen für Suchalgorithmen wird als Indexierung bezeichnet. Indizes werden in Vektordatenbanken wie Milvus verwendet. Wenn Sie eine Frage stellen, verwendet die Datenbank den Index, um die nächstgelegenen Vektoren (die Sätze oder Absätze repräsentieren) in Ihrem Domänenwissen-Vektorraum zu Ihrem Fragevektor zu finden. Erstellen Sie Ihren Fragevektor mit demselben Embedding-Modell, das zum Einbetten Ihrer Daten verwendet wurde.
Antwortgenerierung mit einem LLM-Modell: Dies ist der „Generative AI“-Teil. In diesem Schritt nutzt ein LLM-Modell, wie ChatGPT, Ihr relevantes Domänenwissen, um die Frage zu beantworten. RAG-Daten werden dem LLM-Modell zugeführt, indem die Top-K abgerufenen Texte in den Prompt eingefügt werden, der Ihre Frage, den Kontext (Top-K-Texte) und Anweisungen wie „Beantworte die Frage nur mit dem Wissen im Kontext dieses Prompts“ enthält.
Mit RAG generiert das LLM eine Antwort auf Grundlage Ihres gegebenen Domänenwissens, greift sofort auf die neuesten Daten zu und versteht Ihre Fragen besser.
Dieses RAG-Muster wird durch Forschung gestützt; siehe das Paper Lost in the Middle. Das Paper zeigt, dass die Recall-Genauigkeit von Antworten, die von LLMs generiert werden, mit der Anzahl der abgerufenen Texte abnimmt, die in den Kontext-Prompt des Modells gepackt werden. Außerdem:
LLMs haben Grenzen bei der Kontextgröße (derzeit sind es 128K für GPT-4 Turbo).
Kosten pro Token, daher ist es teurer, ständig alle Informationen zu übergeben.
Sentence-BERT Embedding-Modelle
Moderne Embedding-Modelle werden aus dem Encoder-Teil von Transformern abgeleitet; während LLM-Modelle (wie ChatGPT) aus dem Decoder-Teil von Transformern aufgebaut sind. Die gängigste Klasse von Embedding-Modellen ist SBERT (Sentence-BERT), das auf BERT aufbaut, sich aber auf das Verständnis vollständiger Sätze spezialisiert. So kann SBERT den Unterschied zwischen „The cat sat on the mat“ und „The mat sat on the cat“ erkennen – etwas, das das grundlegende BERT nicht könnte!
Semantik bezieht sich auf die Bedeutung hinter Wörtern. Dies ist im Kontext von LLMs besonders wichtig, da dieselben Wörter je nach Kontext, Reihenfolge oder Verwendung unterschiedliche Bedeutungen haben können. Weitere Informationen zu SBERT finden interessierte Leser in diesen guten Hintergrundartikeln zu diesem Modell hier.
Angenommen, Sie programmieren RAG-Anwendungen von Grund auf. Ein ausgezeichneter Ausgangspunkt ist die Auswahl eines Embedding-Modells aus dem HuggingFace MTEB Leaderboard, sortiert (absteigend) nach der Spalte „Retrieval Average“, da sie für RAG am relevantesten ist. Wählen Sie dann das kleinste, am höchsten platzierte Embedding-Modell. Das Leaderboard ändert sich ständig! Aber das Wechseln des Embedding-Modells mit HuggingFace in Python ist so einfach wie das Anpassen einer einzigen Variablen.
Die MTEB-Retrieval-Leistung wird durch Normalized Discounted Cumulative Gain at 10 (NDCG@10) gemessen. Diese Metrik misst die Qualität von Top-K-Listen, indem Verhältnissummen berechnet werden, bei denen höher eingestufte Elemente stärker gewichtet werden als niedriger eingestufte Elemente, wie sie einem Benutzer im Verhältnis zu einer idealen Rangordnung zurückgegeben werden.
Bildquelle: HuggingFace MTEB Leaderboard, abgerufen am 20. Feb. 2024.
Massive Text Embedding Benchmark (MTEB) bewertet Embedding-Modelle über 8 Aufgaben und 58 Datensätze hinweg (10 mehrsprachige, 112 Sprachen). Die acht Aufgaben sind Bitext-Mining, Klassifikation, Clustering, Paarklassifikation, Reranking, Retrieval, semantische Textähnlichkeit (STS) und Zusammenfassung.
6 wichtige in Zilliz Cloud Pipelines integrierte Embedding-Modelle
Zilliz Cloud Pipelines hat kürzlich Unterstützung für eine umfangreiche Auswahl an Embedding-Modellen eingeführt.
| Ersteller | Modell | Embedding Dim | Kontextlänge | Use-Case-Aufgaben | Open Source | *MTEB-Score |
| BAAI | bge-base-en-v1.5 | 768 | 512 | Allgemeiner EN-Text | Ja | 53 |
| BAAI | bge-base-zh-v1.5 | 768 | 512 | Allgemeiner ZH-Text | Ja | 69 |
| VoyageAI | voyage-2 | 1024 | 4K | Hochwertige RAG-Chatbots | Nein | Nicht verfügbar |
| VoyageAI | voyage-code-2 | 1536 | 16K | Code-Vervollständigung mit hoher Recall-Rate | Nein | Nicht verfügbar |
| OpenAI | text-embedding-3-small | 512-1536 | 8K | Echtzeit-Mehrsprachen-Text-Chatbots | Nein | 62 (512) 62 (1536) |
| OpenAI | text-embedding-3-large | 256-3072 | 8K | Echtzeit-Mehrsprachen-Text-Chatbots | Nein | 65 (3072) 62 (256) |
*HuggingFace MTEB Leaderboard, absteigend nach Retrieval sortiert, abgerufen am 26. Feb. 2024.
Embedding Dim = Länge des von einem Modell erzeugten Vektors; größere Vektoren könnten mehr Bedeutung erfassen, sind aber möglicherweise weniger speichereffizient.
Kontextlänge = maximale Anzahl von Tokens, die das Modell zu einem einzelnen Zeitpunkt auf einmal verarbeiten kann. Die Ausgabevektoren der meisten Embedding-Modelle sind normalisiert, sodass Skalarprodukt und Kosinusähnlichkeit gleich sind.
⚠️ Hinweis: Auch wenn MTEB-Benchmarks wertvolle Orientierung bieten, ist bekannt, dass einige Modelle overfittet sind! Führen Sie immer Ihre eigenen Evaluierungen durch!
Mit Zilliz Cloud Pipelines können Sie kostenlos loslegen, indem Sie sich registrieren und Ihre RAG-Anwendung ohne DevOps- oder ML-Infrastruktur-Aufwand erstellen.
Bildquelle: Blog zur Ankündigung von Embedding-Modellen, die in Zilliz Cloud Pipelines integriert sind
BAAI/bge-base-en(oder zh)-v1.5 Embedding-Modelle
Diese Open-Source-SBERT-Modelle sind auf HuggingFace verfügbar. Einige Vorteile dieser kleinen Modelle:
Klein, Open Source und CPU-freundlich.
Es ist eine gute Wahl für die Arbeit auf einem Laptop und/oder mit winzigen Cloud-Ressourcen.
Am schnellsten für die Ingestion beim Chunking von Daten und für die Abfragelatenz jedes Mal, wenn eine Frage gestellt wird.
Kosteneffektiv, da API-Aufrufe kostenlos sind und keine GPU erforderlich ist.
Trainiert in chinesischer und englischer Sprache.
| Ersteller | Modell | Embedding****Dim | Kontextlänge | Use-Case-Aufgaben | Open Source | *MTEB-Score |
| BAAI | bge-base-en-v1.5 | 768 | 512 | Allgemeiner EN-Text | Ja | 53 |
| BAAI | bge-base-zh-v1.5 | 768 | 512 | Allgemeiner ZH-Text | Ja | 69 |
*HuggingFace MTEB Leaderboard, absteigend nach Retrieval sortiert, aufgerufen am 26. Feb. 2024.
VoyageAIs voyage-2 und voyage-code-2 Embedding-Modelle
Diese proprietären Modelle werden mithilfe von contrastive learning und importance resampling auf unterschiedlichen Daten trainiert und für unterschiedliche Aufgaben feinabgestimmt. Voyage-2 wird auf Dialogdaten trainiert und für Konversationsabsicht feinabgestimmt. Voyage-code-2 wird auf Codedaten trainiert und für Code-Vervollständigung feinabgestimmt.
Hinweis: Voyage-lite-02-instruct, das im MTEB-Leaderboard aufgeführt ist (absteigend nach STS oder der Kategorie „diverse corpora“ sortiert), ist anders und sollte nicht mit den hier beschriebenen Produktionsmodellen voyage-2 und voyage-code-2 verwechselt werden.
Einige Vorteile dieser Modelle:
Für RAG-Chatbots für technische Dokumentation zeigte voyage-01 (veraltet) eine höhere Retrieval-Qualität (gemessen als NDCG@10). Voyage-2 ist die neuere Version.
Für Code-Aufgaben hat voyage-code-2 eine um 14 % höhere Recall-Rate für codeintensiven Text.
| Ersteller | Modell | Embedding****Dim | Kontextlänge | Use-Case-Aufgaben | Open Source | MTEB-Score |
| VoyageAI | voyage-2 | 1024 | 4K | Hochwertige RAG-Chatbots | Nein | Nicht verfügbar |
| VoyageAI | voyage-code-2 | 1536 | 16K | Hohe Recall-Rate Code-Vervollständigung | Nein | Nicht verfügbar |
OpenAIs text-embedding-3-small(oder large) Embedding-Modelle
Von OpenAI stammen die neuesten Embedding-Modelle, die auf dem MTEB-Leaderboard höher eingestuft sind als ihr früheres ada-002. Diese neuen Embedding-Modelle bieten außerdem eine höhere mehrsprachige Leistung (MIRACL) und niedrigere Preise.
Laut OpenAIs Blog** wurde compression-aware Training verwendet, um die Embeddings zu erstellen.** Traditionelle Techniken zur Dimensionsreduktion wie Quantisierung sparen Speicherplatz, führen jedoch zu einem enormen Genauigkeitsverlust, da die Komprimierung „post-hoc“ angewendet wird, nachdem die Embeddings gelernt wurden. Compression-aware Training, wie etwa Matryoshka Representation Learning, lernt Embeddings in verschiedenen Größen (Dimensionen), mit einem gewissen Genauigkeitsverlust, der jedoch nicht so erheblich ist wie bei PCA.
Beeindruckenderweise unterstützen beide Modelle kleinere Embeddings, ohne die Retrieval-Qualität stark zu beeinträchtigen. Zum Beispiel reduziert die Verringerung der Vektordimension von 3072 auf 256 den MTEB-Score nur von 65% auf 62%. Allerdings bedeutet das einen 12-fach geringeren Speicherbedarf! Zwar gibt es einen Genauigkeits-Kosten-Kompromiss im Zusammenhang mit niedrigerer Dimensionalität, doch im Zeitalter KI-gestützter Chatbots werden schnelle Antworten manchmal höher priorisiert als die Antwortgenauigkeit.
Einige Vorteile dieser Modelle:
Verbesserte mehrsprachige Fähigkeiten.
Vektoren mit niedrigerer Dimension, dem geringsten Inferenz-Overhead und deutlich weniger Genauigkeitsverlust als bei traditioneller binärer oder Produktquantisierung.
| Ersteller | Modell | Embedding****Dimension | Kontextlänge | Anwendungsfall-Aufgaben | Open Source | *MTEB-Score |
| OpenAI | text-embedding-3-small | 512-1536 | 8K | Mehrsprachige Echtzeit-Text-Chatbots | Nein | 62 (512) 62 (1536) |
| OpenAI | text-embedding-3-large | 256-3072 | 8K | Mehrsprachige Echtzeit-Text-Chatbots | Nein | 65 (3072) 62 (256) |
*HuggingFace MTEB Leaderboard, absteigend nach Retrieval sortiert, abgerufen am 26. Feb. 2024.
Unten finden Sie ein Codebeispiel zum Aufrufen der neuen Embedding-Modelle. Der vollständige Code befindet sich in unserem bootcamp github.
# STEP 1. CONNECT TO MILVUS
# !pip install pymilvus
from pymilvus import connections, utility
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv("ZILLIZ_API_KEY")
# Connect to Zilliz cloud using endpoint URI and API key TOKEN.
CLUSTER_ENDPOINT="https://in03-xxxx.api.gcp-us-west1.zillizcloud.com:443"
connections.connect(
alias='default',
uri=CLUSTER_ENDPOINT,
token=TOKEN,
)
Als Nächstes geben wir das OpenAI-Embedding-Modell an.
# STEP 2. EMBEDDING MODEL.
import openai, pprint
from openai import OpenAI
# OpenAI embedding model name, `text-embedding-3-large` or `ext-embedding-3-small`.
EMBEDDING_MODEL = "text-embedding-3-small"
EMBEDDING_DIM = 512
Als Nächstes erstellen wir eine schemafreie Milvus-Collection und geben einen Index an.
# STEP 3. CREATE A NO-SCHEMA MILVUS COLLECTION AND USE AUTOINDEX.
from pymilvus import MilvusClient
COLLECTION_NAME = "MilvusDocs_text_embedding_3_small"
# https://milvus.io/docs/using_milvusclient.md
mc = MilvusClient(
uri=CLUSTER_ENDPOINT,
token=TOKEN)
# Check if collection already exists, if so drop it.
has = utility.has_collection(COLLECTION_NAME)
if has:
drop_result = utility.drop_collection(COLLECTION_NAME)
print(f"Successfully dropped collection: `{COLLECTION_NAME}`")
# Erstellen Sie die Collection.
mc.create_collection(COLLECTION_NAME,
EMBEDDING_DIM,
consistency_level="Eventually",
auto_id=True,
overwrite=True)
Als Nächstes lesen wir die technischen LangChain-Dokumente als .html-Dateien, die in einen Ordner heruntergeladen wurden. Chunking und Einbetten der Dokumente. Das folgende Beispiel verwendet den integrierten HTML-Parser von LangChain als Chunking-Strategie. Ihre Chunking-Strategie könnte viel einfacher sein.
# STEP 4. PREPARE DATA: CHUNK AND EMBED
# Read docs into LangChain.
from langchain.document_loaders import DirectoryLoader
path = "../RAG/rtdocs/pymilvus.readthedocs.io/en/latest/"
loader = DirectoryLoader(path, glob='*.html')
docs = loader.load()
from langchain.text_splitter import HTMLHeaderTextSplitter, RecursiveCharacterTextSplitter
from bs4 import BeautifulSoup
# Define the headers to split on for the HTMLHeaderTextSplitter
headers_to_split_on = [
("h1", "Header 1"),
("h2", "Header 2"),
]
# Create an instance of the HTMLHeaderTextSplitter
html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
# Specify chunk size and overlap.
chunk_size = 511
chunk_overlap = np.round(chunk_size * 0.10, 0)
print(f"chunk_size: {chunk_size}, chunk_overlap: {chunk_overlap}")
# Create an instance of the RecursiveCharacterTextSplitter
child_splitter = RecursiveCharacterTextSplitter(
chunk_size = chunk_size,
chunk_overlap = chunk_overlap,
length_function = len,
)
# Split the HTML text using the HTMLHeaderTextSplitter.
start_time = time.time()
html_header_splits = []
for doc in docs:
soup = BeautifulSoup(doc.page_content, 'html.parser')
splits = html_splitter.split_text(str(soup))
for split in splits:
# Add the source URL and header values to the metadata
metadata = {}
new_text = split.page_content
for header_name, metadata_header_name in headers_to_split_on:
# Handle exceptions if h1 does not exist.
try:
header_value = new_text.split("¶ ")[0].strip()[:100]
metadata[header_name] = header_value
except:
break
split.metadata = {
**metadata,
"source": doc.metadata["source"]
}
# Add the header to the text
split.page_content = split.page_content
html_header_splits.extend(splits)
# Split the documents further into smaller, recursive chunks.
chunks = child_splitter.split_documents(html_header_splits)
Fügen Sie die Chunks und Embeddings in Milvus ein.
# STEP 5. INSERT CHUNKS AND EMBEDDINGS IN ZILLIZ.
# Convert chunks to a list of dictionaries.
chunk_list = []
for chunk in chunks:
# Generate the embeddings.
response = openai_client.embeddings.create(
input=chunk.page_content,
model=EMBEDDING_MODEL,
dimensions=EMBEDDING_DIM
)
embeddings = response.data[0].embedding
# Assemble embedding vector, original text chunk, metadata.
chunk_dict = {
'vector': embeddings,
'chunk': chunk.page_content,
'source': chunk.metadata['source'],
'h1': chunk.metadata['h1'][:50],
}
chunk_list.append(chunk_dict)
# Insert data into the Milvus collection.
insert_result = mc.insert(
COLLECTION_NAME,
data=chunk_list,
progress_bar=True)
# After the final entity is inserted, call flush to stop growing segments left in memory.
mc.flush(COLLECTION_NAME)
Stellen Sie Milvus eine Frage, das jetzt mit Embeddings der technischen Milvus-Dokumentation geladen ist.
# Define a sample question about your data.
SAMPLE_QUESTION = "What do the parameters for HNSW mean?"
# Embed the question using the same encoder.
response = openai_client.embeddings.create(
input=SAMPLE_QUESTION,
model=EMBEDDING_MODEL,
dimensions=EMBEDDING_DIM
)
query_embeddings = response.data[0].embedding
# Define output fields to return.
OUTPUT_FIELDS = ["h1", "h2", "source", "chunk"]
# Run semantic vector search using your query and Milvus vector database.
start_time = time.time()
results = mc.search(
COLLECTION_NAME,
data=[query_embeddings],
output_fields=OUTPUT_FIELDS,
limit=2,
consistency_level="Eventually"
)
Generiere eine Antwort mit ChatGPT und den abgerufenen Textkontext-Abschnitten.
LLM_NAME = "gpt-3.5-turbo"
TEMPERATURE = 0.1
RANDOM_SEED = 415
# Separate all the context together by space.
contexts_combined = ' '.join(context)
SYSTEM_PROMPT = f"""Use the Context below to answer the user's question. Be clear, factual, complete, concise.
If the answer is not in the Context, say "I don't know".
Otherwise answer with fewer than 4 sentences and cite the grounding sources.
Context: contexts_combined
Answer: The answer to the question.
Grounding sources: {context_metadata[0]['source']}
"""
# Generate response using the OpenAI API.
response = openai_client.chat.completions.create(
messages=[
{"role": "system", "content": SYSTEM_PROMPT,},
{"role": "user", "content": f"question: {SAMPLE_QUESTION}",}
],
model=LLM_NAME,
temperature=TEMPERATURE,
seed=RANDOM_SEED,
)
# Print the question and answer along with grounding sources and citations.
print(f"Question: {SAMPLE_QUESTION}")
for i, choice in enumerate(response.choices, 1):
pprint.pprint(f"Answer: {choice.message.content}")
print("\n")
Die Antwort mit text-embedding-3-small und reduzierten Embeddings dim=256 ist perfekt im Vergleich zur gleichen Antwort mit dim=1536, zumindest für dieses RAG-Beispiel!
Fazit
In diesem Blog haben wir vorgestellt, wie Embedding-Modelle in RAG und SBERT, dem häufigsten Typ von Embedding-Modell, verwendet werden. Wir haben das MTEB-Leaderboard für Embedding-Modelle gezeigt und erklärt, wie man es verwendet. Dann sind wir die sechs verschiedenen Embedding-Modelle durchgegangen, die automatisch in Zilliz Pipelines enthalten sind. Verschiedene Embedding-Modelle eignen sich am besten für unterschiedliche Anwendungsfälle; wir haben besprochen, wann welches Modell gewählt werden sollte. Schließlich haben wir Code gezeigt, um die neuen OpenAI-Embedding-Modelle aufzurufen; und der vollständige Code befindet sich in unserem bootcamp github.
Referenzen
Milvus (gib uns einen Stern!)
Tutorial zu Encoder-Decoder-Teilen von Transformers
Tutorial zu SBERT-Encoder-Embedding-Modellen
HuggingFace MTEB Leaderboard für Embedding-Modelle
HuggingFace-Modellkarte für BAAI/bg-large-en-v1.5
VoyageAI Embedding-Modelle
OpenAI Embedding-Modelle
Weiterlesen
Stop Building AI Data Infra for the Wrong Stage
Learn how AI data infrastructure should evolve from prototype to enterprise scale, and when Vector Lakebase becomes the right architecture for AI apps.

How to Build an Enterprise-Ready RAG Pipeline on AWS with Bedrock, Zilliz Cloud, and LangChain
Build production-ready enterprise RAG with AWS Bedrock, Nova models, Zilliz Cloud, and LangChain. Complete tutorial with deployable code.

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.



