
Vertex AI 对自定义容器模型有强制接口契约要求:必须提供 /health 健康检查端点(返回 200 OK)和 /predict 推理端点(符合 JSON 输入/输出约定),且需在模型上传时显式声明端口与路由,否则服务将无法就绪并静默失败。
vertex ai 对自定义容器模型有强制接口契约要求:必须提供 `/health` 健康检查端点(返回 200 ok)和 `/predict` 推理端点(符合 json 输入/输出约定),且需在模型上传时显式声明端口与路由,否则服务将无法就绪并静默失败。
在 Vertex AI 上成功部署 YOLO 类 FastAPI 容器,关键不在于“能否运行”,而在于是否满足其生产级服务契约。你已验证本地与 Cloud Run 的功能完备性——这恰恰说明模型逻辑和基础镜像无问题;失败根源是 Vertex AI 的调度与生命周期管理机制与 Cloud Run 有本质差异:它依赖标准化的 HTTP 探针进行就绪(readiness)与存活(liveness)判定,并严格约束推理入口协议。
✅ 必须补全的两个核心端点
你的 FastAPI 应用需显式暴露以下端点(推荐在 main.py 中统一注册):
from fastapi import FastAPI
import torch
app = FastAPI()
# ✅ 强制要求:/health 端点 —— Vertex AI 每 5–10 秒轮询,仅当返回 200 且响应体为 {} 或 {"status": "ok"} 时才标记实例为“就绪”
@app.get("/health")
def health_check():
# 可选:轻量级校验(如模型是否已加载、GPU 是否可用)
try:
if torch.cuda.is_available():
torch.cuda.current_device() # 触发初始化检查
return {"status": "ok", "cuda": torch.cuda.is_available()}
except Exception as e:
return {"status": "error", "detail": str(e)}
# ✅ 强制要求:/predict 端点 —— Vertex AI 所有推理请求均发往此路径,且必须接收 application/json,返回 application/json
@app.post("/predict")
def predict(request: dict):
# 示例:解析 base64 图像(匹配你的业务逻辑)
import base64, io, numpy as np
from PIL import Image
from ultralytics import YOLO
image_b64 = request.get("image")
if not image_b64:
return {"error": "Missing 'image' field in JSON body"}
try:
image_bytes = base64.b64decode(image_b64)
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
results = model(image) # 假设 model 已全局加载
return {
"detections": [
{
"bbox": [int(x) for x in box.xyxy[0].tolist()],
"class": int(box.cls[0]),
"confidence": float(box.conf[0])
}
for box in results[0].boxes
]
}
except Exception as e:
return {"error": f"Inference failed: {str(e)}"}
⚠️ 注意:
/predict不能是/、/api/predict或其他路径;Vertex AI 不支持自定义前缀或重写。请求体结构由你定义,但 HTTP 方法、路径、Content-Type 必须严格匹配。
? 部署命令必须显式声明路由与端口
你在 gcloud ai models upload 步骤中遗漏了关键参数——Vertex AI 不会自动探测 FastAPI 的端口或路径。请立即更新模型上传命令:
gcloud ai models upload \ --region=$REGION \ --display-name=freshpet-mobile \ --container-image-uri=$IMAGE_NAME_MOBILE \ --container-health-route="/health" \ --container-predict-route="/predict" \ --container-ports=8080 \ # FastAPI 默认监听 8080(Uvicorn/Gunicorn 需配置 --host 0.0.0.0:8080) --container-command="bash" \ --container-args="startup.sh" # 确保 startup.sh 最终执行:uvicorn main:app --host 0.0.0.0:8080 --port 8080
✅ 关键参数说明:
-
--container-health-route:指定健康检查路径(必须返回 200) -
--container-predict-route:指定推理入口路径(Vertex AI 将所有 POST 请求转发至此) -
--container-ports:声明容器监听端口(必须与startup.sh中启动命令一致)
? 调试与日志:启用 Cloud Logging 是唯一有效手段
Vertex AI 不会透出容器 stdout/stderr 到控制台,所有日志必须通过 Cloud Logging 查看:
- 进入 Google Cloud Console → Logging → Logs Explorer
- 设置查询(推荐):
resource.type="aiplatform.googleapis.com/Endpoint" resource.labels.endpoint_id="YOUR_ENDPOINT_ID" severity>=DEBUG
- 关键日志线索:
-
Readiness probe failed→/health未响应或返回非 200 -
Container failed to start→startup.sh启动失败(检查--container-command和--container-args) -
Prediction request rejected→/predict返回非 200 或 Content-Type 错误
-
? 补充最佳实践(避免踩坑)
-
GPU 初始化延迟:P4 GPU 在 Vertex AI 上首次调用
torch.cuda.*可能耗时 5–15 秒。/health中加入torch.cuda.synchronize()或预热逻辑,避免就绪探针超时。 -
端口绑定必须为 0.0.0.0:Uvicorn/Gunicorn 启动时务必使用
--host 0.0.0.0:8080,而非127.0.0.1(否则外部不可达)。 -
避免在
/predict中加载模型:模型应在startup.sh或 FastAPIon_event("startup")中一次性加载,否则每次请求都触发 CUDA 初始化,导致超时。 -
验证 Artifact Registry 权限:确保 Vertex AI 服务账号(格式为
PROJECT_NUMBER@cloud-ai-platform.iam.gserviceaccount.com)拥有roles/artifactregistry.reader权限。
完成上述修改后,重新构建镜像、推送、上传模型并部署——你将看到 Endpoint 状态从 UNHEALTHY 变为 HEALTHY,且 Cloud Logging 中开始出现 /health 探针日志与实际推理记录。这才是 Vertex AI 生产环境可审计、可运维的正确打开方式。










