Развертывание Imagen в Cloud Run

1. Об этой кодовой лаборатории

Последнее обновление: 11 октября 2024 г.

Сценарист: Лори Уайт

Генерация изображений

Давайте будем честными: генерация изображений с помощью больших языковых моделей (LLM) может быть интересной. Конечно, существует множество бизнес-приложений для создания изображений из подсказки: от индивидуальной рекламы до привлекательных презентаций. ( На веб-сайте Google Cloud есть много конкретных применений компаний, использующих Creative Agents.) Тем не менее, наблюдать за тем, какие результаты дает изображение «счастливых зеленых собак в поле», может быть довольно забавно.

Независимо от того, интересуетесь ли вы созданием изображений по профессиональным или развлекательным причинам (или по тому и другому!), существуют некоторые проблемы между использованием программы создания изображений и ее развертыванием в веб-приложении. Эта лаборатория поможет вам справиться с этими проблемами.

Что ты построишь

В этой лаборатории кода вы создадите приложение, которое будет принимать текстовое приглашение и возвращать веб-страницу с изображением, созданным с использованием этого приглашения.

Что вы узнаете

В этой лабораторной работе вы узнаете:

  • Как использовать Google Imagen для создания изображений из текстовых подсказок в блокнотах
  • Трудности с переносом кода Imagen из блокнота в веб-приложение
  • Как развернуть приложение Cloud Run, которое использует Imagen для создания изображений
  • Как включить изображение из Imagen в HTML

Эта лаборатория кода ориентирована на Imagen и развертывание. Нерелевантные концепции и блоки кода замалчиваются и предоставляются для простого копирования и вставки.

Что вам понадобится

Полный код этой лаборатории доступен по адресу https://github.com/Annie29/imagen-deployment .

2. Включите API

Выберите проект, который будет использоваться для этой Codelab. Возможно, вы захотите создать новый проект, чтобы упростить удаление всей вашей работы, когда вы закончите.

Прежде чем вы сможете начать работу с Imagen, вам необходимо включить некоторые API.

  1. Перейдите в облачную консоль Google.
  2. Перейдите на панель управления Vertex AI.
  3. Выберите «Включить все рекомендуемые API».

a8f336f7380a9eab.png

3. Изучение Google Imagen (необязательно)

Если вы знакомы с Imagen, можете пропустить этот раздел.

Прежде чем пытаться создать веб-приложение, использующее Imagen, полезно посмотреть, на что способен Imagen. К счастью, существует множество ноутбуков, на которых выполняется простой код Imagen, поэтому давайте начнем с одного из них.

  1. Перейдите в блокнот по адресу https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb .
  2. Выберите «Открыть в Colab», чтобы открыть блокнот на сервере блокнотов Google.
  3. Выберите «Файл -> Сохранить копию на Диске» или нажмите «Копировать на диск» вверху страницы, чтобы создать собственную копию этого блокнота.
  4. Закройте исходную копию (просто чтобы не работать не с той!).
  5. Вам нужно будет подключиться к среде выполнения, нажав кнопку «Подключиться» в правом верхнем углу. 2afdc8fa660a89bd.png
  6. Начните прорабатывать каждую ячейку тетради.
  7. Чтобы запустить ячейку, вы можете щелкнуть [] или стрелку слева от ячейки или использовать параметр «Выполнить выбор» в меню «Среда выполнения» (или его ярлыке): dfec032ef6c31296.png
  8. Когда вы перезапустите текущую среду выполнения, вы получите сообщение о сбое вашей системы. Не паникуйте. Это нормально.
  9. Вам необходимо будет аутентифицировать среду вашего ноутбука.
  10. Вы можете ввести идентификатор своего проекта (не имя) и местоположение (us-central1 работает, если вы не указали местоположение) в полях справа от кода, и Colab вставит их в код за вас.
  11. Когда вы доберетесь до «Создать изображение», у вас будет возможность увидеть, на что способен Imagen. Не стесняйтесь изменить подсказку и перезапустить ячейку, чтобы увидеть разнообразие изображений, которые вы можете получить.
  12. На этом этапе вы должны иметь хорошее представление о том, как Imagen может создавать изображения из блокнота. Заполните этот блокнот, чтобы узнать больше о параметрах изображения сейчас или в удобное время.

4. Начните создавать веб-приложение для показа изображения.

Для создания нашего приложения мы будем использовать Python с использованием платформы Flask в Cloud Run.

Приложения Python Flask настраиваются в папке следующим образом:

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

Шаблоны — это файлы, содержащие HTML, обычно с именованными заполнителями, куда программа будет вставлять сгенерированный текст. main.py — это само приложение веб-сервера, а requirements.txt — это список всех нестандартных библиотек, которые использует main.py

Приложение будет иметь две страницы: первая для получения подсказки, вторая для отображения изображения и предоставления пользователю возможности ввести еще одну подсказку.

Сначала создайте структуру проекта.

Создание файловой структуры

В этой лаборатории кода предполагается, что ваш проект находится в папке imageapp . Если вы используете другое имя, обязательно обновите команды соответствующим образом.

Войдите в Cloud Shell, выбрав значок подсказки в правом верхнем углу экрана.

28135f700c5b12b0.png

Вы можете получить больше места для работы, если переместите оболочку на новую вкладку, используя стрелку в верхней части окна оболочки:

310422ac131813e1.png

В своем домашнем каталоге Cloud Shell создайте папку imageapp , перейдите в нее и создайте папки templates . Это можно сделать либо из командной строки, либо в редакторе Cloud Shell.

Создайте шаблоны

Приложение будет иметь две страницы: первая (назовем ее home.html ) для получения подсказки и вторая (назовем ее display.html ) для отображения изображения и предоставления пользователю возможности ввести еще одну подсказку.

Используя редактор Cloud Shell или редактор Linux по вашему выбору, создайте два шаблона. В папке imageapp/templates создайте начальную страницу, которую увидит пользователь, home.html . Он использует prompt переменной для возврата описания, которое вводит пользователь.

шаблоны/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>

Затем создайте display.html , который будет отображать изображение. Обратите внимание, что местоположение изображения будет в image_url .

шаблоны/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. Запуск кода

Вам необходимо создать файл requirements.txt , чтобы убедиться, что все библиотеки, необходимые вашей программе, доступны. А пока просто включите flask в файл requirements.txt .

Файл main.py содержит код, который будет обслуживать веб-запросы. Нам нужно обработать только два запроса: запрос GET для домашней страницы и запрос POST , который отправляет форму, описывающую изображение, которое мы хотим создать.

Используя редактор Cloud Shell или редактор Linux по вашему выбору, создайте файл main.py в папке imageapp . Начнем со скелета ниже:

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)

Собственно, это почти все приложение. В display_image есть три комментария, которые необходимо дополнить кодом Python, и на этом все.

Давайте начнем заполнять недостающие части. Flask упрощает получение подсказки. Добавьте строку после комментария, как показано ниже:

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

Если вы хотите протестировать приложение сейчас, вы можете добавить строку перед оператором return в display_image чтобы задать значение image_url (действительный URL-адрес, указывающий на изображение).

Например: image_url="<your url here>"

Вы можете запустить программу локально из Cloud Shell (с помощью команды python main.py ) и просмотреть ее с помощью предварительного просмотра на порту 8080 в правом верхнем углу экрана.

a80b4abd28cb7eed.png

В текущей версии программы вы всегда будете видеть изображение по указанному вами URL-адресу. Давайте продолжим и посмотрим, как получить это значение из приложения. Обязательно удалите строку, задающую image_url статическое значение.

6. Создание изображения

В Google Cloud есть API Python для генеративного искусственного интеллекта на Vertex AI . Чтобы использовать его, нам нужно добавить строку, импортирующую его вместе с другими импортами, в верхней части нашей программы:

from vertexai.vision_models import ImageGenerationModel

и включите vertexai в файл requirements.txt .

В документации ImageGenerationModel показано, как его использовать. Мы создадим модель, а затем сгенерируем из нее изображение по подсказке. Добавьте код в main.py для второго шага, создав изображение и сохранив его в response :

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

Одновременно можно создать до 4 изображений, в зависимости от параметров, отправленных generate_images , поэтому возвращаемым значением будет список GeneratedImage , даже если возвращено только одно изображение, как в этом случае.

Теперь нам нужно отобразить изображение на WWW-странице. У GeneratedImage есть метод show изображения, но он работает только в среде записной книжки. Но есть способ сохранить изображение. Мы сохраним изображение и отправим URL-адрес сохраненного изображения при визуализации шаблона.

Это немного сложно, и есть много способов сделать это. Давайте шаг за шагом рассмотрим один из более простых подходов. (И ниже есть изображение шагов, если вы предпочитаете визуальное обучение.)

Сначала нам нужно сохранить изображение. Но как оно будет называться? При использовании статического имени могут возникнуть проблемы, поскольку программой могут одновременно пользоваться многие люди. Хотя мы могли бы создать отдельные имена изображений для каждого пользователя (с чем-то вроде UUID), более простой способ — использовать библиотеку tempfile Python, которая создаст временный файл с уникальным именем. Приведенный ниже код создаст временный файл, получит его имя и запишет в него ответ этапа создания изображения. Мы пока не будем вводить его в наш код, так как сначала нам нужно получить 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

Существует несколько способов обработки сохраненного файла, но один из самых простых и безопасных — использование URL-адреса данных .

URL-адреса данных позволяют отправлять в URL-адресе фактические данные, а не просто путь к ним. Синтаксис URL-адреса данных:

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

Чтобы получить кодировку изображения в формате Base64, нам нужно открыть файл, сохраненный с помощью tempfile , и прочитать его в переменную. Да, это будет большая строка, но этого вполне достаточно для современных браузеров и серверов. Затем мы воспользуемся библиотекой base64 , чтобы закодировать это в строку, которую мы сможем отправить в URL-адресе данных.

Наш окончательный код для выполнения третьего шага (создания URL-адреса) будет таким:

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

Вы можете увидеть все эти шаги на изображении ниже:

268876579dc02376.png

Вам нужно будет импортировать временный файл и base64 в начале вашей программы.

import tempfile
import base64

Попробуйте запустить программу из Cloud Shell, убедившись, что вы находитесь в папке с main.py и выполните команду:

python main.py

Затем вы можете просмотреть его, используя «Просмотр на порту 8080» в правом верхнем углу экрана.

a80b4abd28cb7eed.png

7. Распространенная ошибка

В какой-то момент вы можете заметить, что при запуске программы (либо во время тестирования, либо после ее развертывания) вы получаете сообщение, подобное следующему:

2366c3bba6273517.png

Скорее всего, это вызвано подсказкой, которая нарушает правила ответственного ИИ Google . Такая простая подсказка, как «котята играют с разноцветными шариками», может вызвать эту проблему. (Но не бойтесь, вы можете увидеть «котят, играющих с разноцветными игрушками».)

Чтобы справиться с этой ошибкой, мы добавим код для перехвата исключения, возникающего при попытке создать изображение. Если он есть, мы снова отобразим шаблон home.html с сообщением.

Во-первых, давайте добавим div в шаблон 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>
       {% 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>

Затем добавьте код в main.py , чтобы перехватить возможное исключение при вызове кодаgener_images в display_image . Если возникнет исключение, код отобразит шаблон home.html с сообщением.

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

Это не единственная функция Imagen, основанная на ответственном искусственном интеллекте. Есть ряд функций, защищающих генерацию людей и детей и общие фильтры на изображениях. Подробнее об этом можно узнать здесь .

8. Развертывание приложения в Интернете

Вы можете развернуть приложение в Интернете с помощью команды из папки imageapp в Cloud Shell. Обязательно используйте в команде фактический идентификатор проекта.

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

Вы должны увидеть ответ, подобный следующему, сообщающий вам, где найти ваше приложение:

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. Уборка

Хотя Cloud Run не взимает плату, когда служба не используется, с вас все равно может взиматься плата за хранение образа контейнера в реестре артефактов. Вы можете удалить свой репозиторий или проект Cloud, чтобы избежать дополнительных расходов. При удалении облачного проекта прекращается выставление счетов за все ресурсы, используемые в этом проекте.

Чтобы удалить хранилище образов контейнера:

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

Чтобы удалить службу Cloud Run:

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

Чтобы удалить проект Google Cloud:

  1. Получите текущий идентификатор проекта:
PROJECT_ID=$(gcloud config get-value core/project)
  1. Убедитесь, что это именно тот проект, который вы хотите удалить:
echo $PROJECT_ID
  1. Удалить проект:
gcloud projects delete $PROJECT_ID

10. Поздравления

Поздравляем, вы успешно создали веб-приложение, которое будет отображать изображения, созданные Imagen. Как вы можете использовать это в своем приложении?

Что дальше?

Посмотрите некоторые из этих кодовых лабораторий...

Дальнейшее чтение