Wdrażanie Imagen w Cloud Run

1. Informacje o tych ćwiczeniach z programowania

Ostatnia aktualizacja: 2024-10-11

Tekst: Laurie White

Generowanie obrazów

Szczerze mówiąc, generowanie obrazów za pomocą dużych modeli językowych (LLM) może być zabawne. Oczywiście istnieje wiele zastosowań biznesowych do generowania obrazów na podstawie prompta, od dostosowanych reklam po atrakcyjne prezentacje. (Witryna internetowa Google Cloud zawiera wiele konkretnych zastosowań dla firm korzystających z Agentów kreatywnych). Mimo to wyniki wyszukiwania obrazów o hasłach „szczęśliwe zielone psy na polu” mogą być całkiem zabawne.

Niezależnie od tego, czy interesuje Cię generowanie obrazów do celów zawodowych czy rekreacyjnych (a może i jednego i drugiego), stosowanie programu do generowania obrazów i wdrażanie go w aplikacji internetowej wiąże się z pewnymi wyzwaniami. Ten moduł pomoże Ci pokonać te wyzwania.

Co utworzysz

W tym ćwiczeniu w Codelab utworzysz aplikację, która przyjmie prompt tekstowy i zwróci stronę internetową z obrazem wygenerowanym na podstawie tego prompta.

Czego się nauczysz

W tym module dowiesz się:

  • Jak używać Google Imagen do tworzenia obrazów na podstawie promptów tekstowych w środowiskach notebooków
  • trudności z przenoszeniem kodu Imagen z notebooka do aplikacji internetowej.
  • Wdrażanie aplikacji Cloud Run, która korzysta z Imagen do generowania obrazów
  • Jak umieścić obraz z Imagen w pliku HTML

Ten warsztat dotyczy głównie Imagen i wdrażania. Nieistotne koncepcje i bloki kodu zostały zamaskowane. Można je po prostu skopiować i wkleić.

Czego potrzebujesz

Pełny kod do tego ćwiczenia z programowania jest dostępny na stronie https://github.com/Annie29/imagen-deployment .

2. Włącz interfejsy API

Wybierz projekt, którego chcesz użyć w tym Codelab. Możesz utworzyć nowy projekt, aby łatwiej usunąć całą pracę po zakończeniu.

Zanim zaczniesz korzystać z Imagen, musisz włączyć niektóre interfejsy API.

  1. Otwórz konsolę Google Cloud.
  2. Otwórz panel Vertex AI.
  3. Wybierz „Włącz wszystkie zalecane interfejsy API”.

a8f336f7380a9eab.png

3. Eksplorowanie Google Imagen (opcjonalnie)

Jeśli znasz już Imagen, możesz pominąć tę sekcję.

Zanim spróbujesz utworzyć aplikację internetową korzystającą z Imagen, warto sprawdzić, co potrafi ten model. Na szczęście istnieje wiele notebooków, które uruchamiają prosty kod Imagen, więc zacznijmy od jednego z nich.

  1. Otwórz notebook https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb .
  2. Wybierz Otwórz w Colab, aby otworzyć notatnik na serwerze notatników Google.
  3. Aby utworzyć własną kopię tego zeszytu, wybierz „Plik -> Zapisz kopię na Dysku” lub kliknij „Kopiuj na Dysk” u góry strony.
  4. Zamknij oryginalną kopię (aby uniknąć pracy nad niewłaściwą kopią).
  5. Aby połączyć się ze środowiskiem wykonawczym, w prawym górnym rogu kliknij przycisk Połącz. 2afdc8fa660a89bd.png
  6. Zacznij pracować nad komórkami w notatniku.
  7. Aby uruchomić komórkę, możesz kliknąć w nawiasach kwadratowych [] lub strzałkę po lewej stronie komórki albo użyć opcji Uruchom zaznaczenie w menu Środowisko wykonawcze (lub jej skrótu): dfec032ef6c31296.png
  8. Gdy ponownie uruchomisz bieżące środowisko uruchomieniowe, zobaczysz komunikat o awarii systemu. Nie panikuj. To zupełnie normalne.
  9. Musisz uwierzytelnić środowisko notebooka.
  10. Możesz wpisać identyfikator projektu (a nie nazwę) i lokalizację (jeśli nie ustawisz lokalizacji, możesz użyć us-central1) w pole po prawej stronie kodu, a Colab wstawi je do kodu za Ciebie.
  11. Gdy dojdziesz do sekcji „Generowanie obrazu”, będziesz mieć okazję zobaczyć, co potrafi Imagen. Możesz zmienić prompt i ponownie uruchomić komórkę, aby zobaczyć różnorodność obrazów, które możesz uzyskać.
  12. W tym momencie powinieneś już mieć ogólne pojęcie o tym, jak Imagen może tworzyć obrazy z notatek. Możesz wypełnić ten notebook, aby dowiedzieć się więcej o parametrach obrazu w dogodnym momencie.

4. Rozpocznij tworzenie aplikacji internetowej, która wyświetla obraz

Do tworzenia aplikacji użyjemy Pythona z platformą Flask w Cloud Run.

Aplikacje Python Flask są konfigurowane w folderze w ten sposób:

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

Szablony to pliki zawierające kod HTML, zwykle z nazwami zastępczymi, w których program wstawia wygenerowany tekst. main.py to sama aplikacja serwera WWW, a requirements.txt to lista wszystkich niestandardowych bibliotek używanych przez main.py.

Aplikacja będzie miała 2 strony: pierwsza do wyświetlania promptu, a druga do wyświetlania obrazu i wprowadzania przez użytkownika kolejnego promptu.

Najpierw utwórz ramy projektu.

Tworzenie struktury pliku

W tym laboratorium kodu zakładamy, że Twój projekt znajduje się w folderze imageapp. Jeśli używasz innej nazwy, odpowiednio zaktualizuj polecenia.

Aby otworzyć Cloud Shell, kliknij ikonę prompta w prawym górnym rogu ekranu.

28135f700c5b12b0.png

Możesz uzyskać więcej miejsca do pracy, przenosząc powłokę na nową kartę za pomocą strzałki u góry okna powłoki:

310422ac131813e1.png

W katalogu domowym w Cloud Shell utwórz folder imageapp, przejdź do niego i utwórz foldery templates. Możesz to zrobić w wierszu poleceń lub w edytorze Cloud Shell.

Tworzenie szablonów

Aplikacja będzie mieć 2 strony: pierwsza (nazwijmy ją home.html) będzie służyć do wyświetlania promptu, a druga (nazwijmy ją display.html) do wyświetlania obrazu i umożliwiania użytkownikowi wpisania kolejnego promptu.

Utwórz 2 szablony za pomocą edytora Cloud Shell lub dowolnego edytora systemu Linux. W folderze imageapp/templates utwórz pierwszą stronę, którą zobaczy użytkownik, home.html. Używa ona zmiennej prompt do zwracania opisu wpisanego przez użytkownika.

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>

Następnie utwórz element display.html, który będzie wyświetlać obraz. Zwróć uwagę, że obraz będzie znajdować się w folderze 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. Uruchamianie kodu

Musisz utworzyć plik requirements.txt, aby mieć pewność, że wszystkie biblioteki potrzebne do działania programu są dostępne. Na razie dodaj tylko flask do pliku requirements.txt.

Plik main.py zawiera kod, który będzie obsługiwał żądania internetowe. Musimy obsłużyć tylko 2 prośby: GET dotyczącą strony głównej oraz POST dotyczącą przesłania formularza opisującego obraz, który chcemy wygenerować.

Za pomocą edytora Cloud Shell lub wybranego edytora systemu Linux utwórz plik main.py w folderze imageapp. Zaczniemy od szkieletu:

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)

To prawie cała aplikacja. W pliku display_image są 3 komentarze, które trzeba uzupełnić kodem Pythona.

Zacznijmy uzupełniać brakujące elementy. Flask ułatwia pobieranie prompta. Dodaj wiersz po komentarzu, jak pokazano poniżej:

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

Jeśli chcesz przetestować aplikację teraz, możesz dodać wiersz przed instrukcją returndisplay_image, aby nadać wartość zmiennej image_url (prawidłowy adres URL, który wskazuje obraz).

Na przykład: image_url="<your url here>"

Możesz uruchomić program lokalnie w Cloud Shell (za pomocą polecenia python main.py) i wyświetlić jego podgląd, klikając Podgląd na porcie 8080 w prawym górnym rogu ekranu.

a80b4abd28cb7eed.png

W obecnej wersji programu zawsze będziesz widzieć obraz pod podanym przez Ciebie adresem URL. Zobaczmy, jak pobrać tę wartość z aplikacji. Pamiętaj, aby usunąć wiersz, który nadaje wartości statycznej image_url.

6. Tworzenie obrazu

Google Cloud udostępnia interfejs Python API do generatywnej AI w Vertex AI. Aby go użyć, musimy dodać wiersz importujący go z innymi importami u góry programu:

from vertexai.vision_models import ImageGenerationModel

i umieścić w pliku requirements.txt wartość vertexai.

W dokumentacji modelu ImageGenerationModel znajdziesz informacje o sposobie jego używania. Utworzymy model, a potem na jego podstawie wygenerujemy obraz na podstawie promptu. Dodaj kod do pliku main.py, aby utworzyć obraz i zapisać go w pliku response:

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

W zależności od parametrów wysłanych do funkcji generate_images można utworzyć maksymalnie 4 obrazy naraz, więc zwrócona wartość będzie listą GeneratedImage, nawet jeśli zwrócony zostanie tylko jeden obraz, jak w tym przypadku.

Teraz musimy wyświetlić obraz na stronie WWW. GeneratedImage ma metodę show obrazu, ale działa tylko w środowisku notebooka. Istnieje jednak sposób na zapisanie obrazu. Zapiszemy obraz i wyślemy adres URL zapisanego obrazu, gdy renderujemy szablon.

Jest to trochę trudne i można to zrobić na wiele sposobów. Przyjrzyjmy się jednemu z prostszych podejść krok po kroku. (Jeśli wolisz uczyć się na podstawie obrazów, poniżej znajdziesz zdjęcie z instrukcjami).

Najpierw musimy zapisać obraz. Jaka będzie miała nazwę? Korzystanie z nazwy statycznej może powodować problemy, ponieważ z programu może korzystać wiele osób jednocześnie. Chociaż możemy tworzyć osobne nazwy obrazów dla każdego użytkownika (za pomocą czegoś takiego jak UUID), łatwiej jest użyć biblioteki tempfile w Pythonie, która utworzy plik tymczasowy z unikalną nazwą. Podany niżej kod utworzy plik tymczasowy, pozyska jego nazwę i zapisz do niego odpowiedź z etapu generowania obrazu. Nie będziemy go jeszcze wpisywać w kodzie, ponieważ najpierw musimy uzyskać adres 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

Zapisane pliki można przetwarzać na wiele sposobów, ale jednym z najprostszych i najbezpieczniejszych jest użycie adresu URL danych.

Adresy URL danych umożliwiają wysyłanie rzeczywistych danych, a nie tylko ścieżki do nich. Składnia adresu URL danych:

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

Aby uzyskać kodowanie base64 obrazu, musimy otworzyć plik zapisany przez tempfile i odczytać go do zmiennej. Tak, będzie to długi ciąg znaków, ale nie powinno to stanowić problemu w przypadku nowoczesnych przeglądarek i serwerów. Następnie użyjemy biblioteki base64, aby zakodować go w postaci ciągu znaków, który możemy wysłać w adresie URL danych.

Nasz ostateczny kod do wykonania trzeciego kroku (tworzenia adresu URL) będzie wyglądał tak:

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

Wszystkie te czynności możesz zobaczyć na obrazku poniżej:

268876579dc02376.png

Na początku programu musisz zaimportować plik tymczasowy i kod base64.

import tempfile
import base64

Spróbuj uruchomić program z Cloud Shell. Upewnij się, że jesteś w folderze z main.py i uruchom to polecenie:

python main.py

Następnie możesz wyświetlić podgląd aplikacji, klikając opcję Podgląd na porcie 8080 w prawym górnym rogu ekranu.

a80b4abd28cb7eed.png

7. Typowy błąd

W pewnym momencie możesz zauważyć, że podczas uruchamiania programu (podczas testowania lub po wdrożeniu) pojawia się komunikat podobny do tego:

2366c3bba6273517.png

Najprawdopodobniej jest to spowodowane promptem, który narusza zasady Google dotyczące odpowiedzialnej AI . Wystarczy proste prompty, takie jak „kocięta bawiące się kolorowymi kulkami”, aby spowodować ten problem. (Nie martw się, możesz znaleźć zdjęcia „kotków bawiących się kolorowymi zabawkami”).

Aby rozwiązać ten problem, dodamy kod, który przechwytuje wyjątek wywoływany podczas próby wygenerowania obrazu. Jeśli tak, ponownie wyrenderujemy szablon home.html, wyświetlając odpowiedni komunikat.

Najpierw dodaj element div w szablonie home.html po pierwszym formularzu, który będzie wyświetlany w przypadku błędu:

<!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>

Następnie dodaj kod w pozycji main.py, aby przechwycić ewentualny wyjątek podczas wywołania kodu generate_images w pozycji display_image. Jeśli wystąpi wyjątek, kod wyrenderuje szablon home.html z komunikatem.

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

To nie jedyna funkcja odpowiedzialnej AI w Imagenie. Dostępne są różne funkcje, które chronią generowanie twarzy osób dorosłych i dzieci oraz ogólne filtry na zdjęciach. Więcej informacji znajdziesz tutaj.

8. Wdrażanie aplikacji w internecie

Aplikację możesz wdrożyć w internecie, używając polecenia z folderu imageapp w Cloud Shell. Pamiętaj, aby w tym poleceniu podać rzeczywisty identyfikator projektu.

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

Powinna pojawić się odpowiedź podobna do tej, która informuje, gdzie można znaleźć aplikację:

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. Czyszczenie

Cloud Run nie nalicza opłat, gdy usługa nie jest używana, ale może zostać pobrana należność za przechowywanie obrazu kontenera w Artifact Registry. Aby uniknąć opłat, możesz usunąć repozytorium lub projekt Cloud. Usunięcie projektu Cloud powoduje zaprzestanie naliczania opłat za wszystkie zasoby używane w tym projekcie.

Aby usunąć repozytorium obrazów kontenerów:

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

Aby usunąć usługę Cloud Run:

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

Aby usunąć projekt Google Cloud:

  1. Pobierz identyfikator bieżącego projektu:
PROJECT_ID=$(gcloud config get-value core/project)
  1. Sprawdź, czy to jest projekt, który chcesz usunąć:
echo $PROJECT_ID
  1. Usuń projekt:
gcloud projects delete $PROJECT_ID

10. Gratulacje

Gratulacje! Udało Ci się utworzyć aplikację internetową, która będzie wyświetlać obrazy utworzone przez Imagen. Jak możesz wykorzystać te informacje w swojej aplikacji?

Co dalej?

Zapoznaj się z tymi ćwiczeniami z programowania

Więcej informacji