NLP nas empresas | Como ajustar um modelo de linguagem natural como BERT para a tarefa de classificação de tokens (NER) com um Adapter?
Seguindo nosso artigo apresentando os adapters da biblioteca de adapter-transformers e seus diversos interesses para empresas e organizações que desejam utilizar modelos de Inteligência Artificial (IA) para automatizar seus processos de NLP (Natural Language Processing) internos e externos, estamos publicando uma série de artigos acompanhados de notebooks e/ou scripts que são tutoriais que permitem implementar os adapters em seus negócios e atividades. Continuamos essa série com este artigo sobre o task adapter que permite ajustar um modelo de linguagem natural como BERT para a tarefa de classificação de tokens (NER: Named Entity Recognition).
- Publicamos um notebook no github (versão nbviewer): token_classification_adapter.ipynb
- Outros artigos a ler:
NLP nas empresas | Adapter-Transformers Para Dummies
[ post e notebook atualizados no dia 19 de julho de 2021 ]
Sumário
- Contexto
- Modelo de linguagem natural ajustado para a tarefa de classificação de tokens (NER: Named Entity Recognition)
- Tutorial | Ajusto fino do BERT geral em português para a tarefa NER com o dataset jurídico LeNER-Br
— Notebook token_classification_adapter.ipynb
— Mudanças principais em notebooks e scripts originais
— Configuração do task adapter e resultados de treinamento dos modelos
— Número de parâmetros do modelo com um lang e task adapter - Uso do modelo com lang e task adapter
Contexto
No artigo “NLP nas empresas | Uma solução para colocar os modelos BERT em produção com Adapters para transformers”, apresentamos a biblioteca adapter-transformers que permite treinar módulos chamados adapter a partir de um modelo transformer do tipo BERT sem alterar os valores de seus embeddings, nem os dos parâmetros de suas camadas.
O interesse é imediato: assim, é possível treinar tantos adapters quanto uma empresa ou organização tenha tarefas de NLP (Natural Language Processing) para realizar em um determinado idioma e isso a partir do mesmo modelo de linguagem natural. Na produção, apenas esse modelo deve ser armazenado e acessível por meio de uma API, bem como os vários adapters.
Essa solução simplifica muito o uso desses diferentes modelos de NLP (um modelo = modelo original + adapter), pois apenas um modelo de linguagem natural deve ser armazenado (o modelo original) mais os adapters (o peso de um task adapter é apenas entre 1 e 3% do peso do modelo original).
Imagine se uma empresa ou organização tivesse que arquivar tantos modelos originais ajustados quanto tem tarefas de NLP quando um modelo BERT large pesa mais de 1,3 GB …
Modelo de linguagem natural ajustado para a tarefa de classificação de tokens (NER: Named Entity Recognition)
Na Internet hoje é fácil baixar um modelo de linguagem natural como o BERT que já é treinado em sua língua. Por exemplo, existe o modelo BERT base em português da Neuralmind e o modelo BERT large em português da Neuralmind que estão no hub de modelos de Hugging Face.
Como explicamos no artigo “NLP nas empresas | Como ajustar um modelo de linguagem natural como BERT a um novo domínio linguístico com um Adapter?”, é aconselhável ajustar esse modelo ao domínio linguístico específico de seus dados (saúde, jurídico, etc.) antes de usar esse modelo ajustado para se especializar em tarefas de NLP como a classificação de tokens (NER), a busca por respostas a perguntas (QA: Question-Answering), a classificação de sentenças ou documentos, etc.
Esse ajuste (finetuning) com a biblioteca adapter-transformers fornecerá o lang adapter e a head do modelo de NLP original usado.
Em segunda etapa, pode treinar seu modelo original para uma tarefa específica, como classificação de token (NER), treinando um task adapter. Esse treinamento só se relacionará aos novos parâmetros, aqueles do task adapter, e não aos do modelo original, nem aos do lang adapter se decidir acrescentá-lo ao modelo a ser treinado.
Tutorial | Ajusto fino do BERT geral em português para a tarefa NER com o dataset jurídico LeNER-Br
Notebook token_classification_adapter.ipynb
Estamos usando aqui o dataset jurídico LeNER-Br (LeNER-Br: a Dataset for Named Entity Recognition in Brazilian Legal Text) para treinar o modelo na tarefa de classificação de tokens com a biblioteca adapter-transformers.
Por fazer isso, publicamos um notebook (token_classification_adapter.ipynb e sua versão nbviewer) realizado a partir dos seguintes notebooks e scripts para o ajuste fino de um Modelo de Linguagem de tipo transformer como o BERT (base ou grande) com qualquer datasets para a tarefa NER:
- adapter-transformers | notebook 07a_Adapter_train_NER_with_id2label.ipynb e o script run_ner.py (esse script é um ajuste do script run_qa.py da HF)
- transformers of Hugging Face | notebook token_classification.ipynb e o script run_ner.py
Esse notebook pode ser usado para BERT base or large com qualquer dataset para a tarefa NER. Deixamos os valores do nosso treinamento com o modelo BERT large em português da Neuralmind com um task adapter pfeiffer ajustado com o o dataset LeNER-Br em português.
Nota: o notebook token_classification_adapter.ipynb está na pasta token-classification no github.
Mudanças principais em notebooks e scripts originais
Atualizamos o notebook token_classification.ipynb para o nosso notebook token_classification_adapter.ipynb com as seguintes alterações:
- Weighted Loss: como a distribuição de entidades (tokens a serem encontrados) é muito desequilibrada, pode escolher treinar o modelo com uma perda ponderada (weighted loss).
- EarlyStopping: selecionando o modelo com a maior precisão de avaliação (paciência de 3 antes de terminar o treinamento).
- MAD-X 2.0: opção que permite não treinar adapters na última camada do modelo transformer (leia a página 6 de UNKs Everywhere: Adapting Multilingual Language Models to New Scripts).
- Stack method para os lang e task adapters quando um lang adapter é carregado (doc).
- Houlsby MHA last layer (para a configuração de Houlsby) que não permite treinar o adapter após a camada de Feed Forward, mas somente após a de MHA (Multi-Head Attention) no último bloco transformer.
Configuração do task adapter e resultados de treinamento dos modelos
Para fazer o ajuste fino do modelo BERT para a tarefa NER usando um task adapter, precisamos inserir um adapter no nível de cada uma das camadas transformer do modelo original. Podemos escolher entre 2 configurações houlsby ou pfeiffer. Simplificando, o segundo tem 2 vezes menos parâmetros, mas permite aproximar o desempenho do primeiro.
No entanto, como a gente provou no artigo “NLP nas empresas | Como ajustar um modelo de linguagem natural como BERT a um novo domínio linguístico com um Adapter?”, que o desempenho do modelo com a configuração pfeiffer é muito próximo ao do modelo com a configuração houlsby mas com muito menos parâmetros, a gente decidiu de continuar com a configuração pfeiffer (leia Adapter types).
Além disso, a gente tem a opção de treinar o task adapter com a presença do lang adapter ou não (nota: o lang adapter é um adapter de configuração pfeiffer+inv treinado a partir does textos do dataset LeNER-Br para ajustar o Modelo de Linguagem Natural original (BERT large da Neuralmind em português aqui) às particularidades linguísticas desse dataset).
Para comparar o desempenho dessas 2 configurações entre si e com um modelo BERT sem adapter ajustado de uma forma clássica (ajuste fino de todas as camadas do modelo), treinamos os 4 modelos seguintes para a tarefa NER com o dataset LeNER-Br (sem e com Weighted Loss):
- (modelo 1 — original) modelo BERT Neuralmind large sem adapter.
- (modelo 2) modelo BERT Neuralmind large sem adapter (o original) já ajustado aos textos do dataset LeNER-Br.
- (modelo 3) o modelo original com adapter pfeiffer mas sem adapter no último bloco transformer (se chama MAD-X 2.0).
- (modelo 4) o modelo original com adapter pfeiffer+inv mas sem adapter no último bloco transformer (se chama MAD-X 2.0)
Só para constar, o ajuste fino com adapter significa que congelamos todo os parâmetros do modelo BERT original (e do lang adapter quando tiver). Apenas os parâmetros do task adapter são treinados.
Aqui estão os resultados (use a lupa para aumentar o tamanho da imagem de tabela):
O melhor modelo com adapters é o modelo 4 (modelo com lang e task adapters, e sem Weighted Loss) que conseguiu um f1 de quase 90% (89.78%), seja uma diminuição de apenas 0.77% em comparação do f1 do modelo publicado pela equipe do dataset LeNER-Br… mas com apenas 0.91% de novo parâmetros treinado (ao total, esse modelo 4 tem 8.31% de parâmetros de tipo adapter: os dos lang e task adapters).
Em relação aos hiperparâmetros de treinamento, podemos destacar o fato de que sempre usamos os mesmos (taxa de aprendizagem de 1e-4, batch size de 8) para os modelos com task adapter (mas sem uma grande mudança em f1)! Pode alterar o número de épocas, mas como usamos EarlyStopping, colocamos um número alto (20) e modelos com adapters pararam o treinamento antes desse limite (modelos 3 e 4).
Em resumo, como procuramos eficácia em produção (em particular, velocidade no uso do modelo), poderíamos claramente usar essa configuração pfeiffer para o nosso task adapter.
Nota: se usar a configuração pfeiffer, é aconselhável não inserir um adapter na última camada de transformação do modelo original para obter um melhor desempenho (isso se chama MAD-X 2.0 como definido no parágrafo precedente).
Número de parâmetros do modelo com um task adapter
Se usar o modelo BERT large em português da Neuralmind, pode calcular a porcentagem de parâmetros do modelo com um lang e task adapter em comparação com ao modelo sem adapter.
O aumento mínimo é de 0.91% (modelo 3) com a configuração pfeiffer com MAD-X 2.0 para o task adapter e o máximo de 8.31% (modelo 4) com a configuração pfeiffer+inv para o lang adapter e pfeiffer para o task adapter sem MAD-X 2.0 (com adapter depois da camada de MHA no último bloco transformer).
No caso do modelo 4, Significa que em vez de armazenar a cada vez um modelo de 1.34 GB (BERT large da Neuralmind), vai armazenar 8.31x 1.34 GB= 111 MB (+55 KB para os parâmetros de head do modelo)
Vale a pena, não?
Uso do modelo com lang e task adapter
Em primeiro lugar, deve baixar o modelo original do hub de modelos da Hugging Face:
from transformers import AutoModelForTokenClassification, AutoTokenizermodel_checkpoint = "neuralmind/bert-large-portuguese-cased"model_ner = AutoModelForTokenClassification.from_pretrained(model_checkpoint, num_labels=len(label_list))tokenizer_ner = AutoTokenizer.from_pretrained(model_checkpoint, use_fast=True)
Então, é necessário acrescentar o lang adapter que treinamos (porque a gente o usa durante o treinamento):
# load the language adapter without head
task_mlm_load_as = 'mlm'
lang_adapter_name = model_ner.load_adapter(
load_lang_adapter,
config=lang_adapter_config,
load_as=task_mlm_load_as,
with_head=False
)
Depois, precisamos acrescentar o task adapter que treinamos:
# load the task adapter with head
task_name = 'ner'
model_ner.load_adapter(
load_adapter,
config=adapter_config,
load_as=task_name,
with_head = True
)
Agora, temos de ativar esses 2 adapters no forward do nosso modelo:
# Set the adapters to be used in every forward pass
from transformers.adapters.composition import Stack
if lang_adapter_name:
model_ner.active_adapters = Stack(task_mlm_load_as, task_name)
else:
model_ner.set_active_adapters(task_name)
Finalmente, podemos usar nosso modelo com lang e task adapters para encontrar as entidades nomeadas de um texto (aqui, um texto jurídico em português):
from transformers import pipelinenlp = pipeline("question-answering", model=model_qa, tokenizer=tokenizer_qa)
… com o texto seguinte:
text = """
Acrescento que o Juiz Pedro DA SILVA do tribunal STF em Brasília (Brasil) reconheceu a limitação do pedido único e, com base no artigo 487, inciso II, do Código de Processo Civil, encerrou o processo no dia 3 de janeiro de 2014, com resolução do mérito, condenando o autor às custas judiciais e advocatícias, que são fixadas em 10% (dez por cento) do valor da causa.
"""
Nota: veja o nosso notebook para ter acesso ao código correspondente a essa parte.
Aqui está o resultado:
Sobre o autor: Pierre Guillou é consultor de IA no Brasil e na França, pesquisador em Deep Learning e NLP do AI Lab (Unb) e professor de Inteligência Artificial (UnB). Entre em contato com ele por meio de seu perfil no LinkedIn.