在 Google Cloud Run 上部署 Hugging Face Transformers 情感分析 Pipeline

TL;DR

一篇 Hugging Face 社群文章詳細介紹了如何將 distilbert-base-uncased-finetuned-sst-2-english 情感分析 pipeline 逐步部署到 Google Cloud Run,展示了如何構建輕量級 Docker 鏡像、配置服務,並在每月低於 2,000 次請求的情況下,以低成本實現低於 5 秒的請求延遲。


微服務的目標

作者需要一個無伺服器端點,用於將 Discord 客戶評論分類為正面或負面。由於該案例每月僅需幾千次請求,因此高吞吐量和極低延遲並非主要考量。


Transformers 函式庫

Hugging Face 的 transformers 函式庫提供了一個 pipeline 抽象,可以同時載入模型檢查點(checkpoint)和分詞器(tokenizer)。以下是一個獲取情感標籤的最小範例:

from transformers import pipeline
classifier = pipeline('sentiment-analysis')
print(classifier('We are very happy to include pipeline into the transformers repository.'))
# [{'label': 'POSITIVE', 'score': 0.9978193640708923}]

作者最初將 .h5 檢查點與 Keras SavedModel 混淆,但發現它是一個必須透過 pipeline API 載入的權重文件。


Google Cloud 選項探索

作者評估了四種 GCP 服務:

  1. AI-Platform Prediction – 不適用,因為模型是檢查點,而非純 TensorFlow SavedModel。
  2. App Engine – 遇到 TensorFlow 系統依賴錯誤;PyTorch 可以運作,但只能處理兩個並行請求。
  3. Cloud Run – 使用 Docker 提供了配置性(記憶體、vCPU)與簡便性的最佳平衡。
  4. Research – 確定了對自定義預處理和後處理鉤子(hooks)的需求,雖然 AI-Platform 支援,但最終解決方案並不需要。

最終無伺服器架構

生產環境設置包含四個組件:

  • main.py – 一個 Flask app,接收帶有 review 和可選 api_keyGET 請求,載入情感分析 pipeline,並返回第一個結果。
  • Dockerfile – 構建 Python 3.7 鏡像,安裝依賴項,複製代碼,暴露 5000 端口,並使用 Gunicorn 以單個 worker 和線程來運行 app,以限制記憶體使用量。
  • requirements.txt – 固定了 Flask 1.1.2、torch 1.7.1、transformers ~4.2.0 和 gunicorn ≥20.0.0。
  • 模型目錄 – 包含 DistilBERT SST-2 模型的 pytorch_model.binconfig.jsonvocab.txtrust_model.ottf_model.h5 文件是不必要的。

main.py (節錄)

import os
from flask import Flask, jsonify, request
from transformers import pipeline

app = Flask(__name__)
model_path = "./model"

@app.route('/')
def classify_review():
    review = request.args.get('review')
    api_key = request.args.get('api_key')
    if review is None or api_key != "MyCustomerApiKey":
        return jsonify(code=403, message="bad request")
    classify = pipeline("sentiment-analysis", model=model_path, tokenizer=model_path)
    return classify(review)[0]

if __name__ == '__main__':
    app.run(debug=False, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

Dockerfile (節錄)

FROM python:3.7
ENV PYTHONUNBUFFERED True
COPY requirements.txt /
RUN pip install -r requirements.txt
COPY . /app
EXPOSE 5000
ENV PORT 5000
WORKDIR /app
CMD exec gunicorn --bind :$PORT main:app --workers 1 --threads 1 --timeout 0

單個 worker 和單個線程的配置可以保持低記憶體佔用(≈4 GB)並避免產生多個實例以增加帳單費用。


部署步驟

  1. Prerequisites – 創建 GCP 專案,啟用帳單,並安裝 gcloud CLI。
  2. 構建容器:
    gcloud builds submit --tag gcr.io/PROJECT-ID/ai-customer-review
    
  3. 部署到 Cloud Run (managed platform):
    gcloud run deploy --image gcr.io/PROJECT-ID/ai-customer-review --platform managed
    
  4. 增加記憶體 – 部署後,在 Cloud Run 控制台編輯修訂版本(revision),將記憶體從 256 MiB 提高到 4 GiB 以容納 PyTorch 模型。

性能特性

  • Latency – 首次請求(冷啟動)耗時 ~10 s;隨後的請求在包含模型載入和推理的情況下,可在 <5 s 內完成。
  • Optimization tip – 在模組導入時載入 pipeline(使用全域變數)以消除每次請求的模型載入,從而降低延遲和記憶體抖動。

成本估算

使用 Google 的定價計算器,一個處理每月 ~1,000–2,000 次請求的 4 GiB Cloud Run 實例,每月每 GB 存儲的容器鏡像成本約為 €0.10,外加微不足道的計算費用。Docker 鏡像大小約為 1 GB (≈700 MB PyTorch + 250 MB 模型)。


結論與未來工作

在 Cloud Run 上部署 Hugging Face 情感分析 pipeline 提供了一個快速、具備成本效益的解決方案,用於低容量的 NLP 微服務。該方法避免了對自定義 TensorFlow serving 的需求,利用 PyTorch 進行更快的模型載入,並展示了無伺服器容器可以託管 transformer 模型並具有可接受的延遲。

未來改進可以包括:

  • 提供純 TensorFlow SavedModel 以啟用 AI-Platform Prediction。
  • 實是在執行預熱策略或使用背景 worker 以保持模型常駐。
  • 探索使用更輕量級的 "lite" 版本模型以獲得更低的記憶體佔用。

Sources