Почему кодировка BPE, обученная на английском и примененная на бенгальском, не возвращает неизвестные токены?

#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. Специальный символ пробела, добавляемый к каждой строке ( Ġ ), и
  2. Четыре байта, представляющие ваш персонаж,

это означает, что символ বা отсутствует в словаре, поэтому он в конечном итоге представляется в виде четырех байтов, а байты всегда известны.

Комментарии:

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'] `