Erfahre, wie du Text in Zahlen umwandelst und damit Anwendungsfälle wie die Suche ermöglichst.
New embedding models
text-embedding-3-small and text-embedding-3-large, our newest and most performant embedding models, are now available. They feature lower costs, higher multilingual performance, and new parameters to control the overall size.
Was sind Embeddings?
Die Text-Embeddings von OpenAI messen, wie eng Texte inhaltlich miteinander zusammenhängen. Embeddings werden häufig für folgende Zwecke verwendet:
Suchen (Ergebnisse werden nach ihrer Relevanz für eine Suchanfrage sortiert)
Clustering (Texte werden nach ihrer Ähnlichkeit gruppiert)
Empfehlungen (Elemente mit inhaltlich verwandten Texten werden empfohlen)
Anomalieerkennung (Ausreißer mit geringer inhaltlicher Ähnlichkeit werden erkannt)
Messung der Diversität (Ähnlichkeitsverteilungen werden analysiert)
Klassifikation (Texte werden dem Label zugeordnet, dem sie am ähnlichsten sind)
Ein Embedding ist ein Vektor (eine Liste) aus Gleitkommazahlen. Der Abstand zwischen zwei Vektoren misst ihre Ähnlichkeit. Kleine Abstände deuten auf eine hohe Ähnlichkeit hin, große Abstände auf eine geringe.
Auf unserer Preisseite findest du Informationen zu den Preisen für Embeddings. Anfragen werden anhand der Anzahl der Token in der Eingabe abgerechnet.
So erhältst du Embeddings
Um ein Embedding zu erhalten, sende deinen Text zusammen mit dem Namen des Embedding-Modells (z. B. text-embedding-3-small) an den API-Endpunkt für Embeddings:
Die Antwort enthält den Embedding-Vektor (eine Liste aus Gleitkommazahlen) sowie zusätzliche Metadaten. Du kannst den Embedding-Vektor extrahieren, in einer Vektordatenbank speichern und für viele verschiedene Anwendungsfälle nutzen.
Standardmäßig beträgt die Länge des Embedding-Vektors 1536 bei text-embedding-3-small bzw. 3072 bei text-embedding-3-large. Um die Anzahl der Dimensionen des Embeddings zu reduzieren, ohne dass es seine Fähigkeit verliert, Konzepte abzubilden, übergib den Parameter dimensions. Weitere Informationen zu Embedding-Dimensionen findest du im Abschnitt zu Anwendungsfällen für Embeddings.
Embedding-Modelle
OpenAI bietet zwei leistungsstarke Embedding-Modelle der dritten Generation an (erkennbar an -3 in der Modell-ID). Weitere Informationen findest du im Blogbeitrag zur Ankündigung der Embedding-Modelle v3.
Die Nutzung wird pro Eingabetoken abgerechnet. Die folgende Tabelle zeigt beispielhaft, wie viele Textseiten du für 1 USD verarbeiten kannst (bei etwa 800 Token pro Seite):
Der Datensatz enthält insgesamt 568.454 Lebensmittelrezensionen, die bis Oktober 2012 auf Amazon veröffentlicht wurden. Zur Veranschaulichung verwenden wir eine Teilmenge mit den 1000 neuesten Rezensionen. Die Rezensionen sind auf Englisch und fallen tendenziell positiv oder negativ aus. Jede Rezension enthält die Felder ProductId, UserId, Score, einen Rezensionstitel (Summary) und einen Rezensionstext (Text). Zum Beispiel:
Produkt-ID
Nutzungs-ID
Bewertung
Zusammenfassung
Text
B001E4KFG0
A3SGXH7AUHU8GW
5
Hochwertiges Hundefutter
Ich habe mehrere Dosen Vitality gekauft …
B00813GRG4
A1D87F6ZCVE5NK
1
Nicht wie beworben
Das Produkt kam mit der Aufschrift „Jumbo Salted Peanut“ …
Im Folgenden fassen wir die Zusammenfassung und den Text der Rezension zu einem einzigen Text zusammen. Das Modell kodiert diesen kombinierten Text und gibt ein einzelnes Vektor-Embedding aus.
Größere Embeddings zu verwenden, etwa sie für den Informationsabruf in einem Vektorspeicher abzulegen, kostet in der Regel mehr und benötigt mehr Rechenleistung, Arbeitsspeicher und Speicherplatz als die Verwendung kleinerer Embeddings.
Unsere beiden neuen Embedding-Modelle wurden mit einer Technik trainiert, mit der Entwickelnde die Leistung und die Kosten von Embeddings gegeneinander abwägen können. Konkret lassen sich Embeddings durch Übergabe des API-Parameters dimensions kürzen, also um einige Zahlen am Ende der Sequenz reduzieren, ohne dass sie ihre Fähigkeit verlieren, Konzepte abzubilden. Beispielsweise lässt sich ein Embedding von text-embedding-3-large auf eine Größe von 256 kürzen und übertrifft im MTEB-Benchmark dennoch ein ungekürztes Embedding von text-embedding-ada-002 mit einer Größe von 1536. Wie sich eine Änderung der Dimensionen auf die Leistung auswirkt, erfährst du in unserem Blogbeitrag zur Einführung von Embeddings v3.
Im Allgemeinen empfehlen wir, den Parameter dimensions beim Erstellen des Embeddings zu verwenden. In bestimmten Fällen musst du die Anzahl der Dimensionen möglicherweise nach der Generierung ändern. Wenn du sie manuell änderst, musst du das Embedding wie unten gezeigt normalisieren.
Durch die dynamische Anpassung der Dimensionen lassen sich Embeddings sehr flexibel einsetzen. Wenn ein Vektorspeicher beispielsweise nur Embeddings mit bis zu 1024 Dimensionen unterstützt, kannst du jetzt trotzdem unser bestes Embedding-Modell text-embedding-3-large verwenden und für den API-Parameter dimensions den Wert 1024 angeben. Dadurch wird das Embedding von 3072 auf 1024 Dimensionen gekürzt. Für die kleinere Vektorgröße nimmst du eine etwas geringere Genauigkeit in Kauf.
Häufig wurde ein Modell nicht mit Daten trainiert, die wichtige Fakten und Informationen enthalten, auf die es beim Beantworten einer Nutzeranfrage zugreifen soll. Eine mögliche Lösung besteht darin, zusätzliche Informationen in das Kontextfenster des Modells aufzunehmen, wie unten gezeigt. Das funktioniert für viele Anwendungsfälle gut, führt aber zu höheren Token-Kosten. In diesem Notebook untersuchen wir die Vor- und Nachteile dieses Ansatzes im Vergleich zur Embedding-basierten Suche.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import OpenAI from"openai";constclient=newOpenAI();constarticle="At the 2022 Winter Olympics, Great Britain won women's curling and Sweden won men's curling.";constquestion=`Use the article below to answer the question. If the answer cannot be found, say "I don't know."Article:${article}Question: Which athletes won the gold medal in curling at the 2022 Winter Olympics?`;constresponse=await client.chat.completions.create({ model: "gpt-4.1-mini", messages: [ { role: "system", content: "You answer questions about the 2022 Winter Olympics.", }, { role: "user", content: question }, ], temperature: 0,});console.log(response.choices[0].message.content);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22query = f"""Use the below article on the 2022 Winter Olympics to answer the subsequent question. If the answer cannot be found, write "I don't know."Article:\"\"\"{wikipedia_article_on_curling}\"\"\"Question: Which athletes won the gold medal in curling at the 2022 Winter Olympics?"""response = client.chat.completions.create( messages=[ { "role": "system", "content": "You answer questions about the 2022 Winter Olympics.", }, {"role": "user", "content": query}, ], model=GPT_MODEL, temperature=0,)print(response.choices[0].message.content)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.chat.completions.ChatCompletionCreateParams;String article = "At the 2022 Winter Olympics, Great Britain won women's curling and Sweden won men's curling.";String question = "Use the below article on the 2022 Winter Olympics to answer the subsequent question. " + "If the answer cannot be found, write \"I don't know.\"\n\n" + "Article:\n" + article + "\n\nQuestion: Which athletes won the gold medal in curling at the 2022 Winter Olympics?";ChatCompletionCreateParams params = ChatCompletionCreateParams.builder() .model("gpt-4.1-mini") .addSystemMessage("You answer questions about the 2022 Winter Olympics.") .addUserMessage(question) .temperature(0) .build();client.chat().completions().create(params).choices().stream() .flatMap(choice -> choice.message().content().stream()) .forEach(System.out::println);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29require "openai"client = OpenAI::Client.newarticle = "At the 2022 Winter Olympics, Great Britain won women's curling and Sweden won men's curling."question = <<~QUESTION Use the article below to answer the question. If the answer cannot be found, say "I don't know." Article: #{article} Question: Which athletes won the gold medal in curling at the 2022 Winter Olympics?QUESTIONresponse = client.chat.completions.create( model: "gpt-4.1-mini", messages: [ { role: :system, content: "You answer questions about the 2022 Winter Olympics." }, { role: :user, content: question } ], temperature: 0)puts(response.choices.fetch(0).message.content)
Um die relevantesten Dokumente abzurufen, berechnen wir die Kosinus-Ähnlichkeit zwischen dem Embedding-Vektor der Anfrage und dem jedes Dokuments. Anschließend geben wir die Dokumente mit den höchsten Werten zurück.
Die Codesuche funktioniert ähnlich wie die Embedding-basierte Textsuche. Wir stellen eine Methode bereit, um Python-Funktionen aus allen Python-Dateien eines bestimmten Repositorys zu extrahieren. Anschließend wird jede Funktion mithilfe des Modells text-embedding-3-small indexiert.
Für die Codesuche erstellen wir mit demselben Modell ein Embedding der natürlichsprachlichen Anfrage. Dann berechnen wir die Kosinus-Ähnlichkeit zwischen dem entstandenen Anfrage-Embedding und jedem Funktions-Embedding. Die Ergebnisse mit der höchsten Kosinus-Ähnlichkeit sind am relevantesten.
Da kleinere Abstände zwischen Embedding-Vektoren eine größere Ähnlichkeit bedeuten, können Embeddings für Empfehlungen nützlich sein.
Unten zeigen wir ein einfaches Empfehlungssystem. Es nimmt eine Liste von Zeichenfolgen und eine „Ausgangszeichenfolge“ entgegen, berechnet deren Embeddings und gibt die Zeichenfolgen nach absteigender Ähnlichkeit sortiert zurück. Als konkretes Beispiel wendet das unten verlinkte Notebook eine Variante dieser Funktion auf den AG-Nachrichtendatensatz an, der auf eine Stichprobe von 2.000 Beschreibungen von Nachrichtenartikeln reduziert wurde. So liefert es zu einem beliebigen Ausgangsartikel die 5 ähnlichsten Artikel.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import OpenAI from"openai";constclient=newOpenAI();conststrings= ["A cheetah is a fast land animal.","A peregrine falcon is a fast bird.","A tortoise moves slowly.",];const { data } =await client.embeddings.create({ model: "text-embedding-3-small", input: strings,});constquery= data[0].embedding;constrecommendations= data .map(({ embedding }, index) => {constdotProduct= embedding.reduce( (total, value, dimension) => total + value * query[dimension],0 );constsimilarity= dotProduct / (Math.hypot(...embedding) * Math.hypot(...query));return { index, text: strings[index], similarity }; }) .sort((left, right) => right.similarity - left.similarity);console.log(recommendations);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23def recommendations_from_strings( strings: list[str], index_of_source_string: int, model="text-embedding-3-small",) -> list[int]: """Return nearest neighbors of a given string.""" # get embeddings for all strings embeddings = [embedding_from_string(string, model=model) for string in strings] # get the embedding of the source string query_embedding = embeddings[index_of_source_string] # get distances between the source embedding and other embeddings (function from embeddings_utils.py) distances = distances_from_embeddings( query_embedding, embeddings, distance_metric="cosine" ) # get indices of nearest neighbors (function from embeddings_utils.py) indices_of_nearest_neighbors = indices_of_nearest_neighbors_from_distances( distances ) return indices_of_nearest_neighbors
Die Größe der Embeddings hängt von der Komplexität des zugrunde liegenden Modells ab. Um diese hochdimensionalen Daten zu visualisieren, reduzieren wir sie mit dem t-SNE-Algorithmus auf zwei Dimensionen.
Wir färben die einzelnen Rezensionen entsprechend der jeweils vergebenen Sternebewertung ein:
1 Stern: rot
2 Sterne: dunkelorange
3 Sterne: gold
4 Sterne: türkis
5 Sterne: dunkelgrün
In der Visualisierung scheinen sich etwa 3 Cluster abzuzeichnen. Eines davon enthält überwiegend negative Rezensionen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import numpy as npimport pandas as pdfrom sklearn.manifold importTSNEimport matplotlib.pyplot as pltimport matplotlibdf = pd.read_csv("output/embedded_1k_reviews.csv")matrix = np.array(df.ada_embedding.apply(eval).to_list())# Create a t-SNE model and transform the datatsne = TSNE(n_components=2, perplexity=15, random_state=42, init="random", learning_rate=200)vis_dims = tsne.fit_transform(matrix)colors = ["red", "darkorange", "gold", "turquoise", "darkgreen"]x = [x for x, y in vis_dims]y = [y for x, y in vis_dims]color_indices = df.Score.values -1colormap = matplotlib.colors.ListedColormap(colors)plt.scatter(x, y, c=color_indices, cmap=colormap, alpha=0.3)plt.title("Amazon ratings visualized in language using t-SNE")
Ein Embedding lässt sich in einem Modell für maschinelles Lernen allgemein zur Kodierung von Freitextmerkmalen verwenden. Die Einbindung von Embeddings verbessert die Leistung jedes solchen Modells, wenn einige der relevanten Eingaben Freitext sind. Ein Embedding kann in einem ML-Modell auch kategoriale Merkmale kodieren. Das ist besonders nützlich, wenn die kategorialen Variablen zahlreiche, aussagekräftige Bezeichnungen haben, etwa bei Jobtiteln. Ähnlichkeits-Embeddings erzielen bei dieser Aufgabe im Allgemeinen bessere Ergebnisse als Such-Embeddings.
Wir haben beobachtet, dass die Darstellung durch Embeddings im Allgemeinen sehr reichhaltig ist und eine hohe Informationsdichte aufweist. So führt etwa eine Reduktion der Eingabedimensionen mit SVD oder PCA in der Regel zu schlechteren Ergebnissen bei bestimmten nachgelagerten Aufgaben, selbst wenn die Reduktion nur 10 % beträgt.
Dieser Code teilt die Daten in einen Trainings- und einen Testdatensatz auf. Beide werden für die folgenden zwei Anwendungsfälle verwendet: Regression und Klassifikation.
Embeddings bieten eine elegante Möglichkeit, numerische Werte vorherzusagen. In diesem Beispiel sagen wir anhand des Rezensionstextes voraus, wie viele Sterne die rezensierende Person vergeben hat. Da Embeddings viele semantische Informationen enthalten, liefert die Vorhersage selbst mit sehr wenigen Rezensionen brauchbare Ergebnisse.
Wir nehmen an, dass die Bewertung eine kontinuierliche Variable zwischen 1 und 5 ist, und lassen den Algorithmus beliebige Gleitkommawerte vorhersagen. Der ML-Algorithmus minimiert den Abstand zwischen dem vorhergesagten Wert und der tatsächlichen Bewertung. Dabei erreicht er einen mittleren absoluten Fehler von 0,39. Das bedeutet, dass die Vorhersage im Durchschnitt um weniger als einen halben Stern abweicht.
Diesmal lassen wir den Algorithmus keinen beliebigen Wert zwischen 1 und 5 vorhersagen. Stattdessen versuchen wir, die genaue Anzahl der Sterne einer Rezension zu bestimmen, indem wir sie einer von 5 Klassen zuordnen, von 1 bis 5 Sternen.
Nach dem Training kann das Modell Rezensionen mit 1 oder 5 Sternen deutlich besser vorhersagen als die differenzierteren Rezensionen mit 2–4 Sternen. Das liegt vermutlich daran, dass die Stimmung darin stärker zum Ausdruck kommt.
Wir können Embeddings für die Zero-Shot-Klassifikation verwenden, ohne dafür gelabelte Trainingsdaten zu benötigen. Für jede Klasse erstellen wir ein Embedding ihres Namens oder einer kurzen Beschreibung. Um einen neuen Text nach dem Zero-Shot-Prinzip zu klassifizieren, vergleichen wir sein Embedding mit allen Klassen-Embeddings und sagen die Klasse mit der höchsten Ähnlichkeit voraus.
Wir können ein Embedding für eine Person erstellen, indem wir den Mittelwert über alle ihre Rezensionen bilden. Ebenso können wir ein Produkt-Embedding erstellen, indem wir den Mittelwert über alle Rezensionen zu diesem Produkt bilden. Um den Nutzen dieses Ansatzes zu zeigen, verwenden wir eine Teilmenge von 50.000 Rezensionen. So erfassen wir mehr Rezensionen pro Person und Produkt.
Wir bewerten den Nutzen dieser Embeddings anhand eines separaten Testdatensatzes. Dabei stellen wir die Ähnlichkeit zwischen dem Embedding einer Person und dem Produkt-Embedding in Abhängigkeit von der Bewertung dar. Interessanterweise können wir mit diesem Ansatz schon vor Erhalt des Produkts besser als durch Zufall vorhersagen, ob es der Person gefallen würde.
Clustering ist eine Möglichkeit, große Mengen an Textdaten zu erschließen. Embeddings eignen sich dafür, weil sie jeden Text als semantisch aussagekräftigen Vektor darstellen. So kann Clustering mit einem unüberwachten Verfahren verborgene Gruppen in unserem Datensatz aufdecken.
In diesem Beispiel finden wir vier unterschiedliche Cluster: eines zu Hundefutter, eines mit negativen Rezensionen und zwei mit positiven Rezensionen.
Wie kann ich die Anzahl der Token in einer Zeichenfolge ermitteln, bevor ich ein Embedding dafür erstelle?
In Python kannst du eine Zeichenfolge mit dem Tokenizer tiktoken von OpenAI in Token aufteilen.
Beispielcode:
1
2
3
4
5
6
7
8
9
10
11import tiktokendefnum_tokens_from_string(string: str, encoding_name: str) -> int:"""Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_name) num_tokens =len(encoding.encode(string))return num_tokensnum_tokens_from_string("tiktoken is great!", "cl100k_base")
Verwende für Embedding-Modelle der dritten Generation wie text-embedding-3-small die Kodierung cl100k_base.
Weitere Details und Beispielcode findest du in der Anleitung Token mit tiktoken zählen im OpenAI Cookbook.
Wie kann ich die K nächstgelegenen Embedding-Vektoren schnell abrufen?
Um große Mengen von Vektoren schnell zu durchsuchen, empfehlen wir eine Vektordatenbank. Beispiele für die Arbeit mit Vektordatenbanken und der OpenAI API findest du in unserem Cookbook auf GitHub.
Welche Distanzfunktion sollte ich verwenden?
Wir empfehlen die Kosinusähnlichkeit. Die Wahl der Distanzfunktion macht in der Regel keinen großen Unterschied.
OpenAI-Embeddings sind auf die Länge 1 normiert. Das bedeutet:
Die Kosinusähnlichkeit lässt sich allein mit einem Skalarprodukt etwas schneller berechnen
Kosinusähnlichkeit und euklidische Distanz ergeben dieselbe Rangfolge
Kann ich meine Embeddings online teilen?
Ja, unserer Kundschaft gehören ihre Eingaben und die Ausgaben unserer Modelle. Das gilt auch für Embeddings. Du bist dafür verantwortlich, dass die Inhalte, die du an unsere API übermittelst, weder gegen geltendes Recht noch gegen unsere Nutzungsbedingungen verstoßen.
Kennen die V3-Embedding-Modelle aktuelle Ereignisse?
Nein, die Modelle text-embedding-3-large und text-embedding-3-small haben kein Wissen über Ereignisse nach September 2021. Das ist in der Regel weniger einschränkend als bei Modellen zur Textgenerierung, kann aber in bestimmten Ausnahmefällen die Leistung beeinträchtigen.