XGBoost

XGBoost 是一个优化的分布式梯度提升库,设计宗旨是实现高效率、灵活性和可移植性。它在梯度提升框架下实现了机器学习算法。

本文档解释了如何使用 BentoML 服务和部署用于预测乳腺癌的 XGBoost 模型。

您可以使用乳腺肿瘤数据查询公开的预测端点。例如:

{
     "data": [
                 [1.308e+01, 1.571e+01, 8.563e+01, 5.200e+02, 1.075e-01, 1.270e-01,
                 4.568e-02, 3.110e-02, 1.967e-01, 6.811e-02, 1.852e-01, 7.477e-01,
                 1.383e+00, 1.467e+01, 4.097e-03, 1.898e-02, 1.698e-02, 6.490e-03,
                 1.678e-02, 2.425e-03, 1.450e+01, 2.049e+01, 9.609e+01, 6.305e+02,
                 1.312e-01, 2.776e-01, 1.890e-01, 7.283e-02, 3.184e-01, 8.183e-02]
             ]
 }

预期输出

[[0.02664177 0.9733583 ]] # 2.66% chance benign and 97.34% chance malignant

该示例已准备好在 BentoCloud 上进行快速部署和扩展。只需一条命令,您就能获得一个生产级别的应用,它具有快速自动扩缩容、在您的云中安全部署以及全面的可观测性。

Screenshot of the XGBoost breast cancer classifier model running on BentoCloud showing the prediction interface with input data and results

代码说明

您可以在 GitHub 中找到源代码。以下是本项目中关键代码实现的分解。

save_model.py

本示例使用 scikit-learn 框架加载和预处理乳腺癌数据集,然后将其转换为 XGBoost 兼容的格式(DMatrix)来训练机器学习模型。

save_model.py
import typing as t
from sklearn.datasets import load_breast_cancer
from sklearn.utils import Bunch
import xgboost as xgb

# Load the data
cancer: Bunch = t.cast("Bunch", load_breast_cancer())
cancer_data = t.cast("ext.NpNDArray", cancer.data)
cancer_target = t.cast("ext.NpNDArray", cancer.target)
dt = xgb.DMatrix(cancer_data, label=cancer_target)

# Specify model parameters
param = {
    "max_depth": 3,
    "eta": 0.3,
    "objective": "multi:softprob",
    "num_class": 2
}

# Train the model
model = xgb.train(param, dt)

训练完成后,使用 bentoml.xgboost.save_model API 将模型保存到 BentoML 的模型仓库 (Model Store),这是一个本地目录,用于存储和管理模型。您可以在后续的其他服务中检索此模型以运行预测。

import bentoml

# Specify the model name and the model to be saved
bentoml.xgboost.save_model("cancer", model)

要验证模型是否已成功保存,请运行:

$ bentoml models list

Tag                      Module           Size       Creation Time
cancer:xa2npbboccvv7u4c  bentoml.xgboost  23.17 KiB  2024-06-19 07:51:21

test.py

为确保保存的模型能正常工作,请尝试加载它并运行预测:

test.py
import bentoml
import xgboost as xgb

# Load the model by setting the model tag
booster = bentoml.xgboost.load_model("cancer:xa2npbboccvv7u4c")

# Predict using a sample
res = booster.predict(xgb.DMatrix([[1.308e+01, 1.571e+01, 8.563e+01, 5.200e+02, 1.075e-01, 1.270e-01,
    4.568e-02, 3.110e-02, 1.967e-01, 6.811e-02, 1.852e-01, 7.477e-01,
    1.383e+00, 1.467e+01, 4.097e-03, 1.898e-02, 1.698e-02, 6.490e-03,
    1.678e-02, 2.425e-03, 1.450e+01, 2.049e+01, 9.609e+01, 6.305e+02,
    1.312e-01, 2.776e-01, 1.890e-01, 7.283e-02, 3.184e-01, 8.183e-02]]))

print(res)

预期结果

[[0.02664177 0.9733583 ]]

service.py

service.py 文件是定义服务逻辑并将模型作为 Web 服务公开的地方。

service.py
import bentoml
import numpy as np
import xgboost as xgb
import os

@bentoml.service(
    resources={"cpu": "2"},
    traffic={"timeout": 10},
)
class CancerClassifier:
    # Declare the model as a class variable
    bento_model = bentoml.models.BentoModel("cancer:latest")

    def __init__(self):
        self.model = bentoml.xgboost.load_model(self.bento_model)

        # Check resource availability
        if os.getenv("CUDA_VISIBLE_DEVICES") not in (None, "", "-1"):
            self.model.set_param({"predictor": "gpu_predictor", "gpu_id": 0})  # type: ignore (incomplete XGBoost types)
        else:
            nthreads = os.getenv("OMP_NUM_THREADS")
            if nthreads:
                nthreads = max(int(nthreads), 1)
            else:
                nthreads = 1
            self.model.set_param(
                {"predictor": "cpu_predictor", "nthread": nthreads}
            )

    @bentoml.api
    def predict(self, data: np.ndarray) -> np.ndarray:
        return self.model.predict(xgb.DMatrix(data))

服务代码:

  • 使用 @bentoml.service 装饰器定义一个 BentoML 服务 (Service)。您可以选择设置额外的配置 (configurations),例如 BentoCloud 上的资源分配和流量超时。

  • 从模型仓库中检索模型,并将其定义为类变量。

  • 检查资源可用性,例如 GPU 和线程数。

  • 使用 @bentoml.api 装饰器将 predict 函数公开为 API 端点,它接受 NumPy 数组作为输入并返回 NumPy 数组。请注意,输入数据被转换为 DMatrix,这是 XGBoost 用于数据集的数据结构。

@bentoml.service 装饰器还允许您为 Bento(BentoML 中的统一分发格式)定义运行时环境。一个 Bento 打包了所有源代码、Python 依赖、模型引用和环境设置,使其易于在不同环境中一致地部署。

以下是一个示例:

service.py
my_image = bentoml.images.Image(python_version="3.11") \
            .python_packages("xgboost", "scikit-learn")

@bentoml.service(
    image=my_image, # Apply the specifications
    ...
)
class CancerClassifier:
    ...

试用

您可以在 BentoCloud 上运行此示例项目,也可以在本地提供服务,将其容器化为符合 OCI 标准的镜像,然后部署到任何地方。

BentoCloud

BentoCloud 为使用 BentoML 构建和扩展云端 AI 应用提供了快速且可扩展的基础设施。

  1. 安装依赖并通过 BentoML CLI 登录 BentoCloud。如果您没有 BentoCloud 账户,请在此免费注册

    # Recommend Python 3.11
    pip install bentoml xgboost scikit-learn
    
    bentoml cloud login
    
  2. 克隆仓库。

    git clone https://github.com/bentoml/BentoXGBoost.git
    cd BentoXGBoost
    
  3. 训练并保存 MLflow 模型到 BentoML 模型仓库。

    python3 save_model.py
    
  4. 部署服务到 BentoCloud。

    bentoml deploy
    
  5. 启动并运行后,您可以通过以下方式调用端点:

    Screenshot of the XGBoost breast cancer classifier model running on BentoCloud showing the prediction interface with input data and results

    创建一个BentoML 客户端来调用端点。请务必将部署 URL 替换为您在 BentoCloud 上的 URL。详情请参阅获取端点 URL

    import bentoml
    
    with bentoml.SyncHTTPClient("https://cancer-classifier-33e8-e3c1c7db.mt-guc1.bentoml.ai") as client:
          result = client.predict(
              data=[
                  [1.308e+01, 1.571e+01, 8.563e+01, 5.200e+02, 1.075e-01, 1.270e-01,
                  4.568e-02, 3.110e-02, 1.967e-01, 6.811e-02, 1.852e-01, 7.477e-01,
                  1.383e+00, 1.467e+01, 4.097e-03, 1.898e-02, 1.698e-02, 6.490e-03,
                  1.678e-02, 2.425e-03, 1.450e+01, 2.049e+01, 9.609e+01, 6.305e+02,
                  1.312e-01, 2.776e-01, 1.890e-01, 7.283e-02, 3.184e-01, 8.183e-02]
              ],
          )
          print(result)
    

    请务必将部署 URL 替换为您在 BentoCloud 上的 URL。详情请参阅获取端点 URL

    curl -X 'POST' \
          'https://cancer-classifier-33e8-e3c1c7db.mt-guc1.bentoml.ai/predict' \
          -H 'accept: application/json' \
          -H 'Content-Type: application/json' \
          -d '{
          "data": [
              [1.308e+01, 1.571e+01, 8.563e+01, 5.200e+02, 1.075e-01, 1.270e-01,
              4.568e-02, 3.110e-02, 1.967e-01, 6.811e-02, 1.852e-01, 7.477e-01,
              1.383e+00, 1.467e+01, 4.097e-03, 1.898e-02, 1.698e-02, 6.490e-03,
              1.678e-02, 2.425e-03, 1.450e+01, 2.049e+01, 9.609e+01, 6.305e+02,
              1.312e-01, 2.776e-01, 1.890e-01, 7.283e-02, 3.184e-01, 8.183e-02]
            ]
          }'
    
  6. 为确保部署在一定的副本范围内自动扩缩容,请添加扩缩容标志:

    bentoml deploy --scaling-min 0 --scaling-max 3 # Set your desired count
    

    如果已经部署,请按如下方式更新其允许的副本数:

    bentoml deployment update <deployment-name> --scaling-min 0 --scaling-max 3 # Set your desired count
    

    有关更多信息,请参阅如何配置并发和自动扩缩容

本地服务

BentoML 允许您在本地运行和测试代码,以便您可以使用本地计算资源快速验证代码。

  1. 克隆项目仓库并安装依赖。

    git clone https://github.com/bentoml/BentoXGBoost.git
    cd BentoXGBoost
    
    # Recommend Python 3.11
    pip install bentoml xgboost scikit-learn
    
  2. 训练模型并将其保存到 BentoML 模型仓库。

    python3 save_model.py
    
  3. 在本地提供服务。

    bentoml serve
    
  4. 访问或向 https://:3000 发送 API 请求。

对于您自己的基础设施中的自定义部署,使用 BentoML 生成符合 OCI 标准的镜像