Oneflow-Inc / oneflow

OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.
http://www.oneflow.org
Apache License 2.0
5.86k stars 662 forks source link

OneFlow 算子对齐 PyTorch 完备计划推进表 #4936

Closed doombeaker closed 2 years ago

doombeaker commented 3 years ago

背景

本 issue 主贴(此贴)记录分工和对应的 PR,方便跟进。

解决的时间节点

Hard难度的应该在0.7.0版本之前解决,Medium应该在0.6.0版本之前完全解决,Easy难度的应该在分配当周或者下周进行解决。

相关文档

负责人

@BBuf

任务分工表

https://github.com/Oneflow-Inc/oneflow/issues/6156

chengtbf commented 3 years ago

0.4.0 发布后,后续预计在 6.21 左右发布 0.5.0, 由 @doombeaker 列出来其中的属于 0.5.0 的 TODO,发一个新的issue,新的issue只用来最终生成 0.5.0 的 release note,不需要记录哪个算子是谁开发的、谁 review、和什么时候合并的这些细节。

BBuf commented 3 years ago

第一阶段搬运的Module

OneFlow

对齐目标 现有算子 认领人 reviewer PR 备注
torch.abs(torch.absolute) oneflow.math.abs 王宏升 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/4952
torch.acosh oneflow.math.acosh 黎晨阳 姚迟 https://github.com/Oneflow-Inc/oneflow/pull/4987
/ oneflow.math.add_n
torch.asin oneflow.math.asin 陈岱渊 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4955
torch.asinh oneflow.math.asinh 陈岱渊 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4955
torch.atan oneflow.math.atan 张子涵 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4956
torch.atan2 oneflow.math.atan2 应志文 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/4991
torch.atanh oneflow.math.atanh 王一张 姚迟 https://github.com/Oneflow-Inc/oneflow/pull/4960
torch.ceil oneflow.math.ceil 杨羿 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4953
torch.clamp(torch.clip) oneflow.math.clip_by_value 钟昊文 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4946
torch.cosh oneflow.math.cosh 石永涛 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/4943
torch.erf oneflow.math.erf 陆陈昊 梁德澎 https://github.com/Oneflow-Inc/oneflow/pull/4954
torch.erfc oneflow.math.erfc 陆陈昊 梁德澎
torch.expm1 oneflow.math.expm1 杨羿 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4953
torch.floor oneflow.math.floor 徐嘉梁 梁德澎 https://github.com/Oneflow-Inc/oneflow/pull/4964
/ oneflow.math.floordiv 俞再亮 梁德澎
torch.topk oneflow.math.top_k 黄振华 梁德澎 #4963
torch.floor oneflow.math.floor 叶娇娇 梁德澎
torch.as_tensor oneflow.Tensor构造 陈岱渊
torch.from_numpy oneflow.tensor支持从Numpy构造
torch.linspace 参考oneflow.arange module可以做到
torch.logspace 参考oneflow.arange module可以做到
torch.index_select oneflow.gather_nd间接做到
torch.movedim 通过oneflow.transpose间接做到
oneflow.reshape_like
oneflow.dynamic_reshape 这个不用搬
oneflow.slice_v2
oneflow.slice_update
oneflow.experimental.logical_slice
oneflow.experimental.logical_slice_assign
oneflow.reverse
oneflow.gather_nd
oneflow.scatter_nd
oneflow.tensor_scatter_nd_update
oneflow.tensor_scatter_nd_add
oneflow.nonzero
oneflow.elem_cnt
oneflow.sync_dynamic_resize
oneflow.stack
oneflow.random.generate_random_batch_permutation_indices
oneflow.random.shuffle
oneflow.identity_n
oneflow.cast_to_static_shape
oneflow.expand_dims
oneflow.broadcast_like
oneflow.amp_white_identity
oneflow.profiler.nvtx_start
oneflow.profiler.nvtx_end
oneflow.assign
oneflow.system.assign
oneflow.experimental.eager_assign_121
oneflow.categorical_ordinal_encode
oneflow.layers.categorical_ordinal_encoder
oneflow.combined_margin_loss
oneflow.count_not_finite
oneflow.multi_count_not_finite
oneflow.diag
oneflow.nn.fused_self_attention_query_mul_key_and_value
oneflow.eager_nccl_all_reduce
oneflow.linalg.matmul
oneflow.smooth_l1_loss
oneflow.ctc_loss
oneflow.math.floordiv
oneflow.math.xlogy
oneflow.math.add_n
oneflow.math.mod
oneflow.math.unsorted_segment_sum
oneflow.math.unsorted_segment_sum
oneflow.math.unsorted_segment_sum_like
oneflow.math.unsorted_segment_sum_like
oneflow.math.unsorted_batch_segment_sum
oneflow.math.unsorted_batch_segment_sum
oneflow.math.logical_and
oneflow.math.reduced_shape_elem_cnt
oneflow.math.broadcast_to_compatible_with
oneflow.math.l2_normalize
oneflow.math.squared_difference
oneflow.math.tril
oneflow.math.fused_scale_tril
oneflow.math.fused_scale_tril_softmax_dropout
oneflow.math.polyval
oneflow.math.in_top_k
Flowingsun007 commented 3 years ago

1. 待搬运module/op

对齐目标 现有算子 认领人 reviewer PR 备注
nn.Conv1d nn.conv1d
nn.Conv3d nn.conv3d
nn.GroupNorm nn.GroupNorm
nn.InstanceNorm1d nn.InstanceNorm1d
nn.InstanceNorm2d nn.InstanceNorm2d
nn.InstanceNorm3d nn.InstanceNorm3d
nn.MaxPool1d nn.max_pool1d
nn.MaxPool2d nn.max_pool3d
nn.AvgPool1d nn.avg_pool1d
nn.AvgPool3d nn.avg_pool3d
nn.L1Loss nn.L1Loss
nn.BCELos nn.BCELoss
nn.MSELoss nn.MSELoss
nn.BCEWithLogitsLoss nn.BCEWithLogitsLoss
nn.MarginRankingLoss nn.MarginRankingLoss
nn.TripletMarginLos nn.TripletMarginLoss
nn.PixelShuffle nn.PixelShuffle
nn.KLDivLoss nn.KLDivLoss
torch.one_hot one_hot
torch.pad pad
nn.ReflectionPad2d reflection_pad2d
nn.ReplicationPad2d replication_pad2d
nn.ConstantPad2d constant_pad2d
nn.ZeroPad2d zero_pad2d
torch.bernoulli random.bernoulli
torch.random.seed random.gen_seed
torch.any math.reduce_any
torch.min math.reduce_min
torch.max math.reduce_max
torch.prod math.reduce_prod
torch.all math.reduce_all
torch.logsumexp math.reduce_logsumexp
torch.sort sort
torch.argsort argsort

2.其他op(torch没有类似实现/有类似实现但不同命名)

nn.moments bias_add nn.compat_conv2d nn.fused_bias_add_gelu nn.fused_bias_add_dropout nn.softmax_grad nn.sparse_cross_entropy nn.softmax_cross_entropy_with_logits nn.sparse_softmax_cross_entropy_with_logits nn.distributed_sparse_softmax_cross_entropy_with_logits nn.sigmoid_cross_entropy_with_logits nn.random_mask_like nn.conv2d_transpose nn.torch_conv2d_transpose nn.mish nn.swish nn.PixelShufflev2 pad_grad same_padding distributed_partial_fc_sample math.two_stage_reduce_max math.two_stage_reduce_min math.reduce_euclidean_norm

optimizer.SGDW optimizer.LARS optimizer.LazyAdam optimizer.LAMB optimizer.CombinedOptimizer optimizer.grad_clipping.by_global_norm optimizer.warmup.constant optimizer.warmup.linear optimizer.CustomScheduler optimizer.PiecewiseConstantScheduler optimizer.PiecewiseScalingScheduler optimizer.PolynomialScheduler optimizer.PolynomialSchduler optimizer.LinearCosineScheduler optimizer.ExponentialScheduler optimizer.InverseTimeScheduler optimizer.NaturalExpScheduler optimizer.loss_scale.static_loss_scale optimizer.loss_scale.dynamic_loss_scale

quantization.min_max_observer quantization.moving_average_min_max_observer quantization.fake_quantization

regularizers.l1_l2 regularizers.l1 regularizers.l2

summary.scalar summary.create_summary_writer summary.flush_summary_writer summary.histogram summary.pb summary.image

gen_tensor_buffer tensor_buffer_to_tensor tensor_to_tensor_buffer tensor_buffer_to_list_of_tensors

data.OFRecordRawDecoder data.OFRecordBytesDecoder data.OFRecordImageDecoderRandomCrop data.OFRecordImageDecoder data.coco_reader data.ofrecord_image_classification_readerd data.OneRecDecoder data.megatron_gpt_mmap_data_loader

image.resize image.target_resize image.image.CropMirrorNormalize image.random_crop image.decode image.batch_align iamge.normalize image.flip random.CoinFlip detection.object_bbox_flip detection.object_bbox_scale detection.object_segmentation_polygon_flip detection.object_segmentation_polygon_scale detection.object_segmentation_polygon_to_mask

doombeaker commented 3 years ago

备份(从这个表里筛选出每周的计划)

对齐目标 现有算子 认领人 reviewer PR 备注
torch.subtract torch.sub flow.sub 姚迟 https://github.com/Oneflow-Inc/oneflow/pull/4993 已搬,需完善 doctest 和 testcase
torch.arcsinh flow.arcsinh 陈岱渊 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4955 merged
torch.clamp(torch.clip) oneflow.math.clip_by_value 钟昊文 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/4946 merged
/ oneflow.math.floordiv 俞再亮 梁德澎
torch.topk oneflow.math.top_k(需要重写kernel) 黄振华 梁德澎 #4963
torch.floor oneflow.math.floor 叶娇娇 梁德澎 https://github.com/Oneflow-Inc/oneflow/pull/4995
torch.as_tensor oneflow.Tensor构造
torch.from_numpy oneflow.tensor支持从Numpy构造
torch.linspace 参考oneflow.arange module可以做到
torch.logspace 参考oneflow.arange module可以做到
torch.index_select oneflow.gather_nd间接做到
torch.movedim 通过oneflow.transpose间接做到 这个不用搬
torch.subtract flow.sub 徐芬 姚迟 https://github.com/Oneflow-Inc/oneflow/pull/4993
oneflow.reshape_like
oneflow.dynamic_reshape
oneflow.slice_v2
oneflow.slice_update
oneflow.experimental.logical_slice
oneflow.experimental.logical_slice_assign
oneflow.reverse
oneflow.gather_nd
oneflow.scatter_nd
oneflow.tensor_scatter_nd_update
oneflow.tensor_scatter_nd_add
oneflow.nonzero
torch.numel(torch.Tensor.nelement) oneflow.elem_cnt 钟昊文
oneflow.sync_dynamic_resize
oneflow.stack 陈岱渊
oneflow.random.generate_random_batch_permutation_indices
oneflow.random.shuffle
oneflow.identity_n
oneflow.cast_to_static_shape
oneflow.expand_dims
oneflow.broadcast_like
oneflow.amp_white_identity
oneflow.profiler.nvtx_start
oneflow.profiler.nvtx_end
oneflow.assign
oneflow.system.assign
oneflow.experimental.eager_assign_121
oneflow.categorical_ordinal_encode
oneflow.layers.categorical_ordinal_encoder
oneflow.combined_margin_loss
oneflow.count_not_finite
oneflow.multi_count_not_finite
oneflow.diag 唐娜娜
oneflow.nn.fused_self_attention_query_mul_key_and_value
oneflow.eager_nccl_all_reduce
oneflow.linalg.matmul
oneflow.smooth_l1_loss 叶娇娇 https://github.com/Oneflow-Inc/oneflow/pull/5256
oneflow.ctc_loss
oneflow.math.xlogy
oneflow.math.add_n
oneflow.math.mod
oneflow.math.unsorted_segment_sum
oneflow.math.unsorted_segment_sum
oneflow.math.unsorted_segment_sum_like
oneflow.math.unsorted_segment_sum_like
oneflow.math.unsorted_batch_segment_sum
oneflow.math.unsorted_batch_segment_sum
oneflow.math.logical_and
oneflow.math.reduced_shape_elem_cnt
oneflow.math.broadcast_to_compatible_with
oneflow.math.l2_normalize
oneflow.math.squared_difference
oneflow.math.tril
oneflow.math.fused_scale_tril
oneflow.math.fused_scale_tril_softmax_dropout
oneflow.math.polyval
oneflow.math.in_top_k
nn.Conv1d nn.conv1d 杨羿
nn.Conv3d nn.conv3d 吴方闻
nn.GroupNorm nn.GroupNorm
nn.InstanceNorm1d nn.InstanceNorm1d 杜承垚 https://github.com/Oneflow-Inc/oneflow/pull/5131 merged
nn.InstanceNorm2d nn.InstanceNorm2d 杜承垚 https://github.com/Oneflow-Inc/oneflow/pull/5131 merged
nn.InstanceNorm3d nn.InstanceNorm3d 杜承垚 https://github.com/Oneflow-Inc/oneflow/pull/5131 merged
nn.MaxPool1d nn.max_pool1d 石永涛 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/5021 C++反向描述已完成并merge,python接口未实现(cudnn bug)
nn.MaxPool3d nn.max_pool3d 石永涛 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/5021 merged
nn.AvgPool1d nn.avg_pool1d 应志文 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/5165 merge,python接口未实现(cudnn bug)
nn.AvgPool3d nn.avg_pool3d 应志文 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/5165 merged
nn.L1Loss nn.L1Loss 王宏升 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/5084
nn.Smooth_L1_Loss nn.Smooth_L1_Loss 王宏升 赵露阳
nn.BCELos nn.BCELoss 王宏升 赵露阳
nn.MSELoss nn.MSELoss 石永涛 张晓雨 https://github.com/Oneflow-Inc/oneflow/pull/5116 merged
nn.BCEWithLogitsLoss nn.BCEWithLogitsLoss 叶娇娇 https://github.com/Oneflow-Inc/oneflow/pull/5173
nn.MarginRankingLoss nn.MarginRankingLoss 钟昊文
nn.TripletMarginLos nn.TripletMarginLoss 钟昊文
nn.PixelShuffle nn.PixelShuffle 石永涛 merged
nn.KLDivLoss nn.KLDivLoss 石永涛 赵露阳 https://github.com/Oneflow-Inc/oneflow/pull/5155 merged
torch.one_hot one_hot 钟昊文
torch.pad pad 叶娇娇
nn.ReflectionPad2d reflection_pad2d 吴方闻 #5172 merged
nn.ReplicationPad2d replication_pad2d
nn.ConstantPad2d constant_pad2d 陈岱渊
nn.ZeroPad2d zero_pad2d
torch.bernoulli random.bernoulli
torch.random.seed random.gen_seed
torch.any math.reduce_any 王宏升
torch.min math.reduce_min 黄振华 #5022
torch.max math.reduce_max 黄振华 #5022
torch.prod math.reduce_prod 黄振华 #5022
torch.all math.reduce_all 王宏升
torch.logsumexp math.reduce_logsumexp
torch.sort sort
torch.argsort argsort

nn.moments bias_add nn.compat_conv2d nn.fused_bias_add_gelu nn.fused_bias_add_dropout nn.softmax_grad nn.sparse_cross_entropy nn.softmax_cross_entropy_with_logits nn.sparse_softmax_cross_entropy_with_logits nn.distributed_sparse_softmax_cross_entropy_with_logits nn.sigmoid_cross_entropy_with_logits nn.random_mask_like nn.conv2d_transpose nn.torch_conv2d_transpose nn.mish nn.swish nn.PixelShufflev2 pad_grad same_padding distributed_partial_fc_sample math.two_stage_reduce_max math.two_stage_reduce_min math.reduce_euclidean_norm

optimizer.SGDW optimizer.LARS optimizer.LazyAdam optimizer.LAMB optimizer.CombinedOptimizer optimizer.grad_clipping.by_global_norm optimizer.warmup.constant optimizer.warmup.linear optimizer.CustomScheduler optimizer.PiecewiseConstantScheduler optimizer.PiecewiseScalingScheduler optimizer.PolynomialScheduler optimizer.PolynomialSchduler optimizer.LinearCosineScheduler optimizer.ExponentialScheduler optimizer.InverseTimeScheduler optimizer.NaturalExpScheduler optimizer.loss_scale.static_loss_scale optimizer.loss_scale.dynamic_loss_scale

quantization.min_max_observer quantization.moving_average_min_max_observer quantization.fake_quantization

regularizers.l1_l2 regularizers.l1 regularizers.l2

summary.scalar summary.create_summary_writer summary.flush_summary_writer summary.histogram summary.pb summary.image

gen_tensor_buffer tensor_buffer_to_tensor tensor_to_tensor_buffer tensor_buffer_to_list_of_tensors

data.OFRecordRawDecoder data.OFRecordBytesDecoder data.OFRecordImageDecoderRandomCrop data.OFRecordImageDecoder data.coco_reader data.ofrecord_image_classification_readerd data.OneRecDecoder data.megatron_gpt_mmap_data_loader

image.resize image.target_resize image.image.CropMirrorNormalize image.random_crop image.decode image.batch_align iamge.normalize image.flip random.CoinFlip detection.object_bbox_flip detection.object_bbox_scale detection.object_segmentation_polygon_flip detection.object_segmentation_polygon_scale detection.object_segmentation_polygon_to_mask

doombeaker commented 3 years ago

doctest 指南

什么是 doctest

doctest 是一个 Python 的标准包,它使得程序运行时,会把写在 docstring 里的特定格式的字符串,当作 Python 代码执行一遍,并且做校验。

简单而言,有了 doctest,我们就可以把测试代码写在 docstring 中,一举两得。

怎么用 doctest

分两步:

简单的例子

def myadd(x, y):
    """
        returns x + y

    Exmaple:
    >>> x = 5
    >>> y = 6
    >>> myadd(x, y)
    11
    """
    return x + y

if __name__ == "__main__":
    import doctest
    doctest.testmod()

以上注意要点:

输出字符串匹配

def myfun(a):
    """
    Example:

    >>> myfun(100) #doctest: +ELLIPSIS
    [0, 1, 2, ..., 99]
    """
    print(list(range(0,a)))

if __name__ == "__main__":
    import doctest
    doctest.testmod()

以上的例子中,使用了 #doctest: +ELLIPSIS,有了这个 flag,在 docstring 中的下一行的“期待输出中”, ... 可以匹配测试时输出的任意字符串。

这对于有内存地址的情况,比较有用。

给 OneFlow 的 Module 添加 doctest

class LeakyReLU(Module):
    r"""Applies the element-wise function:

    .. math::
        \text{LeakyReLU}(x) = \max(0, x) + \text{negative_slope} * \min(0, x)

    or 

    .. math::
        \text{LeakyRELU}(x) = \begin{cases}
            x, & \text{ if } x \geq 0 \\
            \text{negative_slope} \times x, & \text{ otherwise }
        \end{cases}

    Args:
        negative_slope: Controls the angle of the negative slope. Default: 1e-2
        inplace: can optionally do the operation in-place. Default: ``False``

    Shape:
        - Input: :math:`(N, *)` where `*` means, any number of additional
          dimensions
        - Output: :math:`(N, *)`, same shape as the input

    For example: 

    .. code-block:: python

        >>> import oneflow.experimental as flow
        >>> import numpy as np
        >>> flow.enable_eager_execution()
        >>> m = flow.nn.LeakyReLU(0.1)
        >>> input = flow.Tensor(np.array([1, 2]))
        >>> output = m(input)
        >>> output.shape
        flow.Size([2])
    """
    pass

要求

BBuf commented 3 years ago

添加后向算子指南

0x0. 介绍

目前一些Module的后向复用的仍然是User OP中注册的后向,在OneFlow的0.4.0以及以后的版本中,Module的后向将统一放在oneflow/core/autograd/gradient_funcs 这个文件夹中,这里已经实现了不少Module的后向,比如BatchGather,Concat,PReLU,Reshape等等。

新版OneFlow Module后向示例

之前大家搬运的Module只考虑了前向,如果backward的测试可以正常运行原因可能是你实现的Module的后向在这里已经有了,或者是复用了静态图User OP的后向。但当你的Module有动态属性,或者注册后向的User OP是由多个OP拼成的,这个时候测试Module的Backwad可能就会挂掉,我们必须对这些Module重写后向注册代码。(现在是要对所有Module都重写后向,即使Module的Backward可以正常运行,但它的后向没有在gradient_funcs中重写,那么我们就需要为其添加C++后向代码实现

0x1. 以Transpose为例来新增一个后向算子

下面我们以Transpose Module为例,来一步步为其添加C++后向代码实现。

一,首先明确Transpose Module的前向使用的是哪个User OP?

oneflow/python/nn/modules/transpose.py中我们可以发现Transpose Module的构建使用的是transpose这个User OP,那么我们找到transpose这个User OP的梯度注册代码把它迁移到gradient_funcs中就可以了。注意,如果这个Module是由多个Module或者User OP拼出来的,那么我们需要确认这些小的Module或者User OP是否后向都已经在gradient_funcs中实现了,如果没有那么需要为这些小OP继续添加后向C++代码实现。

还需要说明的一点是,某一些OP不需要注册反向,比如greaterlesssargwhere等,记得及时避开。

二,基于User OP的梯度注册代码提取梯度Op

我们先定位到oneflow/user/ops/transpose_ops.cppREGISTER_USER_OP_GRAD("transpose")函数,这个函数就是为transpose 这个User OP添加后向的,我们需要做的事情就是把这个函数迁移到gradient_funcs

这里我们需要关注这个梯度注册的代码中具体使用了哪些Op,比如transpose这个User OP的梯度注册代码中使用到的也是transpose这个OP,这个也是期望中的,只不过它的perm属性参数和前向传入的perm是一个置换关系。我们现在需要将transpose这个求梯度的User Op写到oneflow/core/framework/op_expr_grad_function.honeflow/core/framework/op_expr_grad_function.cpp中,这样就可以将这些求梯度的Op统一定义到一个文件,方便我们查看以及管理。

三,在gradient_funcs中实现梯度注册的具体逻辑

oneflow/core/autograd/gradient_funcs新建transpose.cpp来为transpose这个Module添加反向,首先需要定义一个继承了OpExprInterpStateTransposeInterpState类来记录transpose这个Module的属性参数以及对应输入的梯度信息。

并且这个类由于继承了OpExprInterpState,也拥有了它的SaveTensorForBackward方法,可以保存这个Module的输入Tensor,因为某些Module的反向是必须要知道输入Tensor的信息才可以完成反向计算的。

接下来,我们定义一个Transpose类,继承OpExprGradFunction这个模板类,模板参数即为我们刚才定义好的TransposeInterpState。我们只需要复写这三个类中的三个成员函数即可:

class Transpose : public OpExprGradFunction<TransposeInterpState> {
 public:
  Maybe<void> Init(const OpExpr& op) override;
  Maybe<void> Capture(TransposeInterpState* ctx, const TensorTuple& inputs,
                      const TensorTuple& outputs, const AttrMap& attrs) const override;
  Maybe<void> Apply(const TransposeInterpState* ctx, const TensorTuple& out_grads,
                    TensorTuple* in_grads) const override;

 private:
  AttrMap base_attrs_;
  std::shared_ptr<OpExpr> grad_op_;
};

其中Init用来初始化反向过程中需要用到的Op,比如这里的grad_op_ = JUST(op_expr_helper::TransposeOp(*/\*perm=\*/*perm, GradientOpName(op_name)));就预定义好了反向需要用到的梯度Op。

Capture用来捕获反向Op执行时需要的信息,不仅包含Attr相关的参数信息,也包含我们上面提到的必要的输入Tensor,当前这个Transpose的反向由于不需要知道输入Tensor,所以这里没有捕获输入Tensor。

Apply用来完成真正的反向计算。主要就是通过Apply捕获的Attr参数信息和输入Tensor,以及Module前向的输出Tensor,调用Init预定义的Op来获得结果。

0x2. 重新编译源码

完成在oneflow/core/autograd/gradient_funcs中实现反向的C++代码后,我们需要重新编译OneFlow源码,这样这个Op的反向才会生效。运行:

cmake .. && make -jx
yayeoCddy commented 3 years ago

所有的GAN相关训练都需要基于torch.Tensor.detach 这个算子(目前是@liyurui 在修)

图像生成/超分任务Pix2pix, DCGAN, SRGAN模型需要迁移以下算子: pytorch oneflow待搬运 备注 认领人
torch.Tensor.detach 目前是@liyurui 在搬
torch.nn.ConvTranspose2d flow.nn.conv2d_transpose 不太清楚oneflow原本这两个反卷积的区别 目前是@zhangxiaoyu在搬
flow.nn.torch_conv2d_transpose
flow.nn.bias_add 动态图中是否还需要?
flow.nn.sigmoid_cross_entropy_with_logits 算法层面可拼,pytorch没有对应算子,有无搬运必要?
torch.pad/torch.nn.ConstantPad2d flow.pad/flow.nn.ConstantPad2d 原本没有对齐,如果复杂可以考虑先搬flow.constant_pad2d 陈岱渊
nn.MSELoss flow.math.squared_difference flow是否可以拼?有无搬运必要?
BBuf commented 3 years ago

另外之江最近添加的静态图版本里面的math.xxx的module,在review的时候必须要求把实现和测试放到math_ops.py和test_math_ops.py里面。如果已经合并进主分支了,需要重新调整一下位置。

测试的过程中一定要注意多遍历测试边界,及时报告BUG。

@BBuf 和 @Flowingsun007 已完成。

puchapu commented 3 years ago
ReID 算法所需算子 pytorch oneflow待搬运 备注 认领人
torch.expand
torch.addmm 通过 flow.multipy 和 flow.add 拼 钟昊文
torch.nn.functional.one_hot flow.one_hot 钟昊文
torch.nn.marginrankingloss 可以 python 端拼 钟昊文
torch.max/min flow.math.reduce_max/sum 黄振华,在做
flow.tripletloss 可以 python 端拼 钟昊文
flow.train.CheckPoint
flow.optimizer.PiecewiseScalingScheduler
flow.optimizer.warmup.linear
hengzi commented 3 years ago
  • test_add.py 反向测试边界不够多,需要补充。
  • test_avgpool2d.py 需要重构测试,numpy实现,并且添加反向测试,这个最好删除放到test_pooling里面去。(BBuf)
  • test_batchnorm.py 需要重构测试。
  • test_broadcast_like.py np.allclose精度范围没指定。
  • test_cast.py 需要重构测试,并添加反向测试代码。
  • test_constant.py 需要重构重试,并添加反向测试代码。
  • test_conv.py 需要重构重试,并添加反向测试代码。
  • test_flatten.py 需要重构测试,并添加反向测试代码。
  • test_gather.py 需要重构测试,并添加反向测试代码。
  • test_masked_fill.py 需要重构测试,并添加反向测试代码。
  • test_math_ops.py 大多数Module都需要重构,并添加反向测试代码。
  • test_mean.py 是不是可以放到test_math_ops.py里面,并且需要重构,并添加反向测试代码。
  • test_module_to.py 需要重构。
  • test_mul.py 需要重构,并添加反向测试代码。
  • test_normalization.py 需要重构,并添加反向测试代码。(Luyang)
  • test_ones_like.py 需要重构,并添加反向测试代码。
  • test_pooling.py 需要重构,并添加反向测试代码。
  • test_reciprocal.py 需要重构,并添加反向测试代码。
  • test_slice.py 需要重构,并添加反向测试代码。(Luyang)
  • test_sparse.py 需要重构,并添加反向测试代码。
  • test_sub.py 需要重构,并添加反向测试代码。
  • test_sum.py 需要重构,并添加反向测试代码。
  • test_to.py 需要重构,并添加反向测试代码,建议改名为test_tensor_to.py。

另外之江最近添加的静态图版本里面的math.xxx的module,在review的时候必须要求把实现和测试放到math_ops.py和test_math_ops.py里面。如果已经合并进主分支了,需要重新调整一下位置。

测试的过程中一定要注意多遍历测试边界,及时报告BUG。

sum,mean,max, min 等几个reduce 相关的重构我已经在做了,统一放在了*_reduce_ops.py文件 #5022

YongtaoShi commented 3 years ago
  • test_add.py 反向测试边界不够多,需要补充。
  • test_avgpool2d.py 需要重构测试,numpy实现,并且添加反向测试,这个最好删除放到test_pooling里面去。(BBuf)
  • test_batchnorm.py 需要重构测试。
  • test_broadcast_like.py np.allclose精度范围没指定。
  • test_cast.py 需要重构测试,并添加反向测试代码。
  • test_constant.py 需要重构重试,并添加反向测试代码。
  • test_conv.py 需要重构重试,并添加反向测试代码。
  • test_flatten.py 需要重构测试,并添加反向测试代码。
  • test_gather.py 需要重构测试,并添加反向测试代码。
  • test_masked_fill.py 需要重构测试,并添加反向测试代码。
  • test_math_ops.py 大多数Module都需要重构,并添加反向测试代码。
  • test_mean.py 是不是可以放到test_math_ops.py里面,并且需要重构,并添加反向测试代码。
  • test_module_to.py 需要重构。
  • test_mul.py 需要重构,并添加反向测试代码。
  • test_normalization.py 需要重构,并添加反向测试代码。(Luyang)
  • test_ones_like.py 需要重构,并添加反向测试代码。
  • test_pooling.py 需要重构,并添加反向测试代码。
  • test_reciprocal.py 需要重构,并添加反向测试代码。
  • test_slice.py 需要重构,并添加反向测试代码。(Luyang)
  • test_sparse.py 需要重构,并添加反向测试代码。
  • test_sub.py 需要重构,并添加反向测试代码。
  • test_sum.py 需要重构,并添加反向测试代码。
  • test_to.py 需要重构,并添加反向测试代码,建议改名为test_tensor_to.py。

另外之江最近添加的静态图版本里面的math.xxx的module,在review的时候必须要求把实现和测试放到math_ops.py和test_math_ops.py里面。如果已经合并进主分支了,需要重新调整一下位置。

测试的过程中一定要注意多遍历测试边界,及时报告BUG。

test_pooling.py里面现在只有maxpool的代码,所以我改成test_maxpool.py了 https://github.com/Oneflow-Inc/oneflow/pull/5021 。后面需要的话可以改回来。

doombeaker commented 3 years ago

讨论:算子搬不搬

以下是 6月30 日讨论后,确认暂时不搬运的:

PyTorch OneFlow中已有算子 是否搬运 备注
nn.functional.cross_entropy nn.functional.binary_cross_entropy nn.sparse_cross_entropy nn.softmax_cross_entropy_with_logits nn.sparse_softmax_cross_entropy_with_logits nn.distributed_sparse_softmax_cross_entropy_with_logits nn.sigmoid_cross_entropy_with_logits 看情况 其中的 sparse_softmax_cross_entropy_with_logits 已经封装为 oneflow.experimental.nn.CrossEntropyLoss。其它的几个,需要和原作者郭冉对照,和 PyTorch 对齐搬运。部分是内部调用用于性能优化的,就需要导出为用户接口了
oneflow.sync_dynamic_resize 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.tensor_scatter_nd_update 与 PyTorch 对齐,这种 tf 的接口不需要搬运
oneflow.tensor_scatter_nd_add 与 PyTorch 对齐,这种 tf 的接口不需要搬运
oneflow.random.shuffle
oneflow.identity OneFlow 原有的 identity 应该是静态图中常用,动态图几乎用不到(?)。PyTorch 中有 torch.nn.Identity 类(已经搬运),接口和 oneflow.identity 不大一样,如果要实现 PyTorch 版本,很可能需要重写 userop
oneflow.identity_n 这个内部优化时调用,不应该导出给用户
oneflow.expand_dims PyTorch 中有 unsqueeze ,OneFlow 已经对齐 unsqueeze
oneflow.math.unsorted_segment_sum PyTorch 中使用 torch.index_add 实现类似功能。暂时不搬,除非搭模型遇到了
oneflow.math.reduced_shape_elem_cnt 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.math.squared_difference 计算差的平方,用减法和pow拼就可以。
oneflow.math.fused_scale_tril 可以搬运,但是不用导出给用户使用
oneflow.math.polyval 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.nn.moments 这个算子只是同时计算平均值和标准差。这在 PyTorch 的接口里,可以直接用低级基础的运算符拼接而成
oneflow.bias_add PyTorch 中没有这个算子,动态图中对这个算子也没什么需要
oneflow.nn.fused_bias_add_gelu 可以搬运,但是不用导出给用户使用
oneflow.nn.fused_bias_add_dropout 可以搬运,但是不用导出给用户使用
oneflow.softmax_grad 可以根据需要搬运,但是没必要导出成用户接口
random_mask_like 可以用 ones + dropout 拼凑
conv2d_transpose 现有和 PyTorch 对齐的 conv2d_transpose 已经搬运,原有和 TensorFlow 对齐的 conv2d_transpose 可以舍弃
oneflow.pad_grad 这种算子本身在 OneFlow 中就不应该导出
oneflow.same_padding 感觉不用单独做一个算子,而是作为 padding 算子的一个参数存在
oneflow.math.unsorted_segment_sum_like PyTorch 中使用 torch.index_add 实现类似功能。暂时不搬,除非搭模型遇到了
oneflow.math.unsorted_batch_segment_sum PyTorch 中使用 torch.index_add 实现类似功能。暂时不搬,除非搭模型遇到了
doombeaker commented 3 years ago

全面过了一遍,从原有的 400+ 个 lazy API 中,筛选知道,还剩余以下算子(170+)还没有从 lazy 搬运到 eager。 其中值得搬运的在 50 个左右(考虑交给社区搬运)。

算子 是否搬运 备注
oneflow.broadcast_to_compatible_with
oneflow.categorical_ordinal_encode 可以有需要时再搬
oneflow.combined_margin_loss
oneflow.data.decode_ofrecord
oneflow.data.decode_random
oneflow.data.ImageCodec
oneflow.data.ImageDecoderRandomCropResize
oneflow.data.ImagePreprocessor
oneflow.data.ImageResizePreprocessor
oneflow.data.MegatronGPTMMapDataLoader
oneflow.data.NormByChannelPreprocessor
oneflow.data.ofrecord_image_classification_reader
oneflow.data.ofrecord_loader
oneflow.data.OFRecordBytesDecoder
oneflow.data.onerec_reader
oneflow.data.OneRecDecoder
oneflow.data.RawCodec
oneflow.diag
oneflow.gather_nd
oneflow.image_flip
oneflow.image_random_crop
oneflow.image_target_resize
oneflow.in_top_k
oneflow.nn.conv3d
oneflow.nn.ctc_greedy_decoder
oneflow.nn.dropout
oneflow.nn.leaky_relu
oneflow.nn.PixelShufflev2
oneflow.nn.TripletMarginLoss
oneflow.nonzero
oneflow.object_bbox_flip 王世杰认领
oneflow.object_bbox_scale 王世杰认领
oneflow.object_segmentation_polygon_flip 王世杰认领
oneflow.object_segmentation_polygon_scale 王世杰认领
oneflow.object_segmentation_polygon_to_mask 王世杰认领
oneflow.one_hot
oneflow.pad 需要和 torch.nn.functional.pad 对齐
oneflow.range
oneflow.reflection_pad2d 可以给社区人员搬运
oneflow.replication_pad2d 可以给社区人员搬运
oneflow.reverse 可以给社区人员搬运
oneflow.scatter_nd 和 gather_nd 配套
oneflow.smooth_l1_loss 可以给社区人员搬运,要写 functional
oneflow.to 不是简单的算子搬运,是对齐,好像还没做完
oneflow.acc acc是一个底层的算子,不是普通算子
oneflow.advanced.distribute_add advanced空间的算子与优化有关
oneflow.advanced.distribute_clone advanced空间的算子与优化有关
oneflow.advanced.distribute_concat advanced空间的算子与优化有关
oneflow.advanced.distribute_map advanced空间的算子与优化有关
oneflow.advanced.distribute_split advanced空间的算子与优化有关
oneflow.amp_white_identity 感觉是与底层优化有关的算子
oneflow.cast_to_current_logical_view 与OneFlow里的并行view有关
oneflow.cast_to_static_shape
oneflow.constant 动态图可以用numpy直接赋值
oneflow.constant_initializer 静态同用于修改 variable 才需要的
oneflow.constant_like 动态图可以用numpy直接赋值
oneflow.constant_scalar 动态图可以用numpy直接赋值
oneflow.count_not_finite 不需要导出给用户
oneflow.data.load_mnist 根据 tutorial 的需求重构,或者用已有的
oneflow.distributed_partial_fc_sample 和底层优化有关
oneflow.dynamic_reshape 动态图不需要,本身就是dynamic的
oneflow.eager_nccl_all_reduce 貌似不应该暴露给用户
oneflow.empty_initializer 静态同用于修改 variable 才需要的
oneflow.expand_dims 和 unsqeeuze 功能重复
oneflow.gather tf 的 gather 不好懂不好用
oneflow.get_all_variables 静态图有关
oneflow.get_job_set 静态图有关
oneflow.get_variable 静态图有关
oneflow.hierarchical_parallel_cast 底层并行有关
oneflow.identity 动态图用不上
oneflow.identity_n 动态图用不上
oneflow.indexed_slices_reduce_sum 貌似不应该暴露给用户
oneflow.layers.batch_normalization 暂时不搬,用户需要可以自己拼
oneflow.layers.batch_normalization_add_relu 暂时不搬,用户需要可以自己拼
oneflow.layers.batch_normalization_relu 暂时不搬,用户需要可以自己拼
oneflow.layers.categorical_ordinal_encoder 可以有需要时再搬
oneflow.layers.conv1d 暂时不搬,用户需要可以自己拼
oneflow.layers.conv2d 暂时不搬,用户需要可以自己拼
oneflow.layers.conv3d 暂时不搬,用户需要可以自己拼
oneflow.layers.dense 暂时不搬,用户需要可以自己拼
oneflow.layers.layer_norm 暂时不搬,用户需要可以自己拼
oneflow.layers.layer_norm_grad 暂时不搬,用户需要可以自己拼
oneflow.layers.layer_norm_param_grad 暂时不搬,用户需要可以自己拼
oneflow.layers.prelu 暂时不搬,用户需要可以自己拼
oneflow.layers.upsample_2d 插值再 PyTorch 里都放到 interpolate 里了
oneflow.logical_slice 貌似不应该暴露给用户
oneflow.logical_slice_assign 貌似不应该暴露给用户
oneflow.losses.add_loss PyTorch 风格的方式不这样写了
oneflow.manual_seed 没有docstring,搬运可能需要底层重构
oneflow.math.fused_scale_tril 和底层优化有关
oneflow.math.fused_scale_tril_softmax_dropout 和底层优化有关
oneflow.math.polyval 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.math.reduce_all reduce 逻辑 and,PyTorch里没有,未来有需要再搬运
oneflow.math.reduce_any reduce 逻辑 or,PyTorch里没有,未来有需要再搬运
oneflow.math.reduce_euclidean_norm 可以用oneflow.experimental.linalg.norm算子实现相同功能,默认ord=None为2范数,dim对应tf的axis
oneflow.math.reduce_logsumexp PyTorch里没有,未来有需要再搬运
oneflow.math.reduced_shape_elem_cnt 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.math.rint 和已经搬运的round重复了
oneflow.math.squared_difference 计算差的平方,用减法和pow拼就可以。
oneflow.math.two_stage_reduce_max 和底层优化有关
oneflow.math.two_stage_reduce_min 和底层优化有关
oneflow.math.xdivy 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.math.xlogy 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.nn.batch_normalization PyTorch里的是BatchNormxD,已经用另外的方法实现,未来有需要再搬运
oneflow.nn.bias_add PyTorch里没有,未来有需要再搬运
oneflow.nn.distributed_sparse_softmax_cross_entropy_with_logits 感觉是与底层优化有关的算子
oneflow.nn.fused_bias_add_dropout 感觉是与底层优化有关的算子
oneflow.nn.fused_bias_add_gelu 感觉是与底层优化有关的算子
oneflow.nn.fused_self_attention_query_mul_key_and_value 感觉是与底层优化有关的算子
oneflow.nn.init.calculate_gain
oneflow.nn.init.constant_
oneflow.nn.moments 这个算子只是同时计算平均值和标准差。这在 PyTorch 的接口里,可以直接用低级基础的运算符拼接而成
oneflow.nn.Parameter lazy的这个,应该去掉导出
oneflow.nn.random_mask_like PyTorch里没有,未来有需要再搬运
oneflow.nn.sigmoid_cross_entropy_with_logits PyTorch里没有,未来有需要再搬运
oneflow.nn.softmax_cross_entropy_with_logits PyTorch里没有,未来有需要再搬运
oneflow.nn.softmax_grad 貌似不应该暴露给用户
oneflow.nn.sparse_cross_entropy PyTorch里没有,未来有需要再搬运
oneflow.nn.sparse_softmax_cross_entropy_with_logits PyTorch里没有,未来有需要再搬运
oneflow.pack pack是一个底层的算子,不是普通算子
oneflow.parallel_cast 与OneFlow里的并行view有关
oneflow.placement 与OneFlow里的并行view有关
oneflow.quantization.fake_quantization 量化有关,需要时再搬运
oneflow.quantization.min_max_observer 量化有关,需要时再搬运
oneflow.quantization.moving_average_min_max_observer 量化有关,需要时再搬运
oneflow.random.gen_seed
oneflow.random.generate_random_batch_permutation_indices
oneflow.random.shuffle PyTorch 中有各种更细分的shuffle类,没有这种通用的shuffle方法
oneflow.random_normal_initializer 静态图用于修改 variable 才需要的
oneflow.random_uniform_initializer 静态图用于修改 variable 才需要的
oneflow.regularizers.l1 flow.ling.norm 可以替代
oneflow.regularizers.l1_l2 flow.ling.norm 可以替代
oneflow.regularizers.l2 flow.ling.norm 可以替代
oneflow.reshape_like 动态图不需要
oneflow.same_padding 感觉不需要,PyTorch中融合到其它操作中了,比如AdapativePool
oneflow.square_sum 貌似是一个临时的实验性接口
oneflow.ssp_variable_proxy 貌似不应该暴露给用户
oneflow.tensor_scatter_nd_add 有需要再搬运
oneflow.tensor_scatter_nd_update 有需要再搬运
oneflow.unique_with_counts 貌似是一个临时的实验性接口
oneflow.unpack unpack是一个底层的算子,不是普通算子
oneflow.unsorted_batch_segment_sum 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.unsorted_segment_sum 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.unsorted_segment_sum_like 先搁置,它是静态图常用,动态图不需要。未来动静转换时,遇到具体需求再搬运。
oneflow.variance_scaling_initializer
oneflow.watch 静态图才需要
oneflow.watch_diff 静态图才需要
oneflow.zeros_initializer 静态图用于修改 variable 才需要的
oneflow.ones_initializer 静态图用于修改 variable 才需要的
oneflow.nn.compat_conv2d
oneflow.nn.layer_norm
oneflow.optimizer.CombinedOptimizer
oneflow.optimizer.CustomScheduler
oneflow.optimizer.ExponentialScheduler
oneflow.optimizer.grad_clipping.by_global_norm
oneflow.optimizer.InverseTimeScheduler
oneflow.optimizer.LAMB
oneflow.optimizer.LARS
oneflow.optimizer.LazyAdam
oneflow.optimizer.LinearCosineScheduler
oneflow.optimizer.loss_scale.DynamicLossScalePolicy
oneflow.optimizer.loss_scale.StaticLossScalePolicy
oneflow.optimizer.NaturalExpScheduler
oneflow.optimizer.PiecewiseConstantScheduler
oneflow.optimizer.PiecewiseScalingScheduler
oneflow.optimizer.PolynomialSchduler
oneflow.optimizer.PolynomialScheduler
oneflow.optimizer.SGDW
oneflow.optimizer.warmup.constant
oneflow.optimizer.warmup.linear
knightXun commented 2 years ago

有些算子可以适当分派给社区实现

kaijieshi7 commented 2 years ago

有 is_tensor() 的需求

kaijieshi7 commented 2 years ago

有 nn.Dropout2d 的需求

yuanms2 commented 2 years ago

为什么einsum 这个没有在列表里

ZylOo0 commented 2 years ago

一些 padding 相关的算子:

zhongshsh commented 2 years ago

torch.multinomial 的需求

需求场景描述

在NLP的AI-Writer任务中,预测阶段设置阈值为n,截取所有符合阈值的预测结果,需要在这部分结果中抽取一个作为最终的预测结果,抽样的目的是让每一次预测都在合理的范围内有所不同,从而尽可能接近人类的语言习惯,让模型不那么呆板。

对应代码与解决方案

抽样调用的是 torch.multinomial,调用代码为

ix = torch.multinomial(probs, num_samples=1)

目前已使用 numpy.random.multinomial 或者 np.random.choice 替代,修改代码为

p = probs.numpy().astype(np.float64)
p /= p.sum()

ix = np.random.choice(np.arange(probs.shape[0]), size=1, p=p)

sample = np.random.multinomial(n=1, pvals=p)
ix = np.argmax(sample)
zhongshsh commented 2 years ago

set_grad_enabled 的需求

需求场景描述

部分计算可能不需要梯度更新,部分可能需要,此时在 torch 中可以使用 set_grad_enabled 并通过 is_train 参数进行判断。

with torch.set_grad_enabled(is_train):
 ...

本质上,torch.set_grad_enabled(False) 等同于 torch.no_grad(),但是 set_grad_enabled 因为参数原因更为灵活一些。

解决方案

if is_train:
 with flow.grad_enable():
  ...
else:
 with flow.no_grad():
  ...

其他问题

为啥 torch 叫 enable_grad,oneflow 叫 grad_enable ?二者是存在什么区别吗?

接口上的没对齐,改。