简单版

人工智能、量化投资、web开发有很多知识/工具链是共通的,它们的知识交集是这样的:

intersection

详细版(太长不看版)

以下演示一些工具链的例子。

docker与基础设施

本地开发环境——普通版

使用docker搭建本地开发环境通常只需要一行command docker-compose up和2个配置文件: dockerfiledocker-compose.yml。 其中:

  • dockerfile 定义了 1. 所开发的应用使用操作系统版本; 2.应用运行的各种依赖库,例如操作系统级别 apt-get install / yum instal安装的、php的composer/java的maven/node.js的yarnnpm /python的pip安装的; 3.应用自身的代码;4.更多。。。。

  • docker-compose.yml 定义了应用自身的容器和host机,其它容器间的关系,例如 1.绑定了哪些端口; 2. 挂载/共享哪些文件系统(volume);3.应用所使用或者开发应用需要的其它资源,例如mysql + phpMyAdmin、redis、rambitMQ等; 4.更多。。。

无论你是要搭建java开发环境,还是php、node.js、python、Go还是其它的开发环境,几乎都是上面的一行command + 2个配置文件。

无论你要搭建web开发、机器学习、算法交易/量化投资研究的环境, 几乎都是一行command + 2个配置文件:

本地开发环境—— 一条龙服务/莞式服务版

刚才上面“本地开发环境——普通版”只是搭建了应用运行的环境,平常我们开发、AI/金融研究还需要一系列工具,诸如 postman/Charles/Chrome debugbar 等调试工具, VsCode、jupyter lab等Ide和它们的插件, Git和各种项目管理/协作工具。。。 能不能把这些也一并搞掂? 当然可以。

在上面的 docker-compose.yml 文件新增1个service:

version: '3'

services:
  ml-workspace:
    image: mltooling/ml-workspace
    environment:
      AUTHENTICATE_VIA_JUPYTER: "您的密码"
    ports:
      - "8080:8080"
    volumes:
      - ./:/workspace

terminal执行docker-compose up后浏览器打开 localhost:8080,输入上面AUTHENTICATE_VIA_JUPYTER 就可以看到一个Linux桌面了, VsCode、jupyter lab、postman、Git等等开箱即用。

workspace

而且你还可以使用dockerfile定制你的workspace(把项目clone好,安装好各种ide的插件等等),在windows、mac、云主机使用一样的、熟悉的、习惯的开发环境。还可以轻易和他人分享你的定制成果 —— 当你的同事/朋友们想要使用你根据项目所需定制好的开发时也只需要创建一个docker-compose.yml文件和执行一行docker-compose up command。

在ipad上开发?

根据下文 “上云(云端部署)” 介绍的步骤,把你定制好的workspace部署到云主机,然后你和你的同事/朋友都可以使用任何有浏览器的设备(包括ipad和各种pad)登录 https://server-ip-or-hostname:8080 使用熟悉的workspace工作了。想象一下你的同事只需要打开浏览器就发现:

  • 项目clone好了。
  • ide和各种调试使用的插件安装配置好了。
  • 项目所需要的 /java/php/python/Go/node.js 环境都已经配置好了。

不需要任何折腾可以立即开始web开发、机器学习、算法交易/量化投资研究的工作了,这种一条龙服务/莞式服务 爽不爽?

这个workspace的原始镜像已经经过精心的优化,一般使用只占用500mb - 1Gb的内存,一台8G RAM的云主机可以承载 8 - 15 人远程工作。

上云(云端部署)

《一条大路(捷径)通罗马:一种利用docker进行微服务架构的可行方案》的步骤是一样的,只需要3行command和1个配置文件 stack.yml, 这个stack.yml文件通常都定义了:

  • 上面“本地开发环境——普通版” 的docker-compose.yml的大部分内容
  • 应用可以使用多少 cpu / ram
  • 故障自愈策略
  • 应用升级策略/升级故障自动回滚策略
  • 使用什么域名/端口对外服务
  • 挂载哪些oss到容易本地路径给应用使用
  • 更多省略了

web开发、机器学习、算法交易/量化投资研究 要上云和新版部署上线都是这3行command和1个配置文件, 没有ansible ,没有Jenkins需要配置。

pulumi:程序开发、云端部署、计算资源创建一体化

上面能做到 “3行command和1个配置文件”完成上云和新版部署上线的前提是:

  • 事先登录aws/azure/gcp/阿里云/腾讯云的控制台,把应用所需的云计算资源(cloud resources),包括服务器、负载均衡器、oss、vpc网络、存储docker镜像的registry 等等创建好, 并且把他们关联起来。
  • 或者使用aws cli/ azure cli 等完成上面的工作。

这缺点就是:

  • 每一个云服务提供商的管理控制台使用逻辑都不太一样,需要学习研究,有些还复杂到需要考取他们的“云服务架构师”才能灵活使用。
  • 云服务提供商动不动就升级管理控制台,让我们又得从头学习使用。例如现在的腾讯云管理控制台无论是色调、ui、使用逻辑都和之前的阿里云超级像,而阿里云管理控制台已经升级成另外的样子,让笔者这位老用户都摸不着北。。。又想骗我再考一次阿里云认证“云服务架构师”吗?
  • 知识难以重用: 我学会了阿里云,还得学Azure、aws啊; 我都学会了,到我同事接手我的工作时他不会啊,他又得从头学😞。

pulumi 就是为了解决这些问题而生。pulumi的理念就是让程序开发、云端部署、计算资源创建一体化。 这是指什么呢? 比如,你正在开发Typescript的项目,已经接近尾声该首次部署了,可以在项目根目录仍一个***.ts文件:

import * as awsx from "@pulumi/awsx";

// 1.在aws创建一个集群
const cluster = new awsx.ecs.Cluster("cluster");

// 2.创建一个负载均衡器,并使用集群的安全策略
const alb = new awsx.lb.ApplicationLoadBalancer("lb", {
    securityGroups: cluster.securityGroups,
});
// 3.负载均衡器监听的后端应用端口
const web = alb.createListener("web", { port: 80, external: true });

// Define the scaled-out Fargate service
// 4.创建FargateService
// 5.build 镜像
// 6.创建保存镜像的registry
// 7.推送镜像到registry
// 8.使用这个镜像部署应用,关联端口映射
const appService = new awsx.ecs.FargateService("app-svc", {
    cluster,
    taskDefinitionArgs: {
        container: {
            // 使用./app里面的dockerfile build镜像
            image: awsx.ecs.Image.fromPath("app", "./app"),
            portMappings: [ web ], // 上面的web端口
        },
    },
    desiredCount: 5,
});

// 9.返回应用对外服务的url,下面还可以进一步做更多处理,例如添加这个url健康监控
export const url = web.endpoint.hostname;

在terminal执行pulumi up,等待几秒至几十秒,上面代码注释中的9件事就完成了。项目的程序开发、云端部署、计算资源创建都是靠写Typescript实现,这就是所谓的一体化

PYTHON、GO、C# 、JavaScript程序员都可以像上面一样用自己熟悉的语言使用pulumi实现开发、云端部署、计算资源创建一体化。

也许有人说“我也可以写shell script用aws cli把这一切也串联起来呀!为啥要多学一个pulumi?” 。回答是:可以,但没有必要,因为你在把pulumi实现的事情自己再实现一次 —— 是的, pulumi背后也是利用aws cli / azure cli和云服务商提供的api实现的😄。

记住,无论你要创建web应用、机器学习、算法交易/量化投资研究都是可以像上面一样使用pulumi实现开发、云端部署、计算资源创建一体化

在写这一段的时候,笔者也在想是否可以通过一个我们熟悉的事物比喻,或者拿已有的工具做对比,以让读者能更好、更容易理解pulumi究竟是个什么东东。但是想了想,也看了官方文档的vs横向对比介绍,发现它是一个崭新的工具,它提出了崭新的理念,它不像任何我们熟悉的工具,它神一般地存在。如果你读完上面还没有了解 pulumi, I hope the following will help:

Getting start文档: Modify the Program》 可以了解 TYPESCRIPT、JAVASCRIPT、PYTHON、GO、C# 中使用pulumi大概是什么样的。

《文档:Running Containers on ECS Fargate》 分步介绍pulumi中使用AWS ecs-fargate。

Introducing Pulumi Crosswalk for AWS: The Easiest Way to AWS》 演示了在pulumi中使用AWS的更多例子。

文档:Cloud Providers》介绍支持的云服务提供商,包括阿里云。

Pulumi and Docker: Development to Production》演示了pulumi的抽象化特征,在youtube视频中还总结了使用pulumi优点。

ps.官方原话是“Infrastructure as Software(直译:让基础设施成为应用的一部分)”

Celery分布式计算

Celery的官方介绍:

Celery is a simple, flexible, and reliable distributed system to process vast amounts of messages, while providing operations with the tools required to maintain such a system.

It’s a task queue with focus on real-time processing(注重实时), while also supporting task scheduling.

--

Celery is a task queue with batteries included. It’s easy to use so that you can get started without learning the full complexities of the problem it solves. It’s designed around best practices so that your product can scale and integrate with other languages (和其它开发语言集成), and it comes with the tools and support you need to run such a system in production.

不是明白耶! show me the code? 好的,开始(let's get started)! 下面演示使用Celery沉淀“业务无关/低相关性/稳定不常改变”服务。

每一家公司几乎都有极光推送、短信/邮件发送、内容审核/鉴黄这些功能/服务,使用Celery开发一次,其它Python、PHP、Node.js的项目中就可以像调用本地function一样使用这些公共服务啦。下面演示一个通知推送服务。

# ./tasks.py

from celery import Celery

app = Celery('tasks', broker='amqp://usr:[email protected]:5672/myvhost', backend='redis://user:[email protected]:6379/result_db')

@app.task
def notify(addressee, content):
    """ 这里是极光推送、短信/邮件发送 发送的逻辑代码,省略了! """

def auto_ps(input, out):
    """ 这里部署pytorch的“智能美颜”模型,省略了! """

然后terminal中启动worker监听其它应用发来task:

# 首次使用先安装: pip install celery
celery -A tasks worker --loglevel=info

celery提供node.js的sdk,yarn add celery-ts or npm i celery-ts安装后就可以在node.js的项目中这样调用上面python的function:


import * as Celery from "celery-ts";

const client: Celery.Client = Celery.createClient({
	brokerUrl: "amqp://usr:[email protected]:5672/vhost01",
	resultBackend: "redis://user:[email protected]:6379/result_db",
});

const task: Celery.Task<string> = client.createTask<string>("tasks.notify");
const result: Celery.Result<string> = task.applyAsync({
	args: ['1686868668', '跳楼价大甩卖啦!! 来吗来吗?'],
	kwargs: { },
});

const promise: Promise<string> = result.get();

promise.then(console.log)
	.catch(console.error);

celery也提供php的sdk,在php的项目中调用刚才notify():


$c = new \Celery\Celery('rabbitMQ-server-01', 'usr', 'pwd', 'vhost01');
$result = $c->PostTask('tasks.notify', array('1686868668', '跳楼价大甩卖啦!! 来吗来吗?'));

$result->get();
if ($result->successful()) {
    echo $result->result;
}

You see,这个通知推送(notify(addressee, content))功能是用python开发的,但是我们可以在node.js、php、go、rust和python的项目中像调用本地function一样调用,减少用不同的语言子项目开发同样功能的基础模块的时间。

gocelery for golang, and rusty-celery for Rust等等就不一一举例了。

gocelery既可以是server也可以是client,也就是说对于性能要求/分布式架构很高的应用场景,用gocelery做server的表现可能还优于python版的celery

总结一下Celery给我们带来的好处:

  • 方便配置管理: 就像上面的notify(addressee, content)例子,真正和极光推送、短信服务商打交道的是celery应用,相关的ssl证书,验证凭证只需要在celery项目中存一个copy就行了,node.js和php应用中不需要存,不用搞得证书和验证凭证在不同的子项目中到处都是。
  • 艰难任务代理给python:想象一下你在php开发的后端应用遇到PHP语言不擅长应对的需求,例如模拟爬虫到web抓数据,这是PHP不擅长做的,但是python在爬虫上的解决方案最为完善—— 这时可以用python开发爬虫这以部分,然后在PHP中调用。
  • 并行计算1: 想象一下你在PHP或者node.js开发的web后端需要实现一个“酒店/机票实时比价系统”,需求是:程序通过http request接收到比价请求的时候实时到大约20家酒店供应商+各大酒店预订平台实时询价”。 PHP不能访问线程,代码是按先后顺序执行的,需要等待上一家供应商/平台完成数据返回后才开始下一家的查询 —— 等到PHP程序一个一个龟速般完成20多家供应商和平台的报价查询后用户都已经等傻了。celery方案是多开几个celery worker跑在20台不同的机器上,在celery的应用中实现实时询价的功能,php web后端应用只负责调用/分发任务,让20台不同机器上celery同时到20家酒店供应商/平台询价,这样快多了。
  • 并行计算2: 想象一下机器学习/量化交易训练任务是使用尚未支持分布式训练的算法库,在你的本地机器上需要跑100个小时。正解是使用上面pulumi瞬间创建100台服务器,部署celery worker,1小时完成训练
  • 机器学习模型跨语言部署:想象一下你训练了pytorch的机器学习模型“智能美颜”(刚才上文的auto_ps(input, out)),想部署到web端给高级付费vip用户使用,而检测是否是付费vip用户的web应用是php或者node.js 开发的!! http proxy也是实现这种部署的一种方案,但是使用celery岂不是更容易呢! 而且当付费vip用户增多了,营收增长了,需要扩容时可以像上面并行计算1那样横向扩展。

“SOA 或者自己写代码接MQ也能实现同样的效果啊!为啥要再学习Celery?” 看看Celery完善的监控和调度工具, 这些你都 打算自己写代码接MQ实现吗😮?


总结: 看,人工智能,量化投资,web开发有很多知识/工具链是共通的。 它们之间的知识交集可以总结为:

(基础设施架构 + 编程 + 基础数学) + http相关知识 => web开发
(基础设施架构 + 编程 + 基础数学) + 机器学习知识 => 人工智能
(基础设施架构 + 编程 + 基础数学) + 机器学习知识 + 金融交易知识 => 量化投资

上面是一些小例子,Real world 中肯定还有更多的。