当前位置:   article > 正文

那一年,让我整个人升华的 C++ BERT 项目

bert项目经历


作者 | rumor

来源 | 李rumor(ID:leerumorr)

最近知乎有个很火的问题:「你的编程能力从什么时候开始突飞猛进?」,每次信息流刷到的的时候都会拨动我记忆的缓存,让我想起那段大起大落的时光。

19年夏的某一天,在各大公司陆续推出自己预训练的BERT,并开始用它们做离线任务时,leader把我叫进会议室,说老大想上线BERT,需要尽快写一个C++版本的BERT服务。

不是那种用tfserving或者libtorch哦,是直接用C++写。

我面无波动地答应了下来,实则内心已经裂开了。

自己不是CS科班出身,压根没写过完整的C++项目,虽然有些Java基础,但到底几斤几两我还是蛮清楚的。

打比方的话,就是让第一次玩塞尔达、刚开完四个神庙、出了新手村的我直接去打盖农,悲壮之感难以言表。

整个人都不好了


但我作为新时代的自强女性,还是开启了冲向海拉尔中心的旅程。

第一步,就是搜集可以参考的开源项目。

Fortunately,我找到了知乎开源的cuBERT项目,作者写得特别清楚,并且同时提供了GPU和CPU版本,但老板看了速度之后仍不太满意,最终我靠着极强的搜索技术又找到了英伟达刚开源的fastertransformer,用Cuda C++直接实现了transformer底层运算,速度秒杀其他方案。

在经历了各种make、install的折磨之后,我终于摸清了如何在服务器配置相关lib并运行c++代码,也顺利跑通了官方demo,性能完全符合预期。但不能高兴得太早,因为这个库只有transformer层的实现,前面的tokenization、embedding、pooling都没有写。。所以,这意味着我要读懂源码,然后自己把剩下的补全。

第二步,我开始读源码改项目。

这里有碰到了第一个难点,就是跑官方给的模型没问题,但运行我们自己的模型后就出现了 nan 这个恐怖的结果。于是我开始使用 print 大法,但惊讶地发现 cuda 底层全是并行的,一打日志都是乱的。。。于是我学会了 synchronize,在每个 operation 之后同步再打印结果,最终花了两天时间定位了问题:原来是Softmax没加溢出保护。立刻给作者提issue,不过在等待作者回复的过程中我居然自己给改好了,还默默学会了 Parallel Reduction 算法。

期间我还会卡在各种各样的事情上,经常会卡上一两天,陷入自我放弃的漩涡。

最终还是搞懂了源码,搞懂了cuda运算,并加上输入输出层搞出了完整的C++ BERT。

但仅仅有个程序还是不够,服务接口在哪里呢?

第三步,整一个服务。

于是我又搜啊搜,找到了一个宝藏:TensorRT Inference Server。当时的版本提供以下超赞的功能:

  1. 支持单GPU上的多模型&单模型多实例

  2. 支持多种backends框架(TensorRT、Tensorflow)

  3. 动态Batch增加吞吐

  4. 提供负载均衡及状态监测

所以又花了几天把C++ BERT适配TensorRT框架,成功变成了服务。

变成服务之后又有问题,就是每次换机器都要重新配置环境并部署,于是我又学会了docker,减轻运维负担。

通关了!

整个改造差不多耗时小两个月,也是我工作至今记忆最深的一段时刻。

我永远忘不了,那种看着看着代码就想站起来掀桌子的感觉。可以一起体会下:

  1. template <typename T>
  2.   __inline__ __device__
  3. T blockReduceMax(T val)
  4. {
  5.   static __shared__ T shared[32]; 
  6.   int lane = threadIdx.x & 0x1f// in-warp idx
  7.   int wid = threadIdx.x >> 5;  // warp idx
  8.   val = warpReduceMax(val); // get maxx in each warp
  9.   if(lane == 0// record in-warp maxx by warp Idx
  10.     shared[wid] = val;
  11.   __syncthreads();
  12.   val = (threadIdx.x < (blockDim.x >> 5 )) ? shared[lane] : -1e20f;
  13.   val = warpReduceMax(val);
  14.   return val;
  15. }

当然也忘不了身边同事牺牲自己时间给我的帮助,还有lead和我一起翻了半天C++ Premier才解决问题的欣喜。

故事的后来很圆满,压测效果满意,成功服务了团队的BERT上线。包括后来我在20年初和其他两个大厂团队的人交流,都没有听到过更快的速度,甚至有同学直接质疑了我,因为他们的时延是我们的两倍......

去挑战一座山吧

现在回想起来,这段经历真的太宝贵了。虽然不想再经历一次,但自那以后我再也没怕过任何代码。

做算法也有了底气,我可是搞过CUDA C++的女人,别叫我调包侠。

如果想快速提升,那就去挑战一座山吧,找一个高质量的项目,读懂并进行修改,在一次次自我放弃中成长。

就像走过高考、走过考研、走过校招那样,过去那道坎就没什么了。


☞爱奇艺一程序员用 10 万元“买”了个北京户口
  1. ☞壕!阿里开工红包惊人,最高 1000 万,有人却只收到一杯白开水
  2. ☞谷歌称居家办公影响工作效率!2021 年将回归线下办公
  3. ☞雷军坚持了 10 年的东西,现在彻底凉了
点分享点收藏点点赞点在看
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/493641
推荐阅读
相关标签
  

闽ICP备14008679号