pip install ydf -U
关于本教程¶
本教程展示如何训练一个 YDF 模型,将其导出为 TensorFlow SavedModel 格式,并在 Vertex AI 中运行该模型。此外,本教程还展示如何手动运行 TensorFlow Serving 二进制文件以使用该模型进行推理。
什么是 TF Serving?¶
TensorFlow Serving 是一个用于运行机器学习模型的生产环境。TensorFlow Serving 可以运行 YDF 模型。
什么是 Vertex AI?¶
Vertex AI 是 Google Cloud 提供的一个用于管理和部署机器学习模型的解决方案。Vertex AI 依赖 TensorFlow Serving 来运行 TensorFlow 模型(存储在 TensorFlow SavedModel 格式中)。YDF 模型可以使用 model.to_tensorflow_saved_model 方法导出为 TensorFlow SavedModel 格式,并在 TensorFlow Serving 和 Vertex AI 上运行。
关于 TensorFlow Saved Model 输入的重要说明¶
TensorFlow Saved Model 可以看作是一个通用函数,它将数据作为输入并产生预测作为输出。TensorFlow Serving 和 Vertex AI 定义了三种输入格式用于馈送输入特征,以及三种输出格式用于检索预测。使用不正确的格式可能会导致难以理解的错误消息。理解这些格式对于使用 TensorFlow Serving 和 Vertex AI 并非必需,但有助于调试您的管道。本节概述了这些格式。
YDF 允许您使用 to_tensorflow_saved_model
函数的 servo_api: bool
和 feed_example_proto: bool
参数选择模型的格式类型。
输入格式 #1:输入实例
在这种格式中,数据按示例分组,其中每个示例是列表中特征的字典。这种格式简单直观,但效率不高。所有 API(REST、Python、C++)都可以轻松使用此格式。Vertex AI 的在线预测和 Vertex AI 的 jsonl 批量预测使用此格式。
这是一个示例列表,每个示例有 3 个特征:"f1"、"f2" 和 "f3"
[ {"f1": 1, "f2": 5.9, "f3": "red" }, {"f1": 3, "f2": 2.1, "f3": "blue" } ]
这是 to_tensorflow_saved_model
函数的默认输入格式,即 feed_example_proto=False
。
输入格式 #2:输入特征
在这种格式中,数据按特征分组,其中每个特征是字典中的值列表。这种格式相对直观且效率最高。所有 API(REST、Python、C++)都可以轻松使用此格式。如果可能,应使用此格式。
这是使用此格式表示的同一示例
{"f1": [1, 3], "f2": [5.9, 2.1], "f3": ["red", "blue"] }
这也是 to_tensorflow_saved_model
函数的默认输入格式,即 feed_example_proto=False
。
输入格式 #3:序列化的 TensorFlow 示例
在最后一种格式中,数据被编码为 Google Protobuf 的 TensorFlow Example Protobuf,这也是用于训练大型 TensorFlow 管道的格式。这种格式对于Serving而言效率不高,且使用相对复杂。如果可能,请尽量避免将其用于推理。Vertex AI 对 TensorFlow Records 文件的批量预测要求使用此格式。
在 to_tensorflow_saved_model
函数中,通过设置 feed_example_proto=True
来启用此格式。
输出格式 #1:预测
这种格式最简单、最有效。预测值由模型直接输出。预测的含义由模型决定。例如,分类模型将输出概率,而回归模型将输出值。这是 to_tensorflow_saved_model
函数的默认输出格式,即 servo_api=False
。
这是一个二元分类模型的预测示例
{ "prediction": [0.2, 0.7] }
这是一个多元分类模型的预测示例
{ "prediction": [[0.2, 0.1, 0.7],
[0.8, 0.1, 0.1]] }
Vertex AI 在线预测支持此格式。
输出格式 #2 & 3:分类和回归
在这些格式中,模型输出一个值的字典。值取决于模型类型。例如,分类模型将输出“score”和“labels”值。通过在 to_tensorflow_saved_model
函数中设置 servo_api=True
来启用此输出格式。
Vertex AI 在线预测支持此格式,并且 Vertex AI 批量预测需要此格式。
这是一个二元分类模型的预测示例
{ "scores": [[0.2, 0.8],
[0.1, 0.9]],
"classes": [["v1", "v2"],
["v1", "v2"]]}
# Load libraries
import ydf # Yggdrasil Decision Forests
import pandas as pd # We use Pandas to load small datasets
# Download a classification dataset and load it as a Pandas DataFrame.
ds_path = "https://raw.githubusercontent.com/google/yggdrasil-decision-forests/main/yggdrasil_decision_forests/test_data/dataset"
train_ds = pd.read_csv(f"{ds_path}/adult_train.csv")
test_ds = pd.read_csv(f"{ds_path}/adult_test.csv")
# Print the first 5 training examples
train_ds.head(5)
年龄 | 工作类别 | fnlwgt | 教育程度 | 教育编号 | 婚姻状况 | 职业 | 关系 | 种族 | 性别 | 资本收益 | 资本损失 | 每周工时 | 原籍国 | 收入 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 44 | Private | 228057 | 7th-8th | 4 | Married-civ-spouse | Machine-op-inspct | Wife | White | Female | 0 | 0 | 40 | Dominican-Republic | <=50K |
1 | 20 | Private | 299047 | Some-college | 10 | Never-married | Other-service | Not-in-family | White | Female | 0 | 0 | 20 | United-States | <=50K |
2 | 40 | Private | 342164 | HS-grad | 9 | Separated | Adm-clerical | Unmarried | White | Female | 0 | 0 | 37 | United-States | <=50K |
3 | 30 | Private | 361742 | Some-college | 10 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 50 | United-States | <=50K |
4 | 67 | Self-emp-inc | 171564 | HS-grad | 9 | Married-civ-spouse | Prof-specialty | Wife | White | Female | 20051 | 0 | 30 | England | >50K |
我们训练模型
model = ydf.GradientBoostedTreesLearner(label="income").train(train_ds)
Train model on 22792 examples Model trained in 0:00:02.335818
注意:虽然此处未作演示,但建议在使用模型之前先查看和评估它。使用 model.describe()
方法检查模型的结构和特征,并使用 model.evaluate(...)
方法评估其性能和准确性。详细信息请参阅入门教程。
将模型导出为 TF Saved Model 格式¶
TensorFlow Serving 只能读取 TensorFlow SavedModel 格式的模型。因此,我们将 YDF 模型导出为 TensorFlow SavedModel 格式。
此步骤需要安装TensorFlow Decision Forests 库。
信息:TensorFlow Decision Forests 是 YDF 团队在 YDF 之上构建的 Keras 2 包装器。对于大多数用例,直接使用 YDF 更可取,因为它更快、更容易使用,并且与 Keras 2 和 Keras 3 都兼容。了解更多。
!pip install tensorflow_decision_forests -qq
# Export the model to a TensorFlow Saved Model.
# For Vertex AI Online inference.
# The model consumes raw features values, and output raw model predictions.
model.to_tensorflow_saved_model("/tmp/ydf/tf_model", mode="tf")
# For Vertex AI Batch inference.
# The model consumes TensorFlow Example protos, and returns a dictionary.
# model.to_tensorflow_saved_model("/tmp/ydf/tf_model", mode="tf", servo_api=True, feed_example_proto=True)
[INFO 24-04-12 14:12:24.7037 CEST kernel.cc:1233] Loading model from path /tmp/tmp5siwullh/tmppvtwaq00/ with prefix 18bdf8d5_ [INFO 24-04-12 14:12:24.7308 CEST quick_scorer_extended.cc:911] The binary was compiled without AVX2 support, but your CPU supports it. Enable it for faster model inference. [INFO 24-04-12 14:12:24.7316 CEST abstract_model.cc:1344] Engine "GradientBoostedTreesQuickScorerExtended" built [INFO 24-04-12 14:12:24.7316 CEST kernel.cc:1061] Use fast generic engine
在 Vertex AI 中导入模型¶
要在 Vertex AI 中导入模型,请按照以下步骤操作
1. 将 TensorFlow Saved Model 导入到 Google Cloud 存储桶中
- 打开 Cloud Storage 页面。
- 创建新存储桶或选择现有存储桶。
- 点击“上传文件夹”并选择之前导出的模型,本例中为
/tmp/ydf/tf_model
。
模型存储桶应包含名为 saved_model.pb
的文件。例如,如果您将模型上传到 gs://my_bucket
存储桶,则应存在 gs://ydf_model_2/tf_model/saved_model.pb
文件。
2. 在 Vertex AI 中注册模型
- 打开 Vertex AI 模型注册表页面。
- 点击“导入”并从云存储桶中选择模型。
- 在“导入模型”对话框中,配置以下选项
- 名称:输入模型的名称。
- 模型框架:选择 TensorFlow。
- 模型框架版本:选择最新版本,在撰写本文时为 2.13。
- 加速器:选择 None。
- 模型工件位置:指定模型工件的 Google Cloud Storage (GCS) 路径,例如
gs://my_bucket/tf_model/
。 - 使用优化的 TensorFlow 运行时:禁用此字段。决策森林不适用于此神经网络特定的优化。
- 将其余选项保留默认值,然后点击“继续”。
- 当系统提示有关可解释性的信息时,选择“无需可解释性”,然后点击“导入”。
模型将在几分钟内导入。您可以在模型注册表页面的右上角监控进度。导入后,模型将出现在注册模型列表中。
模型现在已准备好进行推理。
在线预测¶
可以将模型部署到“端点”,并通过 Cloud REST API 进行远程查询。
- 打开 Cloud Model Registry 页面。
- 选择模型,打开“部署和测试”选项卡,然后点击“部署到端点”。
- 按如下方式配置端点
- 端点名称:输入端点的名称。
- 机器类型:选择最小的可用机器,例如
n1-standard-2
- 点击“部署”
端点正在部署中。
在“测试模型”部分,使用以下 JSON 请求查询模型
{
"instances":[
{
"age":39,
"workclass":"State-gov",
"fnlwgt":77516,
"education":"Bachelors",
"education_num":13,
"marital_status":"Never-married",
"occupation":"Adm-clerical",
"relationship":"Not-in-family",
"race":"White",
"sex":"Male",
"capital_gain":2174,
"capital_loss":0,
"hours_per_week":40,
"native_country":"United-States"
}
]
}
结果将是
{
"predictions": [
0.0186043456
],
"deployedModelId": "2255069761266253824",
"model": "projects/734980258708/locations/us-central1/models/8572427068350922752",
"modelDisplayName": "tf_model_servoF_protoF",
"modelVersionId": "1"
}
此预测结果表明,正类为真的概率为 1.66%。换句话说,模型预测为负类。
print("The positive and negative classes are:", model.label_classes())
The positive and negative classes are: ['<=50K', '>50K']
批量预测¶
现在,让我们使用该模型执行批量预测。这包括上传一个包含实例的文件,生成预测,并在 JSON 文件中检索结果。
我们从 CSV 文件加载了训练数据集。然而,将 CSV 文件与 TensorFlow SavedModel 一起使用可能导致错误。为避免此问题,我们将使用 TensorFlow 的官方示例数据集格式,即 tf.train.Example protobuf 的 TFRecord 文件。幸运的是,测试数据集已以这种格式在此处提供。
- 将“adult_test.recordio.gz”下载到您的计算机上。
- 打开 Cloud Storage 页面。
- 在您已创建的存储桶中,点击“上传文件”并选择文件
adult_test.recordio.gz
。 - 在 Cloud storage 页面中,选择该文件并将其重命名为
adult_test.tfrecord.gz
。- Vertex AI 通过文件扩展名检测文件格式。
- 打开 Cloud Model Registry 页面。
- 选择模型,打开“批量预测”选项卡,然后点击“创建批量预测”。
- 按如下方式配置批量预测
- 批量预测名称:输入预测的名称。
- Cloud Storage 上的文件 (JSONL, CSV, TFRecord, and TFRecord (GZIP)):选择
adult_test.tfrecord.gz
文件。 - 目标路径:选择包含模型和数据集的存储桶。
- 计算节点数:输入“1”。这是一个小型数据集,不需要太多计算能力。
- 机器类型:选择最小的可用机器,例如
n1-standard-2
- 点击“创建”
预测正在计算中。计算完成后,您将在存储桶中的新创建的 JSON 文件中找到结果。
以下是生成文件的前五行
{"prediction": {"scores": [0.981395662, 0.0186043456], "classes": ["<=50K", ">50K"]}}
{"prediction": {"scores": [0.638690472, 0.361309558], "classes": ["<=50K", ">50K"]}}
{"prediction": {"scores": [0.161411345, 0.838588655], "classes": ["<=50K", ">50K"]}}
{"prediction": {"scores": [0.956144333, 0.0438556746], "classes": ["<=50K", ">50K"]}}
{"prediction": {"scores": [0.970823526, 0.0291764941], "classes": ["<=50K", ">50K"]}}
您可以看到每个示例和每个类别的预测概率。例如,在第一个示例中,模型预测类别“<=50K”的概率为 98.14%。
在本地 TensorFlow Serving 中运行模型 [高级]¶
可以在本地或远程机器上启动 TensorFlow Serving 二进制文件,并使用 TensorFlow Serving REST API 发送请求。下面展示如何进行
为了测试我们的模型,我们按照tf serving 设置说明启动一个本地版本的 TF Serving。
在另一个终端中,输入
cd /tmp/ydf
docker run -t --rm -p 8501:8501 \
-v /tmp/tf/tf_model:/models/my_saved_model/1 \
-e MODEL_NAME=my_saved_model \
tensorflow/serving
注意:TensorFlow Serving 期望模型路径遵循以下结构:models/<MODEL_NAME>/<VERSION>
TensorFlow Serving 服务器启动并运行后,您可以发送预测请求。以下是每种请求的示例
使用输入实例格式的预测
!curl http://localhost:8501/v1/models/my_saved_model:predict -X POST \
-d '{"instances": [{"age":39,"workclass":"State-gov","fnlwgt":77516,"education":"Bachelors","education_num":13,"marital_status":"Never-married","occupation":"Adm-clerical","relationship":"Not-in-family","race":"White","sex":"Male","capital_gain":2174,"capital_loss":0,"hours_per_week":40,"native_country":"United-States"}]}'
使用输入特征格式的预测
!curl http://localhost:8501/v1/models/my_saved_model:predict -X POST \
-d '{"inputs": {"age":[39],"workclass":["State-gov"],"fnlwgt":[77516],"education":["Bachelors"],"education_num":[13],"marital_status":["Never-married"],"occupation":["Adm-clerical"],"relationship":["Not-in-family"],"race":["White"],"sex":["Male"],"capital_gain":[2174],"capital_loss":[0],"hours_per_week":[40],"native_country":["United-States"]} }'