Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
transformers
Commits
1d9c26a4
Unverified
Commit
1d9c26a4
authored
Feb 08, 2023
by
Joao Gante
Committed by
GitHub
Feb 08, 2023
Browse files
Generate: TF `compute_transition_scores` (#21341)
parent
d3046dad
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
520 additions
and
250 deletions
+520
-250
docs/source/en/main_classes/text_generation.mdx
docs/source/en/main_classes/text_generation.mdx
+1
-0
src/transformers/generation/tf_utils.py
src/transformers/generation/tf_utils.py
+254
-39
src/transformers/generation/utils.py
src/transformers/generation/utils.py
+14
-13
tests/generation/test_framework_agnostic.py
tests/generation/test_framework_agnostic.py
+251
-5
tests/generation/test_utils.py
tests/generation/test_utils.py
+0
-193
No files found.
docs/source/en/main_classes/text_generation.mdx
View file @
1d9c26a4
...
...
@@ -50,6 +50,7 @@ and how to create and save a customized generation configuration, refer to the
[[autodoc]] generation.TFGenerationMixin
- generate
- compute_transition_scores
## FlaxGenerationMixin
...
...
src/transformers/generation/tf_utils.py
View file @
1d9c26a4
This diff is collapsed.
Click to expand it.
src/transformers/generation/utils.py
View file @
1d9c26a4
...
...
@@ -301,9 +301,9 @@ class BeamSearchDecoderOnlyOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
Tuple of `torch.FloatTensor` with up to `max_new_tokens` elements (one element for each generated token),
with each tensor of shape `(batch_size*num_beams*num_return_sequences, config.vocab_size)`.
beam_indices (`
tuple(tuple(
torch.LongTensor
))
`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
beam_indices (`torch.LongTensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
Beam indices of generated token id at each generation step. `torch.LongTensor` of shape
`(batch_size*num_return_sequences,
input_ids.shape[-1]
)`.
`(batch_size*num_return_sequences,
sequence_length
)`.
attentions (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of
`torch.FloatTensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`.
...
...
@@ -338,10 +338,9 @@ class BeamSearchEncoderDecoderOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
Tuple of `torch.FloatTensor` with up to `max_new_tokens` elements (one element for each generated token),
with each tensor of shape `(batch_size*num_beams, config.vocab_size)`.
beam_indices (`
tuple(tuple(
torch.LongTensor
))
`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
beam_indices (`torch.LongTensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
Beam indices of generated token id at each generation step. `torch.LongTensor` of shape
`(batch_size*num_return_sequences, max_length-1)`.
attentions (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
`(batch_size*num_return_sequences, sequence_length)`.
encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
Tuple of `torch.FloatTensor` (one for each layer of the decoder) of shape `(batch_size, num_heads,
sequence_length, sequence_length)`.
...
...
@@ -387,9 +386,9 @@ class BeamSampleDecoderOnlyOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
Tuple of `torch.FloatTensor` with up to `max_new_tokens` elements (one element for each generated token),
with each tensor of shape `(batch_size*num_beams*num_return_sequences, config.vocab_size)`.
beam_indices (`
tuple(tuple(
torch.LongTensor
))
`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
beam_indices (`torch.LongTensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
Beam indices of generated token id at each generation step. `torch.LongTensor` of shape
`(batch_size*num_return_sequences,
input_ids.shape[-1]
)`.
`(batch_size*num_return_sequences,
sequence_length
)`.
attentions (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
Tuple (one element for each generated token) of tuples (one element for each layer of the decoder) of
`torch.FloatTensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`.
...
...
@@ -426,7 +425,7 @@ class BeamSampleEncoderDecoderOutput(ModelOutput):
with each tensor of shape `(batch_size*num_beams, config.vocab_size)`).
beam_indices (`torch.LongTensor`, *optional*, returned when `output_scores=True` is passed or when `config.output_scores=True`):
Beam indices of generated token id at each generation step. `torch.LongTensor` of shape
`(batch_size*num_return_sequences,
max
_length
-1
)`.
`(batch_size*num_return_sequences,
sequence
_length)`.
encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
Tuple of `torch.FloatTensor` (one for each layer of the decoder) of shape `(batch_size, num_heads,
sequence_length, sequence_length)`.
...
...
@@ -937,9 +936,9 @@ class GenerationMixin:
of log probabilities of tokens conditioned on log softmax of previously generated tokens Tuple of
`torch.FloatTensor` with up to `max_new_tokens` elements (one element for each generated token), with
each tensor of shape `(batch_size*num_beams, config.vocab_size)`.
beam_indices (`
tuple(tuple(
torch.LongTensor
))
`, *optional*):
beam_indices (`torch.LongTensor`, *optional*):
Beam indices of generated token id at each generation step. `torch.LongTensor` of shape
`(batch_size*num_return_sequences,
input_ids.shape[-1]
)`. Only required if a `num_beams>1` at
`(batch_size*num_return_sequences,
sequence_length
)`. Only required if a `num_beams>1` at
generate-time.
normalize_logits (`bool`, *optional*, defaults to `False`):
Whether to normalize the logits (which, for legacy reasons, may be unnormalized).
...
...
@@ -1017,11 +1016,10 @@ class GenerationMixin:
# 4. cut beam_indices to longest beam length
beam_indices_mask
=
beam_indices
<
0
max_beam_length
=
(
1
-
beam_indices_mask
.
long
()).
sum
(
-
1
).
max
()
beam_indices
=
beam_indices
[:,
:
max_beam_length
]
beam_indices
=
beam_indices
.
clone
()
[:,
:
max_beam_length
]
beam_indices_mask
=
beam_indices_mask
[:,
:
max_beam_length
]
# 5. Set indices of beams that finished early to 0
# such indices will be masked correctly afterwards
# 5. Set indices of beams that finished early to 0; such indices will be masked correctly afterwards
beam_indices
[
beam_indices_mask
]
=
0
# 6. multiply beam_indices with vocab size to gather correctly from scores
...
...
@@ -3067,6 +3065,9 @@ class GenerationMixin:
next_token_scores_processed
=
logits_processor
(
input_ids
,
next_token_scores
)
next_token_scores
=
next_token_scores_processed
+
beam_scores
[:,
None
].
expand_as
(
next_token_scores
)
# Note: logits warpers are intentionally applied after adding running beam scores. On some logits warpers
# (like top_p) this is indiferent, but on others (like temperature) it is not. For reference, see
# https://github.com/huggingface/transformers/pull/5420#discussion_r449779867
next_token_scores
=
logits_warper
(
input_ids
,
next_token_scores
)
# Store scores, attentions and hidden_states when required
...
...
tests/generation/test_framework_agnostic.py
View file @
1d9c26a4
...
...
@@ -5,7 +5,7 @@ Framework agnostic tests for generate()-related methods.
import
numpy
as
np
from
transformers
import
AutoTokenizer
from
transformers.testing_utils
import
torch_device
from
transformers.testing_utils
import
slow
,
torch_device
class
GenerationIntegrationTestsMixin
:
...
...
@@ -133,16 +133,12 @@ class GenerationIntegrationTestsMixin:
def
test_encoder_decoder_generate_with_inputs_embeds
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
article
=
"""Justin Timberlake and Jessica Biel, welcome to parenthood."""
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
5
)
model
.
config
.
eos_token_id
=
None
input_ids
=
tokenizer
(
article
,
return_tensors
=
return_tensors
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
inputs_embeds
=
model
.
get_input_embeddings
()(
input_ids
)
...
...
@@ -150,3 +146,253 @@ class GenerationIntegrationTestsMixin:
# make sure model generated correctly until `max_length`
self
.
assertEqual
(
output_sequences
.
shape
,
(
1
,
5
))
def
test_transition_scores_greedy_search
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForCausalLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"distilgpt2"
,
padding_side
=
"left"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
model_cls
.
from_pretrained
(
"distilgpt2"
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
,
max_new_tokens
=
5
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
expected_scores
=
np
.
array
(
[
[
-
57.8844
,
-
60.45698
,
-
70.16364
,
-
65.50791
,
-
66.35648
],
[
-
54.417572
,
-
60.216614
,
-
62.661243
,
-
58.621933
,
-
58.298683
],
]
)
self
.
assertTrue
(
np
.
allclose
(
transition_scores
,
expected_scores
,
atol
=
1e-3
))
def
test_transition_scores_greedy_search_normalized
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForCausalLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"distilgpt2"
,
padding_side
=
"left"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
model_cls
.
from_pretrained
(
"distilgpt2"
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
,
max_new_tokens
=
5
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
normalize_logits
=
True
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
expected_scores
=
np
.
array
(
[
[
-
2.538938
,
-
2.2694316
,
-
2.1580915
,
-
1.572299
,
-
2.6719835
],
[
-
1.8826028
,
-
2.2461371
,
-
1.7556462
,
-
2.9644494
,
-
1.7996008
],
]
)
self
.
assertTrue
(
np
.
allclose
(
transition_scores
,
expected_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_search_encoder_decoder
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
outputs
.
sequences_scores
=
outputs
.
sequences_scores
.
cpu
().
numpy
()
self
.
assertTrue
(
np
.
allclose
(
np
.
sum
(
transition_scores
,
axis
=-
1
),
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_search_encoder_decoder_with_eos
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
outputs
.
sequences_scores
=
outputs
.
sequences_scores
.
cpu
().
numpy
()
self
.
assertTrue
(
np
.
allclose
(
np
.
sum
(
transition_scores
,
axis
=-
1
),
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_search_decoder_only
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForCausalLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
,
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
outputs
.
sequences_scores
=
outputs
.
sequences_scores
.
cpu
().
numpy
()
self
.
assertTrue
(
np
.
allclose
(
np
.
sum
(
transition_scores
,
axis
=-
1
),
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_sample_encoder_decoder
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
do_sample
=
True
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
return_tensors
,
padding
=
True
).
input_ids
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
outputs
.
sequences_scores
=
outputs
.
sequences_scores
.
cpu
().
numpy
()
self
.
assertTrue
(
np
.
allclose
(
np
.
sum
(
transition_scores
,
axis
=-
1
),
outputs
.
sequences_scores
,
atol
=
1e-3
))
@
slow
def
test_transition_scores_early_stopping
(
self
):
# This is an aggressive test that makes sure that `beam_search's`
# transition scores are computed correctly for varying `num_return_sequences`, `num_beams` and `batch_size > 1`
# 2 x input_ids for "question: How are you? \n context: I had a long day, "
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
create_tensor_fn
=
self
.
framework_dependent_parameters
[
"create_tensor_fn"
]
is_pt
=
not
model_cls
.
__name__
.
startswith
(
"TF"
)
input_ids
=
create_tensor_fn
(
2
*
[[
822
,
10
,
571
,
33
,
25
,
58
,
2625
,
10
,
27
,
141
,
3
,
9
,
307
,
239
,
6
,
1
]])
model
=
model_cls
.
from_pretrained
(
"t5-small"
)
if
is_pt
:
model
=
model
.
to
(
torch_device
)
input_ids
=
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
,
max_length
=
10
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
forced_eos_token_id
=
model
.
config
.
eos_token_id
,
num_beams
=
4
,
do_sample
=
False
,
num_return_sequences
=
3
,
length_penalty
=
0.0
,
)
transition_scores
=
model
.
compute_transition_scores
(
sequences
=
outputs
.
sequences
,
scores
=
outputs
.
scores
,
beam_indices
=
outputs
.
beam_indices
)
if
is_pt
:
transition_scores
=
transition_scores
.
cpu
().
numpy
()
outputs
.
sequences_scores
=
outputs
.
sequences_scores
.
cpu
().
numpy
()
self
.
assertTrue
(
np
.
allclose
(
np
.
sum
(
transition_scores
,
axis
=-
1
),
outputs
.
sequences_scores
))
tests/generation/test_utils.py
View file @
1d9c26a4
...
...
@@ -17,8 +17,6 @@
import
inspect
import
unittest
import
numpy
as
np
from
transformers
import
is_torch_available
,
pipeline
from
transformers.testing_utils
import
require_torch
,
slow
,
torch_device
...
...
@@ -2220,165 +2218,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
self
.
assertListEqual
(
output_sequences_no_mask
.
tolist
(),
output_sequences_with_mask
.
tolist
())
def
test_transition_scores_greedy_search
(
self
):
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
]
tokenizer
=
GPT2Tokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
GPT2LMHeadModel
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
).
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
,
max_new_tokens
=
5
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
)
expected_scores
=
np
.
array
(
[
[
0.3596273
,
0.39646253
,
0.46157718
,
0.4594633
,
0.44866616
],
[
0.34934354
,
0.4935004
,
0.6373219
,
0.5173545
,
0.57517034
],
]
)
self
.
assertTrue
(
np
.
allclose
(
transition_scores
.
cpu
().
numpy
(),
expected_scores
))
def
test_transition_scores_greedy_search_normalized
(
self
):
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
]
tokenizer
=
GPT2Tokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
GPT2LMHeadModel
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
).
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
,
max_new_tokens
=
5
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
normalize_logits
=
True
)
expected_scores
=
np
.
array
(
[
[
-
6.5532393
,
-
6.5158753
,
-
6.451863
,
-
6.4527144
,
-
6.459402
],
[
-
6.5685124
,
-
6.4277077
,
-
6.282607
,
-
6.399295
,
-
6.340927
],
]
)
self
.
assertTrue
(
np
.
allclose
(
transition_scores
.
cpu
().
numpy
(),
expected_scores
))
def
test_transition_scores_beam_search_encoder_decoder
(
self
):
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
BartTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
BartForConditionalGeneration
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
model
=
model
.
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
transition_scores_sum
=
transition_scores
.
sum
(
-
1
)
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_search_encoder_decoder_with_eos
(
self
):
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
BartTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
BartForConditionalGeneration
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
model
=
model
.
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
transition_scores_sum
=
transition_scores
.
sum
(
-
1
)
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_search_decoder_only
(
self
):
articles
=
[
"Justin Timberlake"
,
"Michael Phelps"
,
]
tokenizer
=
GPT2Tokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
tokenizer
.
pad_token
=
tokenizer
.
eos_token
model
=
GPT2LMHeadModel
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
pad_token_id
=
tokenizer
.
eos_token_id
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
model
=
model
.
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
transition_scores_sum
=
transition_scores
.
sum
(
-
1
)
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_beam_sample_encoder_decoder
(
self
):
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Michael Phelps is arguably the most decorated Olympian of all time."
,
]
tokenizer
=
BartTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
model
=
BartForConditionalGeneration
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
do_sample
=
True
,
max_length
=
10
,
num_beams
=
4
,
num_return_sequences
=
2
,
eos_token_id
=
None
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
length_penalty
=
0.0
,
)
model
=
model
.
to
(
torch_device
)
input_ids
=
tokenizer
(
articles
,
return_tensors
=
"pt"
,
padding
=
True
).
input_ids
.
to
(
torch_device
)
outputs
=
model
.
generate
(
input_ids
=
input_ids
)
transition_scores
=
model
.
compute_transition_scores
(
outputs
.
sequences
,
outputs
.
scores
,
outputs
.
beam_indices
)
transition_scores_sum
=
transition_scores
.
sum
(
-
1
)
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
def
test_transition_scores_group_beam_search_encoder_decoder
(
self
):
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
...
...
@@ -2406,38 +2245,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
@
slow
def
test_transition_scores_early_stopping
(
self
):
# This is an aggressive test that makes sure that `beam_search's`
# transition scores are computed correctly for varying `num_return_sequences`,
# `num_beams` and `batch_size > 1`
# 2 x input_ids for "question: How are you? \n context: I had a long day, "
input_ids
=
torch
.
tensor
(
2
*
[[
822
,
10
,
571
,
33
,
25
,
58
,
2625
,
10
,
27
,
141
,
3
,
9
,
307
,
239
,
6
,
1
]]).
to
(
torch_device
)
model
=
AutoModelForSeq2SeqLM
.
from_pretrained
(
"t5-small"
).
to
(
torch_device
)
result
=
model
.
generate
(
input_ids
,
max_length
=
10
,
return_dict_in_generate
=
True
,
output_scores
=
True
,
forced_eos_token_id
=
model
.
config
.
eos_token_id
,
num_beams
=
4
,
do_sample
=
False
,
num_return_sequences
=
3
,
length_penalty
=
0.0
,
)
transition_scores
=
model
.
compute_transition_scores
(
sequences
=
result
.
sequences
,
scores
=
result
.
scores
,
beam_indices
=
result
.
beam_indices
)
sum_transition_scores
=
torch
.
sum
(
transition_scores
,
dim
=
1
)
self
.
assertListEqual
(
sum_transition_scores
.
cpu
().
tolist
(),
result
.
sequences_scores
.
cpu
().
tolist
())
def
test_log_scores_sample_decoder_only
(
self
):
articles
=
[
"I need input_ids to generate"
,
"Short and"
]
tokenizer
=
GPT2Tokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment