Skip to content

Commit b84fedf

Browse files
authored
API/OP(sequence_first_step,sequence_last_step,sequence_mask,beam_search,beam_search_decode) error message enhancement ,test=release/1.8 (#24668)
1 parent 477a1ee commit b84fedf

15 files changed

+385
-40
lines changed

paddle/fluid/operators/beam_search_decode_op.cc

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,31 @@ class BeamSearchDecodeOp : public framework::OperatorBase {
128128
const LoDTensorArray* ids = ctx.Input<LoDTensorArray>("Ids");
129129
const LoDTensorArray* scores = ctx.Input<LoDTensorArray>("Scores");
130130
const size_t step_num = ids->size();
131-
PADDLE_ENFORCE_GT(step_num, 0UL,
132-
"beam search steps should be larger than 0");
131+
PADDLE_ENFORCE_GT(
132+
step_num, 0UL,
133+
platform::errors::InvalidArgument(
134+
"beam search steps, which is the"
135+
"size of Input(Ids) LoDTensorArray. beam search steps should "
136+
"be larger than 0, but received %d. ",
137+
step_num));
133138
const size_t source_num = ids->at(0).lod().at(0).size() - 1;
134-
PADDLE_ENFORCE_GT(source_num, 0UL, "source num should be larger than 0");
139+
PADDLE_ENFORCE_GT(
140+
source_num, 0UL,
141+
platform::errors::InvalidArgument(
142+
"source_num is the sequence number of the"
143+
"first decoding step, indicating by Input(Ids)[0].lod[0].size. "
144+
"The number of source_num should be larger than"
145+
"0, but received %d. ",
146+
source_num));
135147

136148
for (size_t i = 0; i < step_num; ++i) {
137-
PADDLE_ENFORCE_EQ(ids->at(i).lod().size(), 2UL,
138-
"Level of LodTensor should be 2");
149+
PADDLE_ENFORCE_EQ(
150+
ids->at(i).lod().size(), 2UL,
151+
platform::errors::InvalidArgument(
152+
"For the i step in beam search steps,"
153+
"the size of Input(Ids)[i].lod() should larger than 2,"
154+
"but received %d. ",
155+
ids->at(i).lod().size()));
139156
}
140157

141158
size_t beam_size = ctx.Attr<int>("beam_size");
@@ -190,14 +207,14 @@ hypothesis has.
190207
class BeamSearchDecodeInferShape : public framework::InferShapeBase {
191208
public:
192209
void operator()(framework::InferShapeContext* context) const override {
193-
PADDLE_ENFORCE(context->HasInput("Ids"),
194-
"BeamSearchDecodeOp must have input Ids");
195-
PADDLE_ENFORCE(context->HasInput("Scores"),
196-
"BeamSearchDecodeOp must have input Scores");
197-
PADDLE_ENFORCE(context->HasOutput("SentenceIds"),
198-
"BeamSearchDecodeOp must have output SentenceIds");
199-
PADDLE_ENFORCE(context->HasOutput("SentenceScores"),
200-
"BeamSearchDecodeOp must have output SentenceScores");
210+
OP_INOUT_CHECK(context->HasInput("Ids"), "Input", "Ids",
211+
"BeamSearchDecode");
212+
OP_INOUT_CHECK(context->HasInput("Scores"), "Input", "Scores",
213+
"BeamSearchDecode");
214+
OP_INOUT_CHECK(context->HasOutput("SentenceIds"), "Output", "SentenceIds",
215+
"BeamSearchDecode");
216+
OP_INOUT_CHECK(context->HasOutput("SentenceScores"), "Output",
217+
"SentenceScores", "BeamSearchDecode");
201218
}
202219
};
203220

paddle/fluid/operators/beam_search_decode_op.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ limitations under the License. */
1515
#pragma once
1616

1717
#include <algorithm>
18+
#include <memory>
1819
#include <vector>
1920

2021
#include "paddle/fluid/framework/lod_tensor_array.h"
@@ -82,7 +83,15 @@ void BeamSearchDecoder<T>::ConvertSentenceVectorToLodTensor(
8283
LoDTensor* score_tensor, bool reverse, bool sort_by_score) const {
8384
size_t src_num = sentence_vector_list.size();
8485

85-
PADDLE_ENFORCE_NE(src_num, 0, "src_num should not be 0");
86+
PADDLE_ENFORCE_NE(
87+
src_num, 0,
88+
platform::errors::InvalidArgument(
89+
"src_num is the sequence number of the first decoding step"
90+
", indicating by Input(Ids)[0].lod[0].size."
91+
"src_num has wrong value."
92+
"src_num should not be 0,"
93+
"But received %d.",
94+
src_num));
8695

8796
std::vector<size_t> source_level_lod = {0};
8897
std::vector<size_t> sentence_level_lod = {0};
@@ -144,9 +153,16 @@ void BeamSearchDecoder<T>::Backtrace(const LoDTensorArray& step_ids,
144153
const LoDTensorArray& step_scores,
145154
LoDTensor* id_tensor,
146155
LoDTensor* score_tensor) const {
147-
PADDLE_ENFORCE(!step_ids.empty(), "step num should be larger than 0");
148-
PADDLE_ENFORCE_EQ(step_ids.size(), step_scores.size(),
149-
"step_ids and step_scores should be the same");
156+
PADDLE_ENFORCE_NE(
157+
step_ids.empty(), true,
158+
platform::errors::InvalidArgument("Input(Ids) should not be empty."
159+
"But the Input(Ids) is empty."));
160+
PADDLE_ENFORCE_EQ(
161+
step_ids.size(), step_scores.size(),
162+
platform::errors::InvalidArgument(
163+
"The size of Input(Ids) and Input(Scores) should be "
164+
"the same. But the size of Input(Ids) and Input(Scores) "
165+
"are not equal."));
150166
const size_t step_num = step_ids.size();
151167
const size_t src_num = step_ids.at(0).lod().at(kSourceLevel).size() - 1;
152168
std::vector<SentenceVector<T>> sentence_vector_list(

paddle/fluid/operators/beam_search_decode_op_test.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,17 @@ void GenerateExample(const std::vector<size_t>& level_0,
3535
const std::vector<int>& data, LoDTensorArray* ids,
3636
LoDTensorArray* scores) {
3737
PADDLE_ENFORCE_EQ(level_0.back(), level_1.size() - 1,
38-
"source level is used to describe candidate set");
38+
platform::errors::InvalidArgument(
39+
"source level is used to describe candidate set"
40+
", so it's element should less than levle_1 length. "
41+
"And the value of source"
42+
"level is %d. ",
43+
level_1.size() - 1));
3944
PADDLE_ENFORCE_EQ(level_1.back(), data.size(),
40-
"the lowest level is used to describe data"
41-
", so it's last element should be data length");
45+
platform::errors::InvalidArgument(
46+
"the lowest level is used to describe data"
47+
", so it's last element should be data length %d. ",
48+
data.size()));
4249

4350
CPUPlace place;
4451

paddle/fluid/operators/beam_search_op.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,11 @@ class BeamSearchOp : public framework::OperatorWithKernel {
8989
void InferShape(framework::InferShapeContext *ctx) const override {
9090
for (const std::string &arg :
9191
std::vector<std::string>({"pre_ids", "scores"})) {
92-
PADDLE_ENFORCE(ctx->HasInput(arg), "BeamSearch need input argument '%s'",
93-
arg);
92+
OP_INOUT_CHECK(ctx->HasInput(arg), "Input", arg, "BeamSeach");
9493
}
9594
for (const std::string &arg :
9695
std::vector<std::string>({"selected_ids", "selected_scores"})) {
97-
PADDLE_ENFORCE(ctx->HasOutput(arg),
98-
"BeamSearch need output argument '%s'", arg);
96+
OP_INOUT_CHECK(ctx->HasOutput(arg), "Output", arg, "BeamSeach");
9997
}
10098
}
10199

paddle/fluid/operators/beam_search_op.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,15 @@ class BeamSearchOpKernel : public framework::OpKernel<T> {
2929
auto* pre_ids = context.Input<framework::LoDTensor>("pre_ids");
3030
auto* pre_scores = context.Input<framework::LoDTensor>("pre_scores");
3131

32-
PADDLE_ENFORCE_NOT_NULL(scores);
33-
PADDLE_ENFORCE_NOT_NULL(pre_ids);
34-
PADDLE_ENFORCE_NOT_NULL(pre_scores);
32+
PADDLE_ENFORCE_NOT_NULL(scores,
33+
platform::errors::NotFound(
34+
"Input(scores) of BeamSearchOp is not found."));
35+
PADDLE_ENFORCE_NOT_NULL(
36+
pre_ids, platform::errors::NotFound(
37+
"Input(pre_ids) of BeamSearchOp is not found."));
38+
PADDLE_ENFORCE_NOT_NULL(
39+
pre_scores, platform::errors::NotFound(
40+
"Input(pre_scores) of BeamSearchOp is not found."));
3541

3642
size_t level = context.Attr<int>("level");
3743
size_t beam_size = context.Attr<int>("beam_size");
@@ -42,8 +48,14 @@ class BeamSearchOpKernel : public framework::OpKernel<T> {
4248
auto selected_scores =
4349
context.Output<framework::LoDTensor>("selected_scores");
4450
auto* parent_idx = context.Output<framework::Tensor>("parent_idx");
45-
PADDLE_ENFORCE_NOT_NULL(selected_ids);
46-
PADDLE_ENFORCE_NOT_NULL(selected_scores);
51+
PADDLE_ENFORCE_NOT_NULL(
52+
selected_ids,
53+
platform::errors::NotFound(
54+
"Output(selected_scores) of BeamSearchOp is not found."));
55+
PADDLE_ENFORCE_NOT_NULL(
56+
selected_scores,
57+
platform::errors::NotFound(
58+
"Output(parent_idx) of BeamSearchOp is not found."));
4759

4860
math::BeamSearchFunctor<DeviceContext, T> alg;
4961
alg(context.template device_context<DeviceContext>(), pre_ids, pre_scores,

paddle/fluid/operators/sequence_ops/sequence_mask_op.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class SequenceMaskOp : public framework::OperatorWithKernel {
2323
using framework::OperatorWithKernel::OperatorWithKernel;
2424

2525
void InferShape(framework::InferShapeContext* ctx) const override {
26-
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) must exist");
27-
PADDLE_ENFORCE(ctx->HasOutput("Y"), "Output(Y) must exist");
26+
OP_INOUT_CHECK(ctx->HasInput("X"), "Input", "X", "SequenceMask");
27+
OP_INOUT_CHECK(ctx->HasOutput("Y"), "Output", "Y", "SequenceMask");
2828

2929
int maxlen = ctx->Attrs().Get<int>("maxlen");
3030
auto dim = framework::vectorize<int>(ctx->GetInputDim("X"));

paddle/fluid/operators/sequence_ops/sequence_mask_op.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ class SequenceMaskKernel : public framework::OpKernel<Tx> {
8080
int maxlen = ctx.Attr<int>("maxlen");
8181
if (ctx.HasInput("MaxLenTensor")) {
8282
auto max_len_tensor = ctx.Input<Tensor>("MaxLenTensor");
83-
PADDLE_ENFORCE(max_len_tensor != NULL, "MaxLenTensor is NULL");
83+
PADDLE_ENFORCE_NOT_NULL(max_len_tensor,
84+
platform::errors::InvalidArgument(
85+
"Input(MaxLenTensor) should not be NULL."
86+
"But received Input(MaxLenTensor) is NULL"));
8487
if (platform::is_gpu_place(max_len_tensor->place())) {
8588
framework::Tensor temp;
8689
TensorCopySync(*max_len_tensor, platform::CPUPlace(), &temp);
@@ -93,8 +96,12 @@ class SequenceMaskKernel : public framework::OpKernel<Tx> {
9396
y_dim.push_back(maxlen);
9497
y->Resize(framework::make_ddim(y_dim));
9598

96-
PADDLE_ENFORCE_GT(maxlen, 0,
97-
"MaxLenTensor value should be greater than 0");
99+
PADDLE_ENFORCE_GT(
100+
maxlen, 0,
101+
platform::errors::InvalidArgument(
102+
"Input(MaxLenTensor) value should be greater than 0. But "
103+
"received Input(MaxLenTensor) value = %d.",
104+
maxlen));
98105
}
99106

100107
auto *x_data = x->data<Tx>();

python/paddle/fluid/layers/rnn.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
class RNNCell(object):
5959
"""
60+
6061
RNNCell is the base class for abstraction representing the calculations
6162
mapping the input and state to the output and new state. It is suitable to
6263
and mostly used in RNN.
@@ -221,6 +222,7 @@ def state_dtype(self):
221222

222223
class GRUCell(RNNCell):
223224
"""
225+
224226
Gated Recurrent Unit cell. It is a wrapper for
225227
`fluid.contrib.layers.rnn_impl.BasicGRUUnit` to make it adapt to RNNCell.
226228
@@ -317,6 +319,7 @@ def state_shape(self):
317319

318320
class LSTMCell(RNNCell):
319321
"""
322+
320323
Long-Short Term Memory cell. It is a wrapper for
321324
`fluid.contrib.layers.rnn_impl.BasicLSTMUnit` to make it adapt to RNNCell.
322325
@@ -431,6 +434,7 @@ def rnn(cell,
431434
is_reverse=False,
432435
**kwargs):
433436
"""
437+
434438
rnn creates a recurrent neural network specified by RNNCell `cell`,
435439
which performs :code:`cell.call()` repeatedly until reaches to the maximum
436440
length of `inputs`.
@@ -575,6 +579,7 @@ def _switch_grad(x, stop=False):
575579

576580
class Decoder(object):
577581
"""
582+
578583
Decoder is the base class for any decoder instance used in `dynamic_decode`.
579584
It provides interface for output generation for one time step, which can be
580585
used to generate sequences.
@@ -664,6 +669,7 @@ def finalize(self, outputs, final_states, sequence_lengths):
664669

665670
class BeamSearchDecoder(Decoder):
666671
"""
672+
667673
Decoder with beam search decoding strategy. It wraps a cell to get probabilities,
668674
and follows a beam search step to calculate scores and select candidate
669675
token ids for each decoding step.
@@ -1127,6 +1133,7 @@ def dynamic_decode(decoder,
11271133
return_length=False,
11281134
**kwargs):
11291135
"""
1136+
11301137
Dynamic decoding performs :code:`decoder.step()` repeatedly until the returned
11311138
Tensor indicating finished status contains all True values or the number of
11321139
decoding step reaches to :attr:`max_step_num`.
@@ -1941,6 +1948,7 @@ def dynamic_lstm(input,
19411948
dtype='float32',
19421949
name=None):
19431950
"""
1951+
19441952
**Note**:
19451953
1. This OP only supports LoDTensor as inputs. If you need to deal with Tensor, please use :ref:`api_fluid_layers_lstm` .
19461954
2. In order to improve efficiency, users must first map the input of dimension [T, hidden_size] to input of [T, 4 * hidden_size], and then pass it to this OP.
@@ -2111,6 +2119,7 @@ def lstm(input,
21112119
default_initializer=None,
21122120
seed=-1):
21132121
"""
2122+
21142123
**Note**:
21152124
This OP only supports running on GPU devices.
21162125
@@ -2296,6 +2305,7 @@ def dynamic_lstmp(input,
22962305
cell_clip=None,
22972306
proj_clip=None):
22982307
"""
2308+
22992309
**Note**:
23002310
1. In order to improve efficiency, users must first map the input of dimension [T, hidden_size] to input of [T, 4 * hidden_size], and then pass it to this OP.
23012311
@@ -2505,6 +2515,7 @@ def dynamic_gru(input,
25052515
h_0=None,
25062516
origin_mode=False):
25072517
"""
2518+
25082519
**Note: The input type of this must be LoDTensor. If the input type to be
25092520
processed is Tensor, use** :ref:`api_fluid_layers_StaticRNN` .
25102521
@@ -2665,6 +2676,7 @@ def gru_unit(input,
26652676
gate_activation='sigmoid',
26662677
origin_mode=False):
26672678
"""
2679+
26682680
Gated Recurrent Unit (GRU) RNN cell. This operator performs GRU calculations for
26692681
one time step and it supports these two modes:
26702682
@@ -2821,6 +2833,7 @@ def beam_search(pre_ids,
28212833
name=None,
28222834
return_parent_idx=False):
28232835
"""
2836+
28242837
Beam search is a classical algorithm for selecting candidate words in a
28252838
machine translation task.
28262839
@@ -2922,6 +2935,12 @@ def beam_search(pre_ids,
29222935
beam_size=beam_size,
29232936
end_id=end_id)
29242937
"""
2938+
check_variable_and_dtype(pre_ids, 'pre_ids', ['int64'], 'beam_search')
2939+
check_variable_and_dtype(pre_scores, 'pre_scores', ['float32', 'float64'],
2940+
'beam_search')
2941+
check_type(ids, 'ids', (Variable, type(None)), 'beam_search')
2942+
check_variable_and_dtype(scores, 'scores', ['float32', 'float64'],
2943+
'beam_search')
29252944
helper = LayerHelper('beam_search', **locals())
29262945
score_type = pre_scores.dtype
29272946
id_type = pre_ids.dtype
@@ -2962,6 +2981,7 @@ def beam_search(pre_ids,
29622981

29632982
def beam_search_decode(ids, scores, beam_size, end_id, name=None):
29642983
"""
2984+
29652985
This operator is used after beam search has completed. It constructs the
29662986
full predicted sequences for each sample by walking back along the search
29672987
paths stored in lod of ``ids`` . The result sequences are stored in a
@@ -3015,6 +3035,9 @@ def beam_search_decode(ids, scores, beam_size, end_id, name=None):
30153035
finished_ids, finished_scores = fluid.layers.beam_search_decode(
30163036
ids, scores, beam_size=5, end_id=0)
30173037
"""
3038+
check_variable_and_dtype(ids, 'ids', ['int64'], 'beam_search_encode')
3039+
check_variable_and_dtype(scores, 'scores', ['float32'],
3040+
'beam_search_encode')
30183041
helper = LayerHelper('beam_search_decode', **locals())
30193042
sentence_ids = helper.create_variable_for_type_inference(dtype=ids.dtype)
30203043
sentence_scores = helper.create_variable_for_type_inference(dtype=ids.dtype)
@@ -3041,6 +3064,7 @@ def lstm_unit(x_t,
30413064
bias_attr=None,
30423065
name=None):
30433066
"""
3067+
30443068
Long-Short Term Memory (LSTM) RNN cell. This operator performs LSTM calculations for
30453069
one time step, whose implementation is based on calculations described in `RECURRENT
30463070
NEURAL NETWORK REGULARIZATION <http://arxiv.org/abs/1409.2329>`_ .

0 commit comments

Comments
 (0)