Hugging Face Tokenizers

Hugging Face Tokenizers Hugging Face Tokenizers

Tokenizadores de rostos abraçadoslink image 32

A biblioteca Hugging Face tokenizers fornece uma implementação dos tokenizadores mais usados atualmente, com foco no desempenho e na versatilidade. Na postagem tokens, já vimos a importância dos tokens no processamento de texto, pois os computadores não entendem palavras, mas números. Portanto, é necessário converter palavras em números para que os modelos de linguagem possam processá-las.

Este caderno foi traduzido automaticamente para torná-lo acessível a mais pessoas, por favor me avise se você vir algum erro de digitação..

Instalaçãolink image 33

Para instalar o tokenizers com o pip:

pip install tokenizers
      ```
      
      para instalar o `tokenizers` com o conda:
      
      ````bash
      conda install conda-forge::tokenizers
      ```
      

O pipeline de tokenizaçãolink image 34

Para tokenizar uma sequência, é usado o Tokenizer.encode, que executa as seguintes etapas:

  • Padronização
  • pré-tokenização
  • Tokenização
  • Pós-tokenização

Vamos dar uma olhada em cada um deles

Para esta postagem, usaremos o conjunto de dados [wikitext-103] (https://blog.einstein.ai/the-wikitext-long-term-dependency-language-modeling-dataset/)

!wget https://dax-cdn.cdn.appdomain.cloud/dax-wikitext-103/1.0.1/wikitext-103.tar.gz
      
--2024-02-26 08:14:11--  https://dax-cdn.cdn.appdomain.cloud/dax-wikitext-103/1.0.1/wikitext-103.tar.gz
      Resolving dax-cdn.cdn.appdomain.cloud (dax-cdn.cdn.appdomain.cloud)... 23.200.169.125
      Connecting to dax-cdn.cdn.appdomain.cloud (dax-cdn.cdn.appdomain.cloud)|23.200.169.125|:443... connected.
      HTTP request sent, awaiting response... 
200 OK
      Length: 189603606 (181M) [application/x-gzip]
      Saving to: ‘wikitext-103.tar.gz’
      
      wikitext-103.tar.gz 100%[===================>] 180,82M  6,42MB/s    in 30s     
      
      2024-02-26 08:14:42 (5,95 MB/s) - ‘wikitext-103.tar.gz’ saved [189603606/189603606]
      
      
	
!wget https://dax-cdn.cdn.appdomain.cloud/dax-wikitext-103/1.0.1/wikitext-103.tar.gz
!tar -xvzf wikitext-103.tar.gz
Copy
	
--2024-02-26 08:14:11-- https://dax-cdn.cdn.appdomain.cloud/dax-wikitext-103/1.0.1/wikitext-103.tar.gz
Resolving dax-cdn.cdn.appdomain.cloud (dax-cdn.cdn.appdomain.cloud)... 23.200.169.125
Connecting to dax-cdn.cdn.appdomain.cloud (dax-cdn.cdn.appdomain.cloud)|23.200.169.125|:443... connected.
HTTP request sent, awaiting response...
wikitext-103/
wikitext-103/wiki.test.tokens
wikitext-103/wiki.valid.tokens
wikitext-103/README.txt
wikitext-103/LICENSE.txt
wikitext-103/wiki.train.tokens
	
!rm wikitext-103.tar.gz
Copy

Padronizaçãolink image 35

As normalizações são operações aplicadas ao texto antes da tokenização, como a remoção de espaços em branco, a conversão para letras minúsculas, a remoção de caracteres especiais etc. As seguintes normalizações são implementadas no Hugging Face:

Normalización Descripción Ejemplo
NFD (Normalization for D) Los caracteres se descomponen por equivalencia canónica â (U+00E2) se descompone en a (U+0061) + ^ (U+0302)
NFKD (Normalization Form KD) Los caracteres se descomponen por compatibilidad (U+FB01) se descompone en f (U+0066) + i (U+0069)
NFC (Normalization Form C) Los caracteres se descomponen y luego se recomponen por equivalencia canónica â (U+00E2) se descompone en a (U+0061) + ^ (U+0302) y luego se recompone en â (U+00E2)
NFKC (Normalization Form KC) Los caracteres se descomponen por compatibilidad y luego se recomponen por equivalencia canónica (U+FB01) se descompone en f (U+0066) + i (U+0069) y luego se recompone en f (U+0066) + i (U+0069)
Lowercase Convierte el texto a minúsculas Hello World se convierte en hello world
Strip Elimina todos los espacios en blanco de los lados especificados (izquierdo, derecho o ambos) del texto Hello World se convierte en Hello World
StripAccents Elimina todos los símbolos de acento en unicode (se utilizará con NFD por coherencia) á (U+00E1) se convierte en a (U+0061)
Replace Sustituye una cadena personalizada o regex y la cambia por el contenido dado Hello World se convierte en Hello Universe
BertNormalizer Proporciona una implementación del Normalizador utilizado en el BERT original. Las opciones que se pueden configurar son clean_text, handle_chinese_chars, strip_accents y lowercase Hello World se convierte en hello world

Vamos criar um normalizador para ver como ele funciona.

	
!rm wikitext-103.tar.gz
from tokenizers import normalizers
bert_normalizer = normalizers.BertNormalizer()
input_text = "Héllò hôw are ü?"
normalized_text = bert_normalizer.normalize_str(input_text)
normalized_text
Copy
	
'hello how are u?'

Para usar vários normalizadores, podemos usar o método Sequence.

	
custom_normalizer = normalizers.Sequence([normalizers.NFKC(), normalizers.BertNormalizer()])
normalized_text = custom_normalizer.normalize_str(input_text)
normalized_text
Copy
	
'hello how are u?'

Para modificar o normalizador de um tokenizador

	
import tokenizers
tokenizer = tokenizers.BertWordPieceTokenizer() # or any other tokenizer
Copy
	
import tokenizers
tokenizer = tokenizers.BertWordPieceTokenizer() # or any other tokenizer
tokenizer.normalizer = custom_normalizer
Copy

Pré-tokenizaçãolink image 36

Pretokenização é o ato de dividir o texto em objetos menores. O pretokenizador dividirá o texto em "palavras" e os tokens finais serão partes dessas palavras.

O PreTokenizer se encarrega de dividir a entrada de acordo com um conjunto de regras. Esse pré-processamento permite que você garanta que o tokenizador não crie tokens em várias "divisões". Por exemplo, se você não quiser ter espaços em branco em um token, poderá ter um pré-tokenizador que divida as palavras em espaços em branco.

Os seguintes pré-tokenizadores são implementados no Hugging Face

PreTokenizer Descripción Ejemplo
ByteLevel Divide en espacios en blanco mientras reasigna todos los bytes a un conjunto de caracteres visibles. Esta técnica fue introducida por OpenAI con GPT-2 y tiene algunas propiedades más o menos buenas: Como mapea sobre bytes, un tokenizador que utilice esto sólo requiere 256 caracteres como alfabeto inicial (el número de valores que puede tener un byte), frente a los más de 130.000 caracteres Unicode. Una consecuencia del punto anterior es que es absolutamente innecesario tener un token desconocido usando esto ya que podemos representar cualquier cosa con 256 tokens. Para caracteres no ascii, se vuelve completamente ilegible, ¡pero funciona! Hello my friend, how are you? se divide en Hello, Ġmy, Ġfriend, ,, Ġhow, Ġare, Ġyou, ?
Whitespace Divide en límites de palabra usando la siguiente expresión regular: \w+[^\w\s]+. En mi post sobre expresiones regulares puedes entender qué hace Hello there! se divide en Hello, there, !
WhitespaceSplit Se divide en cualquier carácter de espacio en blanco Hello there! se divide en Hello, there!
Punctuation Aislará todos los caracteres de puntuación Hello? se divide en Hello, ?
Metaspace Separa los espacios en blanco y los sustituye por un carácter especial "▁" (U+2581) Hello there se divide en Hello, ▁there
CharDelimiterSplit Divisiones en un carácter determinado Ejemplo con el caracter x: Helloxthere se divide en Hello, there
Digits Divide los números de cualquier otro carácter Hello123there se divide en Hello, 123, there
Split Pretokenizador versátil que divide según el patrón y el comportamiento proporcionados. El patrón se puede invertir si es necesario. El patrón debe ser una cadena personalizada o una regex. El comportamiento debe ser removed, isolated, merged_with_previous, merged_with_next, contiguous. Para invertir se indica con un booleano Ejemplo con pattern=" ", behavior=isolated, invert=False: Hello, how are you? se divide en Hello,, , how, , are, , you?

Vamos criar um pré-tokenizador para ver como ele funciona.

	
import tokenizers
tokenizer = tokenizers.BertWordPieceTokenizer() # or any other tokenizer
tokenizer.normalizer = custom_normalizer
from tokenizers import pre_tokenizers
pre_tokenizer = pre_tokenizers.Digits(individual_digits=True)
input_text = "I paid $30 for the car"
pre_tokenized_text = pre_tokenizer.pre_tokenize_str(input_text)
pre_tokenized_text
Copy
	
[('I paid $', (0, 8)),
('3', (8, 9)),
('0', (9, 10)),
(' for the car', (10, 22))]

Para usar vários pré-tokenizadores, podemos usar o método Sequence.

	
custom_pre_tokenizer = pre_tokenizers.Sequence([pre_tokenizers.Whitespace(), pre_tokenizers.Digits(individual_digits=True)])
pre_tokenized_text = custom_pre_tokenizer.pre_tokenize_str(input_text)
pre_tokenized_text
Copy
	
[('I', (0, 1)),
('paid', (2, 6)),
('$', (7, 8)),
('3', (8, 9)),
('0', (9, 10)),
('for', (11, 14)),
('the', (15, 18)),
('car', (19, 22))]

Para modificar o pré-tokenizador de um tokenizador

	
tokenizer.pre_tokenizer = custom_pre_tokenizer
Copy

Tokenizaçãolink image 37

Depois que os textos de entrada tiverem sido normalizados e pré-tokenizados, o tokenizador aplica o modelo aos pré-tokens. Essa é a parte do processo que precisa ser treinada no corpus (ou já foi treinada se for usado um tokenizador pré-treinado).

A função do modelo é dividir as "palavras" em tokens usando as regras que aprendeu. Ele também é responsável por atribuir esses tokens às suas IDs correspondentes no vocabulário do modelo.

O modelo tem um tamanho de vocabulário, ou seja, tem um número finito de tokens, portanto, precisa decompor as palavras e atribuí-las a um desses tokens.

Esse modelo é passado quando o Tokenizer é inicializado. Atualmente, a biblioteca 🤗 Tokenizers é compatível:

Modelo Descripción
WordLevel Este es el algoritmo "clásico" de tokenización. Te permite simplemente asignar palabras a IDs sin nada sofisticado. Tiene la ventaja de ser muy fácil de usar y entender, pero requiere vocabularios extremadamente grandes para una buena cobertura. El uso de este modelo requiere el uso de un PreTokenizer. Este modelo no realiza ninguna elección directamente, simplemente asigna tokens de entrada a IDs.
BPE (Byte Pair Encoding) Uno de los algoritmos de tokenización de subpalabras más populares. El Byte-Pair-Encoding funciona empezando con caracteres y fusionando los que se ven juntos con más frecuencia, creando así nuevos tokens. A continuación, trabaja de forma iterativa para construir nuevos tokens a partir de los pares más frecuentes que ve en un corpus. BPE es capaz de construir palabras que nunca ha visto utilizando múltiples subpalabras y, por tanto, requiere vocabularios más pequeños, con menos posibilidades de tener palabras unk (desconocidas).
WordPiece Se trata de un algoritmo de tokenización de subpalabras bastante similar a BPE, utilizado principalmente por Google en modelos como BERT. Utiliza un algoritmo codicioso que intenta construir primero palabras largas, dividiéndolas en varios tokens cuando no existen palabras completas en el vocabulario. A diferencia de BPE, que parte de los caracteres y construye tokens lo más grandes posible. Utiliza el famoso prefijo ## para identificar los tokens que forman parte de una palabra (es decir, que no empiezan una palabra).
Unigram Unigram es también un algoritmo de tokenización de subpalabras, y funciona tratando de identificar el mejor conjunto de tokens de subpalabras para maximizar la probabilidad de una frase dada. Se diferencia de BPE en que no es un algoritmo determinista basado en un conjunto de reglas aplicadas secuencialmente. En su lugar, Unigram podrá calcular múltiples formas de tokenizar, eligiendo la más probable.

Quando você cria um tokenizador, precisa passar a ele o modelo

	
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers import Tokenizer, models
tokenizer = Tokenizer(models.Unigram())
Copy

Passaremos o normalizador e o pré-tokenizador que criamos para ele.

	
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers import Tokenizer, models
tokenizer = Tokenizer(models.Unigram())
tokenizer.normalizer = custom_normalizer
tokenizer.pre_tokenizer = custom_pre_tokenizer
Copy

Agora temos que treinar o modelo ou carregar um modelo pré-treinado. Neste caso, vamos treinar um modelo com o corpus que baixamos.

Treinamento de modeloslink image 38

Para treinar o modelo, temos vários tipos de "treinadores".

Trainer Descripción
WordLevelTrainer Entrena un tokenizador WordLevel
BpeTrainer Entrena un tokenizador BPE
WordPieceTrainer Entrena un tokenizador WordPiece
UnigramTrainer Entrena un tokenizador Unigram

Quase todos os treinadores têm os mesmos parâmetros, que são:

  • vocab_size: o tamanho do vocabulário final, incluindo todos os tokens e o alfabeto.
  • show_progress: Mostrar ou não barras de progresso durante o treinamento
  • special_tokens: Uma lista de tokens especiais dos quais o modelo deve estar ciente.

Além desses parâmetros, cada treinador tem seus próprios parâmetros; consulte a documentação Trainers para obter mais informações.

Para treinar, precisamos criar um Trainer. Como o modelo que criamos é um Unigram, criaremos um UnigramTrainer.

	
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers import Tokenizer, models
tokenizer = Tokenizer(models.Unigram())
tokenizer.normalizer = custom_normalizer
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers.trainers import trainers
trainer = trainers.UnigramTrainer(
vocab_size=20000,
initial_alphabet=pre_tokenizers.ByteLevel.alphabet(),
special_tokens=["<PAD>", "<BOS>", "<EOS>"],
)
Copy

Depois de criarmos o Trainer, há duas maneiras de entrar, usando o método train, que recebe uma lista de arquivos, ou usando o método train_from_iterator, que recebe um iterador.

Treinamento do modelo com o método train.link image 39

Primeiro, criamos uma lista de arquivos com o corpus

	
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers import Tokenizer, models
tokenizer = Tokenizer(models.Unigram())
tokenizer.normalizer = custom_normalizer
tokenizer.pre_tokenizer = custom_pre_tokenizer
from tokenizers.trainers import trainers
trainer = trainers.UnigramTrainer(
vocab_size=20000,
initial_alphabet=pre_tokenizers.ByteLevel.alphabet(),
special_tokens=["<PAD>", "<BOS>", "<EOS>"],
)
files = [f"wikitext-103/wiki.{split}.tokens" for split in ["test", "train", "valid"]]
files
Copy
	
['wikitext-103/wiki.test.tokens',
'wikitext-103/wiki.train.tokens',
'wikitext-103/wiki.valid.tokens']

E agora treinamos o modelo

	
tokenizer.train(files, trainer)
Copy
	
Treinamento do modelo com o método train_from_iterator.link image 40

Primeiro, criamos uma função que retorna um iterador.

	
def iterator():
for file in files:
with open(file, "r") as f:
for line in f:
yield line
Copy

Agora, treinamos novamente o modelo

	
def iterator():
for file in files:
with open(file, "r") as f:
for line in f:
yield line
tokenizer.train_from_iterator(iterator(), trainer)
Copy
	
Treinamento do modelo com o método train_from_iterator a partir de um conjunto de dados Hugging Facelink image 41

Se tivéssemos baixado o conjunto de dados Hugging Face, poderíamos ter treinado o modelo diretamente do conjunto de dados.

	
import datasets
dataset = datasets.load_dataset("wikitext", "wikitext-103-raw-v1", split="train+test+validation")
Copy

Agora podemos criar um iterador

	
import datasets
dataset = datasets.load_dataset("wikitext", "wikitext-103-raw-v1", split="train+test+validation")
def batch_iterator(batch_size=1000):
for i in range(0, len(dataset), batch_size):
yield dataset[i : i + batch_size]["text"]
Copy

Treinamos novamente o modelo

	
import datasets
dataset = datasets.load_dataset("wikitext", "wikitext-103-raw-v1", split="train+test+validation")
def batch_iterator(batch_size=1000):
for i in range(0, len(dataset), batch_size):
yield dataset[i : i + batch_size]["text"]
tokenizer.train_from_iterator(batch_iterator(), trainer=trainer, length=len(dataset))
Copy
	

Salvando o modelolink image 42

Depois que o modelo tiver sido treinado, ele poderá ser salvo para uso futuro. Para salvar o modelo, é necessário salvá-lo em um arquivo json.

	
tokenizer.save("wikitext-103-tokenizer.json")
Copy

Carregando o modelo pré-treinadolink image 43

Podemos carregar um modelo pré-treinado a partir de um json em vez de precisar treiná-lo.

	
tokenizer.save("wikitext-103-tokenizer.json")
tokenizer.from_file("wikitext-103-tokenizer.json")
Copy
	
<tokenizers.Tokenizer at 0x7f1dd7784a30>

Também podemos carregar um modelo pré-treinado disponível no Hugging Face Hub.

	
tokenizer.from_pretrained('bert-base-uncased')
Copy
	
<tokenizers.Tokenizer at 0x7f1d64a75e30>

Pós-processamentolink image 44

Talvez queiramos que nosso tokenizador adicione automaticamente tokens especiais, como [CLS] ou [SEP].

Os seguintes pós-processadores são implementados no Hugging Face

PostProcesador Descripción Ejemplo
BertProcessing Este post-procesador se encarga de añadir los tokens especiales que necesita un modelo Bert (SEP y CLS) Hello, how are you? se convierte en [CLS], Hello, ,, how, are, you, ?, [SEP]
RobertaProcessing Este post-procesador se encarga de añadir los tokens especiales que necesita un modelo Roberta (SEP y CLS). También se encarga de recortar los offsets. Por defecto, el ByteLevel BPE puede incluir espacios en blanco en los tokens producidos. Si no desea que las compensaciones incluyan estos espacios en blanco, hay que inicializar este PostProcessor con trim_offsets=True. Hello, how are you? se convierte en <s>, Hello, ,, how, are, you, ?, </s>
ElectraProcessing Añade tokens especiales para ELECTRA Hello, how are you? se convierte en [CLS], Hello, ,, how, are, you, ?, [SEP]
TemplateProcessing Permite crear fácilmente una plantilla para el postprocesamiento, añadiendo tokens especiales y especificando el type_id de cada secuencia/token especial. La plantilla recibe dos cadenas que representan la secuencia única y el par de secuencias, así como un conjunto de tokens especiales a utilizar Example, when specifying a template with these values: single:[CLS] $A [SEP], pair: [CLS] $A [SEP] $B [SEP], special tokens: [CLS], [SEP]. Input: (I like this, but not this), Output: [CLS] I like this [SEP] but not this [SEP]

Vamos criar um tokenizador de postagem para ver como ele funciona.

	
from tokenizers.processors import TemplateProcessing
post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[("[CLS]", 1), ("[SEP]", 2)],
)
Copy

Para modificar o tokenizador de postagem de um tokenizador

	
from tokenizers.processors import TemplateProcessing
post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[("[CLS]", 1), ("[SEP]", 2)],
)
tokenizer.post_processor = post_processor
Copy

Vamos ver como funciona

	
from tokenizers.processors import TemplateProcessing
post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[("[CLS]", 1), ("[SEP]", 2)],
)
tokenizer.post_processor = post_processor
input_text = "I paid $30 for the car"
decoded_text = tokenizer.encode(input_text)
decoded_text.tokens
Copy
	
['[CLS]', 'i', 'paid', '$', '3', '0', 'for', 'the', 'car', '[SEP]']
	
input_text1 = "Hello, y'all!"
input_text2 = "How are you?"
decoded_text = tokenizer.encode(input_text1, input_text2)
print(decoded_text.tokens)
Copy
	
['[CLS]', 'hell', 'o', ',', 'y', "'", 'all', '!', '[SEP]', 'how', 'are', 'you', '?', '[SEP]']

Se salvarmos o tokenizador agora, o tokenizador de postagem será salvo com ele.

Codificaçãolink image 45

Depois de treinar o tokenizador, podemos usá-lo para tokenizar textos.

	
input_text = "I love tokenizers!"
encoded_text = tokenizer.encode(input_text)
Copy

Vejamos o que obtemos ao tokenizar um texto

	
input_text = "I love tokenizers!"
encoded_text = tokenizer.encode(input_text)
type(encoded_text)
Copy
	
tokenizers.Encoding

Obtemos um objeto do tipo Encoding, contendo os tokens e os ids dos tokens.

Os ids são os ids dos tokens no vocabulário do tokenizador.

	
encoded_text.ids
Copy
	
[1, 17, 383, 10694, 17, 3533, 3, 586, 2]

Tokens são os tokens aos quais os ids são equivalentes.

	
encoded_text.tokens
Copy
	
['[CLS]', 'i', 'love', 'token', 'i', 'zer', 's', '!', '[SEP]']

Se tivermos várias sequências, poderemos codificá-las todas de uma vez

	
encoded_texts = tokenizer.encode(input_text1, input_text2)
print(encoded_texts.tokens)
print(encoded_texts.ids)
print(encoded_texts.type_ids)
Copy
	
['[CLS]', 'hell', 'o', ',', 'y', "'", 'all', '!', '[SEP]', 'how', 'are', 'you', '?', '[SEP]']
[1, 2215, 7, 5, 22, 26, 81, 586, 2, 98, 59, 213, 902, 2]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

No entanto, quando você tem várias sequências, é melhor usar o método encode_batch.

	
encoded_texts = tokenizer.encode_batch([input_text1, input_text2])
type(encoded_texts)
Copy
	
list

Vemos que obtemos uma lista

	
print(encoded_texts[0].tokens)
print(encoded_texts[0].ids)
print(encoded_texts[1].tokens)
print(encoded_texts[1].ids)
Copy
	
['[CLS]', 'hell', 'o', ',', 'y', "'", 'all', '!', '[SEP]']
[1, 2215, 7, 5, 22, 26, 81, 586, 2]
['[CLS]', 'how', 'are', 'you', '?', '[SEP]']
[1, 98, 59, 213, 902, 2]

Decodificaçãolink image 46

Além de codificar os textos de entrada, um Tokenizer também tem um método para decodificar, ou seja, converter os IDs gerados pelo seu modelo de volta para um texto. Isso é feito pelos métodos Tokenizer.decode (para um texto previsto) e Tokenizer.decode_batch (para um lote de previsões).

Os tipos de decodificação que podem ser usados são:

Decodificación Descripción
BPEDecoder Revierte el modelo BPE
ByteLevel Revierte el ByteLevel PreTokenizer. Este PreTokenizer codifica a nivel de byte, utilizando un conjunto de caracteres Unicode visibles para representar cada byte, por lo que necesitamos un Decoder para revertir este proceso y obtener algo legible de nuevo.
CTC Revierte el modelo CTC
Metaspace Revierte el PreTokenizer de Metaspace. Este PreTokenizer utiliza un identificador especial ▁ para identificar los espacios en blanco, por lo que este Decoder ayuda con la decodificación de estos.
WordPiece Revierte el modelo WordPiece. Este modelo utiliza un identificador especial ## para las subpalabras continuas, por lo que este decodificador ayuda a decodificarlas.

O decodificador primeiro converterá os IDs em tokens (usando o vocabulário do tokenizador) e removerá todos os tokens especiais e, em seguida, juntará esses tokens com espaços em branco.

Vamos criar um decodificador

	
from tokenizers import decoders
decoder = decoders.ByteLevel()
Copy

Nós o adicionamos ao tokenizador

	
from tokenizers import decoders
decoder = decoders.ByteLevel()
tokenizer.decoder = decoder
Copy

Nós decodificamos

	
from tokenizers import decoders
decoder = decoders.ByteLevel()
tokenizer.decoder = decoder
decoded_text = tokenizer.decode(encoded_text.ids)
input_text, decoded_text
Copy
	
('I love tokenizers!', 'ilovetokenizers!')
	
decoded_texts = tokenizer.decode_batch([encoded_texts[0].ids, encoded_texts[1].ids])
print(input_text1, decoded_texts[0])
print(input_text2, decoded_texts[1])
Copy
	
Hello, y'all! hello,y'all!
How are you? howareyou?

BERT tokenizerlink image 47

Com tudo o que aprendemos, vamos criar o tokenizador BERT do zero. O Bert usa o WordPiece como modelo, então o passamos para o inicializador do tokenizador.

	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
Copy

O BERT pré-processa os textos removendo acentos e letras minúsculas. Também usamos um normalizador unicode

	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
from tokenizers import normalizers
from tokenizers.normalizers import NFD, Lowercase, StripAccents
bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])
Copy

O pretokenizador divide apenas espaços em branco e sinais de pontuação.

	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
from tokenizers import normalizers
from tokenizers.normalizers import NFD, Lowercase, StripAccents
bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])
from tokenizers.pre_tokenizers import Whitespace
bert_tokenizer.pre_tokenizer = Whitespace()
Copy

E o pós-processamento usa o modelo que vimos na seção anterior

	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
from tokenizers import normalizers
from tokenizers.normalizers import NFD, Lowercase, StripAccents
bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])
from tokenizers.pre_tokenizers import Whitespace
bert_tokenizer.pre_tokenizer = Whitespace()
from tokenizers.processors import TemplateProcessing
bert_tokenizer.post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[
("[CLS]", 1),
("[SEP]", 2),
],
)
Copy

Treinamos o tokenizador com o conjunto de dados wikitext-103.

	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
from tokenizers import normalizers
from tokenizers.normalizers import NFD, Lowercase, StripAccents
bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])
from tokenizers.pre_tokenizers import Whitespace
bert_tokenizer.pre_tokenizer = Whitespace()
from tokenizers.processors import TemplateProcessing
bert_tokenizer.post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[
("[CLS]", 1),
("[SEP]", 2),
],
)
from tokenizers.trainers import WordPieceTrainer
trainer = WordPieceTrainer(vocab_size=30522, special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])
Copy
	
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
bert_tokenizer = Tokenizer(WordPiece(unk_token="[UNK]"))
from tokenizers import normalizers
from tokenizers.normalizers import NFD, Lowercase, StripAccents
bert_tokenizer.normalizer = normalizers.Sequence([NFD(), Lowercase(), StripAccents()])
from tokenizers.pre_tokenizers import Whitespace
bert_tokenizer.pre_tokenizer = Whitespace()
from tokenizers.processors import TemplateProcessing
bert_tokenizer.post_processor = TemplateProcessing(
single="[CLS] $A [SEP]",
pair="[CLS] $A [SEP] $B:1 [SEP]:1",
special_tokens=[
("[CLS]", 1),
("[SEP]", 2),
],
)
from tokenizers.trainers import WordPieceTrainer
trainer = WordPieceTrainer(vocab_size=30522, special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"])
files = [f"wikitext-103/wiki.{split}.tokens" for split in ["test", "train", "valid"]]
bert_tokenizer.train(files, trainer)
Copy
	

Agora vamos testá-lo

	
input_text = "I love tokenizers!"
encoded_text = bert_tokenizer.encode(input_text)
decoded_text = bert_tokenizer.decode(encoded_text.ids)
print(f"El texto de entrada '{input_text}' se convierte en los tokens {encoded_text.tokens}, que tienen las ids {encoded_text.ids} y luego se decodifica como '{decoded_text}'")
Copy
	
El texto de entrada 'I love tokenizers!' se convierte en los tokens ['[CLS]', 'i', 'love', 'token', '##izers', '!', '[SEP]'], que tienen las ids [1, 51, 2867, 25791, 12213, 5, 2] y luego se decodifica como 'i love token ##izers !'

Continuar lendo

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

Você já conversou com um LLM e ele lhe respondeu algo que parece ter bebido café de máquina a noite toda? 😂 Isso é o que chamamos de alucinação no mundo dos LLMs! Mas não se preocupe, pois não é que seu modelo de linguagem esteja louco (embora às vezes possa parecer isso 🤪). A verdade é que os LLMs podem ser um pouco... criativos quando se trata de gerar texto. Mas graças ao DoLa, um método que usa camadas de contraste para melhorar a viabilidade dos LLMs, podemos evitar que nossos modelos de linguagem se transformem em escritores de ficção científica 😂. Nesta publicação, explicarei como o DoLa funciona e mostrarei um exemplo de código para que você possa entender melhor como tornar seus LLMs mais confiáveis e menos propensos a inventar histórias. Vamos salvar nossos LLMs da loucura e torná-los mais úteis! 🚀

Últimos posts -->

Você viu esses projetos?

Subtify

Subtify Subtify

Gerador de legendas para vídeos no idioma que você desejar. Além disso, coloca uma legenda de cor diferente para cada pessoa

Ver todos os projetos -->

Quer aplicar IA no seu projeto? Entre em contato!

Quer melhorar com essas dicas?

Últimos tips -->

Use isso localmente

Os espaços do Hugging Face nos permitem executar modelos com demos muito simples, mas e se a demo quebrar? Ou se o usuário a deletar? Por isso, criei contêineres docker com alguns espaços interessantes, para poder usá-los localmente, aconteça o que acontecer. Na verdade, se você clicar em qualquer botão de visualização de projeto, ele pode levá-lo a um espaço que não funciona.

Ver todos os contêineres -->

Quer aplicar IA no seu projeto? Entre em contato!

Você quer treinar seu modelo com esses datasets?

short-jokes-dataset

Dataset com piadas em inglês

opus100

Dataset com traduções de inglês para espanhol

netflix_titles

Dataset com filmes e séries da Netflix

Ver mais datasets -->