关于我如何阅读源码这件事...

点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

来源丨Oldpan博客

编辑丨极市平台

导读

 

阅读大厂的源码进行模仿和魔改其实是学习代码和规范自己的书写格式的一种很好的方法,本文作者介绍了几个优秀的源码库以及辅助阅读的工具,帮助大家快速结业源码阅读! 

阅读源码本身就是一种学习,就像小时候写作文一样,看别人的好作文也就会模仿一些好的句子,一些好的段落。看源码也一样,不同大厂的源码写的风格也不一样,惯用的技巧也不一样,强调的规范也不一样,使用的C++标注也不一样(C++11、C++14等等)。

但是如果想要深入学习一个框架的底层,看源码是必须的。

我看过不少源码,也模仿过一些大厂源码的例子。最常见的例子就是抽象类、工厂、单例、注册等等机制,这也是设计模型里头最常见的。如果感觉看的挺熟了想贡献的话,相应的也有编码规范(code-guidelines)。像TensorRT[1]开源仓库的贡献代码规范

  • https://github.com/NVIDIA/TensorRT/blob/master/CODING-GUIDELINES.md

里面会要求,使用namespace必须在末尾加上该namespace名称的注释。

namespace foo
{
...
} // namespace foo

或者比如写C++尽量用constconstexpr而不是#define,因为#define是预编译的,编译器对此无能为力检查不了。

等等等等。

有些是很小的细节、有些则是涉及到C++的语法和实用性以及代码后期的维护性以及稳定性。如果觉着自己的代码写的不是很好看,或者感觉不满意,或者有强迫症,就想要写完美没有问题的代码,这时你可以参考下这些大厂的标准...

其实对于C++的编码规范和一些准则,我们平常看的C++ primer里头就有很多。类似的资料也有很多,一般都是用比较新的C++11到C++17的标准。我们多看看多学学就差不多会了:

  • C++ Core Guidelines[2]

  • (More)Effective C++

  • Effective Modern C++

推荐看的一些源码库

深度学习,除了纯粹的研究岗,不论是深度学习研究员还是深度学习算法工程师,或者是深度学习框架工程师、高性能计算工程师...一些源码总是要看的。

我们平常用的Pytorch、Caffe、TensorFlow、Paddle、TVM,这些都是开源的。不论公司还是个人都在用,很好用也很强大,大佬们也会经常魔改。

这都是赤裸裸的宝贵资料啊,不花点时间看真的是可惜了。

我这里也推荐一些值得深入学习的框架。

Caffe[3]

Caffe有多经典就不用说了,大部分的代码是用C++写的,对于学习C++的一些语言很有帮助。

Caffe代码语言分布

值得看的部分都在src目录下:

Caffe核心的部分

值得我们学习的东西有很多:

  • 类的设计、继承、模板、工厂

  • im2col、矩阵运算、反向传播

  • 很多算子的CPU和GPU实现,例如BN、softmax等

  • SyncedMemory,内部的blob数据是如何在CPU和GPU之间传递的

// Caffe中layer的注册机制
// ~/include/caffe/layer_factory.hpp
#define REGISTER_LAYER_CREATOR(type, creator)                                  \
  static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>);     \
  static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>)    \


#define REGISTER_LAYER_CLASS(type)                                             \
  template <typename Dtype>                                                    \
  shared_ptr<Layer<Dtype> > Creator_##type##Layer(const LayerParameter& param) \
  {                                                                            \
    return shared_ptr<Layer<Dtype> >(new type##Layer<Dtype>(param));           \
  }                                                                            \
  REGISTER_LAYER_CREATOR(type, Creator_##type##Layer)

到现在为止,如果追求性能话,Caffe可能已经不是很合适了。CPU和GPU端有OpenVino和TensorRT两位大哥,也有其他优秀的框架。Caffe到现在更加适合作为应用部署入门学习的框架,或者一些对吞吐量要求不高的任务,一些工业嵌入式端现在也会用到Caffe。

Caffe也是前几年面试的常客,这些年可能问的少了,不过我认为还有必要投入一点精力去学习。

Pytorch

Pytorch中值得学习的部分更多。不过Pytorch源码很复杂,我建议还是带着任务去学习比较有效率和针对性。比如你想要写CUDA自定义算子、又或者你想理解Pytorch的自动求导是什么样的,最好是有需求去看。

还有个最直接的方法,自己把Pytorch的源码编译一遍,尽量遇到坑,逼着自己看下是什么问题,这样对Pytorch的整理框架会有一定的了解。Pytorch值得学习的地方很多:

  • autograd[4],也有相应长达40多页的PDF讲解[5]

  • Tensor,Pytorch中的Tensor是如何存储的,如何和op交互,如何在CPU和GPU之前无缝传递的

我之前有过很多源码介绍和源码编译,这里就不赘述了,感兴趣的可以看之前的博客。这里翻出篇关于Tensor的:https://zhuanlan.zhihu.com/p/348179896

除了本身有很多学习的地方,Pytorch也附带了很多优秀的第三方库,也值得我们学习,简单列举两个:

  • fbgemm

  • QNNPACK

triton-inference-server

推理服务器框架,这里更多的是用我们已知的推理框架去实现服务器推理功能,涉及到调用各种推理框架(libtorch、TensorRT、TF)的正确姿势以及多线程推理相关。主要语言也是C++。

包括却不限于:

  • 多线程调度以及队列、动态组batch处理

  • HTTP、GRPC协议;json处理机制(rapidjson)

通过这个源码仓库,我们可以学到很多部署模型推理的实际代码,这个仓库很大,要看的代码很多,你忍一下。源码地址:

  • https://github.com/triton-inference-server/server

编码规范:

  • https://github.com/triton-inference-server/server/blob/main/CONTRIBUTING.md

TVM[6]

TVM是一个C++与python混合的工程,并不是单纯的C++或者python语言所编写的。其中,TVM中两种语言的结合方式是使用python中内置模块ctypes来构建起来的,看到ctypes我们可能想到,这不是和C语言结合的吗,当然是这样的,TVM使用的与python的组合语言是C,而核心的实现语言还是C++,而C++通过C的接口与ctypes相连。

TVM中有很多值得我们学习的点:

  • type-erased函数是如何实现的

  • 反射机制和奇异的递归模板式

  • 可以兼容一切的PackedFunc又是如何实现的

TVM的官方文档有很多其内部实现细节的讲解,在TVM的TVM Runtime System[7]一文中,其实已经简单介绍了TVM的核心部件的使用方式,在运行端中,第一个首要介绍的就是可以接受和返回任意类型参数的函数,通过这个特性TVM实现了很多函数接口来完成TVM的一系列任务:

void MyAdd(TVMArgs args, TVMRetValue* rv) {
    // automatically convert arguments to desired type.
    int a = args[0];
    int b = args[1];
    // automatically assign value return to rv
    *rv = a + b;
}

TVM老潘之前留了很大的坑没有填,后续一定会补上的。

还有很多值得深入的框架就不一一介绍了。

看源码工具

工欲善其事必先利其器,要阅读源码没有好的阅读器(IDE)怎么行呢?

看源码的工具我推荐使用VSCODE,谁用谁知道。看代码的高亮、查找reference、全局查找、宏定义展开、甚至可以运行,大大提升阅读代码的效率。

VSCODE

对于某个文件,还可以看到这个代码文件的OUTLINE以及TIMELINE,可以说是非常强大了。

文件的outline和timeline

如果你就想快速看看代码,可以直接浏览器将某个github的地址换为github1s,有人专门开发了工具,可以通过这种方式直接在github源码处开启网页版VScode,可以方便地阅读源码:

github1s看代码

虽然githubs偶尔会抽风,抽风概率20%,不过确实是一个非常好用的看代码工具。

DEBUG代码

还有很重要的一点,光看代码有些细节的运行逻辑底层实现肉眼一般是看不透的(除非你有写轮眼!),最好跑一下!如果自己不知道跑啥,建议可以看一下源码中的test部分,test部分就是QA,也是测试源码功能实现是否符合预期的重要一步。我们可以跑一些这里的测试样例,所有功能都会覆盖到,边跑边debug,所有细节一清二楚!

比如Pytorch源码中的,test/test_quantization.py源码test部分,我们可以通过python test/test_quantization.py TESTNAME命令执行来测试所有关于量化的功能模块:

# # 1. Quantized Kernels
# TODO: merge the different quantized op tests into one test class
from quantization.core.test_quantized_op import TestQuantizedOps  # noqa: F401
from quantization.core.test_quantized_op import TestQNNPackOps  # noqa: F401
from quantization.core.test_quantized_op import TestQuantizedLinear  # noqa: F401
from quantization.core.test_quantized_op import TestQuantizedConv  # noqa: F401
from quantization.core.test_quantized_op import TestDynamicQuantizedLinear  # noqa: F401
from quantization.core.test_quantized_op import TestComparatorOps  # noqa: F401
from quantization.core.test_quantized_op import TestPadding  # noqa: F401
from quantization.core.test_quantized_op import TestQuantizedEmbeddingOps  # noqa: F401
from quantization.core.test_quantized_op import TestDynamicQuantizedRNNOp  # noqa: F401
# 2. Quantized Functional/Workflow Ops
from quantization.core.test_quantized_functional import TestQuantizedFunctionalOps  # noqa: F401
from quantization.core.test_workflow_ops import TestFakeQuantizeOps  # noqa: F401
from quantization.core.test_workflow_ops import TestFusedObsFakeQuant  # noqa: F401
# 3. Quantized Tensor
from quantization.core.test_quantized_tensor import TestQuantizedTensor  # noqa: F401
# 4. Modules
from quantization.core.test_workflow_module import TestFakeQuantize  # noqa: F401
from quantization.core.test_workflow_module import TestObserver  # noqa: F401
from quantization.core.test_quantized_module import TestStaticQuantizedModule  # noqa: F401
from quantization.core.test_quantized_module import TestDynamicQuantizedModule  # noqa: F401
from quantization.core.test_workflow_module import TestRecordHistogramObserver  # noqa: F401
from quantization.core.test_workflow_module import TestHistogramObserver  # noqa: F401
from quantization.core.test_workflow_module import TestDistributed  # noqa: F401
from quantization.core.test_workflow_module import TestFusedObsFakeQuantModule  # noqa: F401

对于很多源码,大部分是Python和C++混搭的。Python充当前端接口,后端核心逻辑和算法用C++和CUDA实现。对于这种情况,可能运行debug起来比较麻烦,但也不是没有办法,只要编译出带debug符号表的.so,然后gdb-attach一下,是可以从python端口debug到c++内部逻辑的:

  • 各种姿势的debug(从python一路debug到C++)(https://mp.weixin.qq.com/s/Pr6PWNkcs4YE7ML2Q2FGug)

学习地儿

看源码没人交流怎么行,最好的交流方式就是各大GITHUB源码的issue

issue多看、pull request多学、很多精华都在里头了。要搞AI部署工程研究,各种推理框架(TF、Pytorch、TFLITE、TVM、NCNN)的源码更是要看的,需要学习什么,也需要一步一步来。

issue和pull request都是很好的学习论坛

issue区可以提中文也可以提英文,要知道很多大佬也都是中国人,而且和你英文交流的说不定也是中国人。

中英混杂的交流圈

贡献代码

如果你某个项目的源码看的非常熟悉了,然后你发现这个框架的一些bug或者一些改进点,你就可以试着去修改源码然后提交上去。一般的流程:

  • fork一份源码到自己的仓库

  • git clone下来进行修改,记得在新的分支上修改

  • 修改好后更新自己的仓库

  • 到官方的源码仓库上提pull request,将自己仓库上的某一分支merge到官方源码仓库中

  • merge成功

整个过程还是很有意思,或者说,很有成就感的。毕竟你的代码需要被很多大佬查阅,你的代码需要符合这个仓库的规范,无论是代码风格还是代码能够提供的功能性。大佬们帮你review代码的同时也会帮你提出修改意见,让你的代码能够更好地merge到这个仓库中,同时你的代码也焕然一新。

随便点开一个TVM[8]仓库的Pull requests

Pull requests流程

Conversation表示这个pull requests的贡献过程,有贡献者与项目维护者的交流以及代码review环节。Commits即关于这个共享的提交过程;我们可以直接看Files changged来看共享者对源码做了哪些更改,当然也是最核心的部分。

当你成功贡献代码的时候,阅读源码这门课就可以毕业啦!

参考资料

[1]

TensorRT: https://github.com/NVIDIA/TensorRT

[2]

C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#main

[3]

Caffe: https://github.com/BVLC/caffe

[4]

autograd: https://pytorch.org/docs/stable/notes/autograd.html

[5]

PDF讲解: https://arxiv.org/pdf/1502.05767.pdf

[6]

TVM: https://github.com/apache/tvm

[7]

TVM Runtime System: https://docs.tvm.ai/dev/runtime.html?highlight=reflect

[8]

TVM: https://github.com/apache/tvm

本文仅做学术分享,如有侵权,请联系删文。

下载1

在「3D视觉工坊」公众号后台回复:3D视觉即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。

下载2

在「3D视觉工坊」公众号后台回复:3D视觉github资源汇总即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计源码汇总等。

下载3

在「3D视觉工坊」公众号后台回复:相机标定即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配即可下载独家立体匹配学习课件与视频网址。

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。

一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定orb-slam3等视频课程)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

 圈里有高质量教程资料、答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值