最近看到《用 Serverless 架构部署 TensorFlow 模型推理函数》的流动,对 serverless 十分感兴趣,本着学习的心态初步摸索两个 serverless 框架,一个是开源的 OpenFaaS,一个是腾讯云,通过理论应用和比照初步入门 Serverless。
OpenFaaS
按文档阐明在 Ubuntu 20.04 上部署这个框架。
而后创立 Python 函数:
def handle(req):
print("Hello! You said:" + req)
批改配置,这里须要写入 docker hub 的帐号。
version: 1.0
provider:
name: openfaas
gateway: http://127.0.0.1:8080
functions:
pycon:
lang: python3
handler: ./pycon
image: >>> dockerhub 用户名 <<</pycon
OpenFaaS 提供一个叫 faas-cli 的部署工具,faas-cli 会先将镜像上传到相应的 docker hub 帐号名下,而后再下拉到 OpenFaaS 服务。
开始部署胜利后在 Web 界面 127.0.0.1:8080/ui/ 看到方才创立的函数。
测试:
╰─➤ curl localhost:8080/function/pycon -d "Hi"
Hello! You said: Hi
从下面的例子能够看出:
- 开发者只须要写好事件处理的函数,批改配置文件,确认部署即可,而不须要理解服务器的基础架构,甚至也不须要理解代码理论部署在哪个 Web 框架。
- FaaS 服务返回调用接口。
将图像识别服务部署到腾讯云
除了将 Serverless 业务构建在硬件和容器(比方,OpenFaaS 应用 docker)之外,还有一种新兴的办法: 应用特定于应用程序的虚拟机,比方 WebAssembly(Wasm)。
这个例子通过 Second State 的 Serverless Wasm 虚拟机 (SSVM), 把用 Rust 编写的图像识别业务代码最终编译成 .so 文件,通过 serverless 工具 上传到腾讯云的 FaaS 中。
依据 Second State 的 demo 部署之后,在我的项目根目录输出 sls deploy
, 验证腾讯云帐号,100 秒左右就部署胜利,查看腾讯云的控制台,能够看到方才部署的性能。
测试:
魔改
通过魔改 Second State 的例子学习腾讯云 Serverless 的用法。
先理解 tencent-tensorflow-scf 的构造:
cos, layer, scf 三个目录都有 serveress.yml,执行 sls deploy
的时候,能够看到这三个目录的文件被打包上传。
执行 ssvmup build --enable-ext --enable-aot
生成 pkg/scf.so
, 须要将它拷贝至 scf/
目录。
scf/bootstrap
是一个脚本,运行后是一个服务过程。
外围命令如下,其中 “$_HANDLER” 是 scf.so
RESPONSE=$(LD_LIBRARY_PATH=/opt /opt/ssvm-tensorflow "$_HANDLER" <<< "$EVENT_DATA")
这就阐明,咱们能够在本地运行 “$_HANDLER”。咱们能够先在本地调试业务性能。
首先须要编译 ssvm-tensorflow , 也能够间接下载二进制运行。
编译完之后,将 这个 demo 的代码迁徙到 tencent-tensorflow-scf/src/main.rs, 实现魔改:
use std::io::{self, Read};
use ssvm_tensorflow_interface;
use serde::Deserialize;
fn search_vec(vector: &Vec<f32>, labels: &Vec<&str>, value: &f32) -> (i32, String) {for (i, f) in vector.iter().enumerate() {
if f == value {return (i as i32, labels[i].to_owned());
}
}
return (-1, "Unclassified".to_owned());
}
fn main() {let model_data: &[u8] = include_bytes!("mobilenet_v2_1.4_224_frozen.pb");
let labels = include_str!("imagenet_slim_labels.txt");
let label_lines : Vec<&str> = labels.lines().collect();
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();
let flat_img = ssvm_tensorflow_interface::load_jpg_image_to_rgb32f(&img_buf, 224, 224);
let mut session = ssvm_tensorflow_interface::Session::new(model_data, ssvm_tensorflow_interface::ModelType::TensorFlow);
session.add_input("input", &flat_img, &[1, 224, 224, 3])
.add_output("MobilenetV2/Predictions/Softmax")
.run();
let res_vec: Vec<f32> = session.get_output("MobilenetV2/Predictions/Softmax");
let mut sorted_vec = res_vec.clone();
sorted_vec.sort_by(|a, b| b.partial_cmp(a).unwrap());
let top1 = sorted_vec[0];
let top2 = sorted_vec[1];
let top3 = sorted_vec[2];
let r1 = search_vec(&res_vec, &label_lines, &top1);
let r2 = search_vec(&res_vec, &label_lines, &top2);
let r3 = search_vec(&res_vec, &label_lines, &top3);
println!("{}: {:.2}%\n{}: {:.2}%\n{}: {:.2}%"
, r1.1, top1 * 100.0
, r2.1, top2 * 100.0
, r3.1, top3 * 100.0
);
}
#[derive(Deserialize, Debug)]
struct FaasInput {body: String}
测试:
输入排名前三的可能后果。
tomato.json 用于模仿申请数据,将图片数据 base64 之后放在 “body” 前面。
最初从新 sls deploy
部署上线:
总结
本文通过 OpenFaaS 和腾讯云 Serverless 两种服务,初步理解了将业务部署到云平台的过程。通过 FaaS 服务商提供的工具,用户能够防止间接操作 docker, 或设置脚本运行环境变量等不重要的细节,从而将注意力集中在业务开发上。
One More Thing
立刻体验腾讯云 Serverless Demo,支付 Serverless 新用户礼包 👉 serverless/start
欢送拜访:Serverless 中文网!