PaddlePaddle / models

Officially maintained, supported by PaddlePaddle, including CV, NLP, Speech, Rec, TS, big models and so on.
Apache License 2.0
6.9k stars 2.91k forks source link

“covert to c++” occurs error about “pre_ids_emb = fluid.layers.embedding()” #5143

Open GeorgeBohw opened 3 years ago

GeorgeBohw commented 3 years ago

os: ubuntu with gpu paddle1.8

转换paddle到c++运行,下面两种情况,pyhon运行均正常,c++运行报错。 attention.py中的def attention_infer()函数:

情况1: pre_ids_emb = fluid.layers.embedding() 转化的模型在c++环境下运行出现错误:

0 std::string paddle::platform::GetTraceBackString<std::string const&>(std::string const&, char const, int) 1 paddle::platform::EnforceNotMet::EnforceNotMet(std::string const&, char const, int) 2 paddle::operators::LookupTableOp::InferShape(paddle::framework::InferShapeContext) const 3 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&, paddle::framework::RuntimeContext) const 4 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&) const 5 paddle::framework::OperatorBase::Run(paddle::framework::Scope const&, paddle::platform::Place const&) 6 paddle::framework::Executor::RunPartialPreparedContext(paddle::framework::ExecutorPrepareContext, paddle::framework::Scope, long, long, bool, bool, bool) 7 paddle::framework::Executor::RunPreparedContext(paddle::framework::ExecutorPrepareContext, paddle::framework::Scope, bool, bool, bool) 8 paddle::operators::WhileOp::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&) const 9 paddle::framework::OperatorBase::Run(paddle::framework::Scope const&, paddle::platform::Place const&) 10 paddle::framework::NaiveExecutor::Run() 11 paddle::AnalysisPredictor::ZeroCopyRun()

Error: ShapeError: The last dimensions of the 'Ids' tensor must be 1. But received Ids's last dimensions = 128, Ids's shape = [1, 128]. [Hint: Expected ids_dims[ids_rank - 1] == 1, but received ids_dims[ids_rank - 1]:128 != 1:1.] at (/home/george/paddle/paddle/fluid/operators/lookup_table_op.cc:51) [operator < lookup_table > error

情况2: pre_ids_emb = fluid.layers.embedding()改为pre_ids_emb = fluid.embedding() 转化的模型在c++环境下运行出现错误:

0 std::string paddle::platform::GetTraceBackString<std::string const&>(std::string const&, char const, int) 1 paddle::platform::EnforceNotMet::EnforceNotMet(std::string const&, char const, int) 2 long const paddle::framework::Tensor::data() const 3 paddle::operators::LookupTableV2CUDAKernel::Compute(paddle::framework::ExecutionContext const&) const 4 std::_Function_handler<void (paddle::framework::ExecutionContext const&), paddle::framework::OpKernelRegistrarFunctor<paddle::platform::CUDAPlace, false, 0ul, paddle::operators::LookupTableV2CUDAKernel, paddle::operators::LookupTableV2CUDAKernel, paddle::operators::LookupTableV2CUDAKernel >::operator()(char const, char const, int) const::{lambda(paddle::framework::ExecutionContext const&)#1}>::_M_invoke(std::_Any_data const&, paddle::framework::ExecutionContext const&) 5 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&, paddle::framework::RuntimeContext) const 6 paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&) const 7 paddle::framework::OperatorBase::Run(paddle::framework::Scope const&, paddle::platform::Place const&) 8 paddle::framework::Executor::RunPartialPreparedContext(paddle::framework::ExecutorPrepareContext, paddle::framework::Scope, long, long, bool, bool, bool) 9 paddle::framework::Executor::RunPreparedContext(paddle::framework::ExecutorPrepareContext, paddle::framework::Scope, bool, bool, bool) 10 paddle::operators::WhileOp::RunImpl(paddle::framework::Scope const&, paddle::platform::Place const&) const 11 paddle::framework::OperatorBase::Run(paddle::framework::Scope const&, paddle::platform::Place const&) 12 paddle::framework::NaiveExecutor::Run() 13 paddle::AnalysisPredictor::ZeroCopyRun()

InvalidArgumentError: Tensor holds the wrong type, it holds float, but desires to be int64_t. [Hint: Expected valid == true, but received valid:0 != true:1.] at (/home/george/paddle/paddle/fluid/framework/tensor_impl.h:33) [operator < lookup_table_v2 > error]

GeorgeBohw commented 3 years ago

def attention_infer()如下:

def attention_infer(images, num_classes, use_cudnn=True):

max_length = 20
gru_backward, encoded_vector, encoded_proj = encoder_net(
    images, is_test=True, use_cudnn=use_cudnn)

backward_first = fluid.layers.sequence_pool(
    input=gru_backward, pool_type='first')
decoder_boot = fluid.layers.fc(input=backward_first,
                               size=decoder_size,
                               bias_attr=False,
                               act="relu")
init_state = decoder_boot
array_len = fluid.layers.fill_constant(
    shape=[1], dtype='int64', value=max_length)
counter = fluid.layers.zeros(shape=[1], dtype='int64', force_cpu=True)

# fill the first element with init_state
state_array = fluid.layers.create_array('float32')
fluid.layers.array_write(init_state, array=state_array, i=counter)

# ids, scores as memory
ids_array = fluid.layers.create_array('int64')#此OP创建一个LoDTensorArray,它可以用作 array_write , array_read OP的输入,以及和 While OP 一起创建RNN网络
scores_array = fluid.layers.create_array('float32')

init_ids = fluid.data(  #全局block中创建变量(Variable),该全局变量可被计算图中的算子(operator)访问。该变量可作为占位符用于数据输入
    name="init_ids", shape=[None, 1], dtype="int64", lod_level=2)
init_scores = fluid.data(
    name="init_scores", shape=[None, 1], dtype="float32", lod_level=2)

fluid.layers.array_write(init_ids, array=ids_array, i=counter)
fluid.layers.array_write(init_scores, array=scores_array, i=counter)

cond = fluid.layers.less_than(x=counter, y=array_len)
while_op = fluid.layers.While(cond=cond)
with while_op.block():
    pre_ids = fluid.layers.array_read(array=ids_array, i=counter)
    pre_state = fluid.layers.array_read(array=state_array, i=counter)
    pre_score = fluid.layers.array_read(array=scores_array, i=counter)

    pre_ids_emb = fluid.layers.embedding(
        input=pre_ids,
        size=[num_classes + 2, word_vector_dim],
        dtype='float32')

    context = simple_attention(encoded_vector, encoded_proj, pre_state,
                               decoder_size)

    # expand the recursive_sequence_lengths of pre_state to be the same with pre_score
    pre_state_expanded = fluid.layers.sequence_expand(pre_state, pre_score)
    context_expanded = fluid.layers.sequence_expand(context, pre_score)
    fc_1 = fluid.layers.fc(input=context_expanded,
                           size=decoder_size * 3,
                           bias_attr=False)
    fc_2 = fluid.layers.fc(input=pre_ids_emb,
                           size=decoder_size * 3,
                           bias_attr=False)

    decoder_inputs = fc_1 + fc_2
    current_state, _, _ = fluid.layers.gru_unit(
        input=decoder_inputs,
        hidden=pre_state_expanded,
        size=decoder_size * 3)

    current_state_with_lod = fluid.layers.lod_reset(
        x=current_state, y=pre_score)
    # use score to do beam search
    current_score = fluid.layers.fc(input=current_state_with_lod,
                                    size=num_classes + 2,
                                    bias_attr=True,
                                    act='softmax')
    topk_scores, topk_indices = fluid.layers.topk(
        current_score, k=beam_size)

    # calculate accumulated scores after topk to reduce computation cost
    accu_scores = fluid.layers.elementwise_add(
        x=fluid.layers.log(topk_scores),
        y=fluid.layers.reshape(
            pre_score, shape=[-1]),
        axis=0)
    selected_ids, selected_scores = fluid.layers.beam_search(
        pre_ids,
        pre_score,
        topk_indices,
        accu_scores,
        beam_size,
        eos,  # end_id
        #level=0
    )

    fluid.layers.increment(x=counter, value=1, in_place=True)

    # update the memories
    fluid.layers.array_write(current_state, array=state_array, i=counter)
    fluid.layers.array_write(selected_ids, array=ids_array, i=counter)
    fluid.layers.array_write(selected_scores, array=scores_array, i=counter)

    # update the break condition: up to the max length or all candidates of
    # source sentences have ended.
    length_cond = fluid.layers.less_than(x=counter, y=array_len)
    finish_cond = fluid.layers.logical_not(
        fluid.layers.is_empty(x=selected_ids))
    fluid.layers.logical_and(x=length_cond, y=finish_cond, out=cond)

ids, scores = fluid.layers.beam_search_decode(ids_array, scores_array,
                                              beam_size, eos)

return ids