
Présentation de l’aperçu de Gemini Embeddings 2 | Vers la science des données
une version préliminaire de son dernier modèle d’intégration. Ce modèle est remarquable pour une raison principale. Il peut intégrer du texte, des PDF, des images, de l’audio et de la vidéo, ce qui en fait un guichet unique pour intégrer à peu près tout ce que vous voudriez y ajouter.
Si vous débutez dans l’intégration, vous vous demandez peut-être de quoi il s’agit, mais il s’avère que l’intégration est l’une des pierres angulaires de la génération augmentée par récupération ou RAG, comme on l’appelle. À son tour, RAG est l’une des applications les plus fondamentales du traitement moderne de l’intelligence artificielle.
Un bref récapitulatif de RAG et Embedding
RAG est une méthode de regroupement, de codage et de stockage d’informations qui peuvent ensuite être recherchées à l’aide de fonctions de similarité qui font correspondre les termes de recherche aux informations intégrées. La partie codage transforme tout ce que vous recherchez en une série de nombres appelés vecteurs — c’est ce que fait l’intégration. Les vecteurs (plongements) sont ensuite généralement stockés dans une base de données vectorielles.
Lorsqu’un utilisateur saisit un terme de recherche, celui-ci est également codé sous forme d’intégrations et les vecteurs résultants sont comparés au contenu de la base de données de vecteurs, généralement à l’aide d’un processus appelé similarité cosinus. Plus les vecteurs de termes de recherche sont proches de parties des informations contenues dans le magasin de vecteurs, plus les termes de recherche sont pertinents par rapport à ces parties des données stockées. De grands modèles de langage peuvent interpréter tout cela et récupérer et afficher les parties les plus pertinentes pour l’utilisateur.
Il y a tout un tas d’autres choses qui entourent cela, comme la façon dont les données d’entrée doivent être divisées ou fragmentées, mais l’intégration, le stockage et la récupération sont les principales caractéristiques du traitement RAG. Pour vous aider à visualiser, voici un schéma simplifié d’un processus RAG.

Alors, quelle est la particularité de Gemini Embedding ?
Ok, maintenant que nous savons à quel point l’intégration est cruciale pour RAG, pourquoi le nouveau modèle d’intégration Gemini de Google est-il si important ? Simplement ceci. Les modèles d’intégration traditionnels – à quelques exceptions près – ont été limités au texte, aux PDF et à d’autres types de documents, et peut-être aux images d’un seul coup.
Ce que Gemini propose désormais, c’est une véritable entrée multimodale pour les intégrations. Cela signifie du texte, des PDF et des documents, des images, de l’audio et vidéo. Étant un modèle d’intégration d’aperçu, il existe actuellement certaines limitations de taille sur les entrées, mais j’espère que vous pourrez voir la direction du déplacement et à quel point cela pourrait être utile.
Limites d’entrée
J’ai mentionné qu’il existe des limites à ce que nous pouvons saisir dans le nouveau modèle d’intégration Gemini. Ils sont:
- Texte: Jusqu’à 8 192 jetons d’entrée, soit environ 6 000 mots
- Images : Jusqu’à 6 images par demande, prenant en charge les formats PNG et JPEG
- Vidéos : Un maximum de 2 minutes de vidéo aux formats MP4 et MOV
- Audio : Une durée maximale de 80 secondes, prend en charge MP3, WAV.
- Documents : Jusqu’à 6 pages
Ok, il est temps de voir le nouveau modèle d’intégration en pratique avec quelques exemples de codage Python.
Mise en place d’un environnement de développement
Pour commencer, mettons en place un environnement de développement standard pour séparer nos projets. J’utiliserai l’outil UV pour cela, mais n’hésitez pas à utiliser les méthodes auxquelles vous êtes habitué.
$ uv init embed-test --python 3.13
$ cd embed-test
$ uv venv
$ source embed-test/bin/activate
$ uv add google-genai jupyter numpy scikit-learn audioop-lts
# To run the notebook, type this in
$ uv run jupyter notebook
Vous aurez également besoin d’une clé API Gemini, que vous pouvez obtenir sur la page d’accueil d’AI Studio de Google.
Recherchez un lien Obtenir la clé API en bas à gauche de l’écran après vous être connecté. Prenez-en note car vous en aurez besoin plus tard.
Veuillez noter qu’en dehors du fait d’être un utilisateur de leurs produits, je n’ai aucune association ou affiliation avec Google ou l’une de ses filiales.
Code de configuration
Je ne parlerai pas beaucoup de l’intégration de texte ou de documents PDF, car ceux-ci sont relativement simples et sont largement traités ailleurs. Au lieu de cela, nous examinerons l’intégration d’images et d’audio, qui sont moins courants.
Il s’agit du code de configuration commun à tous nos exemples.
import os
import numpy as np
from pydub import AudioSegment
from google import genai
from google.genai import types
from sklearn.metrics.pairwise import cosine_similarity
from IPython.display import display, Image as IPImage, Audio as IPAudio, Markdown
client = genai.Client(api_key='YOUR_API_KEY')
MODEL_ID = "gemini-embedding-2-preview"
Exemple 1 — Incorporation d’images
Pour cet exemple, nous allons intégrer 3 images : une d’un chat roux, une d’un Labrador et une d’un dauphin jaune. Nous établirons ensuite une série de questions ou d’expressions, chacune plus spécifique ou liée à l’une des images, et verrons si le modèle peut sélectionner l’image la plus appropriée pour chaque question. Pour ce faire, il calcule un score de similarité entre la question et chaque image. Plus ce score est élevé, plus la question est pertinente par rapport à l’image.
Voici les images que j’utilise.

J’ai donc deux questions et deux phrases.
- Quel animal est jaune
- Qui s’appelle très probablement Rover
- Il se passe quelque chose de louche ici
- Une image parfaite
# Some helper function
#
# embed text
def embed_text(text: str) -> np.ndarray:
"""Encode a text string into an embedding vector.
Simply pass the string directly to embed_content.
"""
result = client.models.embed_content(
model=MODEL_ID,
contents=[text],
)
return np.array(result.embeddings[0].values)
# Embed an image
def embed_image(image_path: str) -> np.ndarray:
# Determine MIME type from extension
ext = image_path.lower().rsplit('.', 1)[-1]
mime_map = {'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg'}
mime_type = mime_map.get(ext, 'image/png')
with open(image_path, 'rb') as f:
image_bytes = f.read()
result = client.models.embed_content(
model=MODEL_ID,
contents=[
types.Part.from_bytes(data=image_bytes, mime_type=mime_type),
],
)
return np.array(result.embeddings[0].values)
# --- Define image files ---
image_files = ["dog.png", "cat.png", "dolphin.png"]
image_labels = ["dog","cat","dolphin"]
# Our questions
text_descriptions = [
"Which animal is yellow",
"Which is most likely called Rover",
"There's something fishy going on here",
"A purrrfect image"
]
# --- Compute embeddings ---
print("Embedding texts...")
text_embeddings = np.array([embed_text
print("Embedding images...")
image_embeddings = np.array([embed_image(f) for f in image_files])
# Use cosine similarity for matches
text_image_sim = cosine_similarity(text_embeddings, image_embeddings)
# Print best matches for each text
print("\nBest image match for each text:")
for i, text in enumerate(text_descriptions):
# np.argmax looks across the row (i) to find the highest score among the columns
best_idx = np.argmax(text_image_sim[i, :])
best_image = image_labels[best_idx]
best_score = text_image_sim[i, best_idx]
print(f" \"{text}\" => {best_image} (score: {best_score:.3f})")
Voici le résultat.
Embedding texts...
Embedding images...
Best image match for each text:
"Which animal is yellow" => dolphin (score: 0.399)
"Which is most likely called Rover" => dog (score: 0.357)
"There's something fishy going on here" => dolphin (score: 0.302)
"A purrrfect image" => cat (score: 0.368)
Pas trop mal. Le modèle a donné les mêmes réponses que j’aurais données. Et toi?
Exemple 2 — Intégration de l’audio
Pour l’audio, j’ai utilisé la voix d’un homme décrivant une sortie de pêche au cours de laquelle il aperçoit un dauphin jaune vif. Cliquez ci-dessous pour entendre l’audio complet. Cela dure environ 37 secondes.
Si vous ne souhaitez pas écouter, voici la transcription complète.
Bonjour, je m’appelle Glen et je veux vous parler d’un spectacle fascinant dont j’ai été témoin mardi après-midi dernier alors que je pêchais en mer avec des amis. C’était une journée chaude avec un soleil jaune dans le ciel. Nous pêchions le thon et n’avions aucune chance d’attraper quoi que ce soit. Bon sang, nous avons dû passer la majeure partie de 5 heures là-bas. Nous étions donc plutôt maussades alors que nous retournions vers la terre ferme. Mais soudain, et je vous jure que ce n’est pas un mensonge, nous avons vu un banc de dauphins. Non seulement cela, mais l’un d’eux était de couleur jaune vif. Nous n’avons jamais rien vu de tel de notre vie, mais je peux vous dire que toutes les pensées d’une mauvaise journée de pêche ont disparu. C’était fascinant.
Voyons maintenant si nous pouvons préciser où l’orateur parle d’avoir vu un dauphin jaune.
Normalement, lorsqu’il s’agit d’intégrations, nous ne nous intéressons qu’aux propriétés générales, aux idées et aux concepts contenus dans les informations source. Si nous voulons affiner des propriétés spécifiques, telles que l’endroit où se produit une phrase particulière dans un fichier audio ou l’endroit où se produit dans une vidéo une action ou un événement particulier, il s’agit d’une tâche légèrement plus complexe. Pour ce faire, dans notre exemple, nous devons d’abord diviser l’audio en morceaux plus petits avant d’intégrer chaque morceau. Nous effectuons ensuite une recherche de similarité sur chaque morceau intégré avant de produire notre réponse finale.
# --- HELPER FUNCTIONS ---
def embed_text(text: str) -> np.ndarray:
result = client.models.embed_content(model=MODEL_ID, contents=[text])
return np.array(result.embeddings[0].values)
def embed_audio(audio_path: str) -> np.ndarray:
ext = audio_path.lower().rsplit('.', 1)[-1]
mime_map = {'wav': 'audio/wav', 'mp3': 'audio/mp3'}
mime_type = mime_map.get(ext, 'audio/wav')
with open(audio_path, 'rb') as f:
audio_bytes = f.read()
result = client.models.embed_content(
model=MODEL_ID,
contents=[types.Part.from_bytes(data=audio_bytes, mime_type=mime_type)],
)
return np.array(result.embeddings[0].values)
# --- MAIN SEARCH SCRIPT ---
def search_audio_with_embeddings(audio_file_path: str, search_phrase: str, chunk_seconds: int = 5):
print(f"Loading {audio_file_path}...")
audio = AudioSegment.from_file(audio_file_path)
# pydub works in milliseconds, so 5 seconds = 5000 ms
chunk_length_ms = chunk_seconds * 1000
audio_embeddings = []
temp_files = []
print(f"Slicing audio into {chunk_seconds}-second pieces...")
# 2. Chop the audio into pieces
# We use a loop to jump forward by chunk_length_ms each time
for i, start_ms in enumerate(range(0, len(audio), chunk_length_ms)):
# Extract the slice
chunk = audio[start_ms:start_ms + chunk_length_ms]
# Save it temporarily to your folder so the Gemini API can read it
chunk_name = f"temp_chunk_{i}.wav"
chunk.export(chunk_name, format="wav")
temp_files.append(chunk_name)
# 3. Embed this specific chunk
print(f" Embedding chunk {i + 1}...")
emb = embed_audio(chunk_name)
audio_embeddings.append(emb)
audio_embeddings = np.array(audio_embeddings)
# 4. Embed the search text
print(f"\nEmbedding your search: '{search_phrase}'...")
text_emb = np.array([embed_text(search_phrase)])
# 5. Compare the text against all the audio chunks
print("Calculating similarities...")
sim_scores = cosine_similarity(text_emb, audio_embeddings)[0]
# Find the chunk with the highest score
best_chunk_idx = np.argmax(sim_scores)
best_score = sim_scores[best_chunk_idx]
# Calculate the timestamp
start_time = best_chunk_idx * chunk_seconds
end_time = start_time + chunk_seconds
print("\n--- Results ---")
print(f"The concept '{search_phrase}' most closely matches the audio between {start_time}s and {end_time}s!")
print(f"Confidence score: {best_score:.3f}")
# --- RUN IT ---
# Replace with whatever phrase you are looking for!
search_audio_with_embeddings("fishing2.mp3", "yellow dolphin", chunk_seconds=5)
Voici le résultat.
Loading fishing2.mp3...
Slicing audio into 5-second pieces...
Embedding chunk 1...
Embedding chunk 2...
Embedding chunk 3...
Embedding chunk 4...
Embedding chunk 5...
Embedding chunk 6...
Embedding chunk 7...
Embedding chunk 8...
Embedding your search: 'yellow dolphin'...
Calculating similarities...
--- Results ---
The concept 'yellow dolphin' most closely matches the audio between 25s and 30s!
Confidence score: 0.643
C’est assez précis. En réécoutant l’audio, l’expression « dauphin » est mentionnée à la marque des 25 secondes et « jaune vif » est mentionnée à la marque des 29 secondes. Plus tôt dans l’audio, j’ai délibérément introduit l’expression « soleil jaune » pour voir si le modèle serait confus, mais il a bien géré la distraction.
Résumé
Cet article présente Gemini Embeddings 2 Preview en tant que nouveau modèle d’intégration tout-en-un de Google pour le texte, les PDF, les images, l’audio et la vidéo. Cela explique pourquoi cela est important pour les systèmes RAG, où les intégrations aident à transformer le contenu et les requêtes de recherche en vecteurs dont la similarité peut être comparée.
J’ai ensuite parcouru deux exemples Python montrant comment générer des intégrations d’images et d’audio avec le SDK Google GenAI, utiliser le score de similarité pour faire correspondre les requêtes de texte aux images et diviser l’audio en segments plus petits pour identifier la partie d’un enregistrement parlé qui est sémantiquement la plus proche d’une expression de recherche donnée.
La possibilité d’effectuer des recherches sémantiques au-delà du simple texte et d’autres documents est une véritable aubaine. Le nouveau modèle d’intégration de Google promet d’ouvrir une toute nouvelle série de possibilités pour les systèmes multimodaux de recherche, de récupération et de recommandation, rendant ainsi beaucoup plus facile le travail avec des images, de l’audio, de la vidéo et des documents dans un seul pipeline. À mesure que les outils évoluent, ils pourraient devenir une base très pratique pour des applications RAG plus riches qui comprennent bien plus que le texte seul.
Vous pouvez trouver le billet de blog original annonçant Gemini Embeddings 2 en utilisant le lien ci-dessous.
https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-embedding-2



