NLP Course documentation

Modelos

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Modelos

Ask a Question Open In Colab Open In Studio Lab

Nesta seção, vamos analisar mais de perto a criação e a utilização de um modelo. Vamos utilizar a classe AutoModel, que é útil quando você quer instanciar qualquer modelo a partir de um checkpoint.

A classe AutoModel e todas as classes filhas são na verdade simples wrapper sobre a grande variedade de modelos disponíveis na biblioteca. É um wrapper inteligente, pois pode automaticamente “adivinhar” a arquitetura apropriada do modelo para seu checkpoint, e então instancia um modelo com esta arquitetura.

Entretanto, se você conhece o tipo de modelo que deseja usar, pode usar diretamente a classe que define sua arquitetura. Vamos dar uma olhada em como isto funciona com um modelo BERT.

Criando um Transformer

A primeira coisa que precisamos fazer para inicializar um modelo BERT é carregar um objeto de configuração:

from transformers import BertConfig, BertModel

# Construindo a configuração
config = BertConfig()

# Construindo o modelo a partir da configuração
model = BertModel(config)

A configuração contém muitos atributos que são usados para construir o modelo:

print(config)
BertConfig {
  [...]
  "hidden_size": 768,
  "intermediate_size": 3072,
  "max_position_embeddings": 512,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  [...]
}

Embora você ainda não tenha visto o que todos esses atributos fazem, você deve reconhecer alguns deles: o atributo hidden_size define o tamanho do vetor hidden_states, e o num_hidden_layers define o número de camadas que o Transformer possui.

Diferentes métodos de inicializar o modelo

A criação de um modelo a partir da configuração padrão o inicializa com valores aleatórios:

from transformers import BertConfig, BertModel

config = BertConfig()
model = BertModel(config)

# O modelo é inicializado aleatoriamente!

O modelo pode ser utilizado neste estado, mas produzirá saídas errôneas; ele precisa ser treinado primeiro. Poderíamos treinar o modelo a partir do zero na tarefa em mãos, mas como você viu em Capítulo 1, isto exigiria muito tempo e muitos dados, e teria um impacto ambiental não negligenciável. Para evitar esforços desnecessários e duplicados, normalmente é possível compartilhar e reutilizar modelos que já foram treinados.

Carregar um Transformer já treinado é simples - podemos fazer isso utilizando o método from_pretrained():

from transformers import BertModel

model = BertModel.from_pretrained("bert-base-cased")

Como você viu anteriormente, poderíamos substituir o BertModel pela classe equivalente ao AutoModel. Faremos isto de agora em diante, pois isto produz um código generalista a partir de um checkpoint; se seu código funciona para checkpoint, ele deve funcionar perfeitamente com outro. Isto se aplica mesmo que a arquitetura seja diferente, desde que o checkpoint tenha sido treinado para uma tarefa semelhante (por exemplo, uma tarefa de análise de sentimento).

No exemplo de código acima não utilizamos BertConfig, e em vez disso carregamos um modelo pré-treinado através do identificador bert-base-cased. Este é um checkpoint do modelo que foi treinado pelos próprios autores do BERT; você pode encontrar mais detalhes sobre ele em seu model card.

Este modelo agora é inicializado com todos os pesos do checkpoint. Ele pode ser usado diretamente para inferência sobre as tarefas nas quais foi treinado, e também pode ser fine-tuned (aperfeiçoado) em uma nova tarefa. Treinando com pesos pré-treinados e não do zero, podemos rapidamente alcançar bons resultados.

Os pesos foram baixados e armazenados em cache (logo, para as futuras chamadas do método from_pretrained() não será realizado o download novamente) em sua respectiva pasta, que tem como padrão o path ~/.cache/huggingface/transformers. Você pode personalizar sua pasta de cache definindo a variável de ambiente HF_HOME.

O identificador usado para carregar o modelo pode ser o identificador de qualquer modelo no Model Hub, desde que seja compatível com a arquitetura BERT. A lista completa dos checkpoints BERT disponíveis podem ser encontrada [aqui].https://huggingface.co./models?filter=bert).

Métodos para salvar/armazenar o modelo

Salvar um modelo é tão fácil quanto carregar um - utilizamos o método save_pretrained(), que é análogo ao método from_pretrained():

model.save_pretrained("path_no_seu_computador")

Isto salva dois arquivos em seu disco:

ls path_no_seu_computador

config.json pytorch_model.bin

Se você der uma olhada no arquivo config.json, você reconhecerá os atributos necessários para construir a arquitetura modelo. Este arquivo também contém alguns metadados, como a origem do checkpoint e a versão 🤗 Transformers que você estava usando quando salvou o checkpoint pela última vez.

O arquivo pytorch_model.bin é conhecido como o dicionário de estado; ele contém todos os pesos do seu modelo. Os dois arquivos andam de mãos dadas; a configuração é necessária para conhecer a arquitetura de seu modelo, enquanto os pesos do modelo são os parâmetros de seu modelo.

Usando um modelo de Transformer para inferência

Agora que você sabe como carregar e salvar um modelo, vamos tentar usá-lo para fazer algumas predições. Os Transformers só podem processar números - números que o tokenizer gera. Mas antes de discutirmos os tokenizers, vamos explorar quais entradas o modelo aceita.

Os Tokenizers podem se encarregar de lançar as entradas nos tensores da estrutura apropriada, mas para ajudá-lo a entender o que está acontecendo, vamos dar uma rápida olhada no que deve ser feito antes de enviar as entradas para o modelo.

Digamos que temos um par de sequências:

sequences = ["Hello!", "Cool.", "Nice!"]

O tokenizer os converte em índices de vocabulário que são normalmente chamados de IDs de entrada. Cada sequência é agora uma lista de números! A saída resultante é:

encoded_sequences = [
    [101, 7592, 999, 102],
    [101, 4658, 1012, 102],
    [101, 3835, 999, 102],
]

Esta é uma lista de sequências codificadas: uma lista de listas. Os tensores só aceitam shapes (tamanhos) retangulares (pense em matrizes). Esta “matriz” já é de forma retangular, portanto, convertê-la em um tensor é fácil:

import torch

model_inputs = torch.tensor(encoded_sequences)

Usando os tensores como entradas para o modelo

Fazer uso dos tensores com o modelo é extremamente simples - chamamos apenas o modelo com os inputs:

output = model(model_inputs)

Embora o modelo aceite muitos argumentos diferentes, apenas os IDs de entrada são necessários. Explicaremos o que os outros argumentos fazem e quando eles são necessários mais tarde, mas primeiro precisamos olhar mais de perto os tokenizers que constroem as entradas que um Transformer pode compreender.