Cursus
En tant qu’ingénieur·e GenAI, je m’efforce de rester à jour sur les derniers outils et technologies en lisant et en explorant en continu les nouveautés. Récemment, je suis tombé·e sur un article de recherche de Microsoft présentant BridgeTower, un modèle qui facilite l’intégration de la vision et du langage, rendant les tâches multimodales bien plus simples à mettre en œuvre.
Dans ce guide, je vous montre comment créer un système de recherche image‑texte simple mais performant en utilisant BridgeTower depuis la bibliothèque Hugging Face Transformers. Ce tutoriel, pensé pour les débutants, vous guide pas à pas :
- Installation des bibliothèques nécessaires.
- Traitement des images et du texte avec BridgeTower.
- Génération d’embeddings pour les images et le texte.
- Comparaison de ces embeddings via la similarité cosinus.
À la fin, vous disposerez d’un système opérationnel capable d’associer efficacement des images à des requêtes textuelles, illustrant la puissance et la simplicité de l’IA multimodale.
Qu’est-ce que BridgeTower ?
Le modèle BridgeTower, tel qu’expliqué dans l’article BridgeTower: Building Bridges Between Encoders in Vision-Language Representative Learning par Xiao Xu et al., vise à améliorer la coopération entre modèles de vision et de langage.
Imaginez une tâche où le modèle doit comprendre à la fois une image et une description textuelle, comme « un chien courant dans un parc ».
Classiquement, le modèle traite l’image et le texte séparément via des encodeurs dédiés. BridgeTower ajoute un « pont » entre ces encodeurs et l’encodeur cross‑modal (qui combine vision et langage), afin d’améliorer leurs interactions à chaque étape.
Par exemple, en traitant l’image du chien, l’encodeur de vision détecte sa forme et son mouvement. En parallèle, l’encodeur de langage saisit les mots « courir » et « chien ».
Le pont permet à ces informations de réellement interagir, aidant le modèle à relier plus finement les indices visuels et textuels. Le modèle gagne ainsi en performance pour des tâches comme la génération de légendes d’images ou le question‑réponse, sans surcoût de calcul majeur ni perte de vitesse.
Structure des dossiers de l’application
Gardons une structure claire et organisée. Votre répertoire de projet doit ressembler à ceci :
/image-search-app/
│
├── app.py # Frontend (Streamlit UI)
├── search.py # Backend logic (embeddings & similarity search)
├── images/ # Directory for uploaded images
│ ├── image1.jpg
│ ├── image2.png
│ ├── image3.jpeg
│
└── requirements.txt # Python dependencies
- app.py : gère le frontend et les interactions utilisateur.
- search.py : contient la logique de génération d’embeddings et de recherche.
- images/ : stocke les images téléversées.
- requirements.txt : répertorie les bibliothèques requises.
Configuration et installation
Avant d’entrer dans le code, configurons l’environnement pour un développement et des tests fluides. Suivez ces étapes :
1. Installer les dépendances
Assurez‑vous d’abord d’avoir Python installé (version 3.7 ou supérieure recommandée). Exécutez ensuite la commande suivante dans votre terminal pour installer les bibliothèques nécessaires :
pip install torch transformers streamlit Pillow
- torch : le framework de deep learning utilisé pour exécuter le modèle BridgeTower.
- transformers : fournit des modèles pré‑entraînés comme BridgeTower pour un traitement efficace du texte et des images.
- streamlit : un framework web léger pour créer une interface utilisateur interactive.
- Pillow : bibliothèque de traitement d’images, utilisée pour gérer les téléversements et le redimensionnement.
2. Préparer des images d’exemple
Pour tester l’application, placez quelques images d’exemple dans le répertoire /images. Vérifiez qu’elles sont dans des formats pris en charge comme JPG, PNG ou JPEG, largement compatibles avec la plupart des bibliothèques.
Variez les images pour permettre au modèle de retrouver précisément celles correspondant à la requête textuelle.
Logique centrale de BridgeTower expliquée
Le cœur de l’application se divise en deux composants principaux : le backend (search.py) et le frontend (app.py). Chacun joue un rôle clé pour assurer le bon fonctionnement de l’application.
Logique backend (search.py)
Ce fichier regroupe la logique des embeddings texte et image, ainsi que le mécanisme de recherche.
1. Importer les bibliothèques
from transformers import BridgeTowerProcessor, BridgeTowerForImageAndTextRetrieval
from PIL import Image
import torch.nn.functional as F
import os
- BridgeTowerProcessor : classe utilitaire qui prépare les données (images et texte) au bon format pour le modèle BridgeTower. Elle effectue notamment la tokenisation du texte et le prétraitement des images.
- BridgeTowerForImageAndTextRetrieval : classe de modèle pré‑entraîné BridgeTower, conçue spécifiquement pour la recherche image‑texte (trouver l’image la plus pertinente pour une requête textuelle, et inversement).
- PIL (Python Imaging Library) sert à manipuler les images. Ici, on l’utilise pour ouvrir et transformer les images (redimensionnement, recadrage) avant de les fournir au modèle.
- torch.nn.functional propose diverses fonctions (activations, fonctions de perte, opérations sur tenseurs) couramment utilisées avec les réseaux de neurones PyTorch.
- os permet d’interagir avec le système d’exploitation (lecture de fichiers, vérification de répertoires, gestion des chemins, etc.).
2. Charger le modèle et le processeur
processor = BridgeTowerProcessor.from_pretrained("BridgeTower/bridgetower-base-itm-mlm")
model = BridgeTowerForImageAndTextRetrieval.from_pretrained("BridgeTower/bridgetower-base-itm-mlm")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
Cela initialise le modèle et le processeur nécessaires à la génération des embeddings.
3. Trouver la meilleure correspondance
def image_search(query, image_dir):
image_files = [os.path.join(image_dir, img) for img in os.listdir(image_dir) if img.lower().endswith(('jpg', 'jpeg', 'png'))]
scores = {}
for img_path in image_files:
image = Image.open(img_path).convert("RGB")
encoding = processor(text=query, images=image, return_tensors="pt").to(device)
outputs = model(**encoding)
scores[img_path] = outputs.logits[0, 1].item()
best_match = max(scores, key=scores.get)
return best_match
Fonctionnement :
- La fonction image_search traite la requête texte pour générer son embedding grâce au modèle.
- Chaque image est également traitée pour générer son propre embedding.
- Les embeddings sont comparés via les logits de sortie du modèle.
- La similarité cosinus est calculée entre les embeddings texte et image.
- L’image au score de similarité le plus élevé est renvoyée comme meilleure correspondance.
Interface frontend (app.py)
Ce fichier utilise Streamlit pour proposer une interface conviviale.
1. Importer les bibliothèques
import streamlit as st
from search import search_best_match
import os
2. Construire l’interface
st.title("🖼️ AI-Powered Image Search App")
uploaded_files = st.file_uploader("Upload images", accept_multiple_files=True, type=['jpg', 'jpeg', 'png'])
image_folder = 'images'
os.makedirs(image_folder, exist_ok=True)
if uploaded_files:
for uploaded_file in uploaded_files:
with open(os.path.join(image_folder, uploaded_file.name), 'wb') as f:
f.write(uploaded_file.getbuffer())
st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
Les utilisateurs peuvent téléverser plusieurs images. Elles sont enregistrées dans le dossier images/ et affichées.
3. Ajouter une requête de recherche
query = st.text_input("Enter your search query:")
if query and uploaded_files:
best_match, score = search_best_match(image_folder, query)
st.write("### Most Relevant Image:")
st.image(best_match, caption=f"Score: {score:.4f}", use_column_width=True)
L’utilisateur saisit une requête. L’application recherche l’image la plus pertinente et l’affiche.
Implémentation complète : créer une application de recherche d’images avec BridgeTower et Streamlit
1. search.py - Logique backend
from transformers import BridgeTowerProcessor, BridgeTowerForImageAndTextRetrieval
from PIL import Image
import torch
import torch.nn.functional as F
import os
# Load Bridgetower processor and model
processor = BridgeTowerProcessor.from_pretrained("BridgeTower/bridgetower-base-itm-mlm")
model = BridgeTowerForImageAndTextRetrieval.from_pretrained("BridgeTower/bridgetower-base-itm-mlm")
# Search for the best matching image
def image_search(query, image_dir):
image_files = [os.path.join(image_dir, img) for img in os.listdir(image_dir) if img.lower().endswith(('jpg', 'jpeg', 'png'))]
scores = {}
for img_path in image_files:
image = Image.open(img_path).convert("RGB")
encoding = processor(text=query, images=image, return_tensors="pt").to(device)
outputs = model(**encoding)
scores[img_path] = outputs.logits[0, 1].item()
best_match = max(scores, key=scores.get)
return best_match
2. app.py - Interface Streamlit
import streamlit as st
from search import image_search
import os
# Title of the app
st.title("🖼️ Image Search Application with BridgeTower")
# Image upload section
uploaded_files = st.file_uploader("Upload your images", accept_multiple_files=True, type=['jpg', 'jpeg', 'png'])
# Create image folder if not exists
image_folder = 'images'
os.makedirs(image_folder, exist_ok=True)
if uploaded_files:
for uploaded_file in uploaded_files:
with open(os.path.join(image_folder, uploaded_file.name), 'wb') as f:
f.write(uploaded_file.getbuffer())
st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
# Text input for query
query = st.text_input("Enter your search query:")
# Display search results
if query and uploaded_files:
best_match, score = image_search(image_folder, query)
st.write("### Most Relevant Image:")
st.image(best_match, caption=f"Similarity Score: {score:.4f}", use_column_width=True)
3. Lancer l’application
streamlit run app.py
Exemple d’application BridgeTower et Streamlit
Voici un exemple en action ! Une image est téléversée et l’utilisateur saisit la requête « cat ». L’application analyse rapidement l’image et le texte, puis les met en correspondance grâce au modèle BridgeTower.
Elle trouve la meilleure correspondance et affiche correctement l’image d’un chat. Cela illustre la capacité de l’application à relier images et texte pour fournir des résultats précis.
La curiosité ne doit pas s’arrêter là. Le potentiel de ce type d’applications va bien au‑delà de cette première version et ouvre des perspectives passionnantes d’évolution et d’innovation. Les possibilités d’améliorer l’expérience, les performances et les fonctionnalités sont vastes. Voici quelques pistes pour passer à l’échelle.
Améliorations futures avec BridgeTower
Plusieurs améliorations sont possibles, par exemple :
Ajouter un index FAISS pour accélérer la recherche d’images
Implémentez un index FAISS pour accélérer les recherches sur de grands jeux de données. Vous convertirez les images en vecteurs de caractéristiques, construirez un index et effectuerez des recherches de similarité rapidement, afin de garder des temps de réponse efficaces à mesure que la base d’images grandit.
Déployer l’application sur Streamlit Cloud ou AWS
Déployez l’application sur Streamlit Cloud pour une mise en service rapide et simple, notamment si vous travaillez avec Python et Streamlit. Autrement, optez pour AWS pour davantage de contrôle, d’élasticité et une meilleure gestion du trafic à mesure que l’application se développe.
Mettre en place des mises à jour en temps réel lors des téléversements
Activez des mises à jour en temps réel pour que toute nouvelle image téléversée s’affiche instantanément chez tous les utilisateurs, sans rechargement de page. Avec des technologies comme WebSockets ou Socket.IO, vous pouvez pousser les mises à jour dès qu’une image est ajoutée, améliorant ainsi l’interactivité et l’expérience.
Conclusion
Nous avons créé une application de recherche d’images alimentée par l’IA avec BridgeTower, Streamlit et PyTorch, démontrant comment l’IA simplifie et enrichit l’interaction avec des contenus numériques.
Même si elle est pleinement fonctionnelle, des améliorations sont possibles : accélérer les recherches avec FAISS, déployer sur des plateformes comme AWS pour la scalabilité, et ajouter des mises à jour en temps réel pour une expérience plus fluide. Ce projet constitue une base solide pour innover davantage dans les systèmes de recherche intelligents.
Pour aller plus loin, nous vous recommandons ces ressources :
Ingénieur GenAI senior et créateur de contenu qui a recueilli 20 millions de vues en partageant ses connaissances sur la GenAI et la science des données.
