教程|如何在腾讯云上部署 TensorFlow AI 推理函数

2,253 阅读4分钟

通过腾讯 serverless 云函数(SCF) custom runtime 使用 WebAssembly 虚拟机 SSVM,开发者只需编写几行简单的代码,就可以将任何 Tensorflow 模型转换为 Serverless 函数,然后将其作为 web 服务提供。

我们同时提供了一个包含源代码和配置文件的模板, 在此查看。这个模板开箱即用,只需通过命令行将模板部署到腾讯云,然后就会有一个可用的图片分类 web 应用。

Screencast | 在线 demo!

你可以直接 fork 并修改此 模版 ,然后根据你的需求更改为另一个 Tensorflow 模型、个性化解释和展示推理结果、更新 web UI 等等。最后使用 Serverless Framework 在几分钟内部署到腾讯云。在这个教程中我将演示如何做出这些调整。

遵循这些简单的指令来安装 Rustssvmup 以及 Serverless Framework。确保为ssvmup安装了 --enable-aot 扩展。

或者,可以使用 Github Codespaces 或者 Docker 来创建或运行该模版。

修改与模板不同的 TensorFlow 模型

模版中的 src/main.rs 文件是一个 Rust 程序。它接受输入图像,然后对图像数据执行 Tensorflow Lite (TFLite)模型。

在过去5年里,Rust 是 Stackoverflow 用户最喜欢的编程语言。乍一看,它可能看起来很复杂。但是,正如你可以从示例中看到的,SSVM 的 Rust API 非常简单,容易入门。

相关代码如下所示:

fn main() {
 // 1. 加载 TFLite 模型文件以及概率 label 文件 
 let model_data: &[u8] = include_bytes!("lite-model_aiy_vision_classifier_food_V1_1.tflite");
 let labels = include_str!("aiy_food_V1_labelmap.txt");

 // 2. 将上传的图像加载到 img_buf Vector 
 ... ...
 
 // 3. 将 img _ buf 调整为 tensorflow 模型的输入张量所需的大小
 let flat_img = ssvm_tensorflow_interface::load_jpg_image_to_rgb8(&img_buf, 192, 192);

 // 4. 使用图像作为输入张量,运行模型,获取输出张量。
 let mut session = ssvm_tensorflow_interface::Session::new(&model_data, ssvm_tensorflow_interface::ModelType::TensorFlowLite);
 session.add_input("input", &flat_img, &[1, 192, 192, 3])
 .run();
 let res_vec: Vec<u8> = session.get_output("MobilenetV1/Predictions/Softmax");

 // 5. 输出张量是 “labelmap.txt” 文件中每个标签的概率列表(0到255)。
 ... ...
 let mut label_lines = labels.lines();
 for _i in 0..max_index {
 label_lines.next();
 }

 let class_name = label_lines.next().unwrap().to_string();
 ... ...
}

如果你要使用另一个 Tensorflow 模型,需要如下几步操作:

  1. 加载你自己的 Tensorflow 模型文件及其相关数据文件。SSVM 支持 TFLite 和 TF 冻结模型文件。你可以加载你自己训练的 MobileNet 图像分类模型或者一个完全不同的模型。
  2. 加载上传的图像或其他模型输入。详情请参阅下一节。
  3. 根据模型输入张量的要求准备输入数据。在 MobileNet 模型中,我们调整图像大小,并将像素值加载到矢量中。
  4. 将输入数据、输入张量名称和输出张量名称传递给模型。
  5. 获取向量中的输出张量值,并对其进行处理,以生成人们可读的结果。在 MobileNet 模型的情况下,输出值对应于标签图中每个标签的分类概率。以最高的概率输出标签。

查看更多例子,请点击:

输入和输出

由于这个 Tensorflow Serverless 函数运行在腾讯云基础设施中,需要与腾讯云的 API 网关交互来处理 web 请求。腾讯 API 网关将整个传入的 HTTP 请求封装在一个 JSON 对象中,并通过 STDIN 发送到该函数。因此,src/main.rs 函数需要从 STDIN 中读取数据,为 base64编码的图像数据解析 JSON 对象的body 字段,然后将图像加载到 img _ buf 向量中。

通常情况下,不需要更改模板的这一部分,但是了解它是如何工作的非常有用。

fn main() {
 ... ...
 let mut buffer = String::new();
 io::stdin().read_to_string(&mut buffer).expect("Error reading from STDIN");
 let obj: FaasInput = serde_json::from_str(&buffer).unwrap();
 let img_buf = base64::decode_config(&(obj.body), base64::STANDARD).unwrap();
 ... ...
}

#[derive(Deserialize, Debug)]
struct FaasInput {
 body: String
}

函数使用 println! 声明将推理结果返回到 STDOUT

if max_value > 50 && max_index != 0 {
 println!("It {} a <a href='https://www.google.com/search?q={}'>{}</a> in the picture", confidence.to_string(), class_name, class_name);
} else {
 println!("It does not appears to be any food item in the picture.");
}

Web 应用

Serverless 函数的可选 web UI 可以在模板中的 website/content/index.html 文件中找到。你可以根据自己的应用需求对其进行更改。这个用户界面的关键部分是 JavaScript 代码,将选定的图像文件转换成 base64 文本字符串,然后做一个 HTTP POST,将这个 base64文本字符串发送到 Serverless 函数的 API 网关 URL。

var reader = new FileReader();
reader.readAsDataURL(document.querySelector('#select_file').files[0]);
reader.onloadend = function () {
 $.ajax({
 url: window.env.API_URL,
 type: "post",
 data : reader.result.split("base64,")[1],
 dataType: "text",
 success: function (data) {
 document.querySelector('#msg').innerHTML = data;
 },
 error: function(jqXHR, exception){
 document.querySelector('#msg').innerHTML = 'Sorry, there is a problem. Try later';
 }
 });
};

正如我们讨论过的,腾讯云 serverless 运行时将会把 POST 字符串转换为 JSON 对象中的 body字段,然后将 JSON 对象传递给 Rust 函数。

创建和部署

当要建立应用时,我们需要使用 ssvmup 工具创建一个 .so 文件。这是一个 AOT 编译的 WebAssembly 函数,既有高性能又安全。默认文件名是 pkg/scf.so.

$ ssvmup build --enable-ext --enable-aot
$ cp pkg/scf.so scf/

这个模板是根据 Serverless Framework 结构组织的。

  • layer 项目将 Tensorflow 和 SSVM 库添加到 SCF custom runtime。
  • scf 项目创建自定义的 Serverless 运行时及其相关的 API 网关。
  • website 项目创建一个包含 content 文件的网站。部署脚本自动将 web 页面的 JavaScript 连接到上一步的 SCF API 网关 URL。

要在腾讯云上部署该应用,只需运行 Serverless Framework 的以下命令即可。

$ sls deploy
... ...
  website:       https://sls-website-ap-hongkong-kfdilz-1302315972.cos-website.ap-hongkong.myqcloud.com
  vendorMessage: null

63s › Tencent-TensorFlow-SCF › "deploy" ran for 3 apps successfully.

现在可以从已经部署好的的网站 URL 访问该 Web 应用啦

接下来呢

在腾讯云上,我们还部署基于 SSVM 的 TensorFlow-functions-as-a-service 的其他例子,点击这里查看