1. 关于此 Codelab
上次更新时间: 2024 年 10 月 11 日
作者: Laurie White
图片生成
说实话,大语言模型 (LLM) 生成图片可能很有趣。 当然,根据提示生成图片有很多商业应用,从自定义广告到引人注目的演示文稿,应有尽有。( Google Cloud 网站 上有很多公司使用 Creative Agents 的具体用例。)不过,当您要求生成“田野里快乐的绿色狗狗”的图片时,看到结果可能会非常有趣。
无论您是出于专业还是娱乐原因(或两者兼而有之)对图片生成感兴趣,在使用图片生成程序和将其部署到 Web 应用之间都存在一些挑战。 本实验将帮助您克服这些挑战。
构建内容
在此 Codelab 中,您将构建一个应用,该应用将接受文本提示,并返回一个网页,其中包含使用该提示生成的图片。
学习内容
在本实验中,您将学习:
- 如何在笔记本环境中通过文本提示使用 Google Imagen 创建图片
- 将 Imagen 代码从笔记本移至 Web 应用时遇到的困难
- 如何部署使用 Imagen 生成图片的 Cloud Run 应用
- 如何在 HTML 中添加 Imagen 中的图片
此 Codelab 重点介绍 Imagen 和部署。对于不相关的概念,我们仅会略作介绍,但是会提供相应代码块供您复制和粘贴。
所需条件
- 最新版 Chrome 浏览器。
- 对 Cloud Run 有一定的了解。 您可以从此处相当简短的 Codelab 中了解相关信息。
- 熟悉在 Cloud Shell 或 Cloud Shell 编辑器中编辑文件。 您可以从此 Codelab 详细了解 Cloud Shell 和 Cloud Shell 编辑器。
- 启用了结算功能的 Google Cloud 项目。 本 指南将向您展示如何创建项目。有 许多产品提供免费层级和免费试用。
此 Codelab 的完整代码可在 https://github.com/Annie29/imagen-deployment 中找到。
2. 启用 API
选择要用于此 Codelab 的项目。 您可能需要创建一个新项目,以便在完成后更轻松地移除所有工作。
在开始使用 Imagen 之前,您需要启用一些 API。
- 转到 Google Cloud 控制台。
- 导航到 Vertex AI 信息中心。
- 选择“启用所有推荐的 API”

3. 探索 Google Imagen(可选)
如果您熟悉 Imagen,可以跳过此部分。
在尝试创建使用 Imagen 的 Web 应用之前,最好先了解 Imagen 的功能。幸运的是,有许多笔记本可以运行简单的 Imagen 代码,因此我们先从其中一个开始。
- 前往 https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb 中的笔记本。
- 选择“在 Colab 中打开”,以在 Google 的笔记本服务器中打开笔记本。
- 选择“文件 -> 在云端硬盘中保存副本”,或点击页面顶部的“复制到云端硬盘”,以创建此笔记本的副本。
- 关闭原始副本(只是为了避免在错误的副本中工作!)。
- 您需要点击右上角的“连接”按钮来连接到运行时。

- 开始处理笔记本中的每个单元。
- 如需运行单元,您可以点击单元左侧的 [] 或箭头,也可以使用“运行时”菜单中的“运行所选内容”选项(或其快捷方式):

- 当您重启当前运行时时,系统会显示一条消息,指出您的系统已崩溃。请不要惊慌。 这是正常现象。
- 您需要对笔记本环境进行身份验证。
- 您可以在代码右侧的框中输入项目 ID(而非名称)和位置(如果您尚未设置位置,则可以使用 us-central1),然后让 Colab 为您将其插入到代码中。
- 当您看到“生成图片”时,您将有机会了解 Imagen 的功能。您可以随意更改提示并重新运行单元,以查看可以获得的各种图片。
- 此时,您应该对 Imagen 如何从笔记本创建图片有了一个大致的了解。 您可以随时完成此笔记本,详细了解图片参数。
4. 开始构建 Web 应用以显示图片
我们将使用 Cloud Run 上的 Flask 框架来构建应用。
Python Flask 应用的设置文件夹如下所示:
app-folder
templates
template.html
(etc.)
anothertemplate.html
main.py
requirements.txt
模板 是包含 HTML 的文件,通常带有命名占位符,程序将在其中插入生成的文本。main.py 是 Web 服务器应用本身,而 requirements.txt 是 main.py 使用的所有非标准库的列表。
该应用将包含两个页面:第一个页面用于获取提示,第二个页面用于显示图片并允许用户输入其他提示。
首先创建项目框架。
创建文件结构
此 Codelab 假定您的项目位于 imageapp 文件夹中。 如果您使用其他名称,请务必根据需要更新命令。
选择屏幕右上角的提示图标,进入 Cloud Shell。

如果您使用 Shell 窗口顶部的箭头将 Shell 移至新标签页,则可以获得更多工作空间:

在 Cloud Shell 的主目录中,创建 imageapp 文件夹,切换到该文件夹,然后创建 templates 文件夹。 您可以通过命令行或 Cloud Shell 编辑器执行此操作。
创建模板
该应用将包含两个页面:第一个页面(我们将其称为 home.html)用于获取提示,第二个页面(我们将其称为 display.html)用于显示图片并允许用户输入其他提示。
使用 Cloud Shell 编辑器或您选择的 Linux 编辑器创建两个模板。 在 imageapp/templates 文件夹中,创建用户将看到的初始页面 home.html。 它使用变量 prompt 返回用户输入的说明。
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>
然后创建 display.html,它将显示图片。 请注意,图片的位置将位于 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. 启动代码
您需要创建文件 requirements.txt,以确保程序所需的所有库都可用。 目前,只需在 requirements.txt 文件中添加 flask 即可。
main.py 文件包含用于处理 Web 请求的代码。我们只需要处理两个请求:首页的 GET 请求,以及提交表单(描述我们想要生成的图片)的 POST 请求。
使用 Cloud Shell 编辑器或您选择的 Linux 编辑器,在 imageapp 文件夹中创建 main.py 文件。我们将从以下框架开始:
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"]
如果您想立即测试该应用,可以在 display_image 中的 return 语句之前添加一行,为 image_url 赋值(指向图片的有效网址)。
例如:image_url="<your url here>"
您可以从 Cloud Shell 在本地运行该程序(使用命令 python main.py),并使用屏幕右上角的“在端口 8080 上预览”进行预览。

由于程序现在是这样,您将始终看到您提供的网址中的图片。 接下来,我们来看看如何从应用中获取该值。请务必移除为 image_url 赋予静态价值的行。
6. 创建图片
Google Cloud 具有适用于 Vertex AI 上的生成式 AI 的 Python API。如需使用它,我们必须添加一行,在程序顶部附近的其他导入项中导入它:
from vertexai.vision_models import ImageGenerationModel
并在 requirements.txt 文件中添加 vertexai。
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 图片的方法,但它仅在笔记本环境中有效。 不过,有一个方法可以 保存 图片。 我们将在呈现模板时保存图片并发送已保存图片的网址。
这有点棘手,有很多方法可以做到这一点。 我们来逐步了解一种更简单的方法。(如果您是视觉学习者,下面还有这些步骤的图片。)
首先,我们需要保存图片。 但它将命名为什么? 由于该程序可以同时被许多人使用,因此使用静态名称可能会出现问题。 虽然我们可以为每个用户创建单独的图片名称(例如使用 UUID),但更简单的方法是使用 Python 的 tempfile 库,该库将创建一个具有唯一名称的临时文件。以下代码将创建一个临时文件,获取其名称,并将图片生成步骤的响应写入临时文件。 我们暂时不会在代码中输入它,因为我们需要先获取网址。
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
处理已保存文件的方法有很多,但最简单且最安全的方法之一是使用 数据网址。
数据网址允许在网址中发送实际数据,而不仅仅是数据的路径。 数据网址的语法为:
data:[image/png][;base64],<data>
如需获取图片的 base64 编码,我们需要打开 tempfile 保存的文件,并将其读入变量。是的,这将是一个很长的字符串,但对于现代浏览器和服务器来说应该没问题。 然后,我们将使用 base64 库将其编码为字符串,以便在数据网址中发送。
执行第三步(创建网址)的最终代码将是:
# 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}"
您可以在下图看到所有这些步骤:

您需要在程序开头导入 tempfile 和 base64。
import tempfile
import base64
尝试从 Cloud Shell 运行程序,确保您位于包含 main.py 的文件夹中,然后运行以下命令:
python main.py
然后,您可以使用屏幕右上角的“在端口 8080 上预览”进行预览。

7. 常见错误
在某个时间点,您可能会注意到,在运行程序时(无论是在测试期间还是在部署后),您会收到类似如下的消息:

这很可能是由违反 Google 的 Responsible AI 实践 的提示引起的。像“kittens playing with colorful balls”这样简单的提示也可能会导致此问题。 (但请不要担心,您 可以 获取“kittens playing with colorful toys”的图片。)
为了处理此错误,我们将添加代码来捕获尝试生成图片时引发的异常。如果存在异常,我们将再次呈现 home.html 模板,并显示一条消息。
首先,我们在 home.html 模板中的第一个表单后添加一个 div,如果出现错误,该 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 中添加代码,以捕获在 display_image 中调用 generate_images 代码时可能出现的异常。 如果出现异常,代码将呈现带有消息的 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 唯一的 Responsible AI 功能。 有许多功能可以保护人物和儿童的生成,并对图片进行常规过滤。 您可以在此处详细了解这些功能 here。
8. 将应用部署到 Web
您可以使用 Cloud Shell 中 imageapp 文件夹中的命令将应用部署到 Web。 请务必在命令中使用您的实际项目 ID。
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 不会对未在使用中的服务计费,但您可能仍然需要支付将容器映像存储在 Artifact Registry 中而产生的相关费用。为避免产生费用,您可以删除代码库或删除云项目。删除 Cloud 项目后,系统即会停止对该项目中使用的所有资源计费。
如需删除容器映像代码库,请执行以下操作:
gcloud artifacts repositories delete cloud-run-source-deploy \ --location $REGION
如需删除 Cloud Run 服务,请执行以下操作:
gcloud run services delete imageapp \ --platform managed \ --region $REGION
如需删除 Google Cloud 项目,请执行以下操作:
- 检索当前项目 ID:
PROJECT_ID=$(gcloud config get-value core/project)
- 确保这是您要删除的项目:
echo $PROJECT_ID
- 删除项目:
gcloud projects delete $PROJECT_ID
10. 恭喜
恭喜,您已成功构建一个 Web 应用,该应用将显示由 Imagen 创建的图片。如何在应用中使用此功能?
后续操作
查看下列 Codelab…