Como implantar o Imagen no Cloud Run

1. Sobre este codelab

Última atualização:11/10/2024

Escrito por: Laurie White

Geração de imagens

Vamos ser sinceros, a geração de imagens por modelos de linguagem grandes (LLMs) pode ser divertida. É claro que há muitas aplicações comerciais para gerar imagens a partir de um comando, desde publicidade personalizada até apresentações atraentes. O site do Google Cloud tem muitos usos específicos de empresas que usam os Agentes Criativos. Ainda assim, ver os resultados quando você pede uma imagem de "cães verdes felizes em um campo" pode ser muito divertido.

Quer você esteja interessado em gerar imagens por motivos profissionais ou recreativos (ou ambos), há alguns desafios entre usar um programa de geração de imagens e implantar um em um aplicativo da Web. Este laboratório vai ajudar você a superar esses desafios.

O que você vai criar

Neste codelab, você vai criar um app que vai receber um comando de texto e retornar uma página da Web com uma imagem gerada usando esse comando.

O que você vai aprender

Neste laboratório, você vai aprender:

  • Como usar o Google Imagen para criar imagens com base em comandos de texto em ambientes de notebooks
  • As dificuldades em mover o código Imagen de um notebook para um app da Web
  • Como implantar um aplicativo do Cloud Run que usa o Imagen para gerar imagens
  • Como incluir uma imagem do Imagen em HTML

Este codelab é focado em imagens e implantação. Conceitos e blocos de códigos sem relevância não serão abordados. Eles são incluídos somente para você copiar e colar.

O que é necessário

O código completo deste codelab está disponível em https://github.com/Annie29/imagen-deployment .

2. Ativar APIs

Selecione um projeto para usar neste codelab. Talvez seja melhor criar um novo projeto para facilitar a remoção de todo o trabalho quando você terminar.

Antes de começar a usar a Imagen, você precisa ativar algumas APIs.

  1. Acesse o Console do Google Cloud.
  2. Acesse o painel da Vertex AI.
  3. Selecione "Ativar todas as APIs recomendadas".

a8f336f7380a9eab.png

3. Como usar o Imagens do Google (opcional)

Se você já conhece o Imagen, pule esta seção.

Antes de tentar criar um app da Web que usa o Imagen, é útil saber o que ele pode fazer. Felizmente, há vários notebooks que executam códigos simples do Imagen. Vamos começar com um deles.

  1. Acesse o notebook em https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb .
  2. Selecione "Abrir no Colab" para abrir o notebook no servidor de notebooks do Google.
  3. Selecione "Arquivo -> Salvar uma cópia no Drive" ou clique em "Copiar para o Drive" na parte de cima da página para criar sua própria cópia deste notebook.
  4. Feche a cópia original para evitar trabalhar na errada.
  5. Para se conectar a um ambiente de execução, clique no botão "Conectar" no canto superior direito. 2afdc8fa660a89bd.png
  6. Comece a trabalhar em cada uma das células do notebook.
  7. Para executar uma célula, clique no [] ou na seta à esquerda da célula ou use a opção "Executar seleção" no menu "Ambiente de execução" (ou no atalho): dfec032ef6c31296.png
  8. Ao reiniciar o ambiente de execução atual, você vai receber uma mensagem informando que o sistema travou. Não entre em pânico. Isso é normal.
  9. Você vai precisar autenticar seu ambiente de notebook.
  10. Você pode inserir o ID do projeto (não o nome) e o local (us-central1 funciona se você não tiver definido um local) nas caixas à direita do código e pedir que o Colab os insira no código.
  11. Quando você chegar à etapa "Gerar uma imagem", vai ter a oportunidade de conferir o que o Imagen pode fazer. Sinta-se à vontade para mudar o comando e executar novamente a célula para conferir a variedade de imagens que você pode receber.
  12. A essa altura, você já deve ter uma boa ideia de como o Imagen pode criar imagens a partir de um notebook. Você pode concluir este notebook para saber mais sobre os parâmetros de imagem agora ou em um momento conveniente.

4. Começar a criar um aplicativo da Web para mostrar uma imagem

Vamos usar o Python com o framework Flask no Cloud Run para criar nosso app.

Os apps Python Flask são configurados em uma pasta da seguinte maneira:

app-folder
    templates
        template.html
        (etc.)
        anothertemplate.html
    main.py
    requirements.txt

Modelos são arquivos que contêm HTML, geralmente com marcadores de posição nomeados em que o programa insere o texto gerado. main.py é o próprio app do servidor da Web, e requirements.txt é uma lista de todas as bibliotecas não padrão que main.py usa.

O aplicativo terá duas páginas: a primeira para receber uma solicitação e a segunda para mostrar a imagem e permitir que o usuário insira outra solicitação.

Primeiro, crie o framework do projeto.

Como criar a estrutura de arquivos

Este codelab pressupõe que seu projeto esteja na pasta imageapp. Se você usar um nome diferente, atualize os comandos conforme apropriado.

Acesse o Cloud Shell selecionando o ícone de comando no canto superior direito da tela.

28135f700c5b12b0.png

Você pode ter mais espaço para trabalhar se mover o shell para uma nova guia usando a seta na parte de cima da janela do shell:

310422ac131813e1.png

No diretório principal do Cloud Shell, crie a pasta imageapp, mude para ela e crie as pastas templates. Você pode fazer isso na linha de comando ou no editor do Cloud Shell.

Criar os modelos

O aplicativo terá duas páginas: a primeira (que chamaremos de home.html) para receber uma solicitação e a segunda (que chamaremos de display.html) para mostrar a imagem e permitir que o usuário insira outra solicitação.

Crie dois modelos usando o editor do Cloud Shell ou do Linux. Na pasta imageapp/templates, crie a página inicial que o usuário vai encontrar, home.html. Ele usa a variável prompt para retornar a descrição inserida pelo usuário.

templates/home.html

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>
       <form  action="/" method="post" >
           <input type="text" id="prompt" name="prompt">
           <input type="submit" value="Send">
       </form>
   </body>
</html>

Em seguida, crie display.html, que vai mostrar a imagem. O local da imagem será image_url.

templates/display.html

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>

       <div>
           <form  action="/" method="post" >
               <input type="text" id="prompt" name="prompt">
               <input type="submit" value="Send">
           </form>

           <p></p>
       </div>

       <div id="picture">
           <img id="pict" name="pict" alt="The created image" src="{{image_uri}}" style="width:100%;">
       </div>

   </body>
</html>

5. Como iniciar o código

Você vai precisar criar o arquivo requirements.txt para garantir que todas as bibliotecas necessárias para o programa estejam disponíveis. Por enquanto, basta incluir flask no arquivo requirements.txt.

O arquivo main.py contém o código que vai atender às solicitações da Web. Há apenas duas solicitações que precisamos processar: uma GET para a página inicial e uma POST que envia o formulário descrevendo a imagem que queremos gerar.

Usando o editor do Cloud Shell ou do Linux, crie o arquivo main.py na pasta imageapp. Vamos começar com o esqueleto abaixo:

main.py

import flask

app = flask.Flask(__name__)

@app.route("/", methods=["GET"])
def home_page():
    return flask.render_template("home.html")

@app.route("/", methods=["POST"])
def display_image():
    # Code to get the prompt (called prompt) from the submitted form
    # Code to generate the image
    # Code to create a URL for the image (called image_url)

    return flask.render_template("display.html", prompt=prompt, image_url=image_url)

# Initialize the web server app when the code locally (Cloud Run handles it in that environment)
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=8080)

Na verdade, esse é quase todo o app. Há três comentários em display_image que precisam ser preenchidos com código Python.

Vamos começar a preencher as partes que faltam. O Flask facilita a recuperação da solicitação. Adicione uma linha após o comentário, conforme mostrado abaixo:

# Code to get the prompt (called prompt) from the submitted form
prompt = flask.request.form["prompt"]

Se você quiser testar o app agora, adicione uma linha antes da instrução return em display_image para atribuir um valor a image_url (um URL válido que aponta para uma imagem).

Por exemplo: image_url="<your url here>"

É possível executar o programa localmente no Cloud Shell (usando o comando python main.py) e visualizar usando a opção "Visualizar na porta 8080" no canto superior direito da tela.

a80b4abd28cb7eed.png

No programa atual, a imagem sempre vai aparecer no URL fornecido. Vamos conferir como conseguir esse valor do app. Remova a linha que atribui um valor estático a image_url.

6. Como criar a imagem

O Google Cloud tem uma API Python para IA generativa na Vertex AI. Para usá-lo, precisamos adicionar uma linha que o importe com as outras importações perto do topo do programa:

from vertexai.vision_models import ImageGenerationModel

e inclua vertexai no arquivo requirements.txt.

A documentação do ImageGenerationModel mostra como usá-lo. Vamos criar um modelo e gerar uma imagem dele com base em uma solicitação. Adicione o código a main.py para a segunda etapa, criando a imagem e armazenando-a em response:

# Code to generate the image
model = ImageGenerationModel.from_pretrained("imagegeneration@006")
response = model.generate_images(prompt=prompt)[0]

Até quatro imagens podem ser criadas por vez, dependendo dos parâmetros enviados para generate_images. Portanto, o valor retornado será uma lista de GeneratedImage, mesmo que apenas uma imagem seja retornada, como neste caso.

Agora precisamos mostrar a imagem em uma página WWW. O GeneratedImage tem um método para show a imagem, mas ele só funciona em um ambiente de notebook. Mas há um método para salvar a imagem. Vamos salvar a imagem e enviar o URL dela quando renderizarmos o modelo.

Isso é um pouco complicado e há muitas maneiras de fazer isso. Vamos analisar uma das abordagens mais simples, passo a passo. Há uma imagem das etapas abaixo caso você seja uma pessoa que aprende melhor visualmente.

Primeiro, precisamos salvar a imagem. Mas qual será o nome dela? Pode haver problemas ao usar um nome estático, já que o programa pode ser usado por muitas pessoas ao mesmo tempo. Embora seja possível criar nomes de imagem separados para cada usuário (com algo como UUID), uma maneira mais simples é usar a biblioteca tempfile do Python, que cria um arquivo temporário com um nome exclusivo. O código abaixo vai criar um arquivo temporário, extrair o nome dele e gravar a resposta da etapa de geração de imagem no arquivo temporário. Não vamos inserir isso no código ainda, porque precisamos primeiro de um URL.

with tempfile.NamedTemporaryFile("wb") as f:
    filename = f.name
    response.save(filename, include_generation_parameters=False)
    # process the saved file here, before it goes away

Há várias maneiras de processar o arquivo salvo, mas uma das mais simples e seguras é usar um URL de dados.

Os URLs de dados permitem que os dados reais sejam enviados no URL, não apenas um caminho para eles. A sintaxe de um URL de dados é:

data:[image/png][;base64],<data>

Para conseguir a codificação base64 da imagem, precisamos abrir o arquivo salvo por tempfile e ler em uma variável. Sim, essa será uma string grande, mas isso não será um problema para navegadores e servidores modernos. Em seguida, vamos usar a biblioteca base64 para codificar isso em uma string que pode ser enviada no URL de dados.

O código final para fazer a terceira etapa (criar o URL) será:

# Code to create a URL for the image (called image_url)
with tempfile.NamedTemporaryFile("wb") as f:
    filename = f.name
    response.save(filename, include_generation_parameters=False)
    # process the saved file here, before it goes away
    with open(filename, "rb") as image_file:
        binary_image = image_file.read()
        base64_image = base64.b64encode(binary_image).decode("utf-8")
        image_url = f"data:image/png;base64,{base64_image}"

Confira todas essas etapas na imagem abaixo:

268876579dc02376.png

Você vai precisar importar o arquivo temporário e o base64 no início do programa.

import tempfile
import base64

Para executar o programa no Cloud Shell, verifique se você está na pasta com main.py e execute o comando:

python main.py

Em seguida, você pode conferir a visualização usando a opção "Visualizar na porta 8080" no canto superior direito da tela.

a80b4abd28cb7eed.png

7. Um erro comum

Em algum momento, você pode notar que, ao executar o programa (durante o teste ou depois de implantá-lo), você recebe uma mensagem como esta:

2366c3bba6273517.png

Isso provavelmente é causado por um comando que viola as práticas de IA responsável do Google . Uma instrução simples como "gatinhos brincando com bolas coloridas" pode causar esse problema. Mas não se preocupe, você pode encontrar imagens de "gatinhos brincando com brinquedos coloridos".

Para lidar com esse erro, vamos adicionar um código para capturar a exceção gerada ao tentar gerar a imagem. Se houver, renderizaremos o modelo home.html novamente, com uma mensagem exibida.

Primeiro, vamos adicionar um div no modelo home.html após o primeiro formulário que será exibido em caso de erro:

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>
       <form  action="/" method="post" >
           <input type="text" id="prompt" name="prompt">
           <input type="submit" value="Send">
       </form>
       {% if mistake %}
       <div id="warning">
       The prompt contains sensitive words that violate
       <a href=\"https://ai.google/responsibility/responsible-ai-practices\">
           Google's Responsible AI practices</a>.
       Try rephrasing the prompt."</div>

       {% endif %}

   </body>
</html>

Em seguida, adicione o código em main.py para detectar uma possível exceção ao chamar o código generate_images em display_image. Se houver uma exceção, o código renderizará o modelo home.html com uma mensagem.

# Code to generate the image
   model = ImageGenerationModel.from_pretrained("imagegeneration@006")
   try:
       response = model.generate_images(prompt=prompt)[0]   
   except:
       #  This is probably due to a questionable prompt
       return flask.render_template("home.html", warning=True)

Esse não é o único recurso de IA responsável do Imagen. Há vários recursos que protegem a geração de pessoas e crianças e filtros gerais nas imagens. Saiba mais aqui.

8. Implantar o app na Web

É possível implantar o app na Web usando o comando da pasta imageapp no Cloud Shell. Use o ID do projeto real no comando.

gcloud run deploy imageapp \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --project your-project-id

Uma resposta como esta vai aparecer, informando onde encontrar sua inscrição:

Service [imageapp] revision [imageapp-00001-t48] has been deployed and is serving 100 percent of traffic.
Service URL: https://imageapp-708208532564.us-central1.run.app```

9. Como fazer a limpeza

O Cloud Run não gera custos quando o serviço não está em uso, mas você ainda pode receber cobranças pelo armazenamento da imagem do contêiner no Artifact Registry. Você pode excluir seu repositório ou projeto do Cloud para evitar cobranças. A exclusão do projeto do Cloud interrompe o faturamento de todos os recursos usados nesse projeto.

Para excluir o repositório de imagens de contêiner:

gcloud artifacts repositories delete cloud-run-source-deploy \
  --location $REGION

Para excluir seu serviço do Cloud Run:

gcloud run services delete imageapp \
  --platform managed \
  --region $REGION

Para excluir seu projeto do Google Cloud:

  1. Extraia o ID do projeto atual:
PROJECT_ID=$(gcloud config get-value core/project)
  1. Confira se este é o projeto que você quer excluir:
echo $PROJECT_ID
  1. Excluir o projeto:
gcloud projects delete $PROJECT_ID

10. Parabéns

Parabéns, você criou um aplicativo da Web que vai mostrar imagens criadas pelo Imagen. Como você pode usar isso no seu aplicativo?

Qual é a próxima etapa?

Confira alguns destes codelabs:

Leia mais