Crie um estilista de IA com o IBM Granite usando watsonx.ai

Neste tutorial, você será guiado durante a criação de um stylist pessoal impulsionado por IA generativa. Este tutorial aproveita o grande modelo de linguagem (LLM) IBM Granite Vision 3.2 para processar a entrada de imagens, e o Granite 3.2 com os mais recentes recursos de raciocínio aprimorado para formular ideias de trajes personalizáveis.

Introdução

Com que frequência você se pega pensando: “O que devo vestir hoje? Nem sei por onde começar a escolher peças do meu armário!” Esse dilema é compartilhado por muitos de nós. Com o uso de modelos de inteligência artificial (IA) de ponta, isso não precisa mais ser uma tarefa assustadora.

Estilo com IA: como funciona

Nossa solução orientada por IA é composta pelos seguintes estágios:

  1. O usuário faz upload de imagens de seu guarda-roupa atual ou até mesmo de itens em sua lista de desejos, um item de cada vez.
  2. O usuário seleciona os seguintes critérios:   
  • Ocasião: casual ou formal.
  • Hora do dia: manhã, tarde ou noite.
  • Estação do ano: inverno, primavera, verão ou outono.
  • Local (por exemplo, uma cafeteria).

3. Após o envio da entrada, o modelo multimodal Granite Vision 3.2 itera sobre a lista de imagens e retorna a seguinte saída:

  • Descrição do item.
  • Categorias: camisas, calças ou sapatos.
  • Ocasião: casual ou formal.

4. O modelo Granite 3.2 com raciocínio aprimorado atua como um estilista de moda. O LLM usa a saída do modelo Vision para fornecer uma recomendação de visual adequada para o evento do usuário.

5. A sugestão de visual, um quadro de dados de itens que o usuário carregou e as imagens na recomendação personalizada descrita são retornados ao usuário.

Pré-requisitos

Você precisa de uma conta do IBM Cloud para criar um projeto do watsonx.ai .

Etapas

Para utilizar a interface de programação de aplicativos (API) do watsonx, é necessário realizar as seguintes etapas.  Observe que você também pode acessar este tutorial no GitHub. 

Etapa 1. Configure seu ambiente

  1. Faça login no watsonx.ai usando sua conta do IBM Cloud.

  2. Criar um projeto do watsonx.ai.

    Você pode obter a ID do projeto a partir de seu projeto. Clique na guia Gerenciar. Em seguida, copie a ID do projeto da seção Detalhes da página Geral. Você precisa dessa ID para este tutorial.

Etapa 2. Configure o serviço watsonx.ai Runtime e a chave de API

  1. Crie uma instância do serviço watsonx.ai Runtime (escolha o plano Lite, que é uma instância gratuita).

  2. Gere uma chave de API.

  3. Associe o serviço watsonx.ai Runtime ao projeto que você criou no watsonx.ai.

Etapa 3. Clone o repositório (opcional)

Para uma experiência mais interativa ao usar essa ferramenta de IA, clone o repositório do GitHub e siga as instruções de configuração no arquivo Leiame.md no projeto AI stylist para iniciar a aplicação Streamlit em sua máquina local. Caso contrário, se preferir seguir o passo a passo, crie um Jupyter Notebook e continue com este tutorial.

Etapa 4. Instale e importe bibliotecas relevantes e configure suas credenciais

Precisamos de algumas bibliotecas e módulos para este tutorial. Certifique-se de importar os seguintes e, se eles não estiverem instalados, você pode resolver isso com uma instalação rápida do 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

Para definir nossas credenciais, precisamos dos WATSONX_APIKEY  e WATSONX_PROJECT_ID  que você gerou na etapa 1. Também definiremos oURL servindo como endpoint da 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"

Podemos usar a Credentials  classe para encapsular nossas credenciais passadas.

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

Etapa 5. Configure a solicitação de API para o modelo Granite Vision

augment_api_request_body  função recebe a consulta e a imagem do usuário como parâmetros e aumenta o corpo da solicitação de API. Usaremos essa função em cada iteração de inferência do modelo de visão.

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

Também podemos instanciar a interface do modelo usando a 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
    }
)

Etapa 6. Codifique imagens

Para codificar nossas imagens de uma maneira que seja digerível para o LLM, vamos codificá-las para bytes que, em seguida, decodificamos para representação UTF-8. Neste caso, nossas imagens estão localizadas no diretório local de imagens. Você pode encontrar imagens de exemplo no diretório de stylists de IA em nosso repositório do 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)

Etapa 7. Categorize a entrada com o modelo Vision

Agora que carregamos e codificamos nossas imagens, podemos consultar o modelo Vision. Nosso prompt é específico para a saída desejada para limitar a criatividade do modelo enquanto buscamos um resultado JSON válido. Armazenaremos a descrição, categoria e ocasião de cada imagem em uma lista chamada 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)

Saídas:

{
    "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"
}

Etapa 8. Gere trajes com o modelo de raciocínio

Agora que temos cada item de roupa e calçado categorizado, será muito mais fácil para o modelo de raciocínio gerar um traje para a ocasião selecionada. Vamos instanciar e consultar o modelo de raciocínio.

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

Para alinhar os nomes dos arquivos com as descrições das imagens, podemos enumerar a lista de descrições de imagens e criar uma lista de dicionários nos quais armazenamos a descrição, categoria, evento e nome de arquivo de cada item nos respectivos campos.

# 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]

Agora, vamos consultar o modelo Granite 3.2 com um raciocínio para produzir um traje para nossos critérios especificados usando a closet  lista.

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)

Saída

Este é o meu processo de pensamento:
- A roupa precisa ser adequada para uma manhã casual no parque durante o outono.
- Selecionarei uma camisa, um par de cuecas e um par de sapatos que se encaixem na categoria de evento "casual".
- Vou evitar itens formais ou excessivamente vistosos e escolher itens confortáveis para as atividades no parque.

Aqui está minha resposta:

Para uma manhã casual no parque no outono, sugere-se o seguinte traje:

1. **Camisa**: uma camisa xadrez azul com gola e mangas longa (arquivo: 'image13.jpeg')
- A padronagem xadrez é clássica para o outono e combina bem com ambientes casuais de parques. As mangas longa oferecem proteção contra as temperaturas mais baixas da manhã.

2. **Calças**: calça caqui com cós abotoado e fechamento por botão na frente (arquivo: 'image7.jpeg')
- caqui é uma opção versátil que pode combinar com o ambiente casual e também proporcionar um bom equilíbrio com o camisa xadrez. É prático e confortável para caminhar.

3. **Sapatos**: um par de botas de couro bege com sola robusta e design de cano alto (arquivo: 'image3.jpeg')
- Botas de couro bege oferecem uma opção elegante e confortável. A sola robusta proporciona boa aderência e apoio, ideais para navegar pelas trilhas do parque ou em terreno irregular.

Essa combinação proporciona um visual relaxado e adequado para um passeio matinal casual, ao mesmo tempo em que considera o conforto e a praticidade.

Com essa descrição de equipamento gerada, também podemos exibir os itens de roupa que o modelo recomenda! Para isso, podemos simplesmente extrair os nomes dos arquivos. Caso o modelo mencione o mesmo nome de arquivo duas vezes, é importante verificar se a imagem já não foi exibida à medida que iteramos a lista de imagens. Podemos fazer isso armazenando as imagens exibidas na selected_items  lista. Por fim, podemos exibir os itens selecionados.

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']))

Conclusão

Neste tutorial, você criou um sistema que usa IA para fornecer orientação de estilo para o evento específico de um usuário. Usando fotos ou capturas de tela das roupas do usuário, os trajes são personalizados para atender aos critérios especificados. O modelo Granite-Vision-3-2-2b foi crítico para rotular e categorizar cada item. Além disso, o modelo Granite-3-2-8B-instruct aproveitou seus recursos de raciocínio para gerar ideias personalizadas de trajes.

Algumas das próximas etapas para desenvolver essa aplicação podem incluir:

  • Personalizar trajes de acordo com o estilo pessoal do usuário, tipo de corpo, paleta de cores preferida e muito mais.
  • Ampliação dos critérios para incluir jaquetas e acessórios. Por exemplo, o sistema pode propor um blazer para um usuário que participe de uma conferência formal, além da camisa, das cuecas e dos sapatos selecionados.
  • Atuar como um comprador pessoal, fornecendo recomendações de produtos de comércio eletrônico e preços que se alinham com o estilo e orçamento exclusivos do usuário.
  • Adição de funcionalidade de chatbot para fazer perguntas ao LLM sobre cada traje.
  • Proporcionar uma experiência de prova virtual que usa uma selfie do usuário para simular o visual final.
Soluções relacionadas
IBM watsonx.ai

Treine, valide, ajuste e implemente recursos de IA generativa, modelos de base e recursos de aprendizado de máquina com o IBM watsonx.ai, um estúdio empresarial de última geração para construtores de IA. Crie aplicações de IA em uma fração do tempo com uma fração dos dados.

Conheça o watsonx.ai
Soluções de inteligência artificial

Use a IA a serviço de sua empresa com a experiência e o portfólio de soluções líder do setor da IBM à sua disposição.

Explore as soluções de IA
Consultoria e serviços em IA

Reinvente os fluxos de trabalho e operações críticos adicionando IA para maximizar experiências, tomadas de decisão em tempo real e valor de negócios.

Explore os serviços de IA
Dê o próximo passo

Obtenha acesso completo aos recursos que abrangem o ciclo de vida do desenvolvimento da IA. Produza soluções poderosas de IA com interfaces fáceis de usar, fluxos de trabalhos e acesso a APIs e SDKs padrão do setor.

Explore o watsonx.ai Agende uma demonstração em tempo real