2020年3月20日,清华自研的深度学习框架,正式对外开源。清华大学计算机系的图形实验室出品,取名Jittor,中文名计图。
计图(Jittor):一个完全基于动态编译(Just-in-time),内部使用创新的元算子和统一计算图的深度学习框架, 元算子和Numpy一样易于使用,并且超越Numpy能够实现更复杂更高效的操作。而统一计算图则是融合了静态计算图和动态计算图的诸多优点,在易于使用的同时,提供高性能的优化。基于元算子开发的深度学习模型,可以被计图实时的自动优化并且运行在指定的硬件上,如CPU,GPU。
官网链接: https://cg.cs.tsinghua.edu.cn/jittor/
github地址: https://github.com/Jittor/jittor
简单看了一下代码,非常有意思的一个项目。因为看得不深入,所以如果有观察错误的话,我想对作者先致以歉意。
总的来说:项目更加关注在如何进行计算图优化以及just in time compilation上面(所以叫jittor),并不是关注完整的端到端的框架设计(比如说建模前端等等),我觉得定位是比较清楚的,自动代码生成是现在大家都很关注的方向,在校的同学能够着手把这一套都做一次,值得点赞。
一些能看到的工程点:
- 实现了一个比较经典的DAG graph,以及在图上来做fusion和各种pass。从op的实现上,选择了细粒度的op,例如bcast,reduce,等等,然后通过这种方式来形成meta op,比如说convolution:https://github.com/Jittor/jittor/blob/master/notebook/meta_op.src.md 值得关注的一点是,在XLA的早期,也有过对于op粒度的探索,目前大家的一些结论是,常见的op,比如说convolution,gemm,如果用细粒度op来实现,然后这些细粒度op是在一个op graph当中来做jit的,对性能会是一个很大的挑战(除了在代码里面embed constant value,loop reordering等等)之外,很多关于计算的细节信息都丢失了,会对后面的fusion pass有很大的挑战。
- 现在一般的自动编译框架选择的方式其实是选择两层IR,一层做计算图DAG,一层做数学表达(比如说bcast,reduce,最典型的是Halide)。可能值得看一看。编译是通过route到binary call,比如说nvcc和gcc,然后读取编译器的输出来做的(https://github.com/Jittor/jittor/blob/85d9ccc004b83ad2d83769ffd1803fb038a17264/src/jit_compiler.cc#L20)。这个让我想起当年的theano的设计,背后的思想一脉相承。相比较于对接libllvm等runtime library,是一个比较短平快可以来实现从前端到编译的办法。
- 一个小tip,c++其实有demangle的一些utility(https://github.com/pytorch/pytorch/blob/master/c10/util/Type.h#L13),可以不需要把symbol的magic string放在代码里面(https://github.com/Jittor/jittor/blob/85d9ccc004b83ad2d83769ffd1803fb038a17264/src/jit_compiler.cc#L59)
- 因为编译的产出是直接的binary,不需要一个通用的framework runtime,所以编译以后的产出binary size会很小,这个也许会在端上设备、microcontroller等场景比较有意思?
很赞的一些工程细节:
- 有log和flag的设计(应该是学习了google glog和gflags?),并且代码当中做了比较多的logging,这个是个工程实现当中很重要的环节。https://github.com/Jittor/jittor/tree/master/src/utils
- 因为compilation时间比较久,所以考虑了做cache:https://github.com/Jittor/jittor/blob/master/src/utils/cache_compile.h
– 贾扬清1