#huggingface-transformers #huggingface-tokenizers #roberta-language-model
Вопрос:
Я использую токенизатор roberta-base tokenizer = RobertaTokenizerFast.from_pretrained('roberta-base',add_prefix_space=True)
, обученный английским данным, для токенизации бенгальского языка, просто чтобы посмотреть, как он себя ведет . Когда я пытаюсь закодировать бенгальский иероглиф tokenizer.encode('বা')
, я получаю [0, 1437, 35861, 11582, 35861, 4726, 2]
, что означает, что он находит в своем словаре некоторые лексемы, соответствующие бенгальским иероглифам, даже если тренируюсь на английском языке. При дальнейшем исследовании я обнаружил, что все это специальные символы ['<s>', 'Ġ', 'à¦', '¬', 'à¦', '¾', '</s>']
. Мой вопрос в том, почему это происходит, разве он не должен выводить неизвестные токены при применении на новом языке ? Любая помощь будет очень признательна
Комментарии:
1. Роберта использует BPE байтового уровня .
2. Как упоминалось ранее, Роберта использует токенизатор BPE байтового уровня. Это означает, что входные данные маркированы на байтовом уровне и, следовательно, находят маркеры, которые представляют
বা
.
Ответ №1:
Как упоминалось в комментариях, причина в том, что маркировщик RoBERTa основан на байтах, а не на символах.
В UTF-8 символы представлены разным количеством байтов, что сильно смещено в сторону латинского алфавита: символы ASCII являются однобайтовыми, «самые длинные» символы составляют до четырех байтов. Пример из Википедии:
Char | UTF code | Bytes
------------------------------
$ | U 0024 | 24
¢ | U 00A2 | C2 A2
ह | U 0939 | E0 A4 B9
€ | U 20AC | E2 82 AC
𐍈 | U 10348 | F0 90 8D 88
Токенизатор SentecePiece, используемый Робертой, таким образом, сначала разбивает текст на байты, это всегда возможно, и их всего 256, так что ничто не является каждым OOV. Затем известные группы байтов группируются в известные токены из словаря.
Раздел предложений также выполняет специальную обработку пробелов и специальных символов. Во-первых, он сегментирует текст на специальные символы и пробелы и заменяет пробелы специальным символом. В первоначальной реализации это было специальное подчеркивание UTF-8 ▁
, в реализации Huggingface это так Ġ
. Этот специальный символ также добавляется к самому началу предложения, поэтому слова последовательно представлены, когда они находятся в начале или в середине предложения.
Итак, вывод, который вы видите, в основном:
- Специальный символ пробела, добавляемый к каждой строке (
Ġ
), и - Четыре байта, представляющие ваш персонаж,
это означает, что символ বা
отсутствует в словаре, поэтому он в конечном итоге представляется в виде четырех байтов, а байты всегда известны.
Комментарии:
1.
This special character is also prepended to the very beginning of the sentence, so words are consistently represented when they are at the beginning or in the middle of a sentence.
Afaik это не так, пока вы не заставите маркировщик делать это с помощью параметра.t.tokenize('hello world hello world') -> ['hello', 'Ġworld', 'Ġhello', 'Ġworld']
`