将多个模型部署到 Vertex AI 中的同一端点

Deploying multiple models to same endpoint in Vertex AI

我们的用例如下: 我们有多个自定义训练模型(有数百个,随着我们允许应用程序的用户通过 UI 创建模型,我们会即时训练和部署模型,因此数量会增加),因此将每个模型部署到一个单独的端点很昂贵,因为 Vertex AI charges per node used. Based on the documentation 看来我们可以将不同类型的模型部署到同一端点,但我不确定这将如何工作。假设我使用自定义容器部署了 2 个不同的自定义训练模型以预测到同一端点。另外,假设我将两个模型的流量分配指定为 50%。现在,如何向特定模型发送请求?使用 python SDK,我们调用端点,如下所示:

from google.cloud import aiplatform
endpoint = aiplatform.Endpoint(endpoint_id)
prediction = endpoint.predict(instances=instances)

# where endpoint_id is the id of the endpoint and instances are the observations for which a prediction is required

我的理解是,在这种情况下,顶点 AI 会根据流量分配将一些调用路由到一个模型,将一些调用路由到另一个模型。我可以使用 docs 中指定的参数字段来指定模型,然后在自定义预测容器中相应地处理请求,但仍然有一些调用最终会转到它无法访问的模型处理(因为 Vertex AI 不会将所有请求发送到所有模型,否则流量拆分就没有意义)。然后我如何将多个模型部署到同一个端点并确保每个预测请求都得到保证?

documentation 讨论了一个用例,其中 2 个模型在同一特征集上进行训练并共享入口预测流量。正如你所理解的,这不适用于在不同特征集上训练的模型,即不同的模型。

遗憾的是,目前在 Vertex AI 中无法仅使用一个节点将不同模型部署到同一端点。有一个正在进行的功能请求正在处理中。但是,我们无法提供该功能何时可用的确切预计时间。

我重现了多模型设置并注意到以下几点。

流量拆分

I deployed 2 different models to the same endpoint and sent predictions to it. I set a 50-50 traffic splitting rule and saw errors that implied requests being sent to the wrong model.

成本优化

When multiple models are deployed to the same endpoint, they are deployed to separate, independent nodes. So, you will still be charged for each node used. Also, node autoscaling happens at the model level, not at the endpoint level.

一个可行的解决方法是将所有模型打包到一个容器中,并使用自定义 HTTP 服务器逻辑将预测请求发送到适当的模型。这可以使用预测请求正文的 parameters 字段来实现。自定义逻辑看起来像这样。

@app.post(os.environ['AIP_PREDICT_ROUTE'])
async def predict(request: Request):
    body = await request.json()
    parameters = body["parameters"]
    instances = body["instances"]
    inputs = np.asarray(instances)
    preprocessed_inputs = _preprocessor.preprocess(inputs)

    if(parameters["model_name"]=="random_forest"):
        print(parameters["model_name"])
        outputs = _random_forest_model.predict(preprocessed_inputs)
    else:
        print(parameters["model_name"])
        outputs = _decision_tree_model.predict(inputs)

    return {"predictions": [_class_names[class_num] for class_num in outputs]}