1. 程式碼研究室簡介
上次更新時間:2024 年 10 月 11 日
撰文:Laurie White
圖像生成
老實說,由大型語言模型 (LLM) 產生的圖片可能很有趣。當然,許多業務應用程式都會根據提示產生圖片,從客製廣告到吸引人的簡報皆是如此。(Google Cloud 網站上有許多使用 Creative Agent 的具體用途。)不過,當你要求「田野中快樂的綠色狗狗」圖片時,看到的結果可能會很有趣。
無論您是出於工作或休閒 (或兩者皆是) 而有興趣使用圖像生成功能,在使用圖像生成程式和將其部署至網路應用程式之間,都會遇到一些挑戰。本研究室將協助您克服這些挑戰。
建構項目
在本程式碼研究室中,您將建構一個應用程式,該應用程式會接收文字提示,並傳回網頁,其中包含使用該提示產生的圖片。
課程內容
本實驗室的內容包括:
- 如何在筆記本環境中使用 Google Imagen 根據文字提示建立圖像
- 將 Imagen 程式碼從 Notebook 移至 Web 應用程式時遇到的困難
- 如何部署使用 Imagen 產生圖片的 Cloud Run 應用程式
- 如何在 HTML 中加入 Imagen 圖片
本程式碼研究室著重於 Imagen 和部署作業。我們不會對與本主題無關的概念和程式碼多做介紹,但會事先準備好這些程式碼區塊,屆時您只要複製及貼上即可。
軟硬體需求
- 使用最新版 Chrome 瀏覽器。
- 具備一些 Cloud Run 相關知識。您可以透過這裡的簡短程式碼研究室取得這項資訊。
- 熟悉在 Cloud Shell 或 Cloud Shell 編輯器中編輯檔案。如要進一步瞭解 Cloud Shell 和 Cloud Shell 編輯器,請參閱這個程式碼研究室。
- 已啟用計費功能的 Google Cloud 專案。這份指南將說明如何建立專案。許多產品提供免費方案和免費試用期。
您可以在 https://github.com/Annie29/imagen-deployment 中找到本程式碼研究室的完整程式碼。
2. 啟用 API
選取要用於本程式碼研究室的專案。建議您建立新專案,以便在完成後輕鬆移除所有工作。
您必須先啟用某些 API,才能開始使用 Imagen。
- 前往 Google Cloud 控制台。
- 前往 Vertex AI 資訊主頁。
- 選取「啟用所有建議的 API」
3. 探索 Google Imagen (選用)
如果您熟悉 Imagen,可以略過本節。
在嘗試建立使用 Imagen 的網頁應用程式之前,先瞭解 Imagen 的功能會很有幫助。幸運的是,有許多可執行簡單 Imagen 程式碼的 Notebook,因此我們先從其中一個開始吧。
- 前往 https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb 查看 Notebook。
- 選取「在 Colab 中開啟」,即可在 Google 的筆記本伺服器中開啟筆記本。
- 選取「檔案」->「在雲端硬碟中儲存副本」,或是點選頁面頂端的「複製到雲端硬碟」,即可建立這個筆記本的副本。
- 關閉原始副本 (避免在錯誤的副本上工作)。
- 您必須按一下右上方的「連線」按鈕,才能連線至執行階段。
- 開始執行筆記本中的每個儲存格。
- 如要執行儲存格,請點選儲存格左側的 [] 或箭頭,或是使用「執行時間」選單中的「執行所選項目」選項 (或捷徑):
- 重新啟動目前的執行階段時,您會收到系統當機的訊息。別緊張,這是正常情況。
- 您必須驗證筆記本環境。
- 您可以在程式碼右側的方塊中輸入專案 ID (不是名稱) 和位置 (如果未設定位置,則可使用 us-central1),讓 Colab 在程式碼中插入這些資訊。
- 當您看到「產生圖片」時,就能瞭解 Imagen 的功能。您可以隨意變更提示,並重新執行單元格,查看可產生的各種圖片。
- 到目前為止,您應該已瞭解 Imagen 如何從筆記本建立圖片。歡迎您現在或在方便時完成這個 Notebook,進一步瞭解圖片參數。
4. 開始建構網路應用程式,以便顯示圖片
我們會使用 Python 在 Cloud Run 上使用 Flask 架構建構應用程式。
Python Flask 應用程式會在以下資料夾中設定:
app-folder templates template.html (etc.) anothertemplate.html main.py requirements.txt
範本是包含 HTML 的檔案,通常會在其中加入名為「預留位置」的元素,讓程式插入產生的文字。main.py
是網路伺服器應用程式本身,而 requirements.txt
則是 main.py
使用的所有非標準程式庫清單。
應用程式會有兩個頁面:第一個頁面用於取得提示,第二個頁面則用於顯示圖片,並讓使用者輸入另一個提示。
首先建立專案架構。
建立檔案結構
本程式碼研究室假設您的專案位於 imageapp
資料夾中。如果您使用其他名稱,請務必視情況更新指令。
選取畫面右上方的提示圖示,即可進入 Cloud 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
檔案包含用來處理網頁要求的程式碼。我們只需要處理兩個要求:首頁的 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
,但只能在 Notebook 環境中使用。不過,我們有方法儲存圖片。我們會在算繪範本時儲存圖片,並傳送已儲存圖片的網址。
這項操作有點複雜,而且有很多種方法。我們將逐步介紹其中一種較簡單的方法。(如果您是視覺型學習者,請參考下方步驟的圖片)。
首先,我們需要儲存圖片。但要取什麼名稱呢?使用靜態名稱可能會發生問題,因為許多人可能會同時使用該程式。雖然我們可以為每位使用者建立個別的圖片名稱 (使用 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 負責任的 AI 技術做法。只要是「小貓咪玩彩色球」這類簡單的提示,就可能導致這個問題。(不過別擔心,你可以取得「小貓玩彩色玩具」的圖片)。
為了處理這個錯誤,我們會新增程式碼,擷取嘗試產生圖片時發生的例外狀況。如果有,我們會再次轉譯 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
中新增程式碼,以便在 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 功能。我們提供多項功能,可保護人物和兒童的世代,以及圖片上的一般濾鏡。如要進一步瞭解這些功能,請參閱本文。
8. 將應用程式部署至網路
您可以使用 Cloud Shell 中 imageapp
資料夾中的指令,將應用程式部署至網路。請務必在指令中使用實際的專案 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 專案,以免產生費用。刪除 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. 恭喜
恭喜,您已成功建構網頁應用程式,可顯示由 Imagen 建立的圖片。如何在應用程式中使用這項功能?
後續步驟
查看一些程式碼研究室…