计图(Jittor)最新动态


开源机器学习框架——计图(Jittor)

计图(Jittor):一个完全基于动态编译(Just-in-time),内部使用创新的元算子和统一计算图的深度学习框架, 元算子和Numpy一样易于使用,并且超越Numpy能够实现更复杂更高效的操作。而统一计算图则是融合了静态计算图和动态计算图的诸多优点,在易于使用的同时,提供高性能的优化。基于元算子开发的深度学习模型,可以被计图实时的自动优化并且运行在指定的硬件上,如CPU,GPU。


Jittor设计理念

易用且可定制

用户只需要数行代码,就可定义新的算子和模型,在易用的同时,不丧失任何可定制性。

实现与优化分离

用户可以通过前端接口专注于实现,而实现自动被后端优化。从而提升前端代码的可读性,以及后端优化的鲁棒性和可重用性。

所有都是即时的

Jittor的所有代码都是即时编译并且运行的,包括Jittor本身。用户可以随时对Jittor的所有代码进行修改,并且动态运行。


Jittor特性


计图整体架构与创新

从系统角度看,我们的Jittor平台自底向上包括四个层次:系统层、算子层、框架层和应用层。其中包含了计图的两个创新点:统一计算图和元算子融合。

元算子融合

我们将神经网络所需的基本算子定义为元算子,多个元算子之间可以相互融合成更加复杂的算子,如卷积层,归一化层,进一步构成神经网络和深度学习应用。

高阶导数以及反向传播闭包

元算子是反向传播闭包,既元算子的反向传播也是元算子。同时支持计算任意高阶导数。在深度学习算子开发过程中,免去了反向传播算子重复开发工作,同时可以使用统一的优化策略。

算子动态编译

Jittor内置元算子编译器,可以将用户通过元算子编写的Python代码,动态编译成高性能的C++代码。

自动优化

Jittor内置优化编译遍(complier pass),同时和LLVM兼容,这些编译遍会根据硬件设备,自动优化动态编译的代码,常见的优化编译遍有:循环重排,循环分裂,循环融合,数据打包,向量化,GPU并行。这些编译遍对C++代码进一步优化,生成对计算设备友好的底层算子。

统一内存管理

Jittor使用了统一内存管理,统一GPU和CPU之间的内存。当深度学习模型将GPU内存资源耗尽时,将使用CPU内存来弥补。

高效同步异步接口

同步接口编程简单,异步接口更加高效,Jittor同时提供这两种接口,同步和异步接口之间的切换不会产生任何性能损失,让用户同时享受到易用性和高效率。

模型迁移

Jittor采用和PyTorch较为相似的模块化接口,为了方便用户上手,Jittor提供了辅助转换脚本,可以帮助您将PyTorch的代码转换成Jittor的模型。 在参数保存和数据传输上,Jittor使用和PyTorch一样的 Numpy+pickle 协议,所以Jittor和PyTorch的模型可以相互加载和调用。


Jittor(计图): 即时编译深度学习框架

Jittor 是一个基于即时编译和元算子的高性能深度学习框架,整个框架在即时编译的同时,还集成了强大的Op编译器和调优器,为您的模型生成定制化的高性能代码。

Jittor前端语言为Python。前端使用了模块化的设计,类似于PyTorch,Keras,后端则使用高性能语言编写,如CUDA,C++。

下面的代码演示了如何一步一步使用Python代码,从头对一个双层神经网络建模。

import jittor as jt
from jittor import Module
from jittor import nn
class Model(Module):
    def __init__(self):
        self.layer1 = nn.Linear(1, 10)
        self.relu = nn.Relu() 
        self.layer2 = nn.Linear(10, 1)
    def execute (self,x) :
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        return x

def get_data(n): # generate random data for training test.
    for i in range(n):
        x = np.random.rand(batch_size, 1)
        y = x*x
        yield jt.float32(x), jt.float32(y)

model = Model()
learning_rate = 0.1
optim = nn.SGD(model.parameters(), learning_rate)

for i,(x,y) in enumerate(get_data(n)):
    pred_y = model(x)
    loss = ((pred_y - y)**2)
    loss_mean = loss.mean()
    optim.step (loss_mean)
    print(f"step {i}, loss = {loss_mean.data.sum()}")

大纲

教程

在教程部分,我们将简要解释Jittor的基本概念。

要使用Jittor训练模型,您需要了解两个主要概念:

  • Var:Jittor的基本数据类型
  • Operations:Jittor的算子与numpy类似

数据类型

首先,让我们开始使用Var。Var是jittor的基本数据类型,为了运算更加高效Jittor中的计算过程是异步的。 如果要访问数据,可以使用Var.data进行同步数据访问。

import jittor as jt
a = jt.float32([1,2,3])
print (a)
print (a.data)
# Output: float32[3,]
# Output: [ 1. 2. 3.]

此外我们可以给变量起一个名字。

a.name('a')
print(a.name())
# Output: a

数据运算

Jittor的算子与numpy类似。 让我们尝试一些运算, 我们通过Opjt.float32创建Var ab,并将它们相加。 输出这些变量相关信息,可以看出它们具有相同的形状和类型。

import jittor as jt
a = jt.float32([1,2,3])
b = jt.float32([4,5,6])
c = a*b
print(a,b,c)
print(type(a), type(b), type(c))
# Output: float32[3,] float32[3,] float32[3,]
# Output: <class 'jittor_core.Var'> <class 'jittor_core.Var'> <class 'jittor_core.Var'>

除此之外,我们使用的所有算子jt.xxx(Var,...)都具有别名Var.xxx(...)。 例如:

c.max() # alias of jt.max(a)
c.add(a) # alias of jt.add(c, a)
c.min(keepdims=True) # alias of jt.min(c, keepdims=True)

如果您想知道Jittor支持的所有运算,可以运行help(jt.ops)。 您在jt.ops.xxx中找到的所有运算都可以通过别名jt.xxx

help(jt.ops)
# Output:
#   abs(x: core.Var) -> core.Var
#   add(x: core.Var, y: core.Var) -> core.Var
#   array(data: array) -> core.Var
#   binary(x: core.Var, y: core.Var, op: str) -> core.Var
#   ......

更多教程

如果您想进一步了解Jittor,请查看以下教程:

贡献

Jittor还很年轻。它可能存在错误和问题。请在我们的错误跟踪系统中报告它们。我们欢迎您为Jittor做出贡献。此外,如果您对Jittor有任何想法,请告诉我们,Email:jittor@qq.com。

版权声明

如LICENSE.txt文件中所示,Jittor使用Apache 2.0版权协议。

Search

    Table of Contents