找回密码
 立即注册
查看: 280|回复: 5

下一代 AI 框架长什么样?

[复制链接]

1

主题

0

回帖

15

积分

新手上路

积分
15
发表于 2023-5-9 11:34:39 | 显示全部楼层 |阅读模式
考虑几个融合趋势(大数据和ML融合、训练-推理深度融合、稀疏多模融合、AI+Science),显然Deep Learning Frameworks(TF,Torch)是不够了,下一代AI框架长什么样?
回复

使用道具 举报

0

主题

2

回帖

8

积分

新手上路

积分
8
发表于 2023-5-9 11:34:47 | 显示全部楼层
这是从零构建 AI 推理引擎的最后一篇。想从头开始追踪我们整个过程的可以看我们之前的系列文章。
系列文章的,可以前往知乎:
金天:WNNX从0构建一套自己的推理IR金天:WNNX从0构建自己的AI推理IR(二)金天:WNNX从0构建一个AI推理引擎(三)
金天:WNNX从0构建AI推理引擎(四)
金天:2022_06_06_12_WNNX从0实现AI推理引擎(五)
金天:2022_06_07_11_WNNX从零实现一个AI推理引擎(六)金天:2022_08_01_03_WNNX从0实现AI推理引擎之终结篇前序
(理论上来说这应该是最后一篇,但为了让这个自建框架更加完备,我们特地给他实现了一套Python调用API)。
目标是从 0 开始,构建一套我们自己的 AI 推理引擎。现如今推理引擎繁多,但是你越往深入了解,你越会发现开源的推理框架或多或少存在一些问题。我们的目的就是取其精华、去其糟粕,构建一套及其简单同时又很合理的推理引擎,而自己去做一套引擎,其实比登天还难。
这里面涉及到诸多矩阵运算、算子库的把握、优化算法、图解析与调度、图融合、汇编知识、各种语言的灵活运用,以及一些必不可少的运气,当然,发量也是一个极其重要的因素,可能还没有等到你写完,你的头已经秃了。
好在,经过几个月的时间,我们完全自建的推理引擎,拥有了自己的一套完备的模型推理格式 WNNX,同时我们首次实现了再完全不依赖于任何第三方框架的前提下,实现了 NanoDet 的推理。
同时,最近我们也实现了我们完全自研的 MobileOne-YOLOv7 的推理,MobileOneS0 的计算量很小,经过 reparam 之后,差不多就是直来直去的卷积,速度可以说非常的快,即便是在 CPU 下。而它的精度,在 416x512 输入下,可以做到 mAP 35.6 。丝毫不逊色于其他目标检测模型。






这是上一个阶段我们已经完成的事情,这里只是重新回顾一下。
书接上文,上回书我们在实现了一些复杂模型的推理之后,想跟进一步的去挑战更复杂的模型。什么模型呢? 那当然是 Transformer!
但是可想而知,这个尝试进行到一半就失败了。主要原因是 transformer 变种太多,如果你适配了 Vit,Swin 这样的视觉模型,对于 Conformer,EcoFormer 这样的语音里面会用到的模型又会产生新的变种。难以做到非常科学合理。当然我们也可以为每一个变种实现一个 custom op,但是这样的话就会造成库体积过大。
值得一提的是,我们的推理框架到目前为止,库体积依旧很小,并且实现了一个非常有趣的操作:




我们的核心库到目前为止依旧只有 1.8M,用这个 1.8M 你就可以驱动 YOLO!
你可以看到我们应该是业内为数不多的可以把自定义算子单独编译的框架,换句话说,不管你的自定义算子多么多,也不太会影响整体的库体积,也不需要用 reduce op 的方式去挑选你需要的 op。
我们说的这个有趣的操作,就是这个 custom op 的设计。
从这里开始,就点题了。这是一篇写给产品经理看的技术文章,自然有一些对用户体验注重的细节。
按照常理来讲,对于普通程序员来说,如果我们按照上面的方法来实现了 custom op 单独编译,你可能会把这些 custom op 定义的头文件也单独零出来,跟我们的标准算子放一起,给到用户的东西就是一堆乱七八糟的头文件。
而在 wnn 里面,这些都没有。
插件召唤式注入

在我们的自建引擎里面,虽然我们有很多自定义算子,但是这些算子在用的时候,是否需要 include 对应的头文件呢?如果不 include。你怎么让 c++知道你的这些库对应的定义是什么呢?怎么把这些算子注册到的你 Layer Factory 里面去呢?
所有的这些问题,我们通过一个巧妙的方式解决了。
对于用户来说,他需要做的,只有一件事情:
namespace wnn {
    extern void summon_plugins();
}

int main(int argc, char **argv) {
  std::string model_f = argv[1];
  int num_threads = 2;
  int max_batchsize = 8;
  auto wnn_model = wnn::NNForward(num_threads, max_batchsize, wnn::Backend_CPU,
                                  wnn::summon_plugins);
  auto a = wnn_mdoel.infer();
}
没有错,你只需要显式的调用 simmon_plugins() ,你的插件链接库就会被自动调用,你的系统算子库就可以自动的找到你定义的那些自定义算子的定义。
需要 include 对应的头文件么?并不需要,wnn 一如既往的,只需要一个文件 include。
你可能没有什么感觉,让我们来看看 MNN 是怎么使用自定义算子的吧:
#include "ncnn_upsample.h"
#include "ncnn_upsample3x.h"
#include "ncnn_upsample4x.h"

int main() {

    ncnn::Net mynet;
    mynet.register_custom_layer("Upsample", Upsample_layer_creator);
    mynet.register_custom_layer("Upsample3x", Upsample_layer_creator);
    mynet.register_custom_layer("Upsample4x", Upsample_layer_creator);

    mynet.load_param("...\\view_classification.param");
    mynet.load_model("...\\view_classification.bin");
    ncnn::Extractor ex = mynet.create_extractor();

    ex.input("input", in);

    ncnn::Mat out;
    ex.extract("output", out);
}
wnn 只需要调用 summon_plugins,召唤插件,你就可以把插件召唤回来,不需要的时候,拿掉即可。而ncnn需要每个插件都include对应的头文件,并且要显示的定义。 显然这种操作非常的繁琐。
WNN 有史以来第一个Python API

除了更加简洁优雅的插件引入方式以外,我们自己建造的推理框架,似乎还缺少了一点东西。
也许制约新人上手的不仅仅是c++的易用性,更有Python的易用性。
而我们 连Python都没有,何谈易用性??
于是我们说要有Python API!然后他就来了,一个自建框架,并且带有Python API,你可以用自己心爱的语音来把玩你的推理框架了!
先来看看这个Python API到底简单到多么的令人发指!(AI PM必看)
这里演示,我们用自建引擎,来推理Mobilenetv2,一个说难不难,说复杂不复杂的模型(从引擎的角度讲,mbv2有残差、有各种depthwise op,实现难度并不小,要求算子支持广度较广)。
m_f = sys.argv[1]
data_f = sys.argv[2]

model = NNForward()
model.load_from_file(m_f)

a, raw_img = load_input_from_file(data_f)
a = np.ascontiguousarray(a)
res = model.infer([a])[0]

lbl = np.argmax(res)
print(lbl)
没错,就这么简单!说实话,核心代码就3行!3行代码,你可以把玩自己构建的推理引擎了!
这个Python API的设计,我们延续了 C++的接口风格,所谓大道至简。根据我多年的人工智能行业摸爬滚打经验,相信我,这比你看到的任何一个推理框架都要简单!!
但是你不要小看它,有一点你需要注意,那就是你会发现,这里面没有任何申明的操作!一切都显得那么自然:你丢给一个numpy,它丢回给你一个numpy,就是结果!
你是否注意到一个问题,这里面你压根不需要关注输出的维度!基本上没有任何额外的操作。
为了对比,来看看MNNN的Python推理:
self.interpreter = MNN.Interpreter(self.mnn_f)
self.session = self.interpreter.createSession()
self.input_tensor = self.interpreter.getSessionInput(self.session)
self.output_tensor = self.interpreter.getSessionOutput(self.session)

def infer_si(self, inputs):
        if isinstance(inputs, list):
            inputs = np.array(inputs)

        tmp_input = self.np_as_mnn(inputs)
        self.input_tensor.copyFrom(tmp_input)

        self.interpreter.runSession(self.session)

        # output_tensor = self.interpreter.getSessionOutput(self.session, "output")
        output_tensor_dict = self.interpreter.getSessionOutputAll(self.session)

        res = {}
        for k, v in output_tensor_dict.items():
            tmp_output = MNN.Tensor(
                v.getShape(),
                v.getDataType(),
                np.ones(v.getShape()).astype(np.float32),
                MNN.Tensor_DimensionType_Caffe,
            )
            v.copyToHostTensor(tmp_output)
            res[k] = np.array(tmp_output.getData()).reshape(v.getShape())
        return res

def infer(self, inputs):
    if isinstance(inputs, list):
        inputs = np.array(inputs)

    tmp_input = self.np_as_mnn(inputs)
    self.input_tensor.copyFrom(tmp_input)

    self.interpreter.runSession(self.session)

    # output_tensor = self.interpreter.getSessionOutput(self.session, "output")
    output_tensor_dict = self.interpreter.getSessionOutputAll(self.session)

    res = {}
    for k, v in output_tensor_dict.items():
        tmp_output = MNN.Tensor(
            v.getShape(),
            v.getDataType(),
            np.ones(v.getShape()).astype(np.float32),
            MNN.Tensor_DimensionType_Caffe,
        )
        v.copyToHostTensor(tmp_output)
        res[k] = np.array(tmp_output.getData()).reshape(v.getShape())
    return res
说实话,这就是MNN的推理。。。当然你如果非要说它没有必要这么麻烦,但,你可以尝试你精简它,之后你才会发现这些东西都不可或缺。
可以看到,这简单的不止一点半点。。
其他框架我就不贴了,不管是onnxruntime,还是ncnn,都很难做到这样:
model = NNForward()
model.load_from_file(m_f)

a, raw_img = load_input_from_file(data_f)
a = np.ascontiguousarray(a)
res = model.infer([a])[0]
着么简单。
但其实这背后做了很多工作,你不需要关心数据拷贝、上传到device,以及输出的shape,这些运算都在框架内部通过比较合理的方式解决了。
为什么我们能够让用户做到直接丢进来一个numpy就能推理?我们的网络Tensor可不是numpy。因为我们的pybind11 API里面,对输入进行了更加方便的封装,目的就是使得它能够直接接受numpy array的输入。
而不是跟MNN一样。丢给用户手动处理。
关于Python API的思考

其实我们做这套自建推理引擎目的,并不是为了造轮子而造轮子,而是为了解决一些实际的需求。具体来说,我们想要的是:

  • 一个足够有把控能力,可以随意修改,随意插入SOTA推理框架优化结果的框架(拿来主义);
  • 能够解决现有框架弊端,对算子具有足够可控性,可以随意进行图融合和图优化;
  • 足够小,符合自身需求,过犹不及,恰到好处。
  • 它的动态库体积要足够小,大于4M都可以称为臃肿;
  • 它的API要足够精简,精简到小学生二年级上手使用没有难度。
这样下来,我们发现只有从头构建才是出路。而当我们构建完成之后,发现可以做的事情远不止这些。我们重构的Python API就是一个很好的例子。
很多人是拿来主义,这并没有什么,毕竟很多开源的东西就是给你用的,但拿来主义却不去思考底层的原理、甚至觉得拿来主义是一种更聪明的方式,那就有点自作聪明了
在中美对抗的大环境下,更多人拥有这样的能力,才能对抗可能的封锁,不过好在最起码在AI前推框架领域,国内还是走的比较前沿的。但国内的一些作品,跟人家ONNXRuntime这样的东西比,还是有差距的。
为什么我要给自建框架加上Python API,一来是更方便以后的更多测试,二来主要是因为这个:




代码不格式化、python里面非得跟c++一样驼峰命名、函数与函数之间没有任何空行。




这一看就是一个C++程序员用管用的vim写出来的python代码,完事之后也不会格式化一下,且代码动一下可能就跑不起来的shishan。
反过来看看WNN Python的接口:




不仅简单的令人发指,而且一看就是一位Python专业人士写出来的代码。
最后来对标一下C++下的推理结果和Python的:





完美契合,收工!

下一篇

我们的自建推理引擎到这里就要告一段落了。下一步我们要做什么呢?
没有错,继续死磕并优化Transformer!
目的是让Transformer在CPU上跑得飞起!不仅仅是CV,还包括语音识别和语音合成的transformer!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2023-5-9 11:35:00 | 显示全部楼层
开个坑。
AI框架,AI云平台相关工作都有做过,对国内外各个工作都有一定了解。目前而言,PyTorch, TensorFlow还是占据了绝对主流市场。国内的框架MindSpore和PaddlePaddle可以看得出很努力,做的工作很全面,尤其是MindSpore,只要我在论文上见过的他们都会尝试或已经复现,在生态推广和营销方面也是不遗余力。另一个很有趣的工作是OneFlow,我有幸参与其中, 这个框架在分布式方面的设计在我看来确实达到了行业领先,但是受制于开发团队的规模,在框架的生态方面必须要找准方向。
AI框架在做啥?
要分析下一代AI框架长什么样,首先我们得看看AI框架是什么。
简单来说,AI框架是一个张量编程语言。这个语言需要有一个支持神经网络编写的高阶API库,一个能够进行计算图优化,支持反向传播的编译器和一个能够调度系统资源进行张量计算的执行引擎。从运行或者开发效率上来说,在这个大的框架下,静态图、动态图、分布式训练、自动并行等问题都已经或者将要被解决。而从用户的易用性和框架完备性上来说,算子库的丰富,高阶API的增加,甚至一些新的训练方法的增加,或者是对各种AI计算芯片的适配,这些incremental的工作并不足以成为再造个新轮子的动机。
为什么要再做一个新的AI框架?
在我看来,搞一个新的框架,需要满足两点:1. Application,即有人工智能领域有了新的方法,引出了新的计算问题的需求,且现有的框架不能很好解决 2. Insight, 即在张量的计算引擎上有新的设计,利用现有的框架无法实现这样的设计。下面谈自己的几点浅见:

  • 从AI框架的应用来看,现阶段人工智能领域本身的方法其实还是纯粹由数据驱动的弱人工智能,如何将知识与数据结合,是突破现有人工智能领域的对数据极度依赖和模型可解释性不强等瓶颈的关键。那么,新一代的AI框架应该需要有对知识的处理,并且加入深度学习模型训练的环路中。MoE、元学习或者Pathways都可以认为是基于统计经验的知识,其实现有的框架已经可以不错的支持。但是,很多科学知识或者逻辑知识,是以逻辑系统或者微分方程(组)的形式刻画的,这两种知识其实均有相应的语言,且或多或少有AI框架已经涉及到,例如Jax的科学计算,不过还远没有达到PyTorch或TensorFlow那样的成熟度。
  • 过去的一年,很多公司都开始从“大炼模型”转向“炼大模型"。大模型在表征能力,泛化能力,多模态等方面确实令人惊艳,但是在实际研究或业务中,训练或使用大模型的门槛还相当高。所以一方面,下一代的AI框架面临分布式训练时,应该尽量帮助算法开发者把算法逻辑和分布式训练逻辑解耦,提升分布式训练的效率,降低分布式训练的门槛;另一方面,在超大规模模型应用时,应该能方便的进行分布式的推理以及推理测的轻量化工作。
  • 从框架内部的计算逻辑来看,是以计算图的方式,对神经网络中的张量计算进行抽象。在程序语言设计中,我们经常看一个计算任务或者逻辑的level of abstraction。从这个角度看,现在的AI框架、AI编译器或者AI芯片提供的深度学习软件栈,是非常混乱的,这就使得我们无法从一个统一的抽象层面解决所有计算逻辑构建、分配、优化问题。各种层次的计算图、算子、接口的不统一,也为软硬件适配工作带来了巨大的工作量。在新一代的AI框架中,我非常期待能有一个一统天下的标准。
  • 新一代的AI框架做出来是需要给人用,有人用的,AI框架的生态建设也是一大难点,深度学习框架是个烧钱的玩意儿,开发者生态建设更是无底洞。需要学术大牛的背书,需要成熟完善的文档和模型库,甚至需要大量的算力提供白嫖。可怕的是,AI框架说不出一个直接的盈利模式,所以AI框架这玩意儿,既要有情怀,更要有钱。
想到其他的再补充。
回复

使用道具 举报

0

主题

6

回帖

16

积分

新手上路

积分
16
发表于 2023-5-9 11:35:33 | 显示全部楼层
搞AI框架那帮人(第二篇)贾扬清与阿里灵杰

原创 亲爱的数据 主编 谭婧
致谢:感谢贾扬清,他耐心地回答了我的数百个问题,使这篇文章成为可能。




在人工智能(AI)的江湖,常听人言:得框架者,得天下。谁主宰AI模型的生产自动化,谁最有可能主宰AI工业化。所以,深度学习框架是科技巨头兵家必争之地。
深度学习框架属于AI框架,是AI底层技术,而AI技术创新早已深入底层。没有什么道路可以通往底层技术创新,底层技术创新本身就是道路。
这条路,是隐秘的,深度学习框架作为AI系统软件,走近前去,才不断惊叹它那种躲躲藏藏的宽阔;走进前去,才不断惊叹战壕密布,战马喧腾。
低垂的果实已摘光,那些只消小打小闹(对人工智能模型做一些小调整,扩大人工智能模型的规模)就能刷论文、刷面子、刷一切的日子,一去不复返了。
从历史中得到的唯一教训,就是从未从历史中得到教训。 而人工智能算法不同,偏偏擅长从历史中“得(学)到(习)”。
回顾从前,多款深度学习框架,待时而出,常听人言:为什么,这个深度学习框架受人追捧,那个深度学习框架遭人嫌弃?
贾扬清认为:“这背后是AI需求和设计逻辑的变化。”
像深度学习框架这样的计算机系统软件,大型项目经验被极客们追奉为信仰,而贾扬清是开源软件深度学习框架Caffe,Caffe2的作者,是谷歌深度学习框架TensorFlow的核心作者之一,亲手写了ONNX第一版代码。
一位技术大神可以是一个深度学习框架的作者,很难是全球流行深度学习框架的作者,极难成为多款全球大流行的深度学习框架的作者。
伸手一数,这个年龄段,这个履历表,放眼全球,除了贾扬清,很难找到第二人。


车轮破开积水。
开场白,在雨中。撑着伞,边走边聊,贾扬清说:“对于技术来说,有一句话很重要,There is no stupid people, only misaligned priority(没有蠢人蠢事,只有搞错了的优先级)。”
深度学习框架的发展是螺旋式,谈论深度学习框架,绕不过它所解决的核心问题。某一段时间内,性能是第一需求;过一段时间,灵活又会变成第一需求。敲黑板,请记住“第一需求”。
搞人工智能,首先气质这块要跟上,手推公式,一面墙写满密密麻麻的公式,顿时身高一米八,气场八米一。
搞人工智能,其次能力这块要跟上,机房里动不动就是计算集群,一台计算机解决不了,一百台计算机合力上。一顿操作猛如虎,效率还在原地杵,那可是饶君掬尽湘江水,难洗今朝满面羞。
搞人工智能,光会数学不够,还要懂计算机,动不动赤手空拳面对一群计算机。虽然不是打群架,但也难敌成千上万张显卡,性能、资源、带宽、访存、大规模分布式系统,一个都不能少,都要搞定。
搞人工智能,不容易。假设一个工程师这样开始一天的工作:在计算机上每实现一个AI算法,都要用机器指令控制庞大的计算机系统,全盘考虑计算机底层资源是如何运转,如何分配的。这还不够乱,后面还有一千台计算机在排长队,看不到队尾那种。
于是,下班给老板写了一封辞职信,来男厕所第二个隔间处领取。
眼瞅着这种困难和复杂至极的情况,真是闻者伤心,听者落泪。往严重里说,运算AI算法和计算机的效率上不去,会拖住全球人工智能产业落地的后腿。
对此,搞深度学习框架那帮人旗帜鲜明地支持AI算法工程师,全神贯注于算法设计和实现,让深度学习框架解决这个痛点。而那些最先解决痛点的,往往是最先遇到痛点的。


2009年,谷歌公司率先建了一个框架,名叫DistBelief。
谷歌公司擅长计算机系统级软件,它不会放过任何机会。历史反复证明,在计算机系统软件的战场上,谷歌没有输给过任何公司。跑高铁,铺铁轨,跑算法,就要建框架。于是,谷歌建了。
如今谈起DistBelief,仿佛陈年往事。这个谷歌公司的闭源框架,从分步式系统设计的角度看,建得非常好。也有人把DistBelief视为TensorFlow的前身。
虽然最开始设计的时候不是专门为卷积网络设计的,但是,DistBelief给当时非卷积的网络架构提供了很好的设计基础。它的设计原理像大脑,厉害之处在于,那个时候,就能做超大规模的训练,搞定十亿参数。
谷歌浑涵光芒,雄视千军,做大型计算机系统软件,尤为擅长分布式,“大”从来不是问题,就怕不够“大”。
那时候,中国的新浪微博才刚开始走红,不像今天“微博舆论”已是大数据。那些AI训练所使用的数据,像夏汛的河水不断刷新水位线纪录。而那时候的深度学习框架,没有“张量(tensor)”的概念。
曾几何时,张量是物理学家喜欢的概念,但是数学家会说,我不满意物理学家对张量的看法。AI算法开发者说:“只使用,不争论。”
所有的光芒,都需要时间才能被看到。
2010年,深度学习在语音领域实现了突破,其中没有用到卷积网络。转眼一年后,2011年12月29日,一篇论文激起千层浪,一个炫酷黑科技大火了,计算机居然会自动找出猫咪图片。
这个AI技术,是谷歌的。让计算机来回答一张图片上的动物是不是猫,答案只有两个,是猫,不是猫。爱猫人士,一片欢腾,人工智能也爱撸猫,看来普通人和高科技的距离,只有一只猫。
猫火了,论文也火了,谷歌也火了一把,只有深度学习框架没有火。
那篇响当当的论文是在DistBelief深度学习框架上做的。那时候,谷歌公司就能自信地漫步在深度学习框架上,用成千上万的CPU核,训练数十亿参数,游刃有余地管理底层技术细节。


喵星人是网红体质,AI也是。
2012年,AlexNet模型一问世就成了网红,掀起了深度学习在图像识别上的高潮。这个模型有多重要?此后的大约十年内,有无数双渴(想)望(发)真(论)理(文)的眼睛都不停放电,不放过任何一点微小细节,哪怕论文里有些思路已不再适用。
AlexNet模型的背后是图灵奖获得者,杰弗里·辛顿(Geoffrey Hinton),论文的两位作者(Alex Krizhevsky和Ilya Sutskever)同出一个师门。那一年的国际竞赛上,他们的团队是唯一使用神经网络的团队。
日后从创业到被谷歌收购,一路火花带闪电。


Alex是常见英文名,有战士之意,这个名字的常见程度,类似于中国的“建军”。为了训练模型更顺畅,建军博士Alex Krizhevsky手写了一套深度学习框架,名叫Cuda-Convnet,完全是为了搞科研,顺手而做。
起初,建军博士Alex Krizhevsky搭建了支持快速科研迭代的一套代码,在GPU上快速跑神经网络。随后,用比较简单直接的C/C++代码和手工定义模型格式,不加入太多大工程的抽象和设计,一切按从简于易的思路设计。
草率批评的人会说,很难体系化。建军博士Alex Krizhevsky可能会儒雅地回怼:“奇技淫巧,吾不以为意也。”
深度学习框架Cuda-Convnet的整套代码,是典型的科研代码,大牛才能写出来,缺憾是不重(理)视(睬)工程设计,没有太关注模块化和抽象化的能力。那时候,手写框架大神出手对付科研,足矣。
出生于那个时期的深度学习框架,身上留有“时代的烙印”,天时地利决定了它不是为工业化而生。不能往大处用又怎么样?不求孤名做霸王,打遍天下做拳王。


夕阳暮火,纽约大学晚风撩人,加州大学伯克利分校晚霞灿烂。
美国纽约大学杨立昆团队推出的OverFeat深度学习框架,也完全是出于自用,完全以搞科研为目的。甚至连起名字也没有多费心。OverFeat是一篇论文提到的算法名字,时至今日,再度提起这个框架,有一种考古挖掘的既视感。
从2009年8月开始的四年零五个月里,贾扬清在美国加州大学伯克利分校读博士,在计算机视觉小组,他悄然发现Cuda-Convnet是个宝藏,代码在优化方面写得特别精妙。
他按捺不住惊喜,找到了建军博士Alex Krizhevsky,只为此间精妙,哪怕从头写一遍Cuda-Convnet全部代码。
有些问题,早已藏在心底,期待被人问起。作为AI的使徒,建军博士Alex Krizhevsky心底的问题被贾扬清问到了,Cuda-Convnet是怎么设计出来的?
建军博士Alex Krizhevsky的语气儒雅温柔:“因为我们成立了科技公司,代码属于商业知识产权,不能分享代码,但是,如果有什么科研实现上的困难,可以随时问问题。”
为了尊重知识产权,除了开源Cuda-Convnet之外的任何一行代码,都不可分享。但是,智慧和经验都可分享,一段不限时长的在线Q&A开始了。此后,当贾扬清和团队遇到困难,就会得到帮助。这是上一代全球流行的深度学习框架Caffe最开始的故事。
一段伟大的旅程,出发时,往往只为实现一个小目标。
那时候,贾扬清的想法很简单,让加州大学伯克利分校的队友们,更容易尝试花式新算法,跑模型的工作更加体系化。
贾扬清心惟其义,潜心学习了Cuda-Convnet的写法,主要是学习高性能代码的设计思路。
他打算重新写一个框架,实现和Cuda-Convnet一样的功能,设计地更加体系化,更多工程上的抽象,同时又有完整的单元测试。
有些工作,一旦开头,就停不下来了。贾扬清和团队先写了一个基于CPU的框架,叫Decaf。再写了一个基于GPU的框架,叫Caffe(C-A-F-F-E这个五个字母,分别是论文“快速特征提取的卷积框架”英文简称的首字母),读音咖啡。


Caffe的论文还对比了OverFeat,Decaf,Torch7,Theano/Pylearn2,Cuda-Convnet这几位框架界的前辈。
巧合的是,第一眼看到这个开源框架的AI开发者,可能要惊讶到“喝杯咖啡,压压惊”。深度学习框架Caffe的出现,方便了万千AI开发者体系化的开发模型,远离那本叫做《颈椎综合症的康复与治疗》的破(恶)书(梦)。
说深度学习框架Caffe是许多AI开发者的初恋,并不为过,知乎帖子里的回忆杀,至今仍有开发者把Caffe的源码梳理了好几遍,一种经典永流传的既视感。
早期计算机视觉创业公司则拿出看性感美女的眼神打量Caffe,一秒钟也不能等了,立刻上手。谁拦着,就急眼,谁挡着,就拼命。
人头攒动中,人群高喊:Caffe来啦,快用啊,没时间解释了,老司机开车啦。
作为贾扬清创建的开源项目,Caffe由美国加州大学伯克利分校视觉和学习中心在GitHub上一个活跃的贡献者社区的帮助下,维护和开发。
Caffe出生的时候,贾扬清是博士生,买设备,很抠门,好在英伟达公司捐赠了一个6000美元的GPU,他又去美国亚马逊网站攒了一个600美元的电脑。大家开玩笑说,这套装备的净值是6600美元。
谁能想到,老司机的车,是小马拉大车。
这不是传闻,这是贾扬清在Caffe项目上真实的工作条件。直到今日,贾扬清仍然感怀Cuda-Convnet的“功劳”,引用他的原话就是:“特别是一些算子实现,都是受到了它的启发。”
传承是一种科学精神,无论后辈致敬前辈,还是前辈关怀后辈,都好似春风拂面,阳光醉人。


贾扬清曾在知乎上聊过一个小段子。
美国斯坦福大学著名的李飞飞教授(这位是女神版,阿里巴巴还有一位男神版)经常关心华人学生。贾扬清在加州大学伯克利分校念博士的时候,有一天,李飞飞教授突然问了贾扬清的导师Trevor Darrell教授一句:“贾扬清这学期没干啥事儿啊!(Yangqingis just doodling around in the last semester!)”
从斯坦福大学到加州大学伯克利分校,开车需要一小时,AI大牛教授洞察一位博士生只需一个念头。请估算贾扬清的心理阴影面积和感动函数。
那些时光冲不淡、风尘吹不散的日子,偶然念及,岁月静好,人间值得。


一路奔,一路跑,
深度学习算法豹变,深度学习框架虎啸。
著名的AlexNet之后,优秀的VGG,GoogLeNet等深度学习算法模型,以山洪暴发之势,冲刺精确度,横扫江湖。
建军博士Alex Krizhevsky有一句著名的玩笑,“用两个GPU,就超越了谷歌工作的性能”。读懂这句的人,无不感慨算法创新的魅力如此之大。
算法强,就能在同等条件或者更少算力的条件下,仅凭才华,以寡敌众,以穷胜富,以少赢多。然而,深度学习框架那帮人心里却在想另一件事,既然算法创新如此迅猛,就得有相应的软件框架去实现。
那时候,谷歌AI掌门杰夫·迪恩(Jeff Dean)和美国斯坦福大学博士安德烈·卡帕西(Andrej Karpathy)常常叫上精神小伙们,围桌讨论。
这种天才小论坛,在当年,一间屋子也就够坐了。杰夫·迪恩(Jeff Dean)偏超大工业工程,安德烈侧重前沿学术研究。那个时候,这群精神小伙中有很多人还是学生,他们时常讨论AI将有什么样的创新。


有人称杰夫·迪恩(Jeff Dean)为“姐夫”,是杰夫的谐音,但是称他为天才并不为过。
安德烈·卡帕西(Andrej Karpathy)则是“全身热恋”,个人网页向AI告白“karpathy.ai”“我喜欢在大型数据集上训练深度神经网络”。
后话是,安德烈·卡帕西(Andrej Karpathy)于2017年离开谷歌去了特斯拉,同年,建军博士AlexKrizhevsky也离开谷歌。
贾扬清做Caffe项目的时候是博士生,周围很多AI大神也仍在求学。那时候,大家喜欢在性能上比赛,我的性能比你好,你的性能比我好。所以,算得快,很重要。
“自建”深度学习框架时代,“第一需求”是什么?答案是性能。
纵观这个历史时期,深度学习框架先要让模型性能受益,其他顾不太上。深度学习框架没有“大一统”,深度学习框架都很简单,很小。
这好比新石器时代的河姆渡人盖房子,盖得简单,但也可以为原始人遮些风,挡些雨。那时候,哪有毗邻名校,楼层视野,小区绿化,周边配套等讲究。
忆往昔,搞深度学习框架这群人雕刻灵魂,也雕刻了岁月,他们不急不躁,对AI技术的促进自不用说,对AI产业潜移默化,让人敬畏。
深度学习框架当中,Theano比较偏向数据科学家的使用,用Python编程语言,用代码生成模式。而Torch则不同,关注灵活的迭代,用Lua编程语言。
Lua这个语言,小而美,它在游戏领域很受欢迎,允许与C数据结构简单接口,只可惜后来日渐式微了。有不少人很喜欢,用熟了就继续在深度学习框架中使用。
俗话说,熟土难离。这个细节反映出,那个时代,不争抢,不内卷,大家都是怎么熟悉怎么来,怎么顺手怎么来。也反映出,Torch从一开始就是重视易用性理念,而不关心新技术思路的实现。
性能为王的岁月,英伟达公司敏锐参与了趋势,和搞深度学习框架那帮人常有沟通,互帮互助,带动大家伙为深度学习框架贡献代码。
这里加一个小段子,英伟达的产品线刚刚开始有AI计算的时候,有一个捐赠计划可以让贾扬清选两种GPU。一种仅用于AI计算,不能玩游戏。另一种,保留了游戏用途的接口,不仅可以做计算,还可以玩游戏。当时,贾扬清想也没想,选了前者。回头一想,竟然后悔。
(贾扬清打过什么游戏呢?又最喜欢什么游戏呢?这点,留下个伏笔,文末放送福利。)
cuDNN是英伟达用于深度神经网络的GPU算子库。如今,已经是各大品牌的深度学习框架都会调用的工具。英伟达先知先觉,谷歌后知后觉。
2014年前后,深度学习框架DistBelief的设计,不太适合深度学习里的一种新思路,张量(tensor)。所以,谷歌内部也持续有讨论的声音传出来,新的框架应该怎么做。没有人明确说他们正在做的,就叫DistBelief 2.0。
如果要写新的框架,那应该是怎么个写法?这个问题成为谷歌搞深度学习框架的科学家的第一要事。更准确地说,新一套,而不是新一版,迈开大步,换个思路,重新设计。
贾扬清和部分Torch的作者打卡谷歌后,开心地发现,不少老面孔已经在DistBelief团队里了,谷歌让开源深度学习框架作者有机会欢聚一堂。
这时候的谷歌,可谓是,深度学习框架的天下英雄,皆入我营帐之中。于是,谷歌率先发力,一堆石头打得纷飞,流星对空乱撞,好一番激荡。2015年10月,TensorFlow问世了。
人人都知道谷歌的系统能力独步天下,但又都想知道,谷歌公司的系统能力到底有多强?
总体说来,TensorFlow的设计非常有启发性。可以把TensorFlow理解成为谷歌软件能力的综合体现,既能看到,众人拾柴火焰高,开源社区中所能见到的,已有的设计思路,都被很好地用了起来,比如说像计算图,张量(tenor),它是一个集大成者,同时解决了性能和规模化,把分布式也做起来了。
TensorFlow的问世,让人怀疑谷歌不是来做产品的,而是来展示实力的。再细测试能力,规模化分布式的能力,都很强,不偏科。
这是一个深度学习框架的里程碑事件,标志着学术制造(博士生和研究生做框架)的时代,轰然落幕。
那时候参与第一代深度学习框架的人中,有不少搞科研的学生,他们不是师出名门,就是高足弟子,充满科研热情。清点一圈,哪个都非等闲之辈。夜幕降临,深蓝色的星空之下,他们是拓荒者,刀耕火种,围坐篝火。
这时候,谷歌TensorFlow来了,刀耕火种时代的篝火晚会结束,深度学习框架开启军团作战模式,冲锋号吹响了。


岁月弥久,梦已七年。
2016年是TensorFlow高速发展的一年,杰夫·迪恩(Jeff Dean)的演讲里,论文引用次数指数级暴涨。
TensorFlow的热火朝天之中,一个需求像初生嫩芽一样,从土壤中探出了脑袋,并迅速在开源社区产生集体共鸣。
TensorFlow难学难用,恰逢其时的是,性能讲了那么长的时间,GPU的计算速度也很快了,高速迭代不需要100%的性能,85%就可以了。这时候,人力成本上升为最大的成本。
开发者拼了命地呐喊:框架得易上手!这个呐喊,是在呼吁易用性。此时的需求明摆着,就是易用。
Torch是火把的意思,易用性点燃了深度学习框架PyTorch的火把,搞深度学习框架那帮人惊讶地发现,烽火连三月,易用抵万金。
这个让TensorFlow最忠实的用户认为最不符合逻辑的地方,一定藏着最深刻的逻辑。时来天地皆同力,PyTorch生逢其时,正巧解决了TensorFlow一个超大痛点。
PyTorch起步比TensorFlow晚,拼资源也不占优势,谷歌的资源不比市场上任何一家差。创始团队思前想后,决定直捣黄龙,这条龙就是易用性。俗话说,宁走十步远,不走一步险,其他特点不是不重要,而是顾不上,PyTorch团队孤注一掷,把易用性,打穿,打透。
这种打法,逼着PyTorch只靠“易用性”这一拳,打出了四海八荒之力。基础设施投资是巨大的,PyTorch最初的原因是投入少,唯有这种打法需要较少的资源。
这个选择,有赌的成分,但是,这一次,PyTorch赌对了。
上手PyTorch的人,都会觉得好用。相信当谷歌TensorFlow内部的人看到,并且试用PyTorch的时候,也会赞叹其易用性。但是,他们肯定还是相信TensorFlow是世界上最好的框架。
2017年前后,人们会发现很多古老的计算机视觉模型是用 Caffe 写成,很多新研究论文是用 PyTorch 写的,而更多的模型用TensorFlow写成。


不同的框架,不同的格式。
从框架A翻译到框架B,从框架B翻译到框架C……“翻译”完,还要写一堆测试。民怨沸腾了,有关部门得管管。
因此,ONNX(Open Neural Network Exchange)身负重任而来。2017年最后一个月,ONNX的第一个版本发布,第一版代码是贾扬清手写的,而最早投入ONNX的两位开发负责人是白俊杰和张振瑞,前者还在贾扬清团队,后者仍然是PyTorch团队的核心成员。
贾扬清认为,ONNX的定位不是取代各种框架,而是让大家做事顺畅,ONNX辅助性地来解决这个问题。
脸书公司的PyTorch为什么成功?
因为科研的百花齐放,渴求灵活。
谷歌公司TensorFlow为什么成功?因为当时,AI正以熊熊大火燎原之势,席卷工业界。那时那刻,需熔炉炼钢之火。需要集团军作战,需要工业界不可或缺的稳定性。
成也萧何,败也萧何。TensorFlow是工业级的软件,学习门槛非常之高,开发者不禁会发出“危乎高哉,蜀道难”的感慨。这背后是计算机系统软件的稳定性提升,必然伴随复杂性的攀升。
PyTorch,像小汽车,容易上手,但是,规模化难。
TensorFlow,像高铁,体量巨大,但是,新手难操作。
易用性和稳定性,这是两个存在且合理的需求。两者各翻越过生态的天堑,双方各争下了一个山头。设计深度学习框架永远不是需求,而是手段。
TensorFlow解决了AI工业化,PyTorch解决了AI科研百花齐放。
很多人认为,最近几年,深度学习框架这一块,至少在TensorFlow和PyTorch的竞争中,几乎尘埃落定。为什么?因为这两个需求已经基本解决了。
若故事往细里说,那么最初版本的PyTorch是只专注在易用性上,但是,从2018年的PyTorch 1.0版本开始,强调在保持易用性的基础上,重视完善工业化和规模化能力。

实际上,PyTorch 1.0版本是贾扬清在脸书公司主导创建。相对应地,TensorFlow从2.0版本开始,也非常强调加入动态图模式(Eager Execution),来加强易用性。
贾扬清认为,重复建设深度学习框架,好比整条街的咖啡都不太好喝,既不解决咖啡豆的问题,也不解决咖啡机的问题,直接重新开一个咖啡店。
在刀耕火种时代,在“第一代深度学习框架”之中,为什么会出现Caffe,Torch,Theano等多款深度学习框架,因为探索之处确有需求,实实在在的需求。
在贾扬清看来,深度学习框架的效率分为两个,第一个是开发者的效率,第二个是计算机软件系统和执行的效率。
易用性解决的是开发者的效率。那计算机软件系统和执行的效率呢?
此时,深度学习框架要想做得好,关键在于把“很底层很底层”的技术做高效,而不是重新做一个深度学习框架。而这部分的工作很硬核,加料一小段科普。计算图,也可以理解为提前设计好的路线图。
简单说,深度学习框架训练模型的时候,有这样一件事情需要在深度学习框架里完成,且考验效率。出发时得一步一步来,喂数据,顺着路,直到拿到一个输出,完工。
这里的“路”就是,训练模型的路。
到底该怎么走?先去五当山,还是光明顶?
计算图里的“图”,分为静态图和动态图。静态图一早就定好这个过程,不让改(深度学习框架也会把过程做个优化,计算起来效率高)。动态图则不然,每次每批数据出发之前,允许路线图变化。
深度学习框架里的一招鲜,不能吃遍天下。
很多人都在问,有多款深度学习框架可选,这一款有什么不同价值?如今,仅靠一种图的形态已经没法解决问题了,“低垂的果实”已经没有了,需要灵活运用,巧妙出手,才能走出新路。
如今的天下,是人人都有深度学习框架用的天下。
下一步的竞争,是到底算得好不好,快不快,准不准。搞深度学习框架那帮人,就各有各的绝招了。




如今,深度学习框架的核心难点,并不是没有框架可用。
贾扬清认为,如今的深度学习框架的核心难点有两个:往下如何兼容硬件,往上如何实现更好的分布式开发。
兼容硬件这件事,和编译器有关。有句俗话是,男儿有泪不轻弹,只是未见编译器。一位老资格的AI算法工程师曾回忆,大学编译器课上,他哭了,是被编译器给气哭的,因为太难了。所以,一生躲着编译器走。惹不起,还躲不起?
果然,不出意外地出了意外。如果不是亲眼所见,他是万万不敢相信。当AI模型“下地干活”,编译器的糟心事儿,又回来了。
哭有啥用?BM-13“喀秋莎”多管火箭炮已经把炸药倾泻到编译器的战场了。战争不相信眼泪,深度学习框架在拼“谁可以更好地编译和优化”。
一般来说,深度学习框架开发者只想着为少数服务器级硬件(GPU)提供支持,而硬件供应商则更愿为部分框架开发自己的库。两边自顾自高筑墙,把周围的战壕土都用光了,于是,低头一看,竟然挖出一个大坑来。
将AI模型部署到新硬件,需要大量的手动工作,如此一来,谁来填坑?说到底还是深度学习框架。这样问题就总结出了,深度学习框架,往下如何兼容硬件?
只能让深度学习框架和硬件平台对接好,而不是对每种新硬件类型和设备都开发新的编译器和库。
说到编译器,也有很多种,有图学习的编译器,有数据库的编译器。但深度学习编译器一来,就可以将AI编译器单独分一类了。与传统编译器类似,深度学习编译器也采用分层设计,包括前端,中间表达(IR),后端。
其中,编译器和中间表达,就像异父异母的两个亲兄弟。一般来说,编译器的优化是把中间表达部分里一些可以跑得更快的地方,改动一下。
贾扬清心中的未来,可能是,AI编译器可以为运行的任何硬件生成机器原生代码,无需担心中间表达。用深度学习框架写的模型更自动化,模型跑得更快。这样,AI产业有机会整体提效。贾扬清说,互联网大厂的AI工程体系还在整合。AI的落地情况,好比1980年代的“现代化”,楼上楼下,电灯电话。
搞深度学习框架那帮人一个岗位饰演多个角色,从算法研究员,软件工程师,数据工程师,应用工程师,到系统统工程师。千难,万难,自己选的路,跪着也要走完。
讲一个真实的案例,一位多金且懂行的客户说,这里有一个图片识别模型,想跑得快一点。


本质上,事到如今,AI还不是超级APP。
这里有两层含义:
一、不是一个单点产品就能大包大揽AI所有能力,而是一系列能力的组合;
二、AI非常强烈地需要标准软件+定制化服务。
远见者稳进,稳健者远行,贾扬清为什么发布阿里灵杰,发布阿里整体大数据+AI能力?
回望八年前,一个工程师具备训练图像识别模型的能力,就已经是AI开发者里的高手。
如今,已经是将AI的算法和数据、场景结合起来,去构建一个完整的解决方案,解决各行各业当中的实际问题。
贾扬清认为,从开发的角度,从写下第一行代码,到完成第一个AI模型,需要多久?
从应用的角度,从抓住一个需求,到AI产品原型上线,需要多久?
对于阿里灵杰来说,从底座,到上层应用,整体都能让开发者按需取用,开箱即用。
这样,才有可能在云上画出人工智能第二增长曲线。


如今,产业正在经历大数据和AI一体化,需要经久耐用的底座。
在阿里云的底座里,阿里云机器学习平台PAI出手就是一(流)条(水)龙(线)服务,管资源、管任务。大规模分布式训练框架Whale,可以理解为是PAI里的一个软件包。数据仓库MaxCompute支持大型分布式数据计算。DataWorks提供一站式数据开发、管理、治理平台。
学生时代,贾扬清的电脑显卡性能不强,玩3D游戏《荒野大镖客》会把游戏画面设置到最低,以免画质感人。时间一长,“随手最低”习惯成自然。
工作后,贾扬清如愿以偿,换上最强显卡。初初上手,仿若从前,突然,他想起显卡不再是从前的显卡。快,快,快把游戏画面设置调成最高,享受一下。那一刻,贾扬清看到了一个完全不一样的游戏。
从1956年的达特矛斯会议算起,2021年的AI已走过65个春秋,时间好不经用,抬头已过甲子。搞深度学习框架的那群人,说到底是做基础设施的人,他们相信,会有一天,AI生产工业化一片坦荡,大数据和大模型在流水线上高速冲浪……
那时候,人们将看到一个完全不一样的AI。
(全文结束)
ONE MORE THING
(文末彩蛋)


(未完待续,这篇文章太长了,转发后,去你的收藏夹吃灰吧。)
传输门微信号  https://mp.weixin.qq.com/s/zHXaIQLUgtBYnZ6U3Z-pFg

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

0

主题

3

回帖

5

积分

新手上路

积分
5
发表于 2023-5-9 11:35:41 | 显示全部楼层
先简要回答一下吧
AI框架领域最近两年已发生的最大的一个事件是PyTorch以eager模式的优势超越TensorFlow;
AI框架领域最近两年已显现的一个最大需求是大规模预训练模型,进而提出的复杂的并行模式的支持(数据,模型,流水,专家等并行),主流框架还不能原生支持这些需求,都需要通过定制的wrapper或plugin才可以,一些新兴的深度学习框架(譬如OneFlow) 在这方面具有比较明显的领先优势,原生就可以支持这些复杂的并行模式。
一个肉眼可见的事情是“自动placement和自动并行”很快就会被完全解决了,将真正实现单卡代码不需要任何改动就可以扩展到任意多的计算资源上去,分布式并行方面的痛点将不复存在。
所以可以预期,未来的主流框架将继承PyTorch在单卡易用性方面的优点,同时在分布式易用性、分布式效率方面也会非常突出,当然也会解决掉PyTorch今天遇到的部署方面的麻烦(也就是训练推理一体化)。
这是一个比较近期的预测,应该在一年内发生。
更远一点,深度学习编译器领域也会发生一些有趣的事情。
回复

使用道具 举报

0

主题

1

回帖

9

积分

新手上路

积分
9
发表于 2023-5-9 11:36:13 | 显示全部楼层
一直期待有高手来发表下看法,等了几天还没等到,来说说个人拙见吧。
除非神经网络的数学原理(最小化 loss、链式求导、反向梯度、。。。等等)有了本质的变化或者说进步,否则现在的 AI 基础框架(比如 pytorch、paddle、tensorflow)完全能满足需求。
下一代 AI 框架的关注点应该在以下几个方面:

  • 用户组网更加方便、自由。对于一些复杂网络结构,比如 MOE、MMOE 或者 JeffDean 提到的统一结构 Pathway 等,需要减少用户组网的复杂度,也就是说部分组网由框架自动完成,框架应该在 op(算子)粒度上抽象出更高级一点的且通用的"算子",比如 Cell(这是我起的名字哈~)
  • 分布式训练(模型并行,数据并行,混合并行,参数服务器等等)具备极致性能,包括集群资源利用率和训练速度、支持万亿级模型,具体表现在:


  • 自动切图方案
  • 切好的子图能按照最优策略进行自动调度,比如选取最优的通信路由、最佳的硬件资源(算力、存储等)
  • 还有就是和云原生的融合了,嗯,敬请期待~
3. 云上进行推理或者其他高效分布式推理方式,满足线上推理实时性要求
4. 隐私计算。国内对个人数据保护政监管越来越严。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|T9AI - 深度人工智能平台 ( 沪ICP备2023010006号 )

GMT+8, 2024-5-21 08:42 , Processed in 0.068294 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表