部署和管理自定义模型

您可以使用 Firebase 控制台或 Firebase Admin Python 和 Node.js SDK 部署和管理自定义模型和 AutoML 训练模型。如果您只是想部署模型并偶尔更新,使用 Firebase 控制台通常是最简单的方法。在与构建流水线集成,使用 Colab 或 Jupyter 笔记本以及其他工作流时,Admin SDK 会非常有用。

Firebase 控制台中部署和管理模型

TensorFlow Lite 模型

如需使用 Firebase 控制台部署 TensorFlow Lite 模型,请执行以下操作:

  1. Firebase 控制台中打开 Firebase ML 自定义模型页面
  2. 点击添加自定义模型(或再添加一个模型)。
  3. 指定一个名称,用于在 Firebase 项目中识别您的模型,然后上传 TensorFlow Lite 模型文件(通常以 .tflite.lite 结尾)。

部署模型后,您可以在“自定义”页面上找到该模型。您可以在此页面上完成一些任务,例如使用新文件更新模型、下载模型以及从项目中删除模型。

使用 Firebase Admin SDK 部署和管理模型

本部分介绍如何使用 Admin SDK 完成常见的模型部署和管理任务。如需其他帮助,请参阅 PythonNode.js SDK 参考文档。

如需查看所用 SDK 的示例,请参阅 Python 快速入门示例Node.js 快速入门示例

准备工作

  1. 如果您还没有 Firebase 项目,请在 Firebase 控制台中创建一个新项目。然后,打开您的项目并执行以下操作:

    1. 设置页面上,创建服务账号并下载服务账号密钥文件。请将此文件保存在安全的位置,因为它会向管理员授予对您的项目的访问权限。

    2. 在“Storage”页面上,启用 Cloud Storage。记下您的存储桶名称。

      在将模型文件添加到 Firebase 项目时,您需要一个 Cloud Storage 存储桶来临时存储这些文件。如果您使用的是 Blaze 方案,则可以创建一个存储桶,而非使用默认存储桶。

    3. Firebase ML 页面上,如果您尚未启用 Firebase ML,请点击开始使用

  2. Google API 控制台中,打开您的 Firebase 项目并启用 Firebase ML API。

  3. 安装并初始化 Admin SDK

    初始化 SDK 时,请指定服务账号凭据以及要用于存储模型的 Cloud Storage 存储桶:

    Python

    import firebase_admin
    from firebase_admin import ml
    from firebase_admin import credentials
    
    firebase_admin.initialize_app(
      credentials.Certificate('/path/to/your/service_account_key.json'),
      options={
          'storageBucket': 'your-storage-bucket',
      })
    

    Node.js

    const admin = require('firebase-admin');
    const serviceAccount = require('/path/to/your/service_account_key.json');
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      storageBucket: 'your-storage-bucket',
    });
    const ml = admin.machineLearning();
    

部署模型

TensorFlow Lite 文件

如需通过模型文件部署 TensorFlow Lite 模型,请将该模型上传到项目中,然后发布:

Python

# First, import and initialize the SDK as shown above.

# Load a tflite file and upload it to Cloud Storage
source = ml.TFLiteGCSModelSource.from_tflite_model_file('example.tflite')

# Create the model object
tflite_format = ml.TFLiteFormat(model_source=source)
model = ml.Model(
    display_name="example_model",  # This is the name you use from your app to load the model.
    tags=["examples"],             # Optional tags for easier management.
    model_format=tflite_format)

# Add the model to your Firebase project and publish it
new_model = ml.create_model(model)
ml.publish_model(new_model.model_id)

Node.js

// First, import and initialize the SDK as shown above.

(async () => {
  // Upload the tflite file to Cloud Storage
  const storageBucket = admin.storage().bucket('your-storage-bucket');
  const files = await storageBucket.upload('./example.tflite');

  // Create the model object and add the model to your Firebase project.
  const bucket = files[0].metadata.bucket;
  const name = files[0].metadata.name;
  const gcsUri = `gs:/⁠/${bucket}/${name}`;
  const model = await ml.createModel({
    displayName: 'example_model',  // This is the name you use from your app to load the model.
    tags: ['examples'],  // Optional tags for easier management.
    tfliteModel: { gcsTfliteUri: gcsUri },
  });

  // Publish the model.
  await ml.publishModel(model.modelId);

  process.exit();
})().catch(console.error);

TensorFlow 和 Keras 模型

使用 Python SDK,您可以将模型从 TensorFlow 已保存的模型格式转换为 TensorFlow Lite,然后在一个步骤中将其上传到您的 Cloud Storage 存储桶。然后,按照部署 TensorFlow Lite 文件的方式进行部署。

Python

# First, import and initialize the SDK as shown above.

# Convert the model to TensorFlow Lite and upload it to Cloud Storage
source = ml.TFLiteGCSModelSource.from_saved_model('./model_directory')

# Create the model object
tflite_format = ml.TFLiteFormat(model_source=source)
model = ml.Model(
    display_name="example_model",  # This is the name you use from your app to load the model.
    tags=["examples"],             # Optional tags for easier management.
    model_format=tflite_format)

# Add the model to your Firebase project and publish it
new_model = ml.create_model(model)
ml.publish_model(new_model.model_id)

如果您有 Keras 模型,也可以将其转换为 TensorFlow Lite,同样只需一步即可上传。您可以使用已保存到 HDF5 文件的 Keras 模型:

Python

import tensorflow as tf

# Load a Keras model, convert it to TensorFlow Lite, and upload it to Cloud Storage
model = tf.keras.models.load_model('your_model.h5')
source = ml.TFLiteGCSModelSource.from_keras_model(model)

# Create the model object, add the model to your project, and publish it. (See
# above.)
# ...

或者,您可以直接从训练脚本转换 Keras 模型并上传:

Python

import tensorflow as tf

# Create a simple Keras model.
x = [-1, 0, 1, 2, 3, 4]
y = [-3, -1, 1, 3, 5, 7]

model = tf.keras.models.Sequential(
    [tf.keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')
model.fit(x, y, epochs=3)

# Convert the model to TensorFlow Lite and upload it to Cloud Storage
source = ml.TFLiteGCSModelSource.from_keras_model(model)

# Create the model object, add the model to your project, and publish it. (See
# above.)
# ...

AutoML TensorFlow Lite 模型

如果您使用 AutoML Cloud APIGoogle Cloud 控制台界面训练了 Edge 模型,则可以使用 Admin SDK 将该模型部署到 Firebase。

您将需要指定模型的资源标识符,该标识符是类似于以下示例的字符串:

projects/PROJECT_NUMBER/locations/STORAGE_LOCATION/models/MODEL_ID
PROJECT_NUMBER 包含模型的 Cloud Storage 存储桶的项目号。这可能是您的 Firebase 项目或另一个 Google Cloud 项目。您可以在 Firebase 控制台或 Google Cloud 控制台信息中心的“设置”页面内找到此值。
STORAGE_LOCATION 包含模型的 Cloud Storage 存储桶的资源位置。此值始终为 us-central1
MODEL_ID 您通过 AutoML Cloud API 获取的模型 ID。

Python

# First, import and initialize the SDK as shown above.

# Get a reference to the AutoML model
source = ml.TFLiteAutoMlSource('projects/{}/locations/{}/models/{}'.format(
    # See above for information on these values.
    project_number,
    storage_location,
    model_id
))

# Create the model object
tflite_format = ml.TFLiteFormat(model_source=source)
model = ml.Model(
    display_name="example_model",  # This is the name you will use from your app to load the model.
    tags=["examples"],             # Optional tags for easier management.
    model_format=tflite_format)

# Add the model to your Firebase project and publish it
new_model = ml.create_model(model)
new_model.wait_for_unlocked()
ml.publish_model(new_model.model_id)

Node.js

// First, import and initialize the SDK as shown above.

(async () => {
  // Get a reference to the AutoML model. See above for information on these
  // values.
  const automlModel = `projects/${projectNumber}/locations/${storageLocation}/models/${modelId}`;

  // Create the model object and add the model to your Firebase project.
  const model = await ml.createModel({
    displayName: 'example_model',  // This is the name you use from your app to load the model.
    tags: ['examples'],  // Optional tags for easier management.
    tfliteModel: { automlModel: automlModel },
  });

  // Wait for the model to be ready.
  await model.waitForUnlocked();

  // Publish the model.
  await ml.publishModel(model.modelId);

  process.exit();
})().catch(console.error);

列出项目的模型

您可以列出项目的模型,也可以过滤结果:

Python

# First, import and initialize the SDK as shown above.

face_detectors = ml.list_models(list_filter="tags: face_detector").iterate_all()
print("Face detection models:")
for model in face_detectors:
  print('{} (ID: {})'.format(model.display_name, model.model_id))

Node.js

// First, import and initialize the SDK as shown above.

(async () => {
  let listOptions = {filter: 'tags: face_detector'}
  let models;
  let pageToken = null;
  do {
    if (pageToken) listOptions.pageToken = pageToken;
    ({models, pageToken} = await ml.listModels(listOptions));
    for (const model of models) {
      console.log(`${model.displayName} (ID: ${model.modelId})`);
    }
  } while (pageToken != null);

  process.exit();
})().catch(console.error);

您可以按以下字段进行过滤:

字段 示例
display_name display_name = example_model
display_name != example_model

所有带有 experimental_ 前缀的显示名:

display_name : experimental_*

请注意,仅支持前缀匹配。

tags tags: face_detector
tags: face_detector AND tags: experimental
state.published state.published = true
state.published = false

过滤条件可以与 ANDORNOT 运算符以及括号(())结合使用。

更新模型

将模型添加到项目后,您可以更新其显示名、标记和 tflite 模型文件:

Python

# First, import and initialize the SDK as shown above.

model = ...   # Model object from create_model(), get_model(), or list_models()

# Update the model with a new tflite model. (You could also update with a
# `TFLiteAutoMlSource`)
source = ml.TFLiteGCSModelSource.from_tflite_model_file('example_v2.tflite')
model.model_format = ml.TFLiteFormat(model_source=source)

# Update the model's display name.
model.display_name = "example_model"

# Update the model's tags.
model.tags = ["examples", "new_models"]

# Add a new tag.
model.tags += "experimental"

# After you change the fields you want to update, save the model changes to
# Firebase and publish it.
updated_model = ml.update_model(model)
ml.publish_model(updated_model.model_id)

Node.js

// First, import and initialize the SDK as shown above.

(async () => {
  const model = ... // Model object from createModel(), getModel(), or listModels()

  // Upload a new tflite file to Cloud Storage.
  const files = await storageBucket.upload('./example_v2.tflite');
  const bucket = files[0].metadata.bucket;
  const name = files[0].metadata.name;

  // Update the model. Any fields you omit will be unchanged.
  await ml.updateModel(model.modelId, {
    displayName: 'example_model',  // Update the model's display name.
    tags: model.tags.concat(['new']),  // Add a tag.
    tfliteModel: {gcsTfliteUri: `gs:/⁠/${bucket}/${name}`},
  });

  process.exit();
})().catch(console.error);

取消发布或删除模型

如需取消发布或删除模型,请将模型 ID 传递给取消发布或删除方法。取消发布模型后,模型仍会保留在您的项目中,但无法供您的应用下载。删除模型后,模型会从项目中完全移除。(在标准工作流中,取消发布模型并非正常操作,但如果意外发布了新模型且尚未在任何地方使用,或者宁愿用户收到“未找到模型”错误而不是下载“不良”模型,您可以用它来立即取消发布。)

如果您仍然没有模型对象的引用,可能需要使用过滤器列出项目的模型来获取模型 ID。例如,如需删除标记为“face_detector”的所有模型,请运行以下命令:

Python

# First, import and initialize the SDK as shown above.

face_detectors = ml.list_models(list_filter="tags: 'face_detector'").iterate_all()
for model in face_detectors:
  ml.delete_model(model.model_id)

Node.js

// First, import and initialize the SDK as shown above.

(async () => {
  let listOptions = {filter: 'tags: face_detector'}
  let models;
  let pageToken = null;
  do {
    if (pageToken) listOptions.pageToken = pageToken;
    ({models, pageToken} = await ml.listModels(listOptions));
    for (const model of models) {
      await ml.deleteModel(model.modelId);
    }
  } while (pageToken != null);

  process.exit();
})().catch(console.error);