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

1. Об этом практическом занятии.

Последнее обновление: 11.10.2024

Автор: Лори Уайт

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

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

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

Что вы построите

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

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

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

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

Данный практический урок посвящен Imagen и развертыванию. Несущественные концепции и фрагменты кода опущены и предоставлены для простого копирования и вставки.

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

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

2. Включите API.

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

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

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

a8f336f7380a9eab.png

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

Если вы знакомы с 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 для возврата описания, введенного пользователем.

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

шаблоны/дисплей.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 предоставляет Python API для генеративного ИИ на платформе 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]

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

Теперь нам нужно отобразить изображение на веб-странице. 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-адреса с данными следующий:

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

В начале программы вам потребуется импортировать tempfile и base64.

import tempfile
import base64

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

python main.py

Затем вы можете просмотреть его, используя функцию предварительного просмотра на порту 8080 в правом верхнем углу экрана.

a80b4abd28cb7eed.png

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

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

2366c3bba6273517.png

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

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

Для начала добавим в шаблон home.html div-элемент после первой формы, который будет отображаться в случае ошибки:

<!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 код для обработки возможного исключения при вызове функции generate_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, чтобы избежать дополнительных расходов. Удаление проекта 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. Как вы можете использовать это в своем приложении?

Что дальше?

Посмотрите некоторые из этих практических занятий по программированию...

Дополнительная информация