Créer un styliste alimentée par l’IA avec IBM Granite et watsonx.ai

Ce tutoriel vous guidera pas à pas pour créer un styliste personnel alimenté par l’intelligence artificielle générative. Ce tutoriel utilise le grand modèle de langage (LLM) IBM Granite Vision 3.2 pour le traitement des entrées images, et Granite 3.2, avec des capacités de raisonnement améliorées, pour formuler des idées de tenue personnalisables.

Introduction

Combien de fois vous est-il arrivé de vous demander : « Comment vais-je m’habiller aujourd’hui ? Je manque d’inspiration ! » Un dilemme auquel beaucoup d’entre nous sont confrontés. Grâce aux modèles d’intelligence artificielle (IA) de pointe, fini le tracas.

Stylisme alimenté par l’IA : comment ça marche ?

Notre solution pilotée par l’IA comporte les étapes suivantes :

  1. L’utilisateur télécharge des photos de sa garde-robe actuelle, voire des articles de sa liste de souhaits, un article à la fois.
  2. L’utilisateur sélectionne les critères suivants :   
  • Occasion : décontractée ou formelle.
  • Moment de la journée : matin, après-midi ou soir.
  • Saison : hiver, printemps, été ou automne.
  • Lieu (par exemple, un café).

3. Lors de la soumission de l’entrée, le modèle multimodal Granite Vision 3.2 itère sur la liste d’images et renvoie la sortie suivante :

  • Description de l’article.
  • Catégorie : chemise, pantalon ou chaussures.
  • Occasion : décontractée ou formelle.

4. Le modèle Granite 3.2, doté d’un raisonnement renforcé, sert de styliste. Le LLM utilise la sortie du modèle Vision pour recommander une tenue adaptée à l’événement de l’utilisateur.

5. La tenue suggérée, un cadre de données portant sur les articles téléchargés par l’utilisateur et les images de la recommandation personnalisée décrite sont toutes renvoyées à l’utilisateur.

Prérequis

Vous devez disposer d’un compte IBM® Cloud pour créer un projet watsonx.ai. 

Étapes

Pour utiliser l’interface de programmation d’application (API) watsonx, vous devrez suivre les étapes suivantes.  Notez que vous pouvez également accéder à ce tutoriel sur GitHub

Étape 1. Configurer votre environnement

  1. Connectez-vous à watsonx.ai à l’aide de votre compte IBM Cloud.

  2. Créez un projet watsonx.ai.

    Vous pouvez obtenir l’ID de votre projet à partir de ce dernier. Cliquez sur l’onglet Manage (Gérer). Ensuite, copiez l’ID du projet à partir de la section Details (Détails) de la page General (Général). Vous aurez besoin de cet ID pour ce tutoriel.

Étape 2. Configurer le service d’exécution watsonx.ai et une clé d’API

  1. Créez une instance de service d’exécution watsonx.ai (choisissez le forfait Lite, qui est une instance gratuite).

  2. Générez une clé d’API.

  3. Associez le service d’exécution watsonx.ai au projet que vous avez créé dans watsonx.ai.

Étape 3. Cloner le dépôt (facultatif)

Pour une expérience plus interactive avec cet outil d’IA, clonez le dépôt GitHub et suivez les instructions de configuration dans le fichier README.md du projet styliste IA pour lancer l’application Streamlit sur votre machine. Sinon, si vous préférez suivre les étapes une à une, créez un Jupyter Notebook et poursuivez ce tutoriel.

Étape 4. Installer et importer les bibliothèques nécessaires, et configurer vos identifiants

Nous avons besoin de quelques bibliothèques et modules pour ce tutoriel. Veillez à importer les éléments suivants ; s’ils ne sont pas installés, vous pouvez résoudre rapidement ce problème grâce à l’installation pip.

# Install required packages
!pip install -q image ibm-watsonx-ai
# Required imports
import getpass, os, base64, json
from ibm_watsonx_ai import Credentials
from ibm_watsonx_ai.foundation_models import ModelInference
from PIL import Image

Pour définir nos identifiants, nous avons besoin de l’élément WATSONX_APIKEY  et WATSONX_PROJECT_ID  (élément généré à l’étape 1). Nous définirons égalementURL servant de point de terminaison d’API.

WATSONX_APIKEY = getpass.getpass("Please enter your watsonx.ai Runtime API key (hit enter): ")
WATSONX_PROJECT_ID = getpass.getpass("Please enter your project ID (hit enter): ")
URL = "https://us-south.ml.cloud.ibm.com"

Nous pouvons utiliser la Credentials  classe pour encapsuler nos identifiants.

credentials = Credentials(
    url=URL,
    api_key=WATSONX_APIKEY
)

Étape 5. Configurer la requête API pour le modèle Granite Vision

Le augment_api_request_body  prend la requête utilisateur et l’image comme paramètres et augmente le corps de la requête API. Nous utiliserons cette fonction à chaque itération d’inférence du modèle Vision.

def augment_api_request_body(user_query, image):
    messages = [
        {
            "role": "user",
            "content": [{
                "type": "text",
                "text": user_query
            },
            {
                "type": "image_url",
                "image_url": {
                    "url": f"data:image/jpeg;base64,{image}"
                }
            }]
        }
    ]
return messages

Nous pouvons également instancier l’interface du modèle en utilisant ModelInference  (classe).

model = ModelInference(
    model_id="ibm/granite-vision-3-2-2b",
    credentials=credentials,
    project_id=WATSONX_PROJECT_ID,
    params={
        "max_tokens": 400,
        "temperature": 0
    }
)

Étape 6. Encoder les images

Pour encoder nos images d’une manière assimilable par le LLM, nous le ferons en octets, puis nous les décoderons en représentation UTF-8. Dans ce cas, nos images se trouvent dans le répertoire d’images local. Vous trouverez des exemples d’images dans le répertoire styliste IA de notre dépôt GitHub.

directory = "images" #directory name
images = []
filenames = []
for filename in os.listdir(directory):
    if filename.endswith(".jpeg") or filename.endswith(".png"):
        filepath = directory + '/' + filename
        with open(filepath, "rb") as f:
            images.append(base64.b64encode(f.read()).decode('utf-8'))
        filenames.append(filename)

Étape 7. Catégoriser les entrées avec le modèle Vision

Maintenant que nous avons chargé et encodé nos images, nous pouvons interroger le modèle Vision. Notre prompt est adapté à la sortie souhaitée afin de limiter la créativité du modèle lorsque nous recherchons une sortie JSON valide. Nous stockerons la description, la catégorie et l’occasion de chaque image dans une liste appelée closet .

user_query = """Provide a description, category, and occasion for the clothing item or shoes in this image.
                Classify the category as shirt, pants, or shoes.
                Classify the occasion as casual or formal.
                Ensure the output is valid JSON. Do not create new categories or occasions. Only use the allowed classifications.
                Your response should be in this schema:
                {
                    "description": "<description>",
                    "category": "<category>",
                    "occasion": "<occasion>"
                }
                """

image_descriptions = []
for i in range(len(images)):
    image = images[i]
    message = augment_api_request_body(user_query, image)
    response = model.chat(messages=message)
    result = response['choices'][0]['message']['content']
    print(result)
    image_descriptions.append(result)

Output:

{
    "description": "A pair of polished brown leather dress shoes with a brogue detailing on the toe box and a classic oxford design.",
    "category": "shoes",
    "occasion": "formal"
}
{
    "description": "A pair of checkered trousers with a houndstooth pattern, featuring a zippered pocket and a button closure at the waist.",
    "category": "pants",
"occasion": "casual"
}
{
    "description": "A light blue, button-up shirt with a smooth texture and a classic collar, suitable for casual to semi-formal occasions.",
    "category": "shirt",
    "occasion": "casual"
}
{
    "description": "A pair of khaki pants with a buttoned waistband and a button closure at the front.",
    "category": "pants",
    "occasion": "casual"
}
{
    "description": "A blue plaid shirt with a collar and long sleeves, featuring chest pockets and a button-up front.",
    "category": "shirt",
    "occasion": "casual"
}
{
    "description": "A pair of bright orange, short-sleeved t-shirts with a crew neck and a simple design.",
    "category": "shirt",
    "occasion": "casual"
}
{
    "description": "A pair of blue suede sneakers with white laces and perforations, suitable for casual wear.",
    "category": "shoes",
    "occasion": "casual"
}

{
    "description": "A pair of red canvas sneakers with white laces, isolated on a white background.",
    "category": "shoes",
    "occasion": "casual"
}
{
    "description": "A pair of grey dress pants with a smooth texture and a classic design, suitable for formal occasions.",
    "category": "pants",
    "occasion": "formal"
}
{
    "description": "A plain white T-shirt with short sleeves and a crew neck, displayed from the front and back.",
    "category": "shirt",
    "occasion": "casual"
}
{
    "description": "A black short-sleeved t-shirt with a crew neck and a simple design.",
    "category": "shirt",
    "occasion": "casual"
}
{
    "description": "Black pants with a zippered pocket and a buttoned fly, showing the waistband and pocket details.",
    "category": "pants",
    "occasion": "casual"
}
{
    "description": "A pair of tan leather boots with a chunky sole and a high-top design, suitable for casual wear.",
    "category": "shoes",
    "occasion": "casual"
}

Étape 8. Générer des tenues avec le modèle de raisonnement

Maintenant que nous avons catégorisé chaque vêtement et chaque chaussure, il sera beaucoup plus facile pour le modèle de raisonnement de générer une tenue pour l’occasion sélectionnée. Instancions et interrogeons le modèle de raisonnement.

reasoning_model = ModelInference(
    model_id="ibm/granite-3-2-8b-instruct",
    credentials=credentials,
    project_id=WATSONX_PROJECT_ID
)

Pour aligner les noms de fichiers avec les descriptions d’images, nous pouvons énumérer les descriptions d’images et créer une liste de dictionnaires où nous stockons la description, la catégorie, l’occasion et le nom de fichier pour chaque article dans les champs correspondants.

# Add filenames to the image descriptions
closet = []
for i, desc in enumerate(image_descriptions):
    desc_dict = json.loads(desc)
    desc_dict['filename'] = filenames[i]
    image_descriptions[i] = json.dumps(desc_dict)

closet = [json.loads(js) for js in image_descriptions]

Interrogeons maintenant le modèle Granite 3.2 avec un raisonnement pour produire une tenue correspondant aux critères spécifiés en utilisant la closet  liste.

occasion = input("Enter the occasion") #casual or formal (e.g. "casual")
time_of_day = input("Enter the time of day") #morning, afternoon or evening (e.g. "morning")
location = input("Enter the location") #any location (e.g. "park")
season = input("Enter the season") #spring, summer, fall or winter (e.g. "fall")

prompt = f"""Use the description, category, and occasion of the clothes in my closet to put together an outfit for a {occasion} {time_of_day} at the {location}. The event takes place in the {season} season. Make sure to return only one shirt, bottoms, and shoes. Use the description, category, and occasion provided. Do not classify the items yourself. Include the file name of each image in your output along with the file extension. Here are the items in my closet: {closet}"""

messages = [
        {"role": "control",
        "content": "thinking"},
        {"role": "user",
        "content": [
                {"type": "text",
                 "text": f"{prompt}"}
            ]}
        ]
outfit = reasoning_model.chat(messages=messages)['choices'][0]['message']['content']
print(outfit)

Output

Voici mon mécanisme de pensée :
- La tenue doit être adaptée à une matinée décontractée au
parc en automne.
- Je choisirais une chemise, un pantalon et une paire de chaussures qui correspondent à la catégorie « décontractée ».
- J’éviterais les vêtements formels ou trop habillés et choisirais des vêtements confortables pour les activités au parc.

Voici ma réponse :

Pour une matinée décontractée au parc à l’automne, je suggère la tenue suivante :

1. **Chemise** : une chemise bleue à carreaux avec un col et des manches longues (fichier : ’image13.jpeg’)
- Le motif à carreaux est classique pour l’automne et s’associe bien aux environnements de parc décontractés. Les manches longues offrent une certaine protection contre les températures matinales plus froides.

2. **Pantalon** : pantalon kaki avec ceinture boutonnée et fermeture boutonnée sur le devant (fichier : ’image7.jpeg’)
- Le kaki est un choix polyvalent qui s’accorde bien avec le style décontracté et offre un bel équilibre avec la chemise à carreaux. C’est pratique et confortable pour se promener.

3. **Chaussures** : une paire de boots en cuir beige à semelle épaisse et tige montante (fichier : ’image3.jpeg’)
- Les boots en cuir beige clair sont une option élégante et confortable. La semelle épaisse offre une bonne adhérence et un bon maintien, idéal pour parcourir les sentiers ou les terrains accidentés.

Cette combinaison offre un look informel et soigné, idéal pour une sortie matinale décontractée, tout en restant confortable et pratique.

Grâce à cette description de tenue générée, nous pouvons également afficher les vêtements que le modèle recommande. Pour ce faire, nous pouvons simplement extraire les noms de fichiers. Si le modèle mentionne deux fois le même nom de fichier, il est important de vérifier si l’image n’a pas déjà été affichée au fur et à mesure que nous itérons la liste des images. Pour ce faire, nous stockons les images affichées dans la selected_items  liste. Enfin, nous affichons les articles sélectionnés.

selected_items = []
#extract the images of clothing that the model recommends
for item, uploaded_file in zip(closet, images):
    if item['filename'].lower() in outfit.lower() and not any(key['filename'] == item['filename'] for key in selected_items):
        selected_items.append({
            'image': uploaded_file,
            'category': item['category'],
            'filename': item['filename']
        })

#display the selected clothing items
if len(selected_items) > 0:
    for item in selected_items:
        display(Image.open(directory + '/' + item['filename']))

Conclusion

Dans ce tutoriel, vous avez construit un système qui utilise l’IA pour fournir des conseils vestimentaires adaptés à l’événement spécifié par l’utilisateur. À partir de photos ou de captures d’écran des vêtements de l’utilisateur, les tenues sont personnalisées pour répondre aux critères spécifiés. Le modèle Granite-Vision-3-2-2b a joué un rôle critique dans l’étiquetage et la catégorisation de chaque article. De plus, le modèle Granite-3-2-8B-instruct a exploité ses capacités de raisonnement pour générer des idées de tenues personnalisées.

Les prochaines étapes pour développer cette application peuvent inclure :

  • Personnalisation des tenues en fonction du style, de la morphologie, de la palette de couleurs préférée de l’utilisateur, etc.
  • Élargir les critères pour inclure des vestes et des accessoires. Par exemple, le système peut proposer un blazer à , officielle en plus de la chemise, du pantalon et des chaussures sélectionnés.
  • Agir en tant qu’assistant personnel en fournissant des recommandations de produits e-commerce et des prix adaptés au style et au budget propres à chaque utilisateur.
  • Ajouter une fonctionnalité de chatbot pour poser des questions au LLM sur chaque tenue.
  • Fournir une expérience d’essayage virtuel qui utilise un selfie de l’utilisateur pour simuler le look final.
Solutions connexes
IBM watsonx.ai

Entraînez, validez, réglez et déployez une IA générative, des modèles de fondation et des capacités de machine learning avec IBM watsonx.ai, un studio d’entreprise nouvelle génération pour les générateurs d’IA. Créez des applications d’IA en peu de temps et avec moins de données.

Découvrir watsonx.ai
Solutions d’intelligence artificielle

Mettez l’IA au service de votre entreprise en vous appuyant sur l’expertise de pointe d’IBM dans le domaine de l’IA et sur son portefeuille de solutions.

Découvrir les solutions d’IA
Conseils et services en matière d’IA

Réinventez les workflows et les opérations critiques en ajoutant l’IA pour optimiser les expériences, la prise de décision et la valeur métier en temps réel.

Découvrir les services d’IA
Passez à l’étape suivante

Bénéficiez d’un accès centralisé aux fonctionnalités couvrant le cycle de développement de l’IA. Produisez des solutions IA puissantes offrant des interfaces conviviales, des workflows et un accès à des API et SDK conformes aux normes du secteur.

Découvrir watsonx.ai Réserver une démo en direct