Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caffe2带来的变长序列表示方法的讨论 #3391

Closed
Superjomn opened this issue Aug 10, 2017 · 0 comments
Closed

Caffe2带来的变长序列表示方法的讨论 #3391

Superjomn opened this issue Aug 10, 2017 · 0 comments

Comments

@Superjomn
Copy link
Contributor

Superjomn commented Aug 10, 2017

参考了下 Caffe2 里序列的实现,和 @reyoung @qingqing01 @hedaoyuan 讨论后,觉得 LODTensor 拆成两个 Variable 传入会让框架实现更简单。

LODTensor 及周边设计现状

LODTensor的实现思路借鉴了PaddlePaddle v2 里的 Argument
尝试在原有 Tensor 里添加一些 member及 member function 来支持 LOD 相关的操作。

为了实现 RNNOp -> FCOp -> RNNOp 调用过程中,LOD 的传递问题,
目前在做的是,提供类似 CloneType 的方式来推导outputs的类型,并对不感知LOD的Op保持透明。

这个思路需要继续处理下面问题:

  • Variable CloneType 对继承时的处理(类似类型推导的一部分逻辑)
    • 可能需要一个基于 type_info 的继承关系的记录
    • 类似 REGISTER_INHERIENCE(child_type, father_type) 的接口

对现有框架需要的修改:

  • 每个Op需要在InferShape前,显式调用 output_x->CloneType(input_x) 的接口,来自动推导output的类型

caffe2 对类似结构的表示方法

在查看 Caffe2 中的实现方法时,
发现Caffe2里只有一种Tensor实现,所有其他结构的信息都是通过多个Tensor组合来实现。

其中,类似LOD的一种表示在 https://caffe2.ai/docs/sparse-operations.html#null__more-complex-examples , 部分代码如下

# Assume feature types are defined somewhere as enum {PAGE_ID=1, APP_ID=2, POST_ID=3}
ex1 = {1: {10, 11}, 3: {101}}
ex2 = {1: {11}, 2: {50}, 3: {102, 103}}
batch = {ex1, ex2}# values with lengths
values          = [10, 11, 101, 11, 50, 102, 103]
#                  \____/  \_/  \_/ \_/ \______/
values_lengths  = [   2,    1,   1,  1,    2]
keys            = [   1,    3,   1,  2,    3]
#                  \_________/  \__________/
example_lengths = [     2,            3]

可以当成3层变长sequence 的表示。

Caffe2里非Tensor的表示都是Tensor + 额外的Variable表示id信息的方式给入,比如
SparseLengthsWeightedSum

输入有4个,如下

DATA Input tensor for the summation
SCALARS Scalar multipliers for the input slices. Must be a vector with the length matching the first dimension of DATA
INDICES Integer vector containing indices of the first dimension of DATA for the slices that are being aggregated
LENGTHS Non negative vector with sum of elements equal to INDICES length

其中, INDICESLENGTHS 是与表示方式相关的额外内容。

Caffe2 如此设计的好处:

  • simple && rubust;每个Op在实现时都有明确的参数,所有的信息通过Inputs输入,无需隐含推导类型及其他信息
    • 节约了开发量
  • 不需要的信息,不会参与传递:比如 AddOp 不需要LOD的信息,则inputs里无需传入;RNNOp 需要LOD,则在inputs里传入
  • 避免Tensor类型无限增加的情况;目前PaddlePaddle v2 里Matrix使用了类似LODTensor的设计,光CPU就有8种Matrix实现

缺点:

  • 用户需要显式传递类似序列的信息,比如会有如下代码
data, seqinfo = DataProvider(xxx)
rnn_out, rnn_seqinfo = RNN(rnn_in, seqinfo)
fc_out = fc(rnn_in)
# passin the latest sequence info.
rnn_out, rnn_seqinfo1 = RNN(fc_out, rnn_seqinfo)

一种简单但相对有扩展性的方案

Caffe2的设计的确有其简单可依赖的特点,让Op及Tensor数据类型的实现更加明确,如果用这样的想法来做LODTensor接下来的工作:

  • LOD 会作为一个单独的Variable,作为明确参数传入给需要解析LOD信息的Op中
  • LODTenor 现有一些重要的method拆分成独立的helper function 提供给感知LOD的Op使用
  • 可以在python的底层API里加入LOD的自动传递,来降低用户对序列等信息的感知

衍生的好处:

  • 框架逻辑更简单,Tensor类型很简单,无需类型的Clone/Deduce
  • 框架无需大的修改,核心代码无需引入新的模块或逻辑
  • 暂时无需添加新的Tensor类型,每个Op的inputs里包含的信息类型更明确
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant