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
...
@@ -50,6 +50,7 @@ and how to create and save a customized generation configuration, refer to the
[[autodoc]] generation.TFGenerationMixin
[[autodoc]] generation.TFGenerationMixin
- generate
- generate
- compute_transition_scores
## FlaxGenerationMixin
## 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):
...
@@ -301,9 +301,9 @@ class BeamSearchDecoderOnlyOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
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),
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)`.
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
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`):
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
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)`.
`torch.FloatTensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`.
...
@@ -338,10 +338,9 @@ class BeamSearchEncoderDecoderOutput(ModelOutput):
...
@@ -338,10 +338,9 @@ class BeamSearchEncoderDecoderOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
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),
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)`.
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
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)`.
attentions (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
encoder_attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or `config.output_attentions=True`):
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,
Tuple of `torch.FloatTensor` (one for each layer of the decoder) of shape `(batch_size, num_heads,
sequence_length, sequence_length)`.
sequence_length, sequence_length)`.
...
@@ -387,9 +386,9 @@ class BeamSampleDecoderOnlyOutput(ModelOutput):
...
@@ -387,9 +386,9 @@ class BeamSampleDecoderOnlyOutput(ModelOutput):
of log probabilities of tokens conditioned on log softmax of previously generated tokens in this beam.
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),
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)`.
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
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`):
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
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)`.
`torch.FloatTensor` of shape `(batch_size*num_beams, num_heads, generated_length, sequence_length)`.
...
@@ -426,7 +425,7 @@ class BeamSampleEncoderDecoderOutput(ModelOutput):
...
@@ -426,7 +425,7 @@ class BeamSampleEncoderDecoderOutput(ModelOutput):
with each tensor of shape `(batch_size*num_beams, config.vocab_size)`).
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 (`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
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`):
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,
Tuple of `torch.FloatTensor` (one for each layer of the decoder) of shape `(batch_size, num_heads,
sequence_length, sequence_length)`.
sequence_length, sequence_length)`.
...
@@ -937,9 +936,9 @@ class GenerationMixin:
...
@@ -937,9 +936,9 @@ class GenerationMixin:
of log probabilities of tokens conditioned on log softmax of previously generated tokens Tuple of
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
`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)`.
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
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.
generate-time.
normalize_logits (`bool`, *optional*, defaults to `False`):
normalize_logits (`bool`, *optional*, defaults to `False`):
Whether to normalize the logits (which, for legacy reasons, may be unnormalized).
Whether to normalize the logits (which, for legacy reasons, may be unnormalized).
...
@@ -1017,11 +1016,10 @@ class GenerationMixin:
...
@@ -1017,11 +1016,10 @@ class GenerationMixin:
# 4. cut beam_indices to longest beam length
# 4. cut beam_indices to longest beam length
beam_indices_mask
=
beam_indices
<
0
beam_indices_mask
=
beam_indices
<
0
max_beam_length
=
(
1
-
beam_indices_mask
.
long
()).
sum
(
-
1
).
max
()
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
]
beam_indices_mask
=
beam_indices_mask
[:,
:
max_beam_length
]
# 5. Set indices of beams that finished early to 0
# 5. Set indices of beams that finished early to 0; such indices will be masked correctly afterwards
# such indices will be masked correctly afterwards
beam_indices
[
beam_indices_mask
]
=
0
beam_indices
[
beam_indices_mask
]
=
0
# 6. multiply beam_indices with vocab size to gather correctly from scores
# 6. multiply beam_indices with vocab size to gather correctly from scores
...
@@ -3067,6 +3065,9 @@ class GenerationMixin:
...
@@ -3067,6 +3065,9 @@ class GenerationMixin:
next_token_scores_processed
=
logits_processor
(
input_ids
,
next_token_scores
)
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
)
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
)
next_token_scores
=
logits_warper
(
input_ids
,
next_token_scores
)
# Store scores, attentions and hidden_states when required
# 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.
...
@@ -5,7 +5,7 @@ Framework agnostic tests for generate()-related methods.
import
numpy
as
np
import
numpy
as
np
from
transformers
import
AutoTokenizer
from
transformers
import
AutoTokenizer
from
transformers.testing_utils
import
torch_device
from
transformers.testing_utils
import
slow
,
torch_device
class
GenerationIntegrationTestsMixin
:
class
GenerationIntegrationTestsMixin
:
...
@@ -133,16 +133,12 @@ class GenerationIntegrationTestsMixin:
...
@@ -133,16 +133,12 @@ class GenerationIntegrationTestsMixin:
def
test_encoder_decoder_generate_with_inputs_embeds
(
self
):
def
test_encoder_decoder_generate_with_inputs_embeds
(
self
):
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
model_cls
=
self
.
framework_dependent_parameters
[
"AutoModelForSeq2SeqLM"
]
return_tensors
=
self
.
framework_dependent_parameters
[
"return_tensors"
]
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."""
article
=
"""Justin Timberlake and Jessica Biel, welcome to parenthood."""
tokenizer
=
AutoTokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
)
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
=
model_cls
.
from_pretrained
(
"hf-internal-testing/tiny-random-bart"
,
max_length
=
5
)
model
.
config
.
eos_token_id
=
None
model
.
config
.
eos_token_id
=
None
input_ids
=
tokenizer
(
article
,
return_tensors
=
return_tensors
).
input_ids
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
)
inputs_embeds
=
model
.
get_input_embeddings
()(
input_ids
)
...
@@ -150,3 +146,253 @@ class GenerationIntegrationTestsMixin:
...
@@ -150,3 +146,253 @@ class GenerationIntegrationTestsMixin:
# make sure model generated correctly until `max_length`
# make sure model generated correctly until `max_length`
self
.
assertEqual
(
output_sequences
.
shape
,
(
1
,
5
))
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 @@
...
@@ -17,8 +17,6 @@
import
inspect
import
inspect
import
unittest
import
unittest
import
numpy
as
np
from
transformers
import
is_torch_available
,
pipeline
from
transformers
import
is_torch_available
,
pipeline
from
transformers.testing_utils
import
require_torch
,
slow
,
torch_device
from
transformers.testing_utils
import
require_torch
,
slow
,
torch_device
...
@@ -2220,165 +2218,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
...
@@ -2220,165 +2218,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
self
.
assertListEqual
(
output_sequences_no_mask
.
tolist
(),
output_sequences_with_mask
.
tolist
())
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
):
def
test_transition_scores_group_beam_search_encoder_decoder
(
self
):
articles
=
[
articles
=
[
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
"Justin Timberlake and Jessica Biel, welcome to parenthood."
,
...
@@ -2406,38 +2245,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
...
@@ -2406,38 +2245,6 @@ class GenerationIntegrationTests(unittest.TestCase, GenerationIntegrationTestsMi
self
.
assertTrue
(
torch
.
allclose
(
transition_scores_sum
,
outputs
.
sequences_scores
,
atol
=
1e-3
))
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
):
def
test_log_scores_sample_decoder_only
(
self
):
articles
=
[
"I need input_ids to generate"
,
"Short and"
]
articles
=
[
"I need input_ids to generate"
,
"Short and"
]
tokenizer
=
GPT2Tokenizer
.
from_pretrained
(
"hf-internal-testing/tiny-random-gpt2"
)
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