-
Notifications
You must be signed in to change notification settings - Fork 34k
bump tokenizers, fix added tokens fast #32535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 23 commits
b152964
219af76
12bd0cb
b6847c8
f067ab2
1a71532
fc72737
405276d
4e7af23
4ef021c
6ba221b
950e3cd
4bd9502
92a7288
967201f
5cc3b1c
c44c774
e173de6
750d6bb
122da70
0a33af5
d29d9af
a9a6faa
aedf998
a93f1b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -170,15 +170,8 @@ def __init__(self, *args, **kwargs): | |||||||||||||
|
|
||||||||||||||
| # We call this after having initialized the backend tokenizer because we update it. | ||||||||||||||
| super().__init__(**kwargs) | ||||||||||||||
|
|
||||||||||||||
| # Set the splitting mode for special tokens for the tokenizer to be used throughout the class. | ||||||||||||||
| self._tokenizer.encode_special_tokens = self.split_special_tokens | ||||||||||||||
|
|
||||||||||||||
| # The following logic will be replace with a single add_tokens once a fix is pushed to tokenizers | ||||||||||||||
| # allows converting a slow -> fast, non-legacy: if the `tokenizer.json` does not have all the added tokens | ||||||||||||||
| # uses the information stored in `added_tokens_decoder`. | ||||||||||||||
| # this is costly for fast tokenizers as we re-compute the regex again. But not all tokens are added tokens | ||||||||||||||
| # Use hash to speed up the very slow operation `token not in added_tokens_decoder`. | ||||||||||||||
| added_tokens_decoder_hash = {hash(repr(token)) for token in self.added_tokens_decoder} | ||||||||||||||
| tokens_to_add = [ | ||||||||||||||
| token | ||||||||||||||
|
|
@@ -191,27 +184,7 @@ def __init__(self, *args, **kwargs): | |||||||||||||
| token for token in self.all_special_tokens_extended if token not in encoder and token not in tokens_to_add | ||||||||||||||
| ] | ||||||||||||||
|
|
||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ensures tokens are added as special if they are in all_special_tokens_extended (fixes test failure with
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also somehow
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmmm but I'd rather we just take them from |
||||||||||||||
| if len(tokens_to_add) > 0: | ||||||||||||||
| # super hack: if a token.special is set, tokenizer ignores it for now so FIXME @ArthurZ | ||||||||||||||
| # Accumulate added tokens into batches of special/non-special tokens, because calling add_tokens() for | ||||||||||||||
| # individual tokens would repeatedly rebuild a trie, which can be slow. | ||||||||||||||
| is_last_special = None | ||||||||||||||
| tokens = [] | ||||||||||||||
| special_tokens = self.all_special_tokens | ||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this used to ensure that tokens get added as special if they are in transformers/src/transformers/models/layoutxlm/tokenization_layoutxlm_fast.py Lines 233 to 234 in 2b789f2
But I'm not sure why only the mask token gets added like this in so many models and if we should just pass
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah we should make them special
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually you are right, I kep the logic to check special / change special if in all special tokens
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All tests pass thanks to you |
||||||||||||||
| for token in tokens_to_add: | ||||||||||||||
| is_special = ( | ||||||||||||||
| (token.special or str(token) in special_tokens) | ||||||||||||||
| if isinstance(token, AddedToken) | ||||||||||||||
| else str(token) in special_tokens | ||||||||||||||
| ) | ||||||||||||||
| if is_last_special is None or is_last_special == is_special: | ||||||||||||||
| tokens.append(token) | ||||||||||||||
| else: | ||||||||||||||
| self._add_tokens(tokens, special_tokens=is_last_special) | ||||||||||||||
| tokens = [token] | ||||||||||||||
| is_last_special = is_special | ||||||||||||||
| if tokens: | ||||||||||||||
| self._add_tokens(tokens, special_tokens=is_last_special) | ||||||||||||||
| self._add_tokens(tokens_to_add) | ||||||||||||||
|
|
||||||||||||||
| @property | ||||||||||||||
| def is_fast(self) -> bool: | ||||||||||||||
|
|
@@ -827,6 +800,13 @@ def train_new_from_iterator( | |||||||||||||
| if special_tokens_map is not None: | ||||||||||||||
| tokens = [special_tokens_map.get(token, token) for token in tokens] | ||||||||||||||
| post_processor["special_tokens"][key]["tokens"] = tokens | ||||||||||||||
| for token in tokens: | ||||||||||||||
| token_id = tokenizer.token_to_id(token) | ||||||||||||||
| if token_id is None: | ||||||||||||||
| raise ValueError( | ||||||||||||||
| "Attempted to set a token in the post processor that does not exist in the mapping" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| post_processor["special_tokens"][key]["ids"] = [tokenizer.token_to_id(token) for token in tokens] | ||||||||||||||
|
|
||||||||||||||
| for special_token in ["cls", "sep"]: | ||||||||||||||
|
|
@@ -835,6 +815,10 @@ def train_new_from_iterator( | |||||||||||||
| if special_tokens_map is not None and token in special_tokens_map: | ||||||||||||||
| token = special_tokens_map[token] | ||||||||||||||
| token_id = tokenizer.token_to_id(token) | ||||||||||||||
| if token_id is None: | ||||||||||||||
| raise ValueError( | ||||||||||||||
| "Attempted to set a token in the post processor that does not exist in the mapping" | ||||||||||||||
| ) | ||||||||||||||
| post_processor[special_token] = [token, token_id] | ||||||||||||||
|
|
||||||||||||||
| trained_tokenizer_json["post_processor"] = post_processor | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much cleaner!