用 Go 跑的更快:使用 Golang 为机器学习服务

因此,我们的要求是用尽可能少的资源完成每秒300万次的预测。值得庆幸的是,这是一种比较简单的推荐系统模型,即多臂老虎机(MAB)。多臂老虎机通常涉及从 Beta 分布 等分布中取样。这也是花费时间最多的地方。如果我们能同时做尽可能多的采样,我们就能很好地利用资源。最大限度地提高资源利用率是减少模型所需总体资源的关键。

我们目前的预测服务是用 Python 编写的微服务,它们遵循以下一般结构:

请求->功能获取->预测->后期处理->返回

一个请求可能需要我们对成千上万的用户、内容对进行评分。带有 GIL 和多进程的 Python 处理性能很鸡肋,我们已经实现了基于 cython 和 C++ 的批量采样方法,绕过了GIL,我们使用了许多基于内核数量的 workers 来并发处理请求。

目前单节点的 Python 服务可以做192个 RPS ,每个大约400对。平均 CPU 利用率只有20%左右。现在的限制因素是语言、服务框架和对存储功能的网络调用。

为什么是 Golang?

Golang 是一种静态类型的语言,具有很好的工具性。这意味着错误会被及早发现,而且很容易重构代码。Golang 的并发性是原生的,这对于可以并行运行的机器学习算法和对 Featurestore 的并发网络调用非常重要。它是 这里 基准最快的服务语言之一。它也是一种编译语言,所以它在编译时可以进行很好的优化。

移植现有的 MAB 到 Golang 上

基本思路,将系统分为3个部分:

  • 用于预测和健康的基本 REST API 与存根

  • Featurestore 的获取,为此实现一个模块

  • 使用 cgo 提升和转移 c++ 的采样代码

第一部分很容易,我选择了 Fiber 框架用于REST API。它似乎是最受欢迎的,有很好的文档,类似 Expressjs 的API。而且它在基准测试中的表现也相当出色。

早期代码:

func main() {
    // setup fiber
 app := fiber.New()
    // catch all exception
 app.Use(recover.New())
    // load model struct
 ctx := context.Background()
 md, err := model.NewModel(ctx)
 if err != nil {
  fmt.Println(err)
 }
 defer md.Close()

    // health API
 app.Get("/health", func(c *fiber.Ctx) error {
  if err != nil {
   return fiber.NewError(
                fiber.StatusServiceUnavailable, 
                fmt.Sprintf("Model couldn't load: %v", err))
  }
  return c.JSON(&fiber.Map{
   "status": "ok",
  })
 })
    // predict API
 app.Post("/predict", func(c *fiber.Ctx) err
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值