上周末在上海参加PyCon,第一次与Python爱好者们面基,顺便讲了个机器学习相关的Talk。现场反馈还不错,人工智能会场爆满,还收获不少粉丝。其中一位粉丝是人工智能的PhD,散场后交流了不少,送了我一本《深度学习》的书,才发现他是译者。其他场次比较值得一听的是英伟达讲师的分享,如果早点认识可以省去不少弯路。
大会没有直播和视频,在此分享一下我的PPT和演讲者备注。
关于我:
网易游戏大到w行python项目(听说python不适合大项目:P
Airtest开源作者star
人工智能NLP深度学习
8年Python经验,第一语言:web、自动化、游戏、ai,python可以做很多事情,每个方面的python经验其实都是可以迁移互补的。
那么我们就看看在机器学习领域,如何做python的性能优化
Q:先问一问在座多少是做AI相关,多少是想转AI方向的(应该所有人都是用python的吧
A:大部分做AI的同学都是从算法入门的,对系统和性能了解甚少。这次分享会从entrylevel开始,nodeepshit,即使没有做AI的听众也会收获一些Python和方法论经验
为什么我们这么说呢?
程序员的时间都是钱啊,特别是做优化的都是资深经验的程序员,很贵的
想象一个秒的程序,其中40秒花在运行一个函数
对于人工智能项目,更是如此,先做出效果,确定好整体的pipeline,再考虑优化
对于项目开发周期:1.先做出demo效果、验证产品2.确定整体pipeline3.再考虑性能优化
Q:了解BERT的同学有多少?没事,我尝试用一句话解释
A:BERT是google发布的预训练任务,简单来说就是用很大量的语料训练
输入一句话,转换成向量,向量就可以进行各种操作,比如取平均、取近似、做分类,取近似可以用来推荐、分类就是用来做情感分类
可以想象成一个大黑盒,黑盒里面有3亿参数,对输入的句子进行矩阵运算
bert比之前的厉害的地方是selfattention机制,句子里面的每个词和句子里每个词的关系,可以用矩阵表示
另一个特点是预训练的模型结构都一样,3亿参数,下游任务就很简单的,很简单的模型结构解决问题
完型填空就是其中一个很典型的任务,跟中国英语考试题比较类似
Q:假设我们现在上线了这样一个服务,每秒钟只能处理10个请求,大家一开始要怎么着手
A:很多人拿到这样的程序,一开始就会优化bert模型部分
但是意想不到的是热点在预处理:Tokenization
这样即使你把bert模型部分优化了很多倍,整体效率也提升不大,(因为阿木达尔定律)
只是一个引子,后面会详细讲整个一步步的优化步骤,这里先补一补基础知识
本来是想讲讲这几个资源的,但是那样太无聊,我们直接从两个问题说起:
GPU为什么快?
Python为什么慢?
Q:为什么人们说GPU比CPU快?
难道是两家技术水平差距有这么大?
NVIDIA的数据
人工智能近十年的发展得益于数据和算力的爆发式增长,而GPU的爆发得益于游戏行业的发展。。。游戏行业推动了GPU,人们却用GPU做起了人工智能
Q:为什么,难道是NVIDIA比INTEL技术好这么多吗?
不同的硬件结构,导致了不同的编程范式。GPU编程就是要扬长避短
利用好强大的多线程并行能力
cache较少,充分考虑显存读写的消耗和优化
cpu和gpu是两个硬件,完全异步
当然现在说这些有点抽象,大家有个概念,后面会有具体的例子
当各个语言的爱好者聚集在一起,说到Python总是会说Python“慢”,那么问题来了
Q:为什么人们说Python慢?
对于开发者来说,机器硬件是你的资源,操作系统是你的资源,python语言同样是你的资源。你需要先了解你的资源
为了直击python开发者的痛处,又不太像上课那么无聊,我们来看一个例子
我们来看最简单的一个例子,用flask写了server,看起来毫无问题的服务器,大家会觉得慢。
Q:那么猜一下慢在哪里?有没有同学可以说一下
Flask裸起很慢ThreadedServer,每一个请求启动一个线程。老版本更甚,是单线程server,循环处理
GIL是python语言爱好者的痛点,可以说是唯一的语言缺陷。满负荷运转也只能跑满单核,摩尔定律失效导致多核的发展,动不动就是32核
解释执行,一个1+2语句都有20多层c函数调用。导致计算密集型的函数很慢,比如json序列化。当然这不是语言缺陷,而是各种动态特性的tradeoff
web开发发展这么多年,这三个解决方案非常成熟了
直接看结果
如此一来,我们解决刚刚说的三个问题
1.多核
2.异步
3.高效序列化
我们就可以得到一个跟golang甚至c++差不多性能的webserver,轻松上10wqps
但是很多新手不知道,一跑发现比c++/go慢那么多,就到网上disspython了。
前面我们介绍了优化的哲学,优化的闭环
也初步了解了我们的资源、GPU和python语言的特性
下面我们简单说一下如何定位性能瓶颈:没有profile的优化都是耍流氓
之前都是time.time()就能确定问题,那是我们有一定的范围了,或者粗略地圈定范围。
需要正经做profile,有一个highlevel的了解
pyflame是uber开源的一个profiler,高频采样运行中的python程序,比如每秒采样次,统计正在运行的函数,统计次数就是运行时间。
欢迎使用我二次开发的版本
有了哲学、基础知识,也有了武器库(profiler)
有了之前的背景知识和方法论,我们可以正经开始优化了,第一个解决最大的热点:preprocess
preprocess做的事情很简单,我说一下大家就明白,从词典里面找到对应的词的index,把string转换成int
pybind也是pytorch和TensorFlow实现c++python接口的方式,非常简单直白。
这时候我们的热点变成了网络模型
用户请求是离散的,GPU并行度不高
生产者消费者模型
只需要几行代码进行封装,与框架完全无关,也不用改变数据处理流程
详细的请看readme
买V更好的卡,或者更多的机器
BERT既然有3e参数,我们能不能想办法减少参数
更好的实现,从这点说起
正好NVIDIA针对bert做了一套TensorRT优化,我们看看官方是如何优化实现的。
简单来说就是遵循gpu的编程范式,将数据尽可能并行,减少显存的读写次数。
而这一点可以通过自己写cuda插件来实现。我的这篇博客中有更详细的介绍
分别给个概念,说下局限性
知识蒸馏:
TeacherStudent学的更快
3亿参数始终是个问题
24层/12层蒸出6层
机器学习系统还是非常新的领域,欢迎与我多多交流
预览时标签不可点收录于合集#个上一篇下一篇