Skip to content

Commit 74a2a4d

Browse files
do not index past decoded chars with special tokens (huggingface#45435)
* do not index past decoded chars with special tokens * better test explanation Co-authored-by: Krishnachaitanyakc <22275437+Krishnachaitanyakc@users.noreply.github.com> --------- Co-authored-by: Krishnachaitanyakc <22275437+Krishnachaitanyakc@users.noreply.github.com>
1 parent c71125f commit 74a2a4d

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

src/transformers/models/whisper/tokenization_whisper.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,7 @@ def _split_tokens_on_unicode(tokenizer, tokens: list[int]):
13311331

13321332
if (
13331333
replacement_char not in decoded
1334+
or unicode_offset + decoded.index(replacement_char) >= len(decoded_full)
13341335
or decoded_full[unicode_offset + decoded.index(replacement_char)] == replacement_char
13351336
):
13361337
words.append(decoded)

tests/models/whisper/test_tokenization_whisper.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
import numpy as np
1818

1919
from transformers.models.whisper import WhisperTokenizer
20-
from transformers.models.whisper.tokenization_whisper import _combine_tokens_into_words, _find_longest_common_sequence
20+
from transformers.models.whisper.tokenization_whisper import (
21+
_combine_tokens_into_words,
22+
_find_longest_common_sequence,
23+
_split_tokens_on_unicode,
24+
)
2125
from transformers.testing_utils import require_torch, slow
2226

2327
from ...test_tokenization_common import TokenizerTesterMixin
@@ -269,6 +273,30 @@ def test_combine_tokens_into_words(self):
269273
self.assertEqual(expected_tokens, output[1])
270274
self.assertEqual(expected_indices, output[2])
271275

276+
def test_split_tokens_on_unicode_trailing_replacement_char(self):
277+
"""Test `_split_tokens_on_unicode` with a trailing token that decodes to U+FFFD (Unicode replacement char)."""
278+
from collections import defaultdict
279+
280+
class DummyTokenizer:
281+
def __init__(self):
282+
self.responses = defaultdict(list)
283+
284+
def decode(self, tokens, decode_with_timestamps=False):
285+
key = tuple(tokens)
286+
if self.responses[key]:
287+
return self.responses[key].pop(0)
288+
return ""
289+
290+
tokenizer = DummyTokenizer()
291+
tokenizer.responses[(1, 2)] = ["ab"]
292+
tokenizer.responses[(1,)] = ["ab"]
293+
tokenizer.responses[(2,)] = ["\ufffd"]
294+
295+
words, word_tokens, token_indices = _split_tokens_on_unicode(tokenizer, [1, 2])
296+
self.assertEqual(words, ["ab", "\ufffd"])
297+
self.assertEqual(word_tokens, [[1], [2]])
298+
self.assertEqual(token_indices, [[0], [1]])
299+
272300
def test_basic_normalizer(self):
273301
tokenizer = self.get_tokenizer()
274302

0 commit comments

Comments
 (0)