
本文详解 Vertex AI 部署自定义 Docker 容器(如 YOLO + FastAPI)时的关键缺失项——必须显式声明 /health 和 /predict 端点,否则服务无法通过就绪探针,导致部署失败且日志静默。
本文详解 vertex ai 部署自定义 docker 容器(如 yolo + fastapi)时的关键缺失项——必须显式声明 `/health` 和 `/predict` 端点,否则服务无法通过就绪探针,导致部署失败且日志静默。
在 Vertex AI 上成功部署一个本地验证无误的 YOLO 自定义容器(如基于 FastAPI 的推理服务),却遭遇“模型加载失败”且无有效日志——这是典型的服务就绪性配置缺失问题。与 Cloud Run 不同,Vertex AI 不自动识别任意 HTTP 端口或路径;它严格依赖两个显式声明的路由:健康检查端点(/health)和预测端点(/predict),并要求容器监听固定端口(默认 8080)。若未正确配置,Vertex AI 会持续等待容器“就绪”,最终超时终止,且因服务从未真正启动,Cloud Logging 中几乎无应用层日志可查。
✅ 正确配置 FastAPI 应用(示例代码)
确保你的 main.py(或等效入口文件)中包含以下最小化但必需的端点:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import base64
from io import BytesIO
from PIL import Image
import torch
app = FastAPI()
# ✅ 健康检查端点:必须返回 200 OK,且响应体可为空
@app.get("/health")
def health_check():
return {"status": "ok", "model_loaded": True} # Vertex AI 只校验状态码
# ✅ 预测端点:路径必须为 /predict,方法必须为 POST,Content-Type 为 application/json
class PredictRequest(BaseModel):
image: str # base64 encoded JPEG/PNG
@app.post("/predict")
def predict(request: PredictRequest):
try:
# 解码 base64 图像
image_bytes = base64.b64decode(request.image)
img = Image.open(BytesIO(image_bytes)).convert("RGB")
# 示例:调用已加载的 YOLO 模型(此处需替换为你的真实推理逻辑)
# results = model(img)
# return {"predictions": results.json()}
return {"success": True, "message": "Inference completed"}
except Exception as e:
raise HTTPException(status_code=400, detail=f"Prediction failed: {str(e)}")
⚠️ 注意事项:
/health必须是GET请求,返回200 OK;延迟返回或抛异常将导致部署卡死。建议仅检查模型是否完成加载(如model is not None),避免耗时操作(如 GPU 显存探测)。/predict必须是POST,且请求体结构需与 Vertex AI 的预期一致(通常为 JSON 内含image字段)。不要使用/v1/predict或其他变体路径。- Uvicorn 启动命令中必须绑定
0.0.0.0:8080(而非127.0.0.1:8080):# 在 startup.sh 或 CMD 中确保 uvicorn main:app --host 0.0.0.0:8080 --port 8080 --workers 1
✅ 更新模型上传命令(关键!)
你当前的 gcloud ai models upload 缺失三个强制参数。请立即修正为:
gcloud ai models upload \ --region=YOUR_REGION \ --display-name=freshpet-mobile \ --container-image-uri=us-central1-docker.pkg.dev/YOUR_PROJECT/YOUR_REPO/YOUR_IMAGE:tag \ --container-health-route="/health" \ --container-predict-route="/predict" \ --container-ports="8080" \ --container-command="" \ --container-args=""
-
--container-health-route和--container-predict-route是 Vertex AI 调用容器的唯一入口,不可省略。 -
--container-ports=8080明确告知平台容器监听端口(即使 Dockerfile 中已暴露EXPOSE 8080,此参数仍为必需)。 - 若使用 Gunicorn + Uvicorn 组合,确保
--bind 0.0.0.0:8080已写入 Gunicorn 配置。
✅ 排查与验证步骤
本地模拟 Vertex AI 探针:
启动容器后,手动访问curl http://localhost:8080/health和curl -X POST http://localhost:8080/predict -H "Content-Type: application/json" -d '{"image":"..."}',确认返回 200/200。检查 Cloud Logging 中的系统日志:
部署失败后,前往 Vertex AI → Endpoints → 对应端点 → Logs,筛选logName="projects/YOUR_PROJECT/logs/cloudaudit.googleapis.com%2Factivity"和resource.type="aiplatform.googleapis.com/Endpoint",重点关注Health check failed或Container failed to start类错误。验证 Artifact Registry 权限:
确保 Vertex AI 服务账号(格式为service-PROJECT_NUMBER@aiplatform.gserviceaccount.com)拥有roles/artifactregistry.reader角色,否则镜像拉取会静默失败。
? 总结:Vertex AI 的自定义容器不是“能跑就行”,而是“按契约运行”。它本质是一个受控的 MLOps 运行时——你交付的不是服务,而是一份满足健康探针、预测协议、端口约定、资源声明四要素的可审计合约。跳过任一环,生产环境即失效。这正是为何我们强调:Docker 是载体,Vertex AI 是契约;部署的本质,是让工程实践对齐平台语义。










