NLP nas empresas | Como ajustar um modelo de linguagem natural como BERT para a tarefa de Question-Answering (QA) com um Adapter?

Pierre Guillou
10 min readAug 2, 2021
Um modelo BERT com ajuste fino para a tarefa de Perguntas e Respostas (QA: Question-Answering) usando um adapter
Um modelo BERT com ajuste fino para a tarefa de Perguntas e Respostas (QA: Question-Answering) usando um adapter

Artigo citado no anúncio seguinte publicado aqui: “NLP nas empresas | Como criar um modelo BERT de Question-Answering (QA) de desempenho aprimorado com AdapterFusion?” (18/08/2021).

Anúncio: este artigo será seguido em breve por um artigo sobre Adapter Fusion que permite aumentar o desempenho de um modelo com adapters combinando os adapters treinados em diferentes datasets e/ou tarefas, o que equivale a treinar um modelo para multitarefas (multi-tasks), mas de uma forma muito mais simples do que o método padrão para este tipo de objetivo. Adapter fusion ou adapter multi-tasks permite aproveitar o conhecimento adquirido por um modelo do tipo BERT em diferentes tarefas. Um pouco como o funcionamento do nosso cérebro, que muitas vezes usa o conhecimento adquirido em um domínio para efetuar uma tarefa em outro …

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 Perguntas e Respostas (QA: Question-Answering).

NLP nas empresas | Como criar um modelo BERT de Question-Answering (QA) de desempenho aprimorado com AdapterFusion?

NLP nas empresas | Adapter-Transformers Para Dummies

Sumário

  • Contexto
  • Modelo de linguagem natural ajustado para a tarefa de Perguntas e Respostas (QA: Question-Answering)
  • Tutorial | Ajusto fino do BERT geral em português para a tarefa QA com o dataset SQuAD 1.1
    — Notebooks
    — 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 Perguntas e Respostas (QA: Question-Answering)

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 Perguntas e Respostas (QA), 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 QA com o dataset SQuAD 1.1

Notebooks

Estamos usando aqui dataset SQuAD 1.1 em português (versão em português do dataset SQuAD v1.1 inglês cuja tradução foi feita pelo grupo Deep Learning Brasil: squad-pt.tar.gz no Google Drive (fonte)) para treinar o modelo na tarefa de Question-Answering (QA) com a biblioteca adapter-transformers.

Por fazer isso, publicamos 2 notebooks (question_answering_adapter.ipynb (versão nbviewer) e question_answering_adapter_script.ipynb (versão nbviewer)) realizados 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 QA:

Esses 2 notebooks são 2 maneiras diferentes de treinar os modelos: apenas com o código do notebook (question_answering_adapter.ipynb), ou com a chamada de um script externo (question_answering_adapter_script.ipynb).

Esses notebooks podem ser usados para BERT base or large com qualquer dataset para a tarefa QA. 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 SQuAD 1.1 em português.

Nota: os notebooks estão na pasta question-answering no github.

Mudanças principais em notebooks e scripts originais

Atualizamos os notebooks e scripts originais com as seguintes alterações:

  • 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 task 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 QA 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).

Nota: no entanto, para verificar se o desempenho da configuração houlsby ainda é (ligeiramente) superior ao da configuração pfeiffer, treinamos um modelo BERT large QA com um adapter houlsby e o modo Houlsby MHA last layer. Nosso modelo obteve um exact-match de 72,176 e um f1 de 83,9467, que são melhores resultados do que nosso melhor modelo na configuração pfeiffer (veja abaixo), mas por um custo em número de parâmetros do adapter 2 vezes maior (1,86% contra 0,92% do número de parâmetros do BERT large da Neuralmind usado como modelo original).

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 SQuAD 1.1 em português 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 QA com o dataset SQuAD 1.1 em português:

  • (modelo 1 — original) modelo BERT Neuralmind large sem adapter (esse modelo QA é o nosso modelo de referência; ele está online no model hub da Hugging Face: Portuguese BERT large cased QA (Question Answering), finetuned on SQUAD v1.1).
  • (modelo 2) modelo BERT Neuralmind large sem adapter (o original) já ajustado aos textos do dataset SQuAD 1.1 em português.
  • (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:

resultados dos 4 modelos ajustados para a tarefa QA com o dataset SQuAD 1.1 pt (cor verde: número superior ao do modelo oficial no model hub da Hugging Face; cor vermelha: número inferior ao mesmo modelo oficial)
resultados dos 4 modelos ajustados para a tarefa QA com o dataset SQuAD 1.1 pt (cor verde: número superior ao do modelo oficial no model hub da Hugging Face; cor vermelha: número inferior ao mesmo modelo oficial)

O melhor modelo com adapters é o modelo 4 (modelo com lang e task adapters) que conseguiu um f1 superior a 83.60% (83.6014%), seja uma diminuição de apenas 0.98% em comparação do f1 do modelo publicado no modelo hub da Hugging Facemas com apenas 0.92% de novo parâmetros treinado (ao total, esse modelo 4 tem 8.32% 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 16) 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 (15) 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.92% (modelo 3) com a configuração pfeiffer com MAD-X 2.0 para o task adapter e o máximo de 8.32% (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.32x 1.34 GB= 111 MB (+9,2 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 AutoModelForQuestionAnswering, AutoTokenizermodel_checkpoint = "neuralmind/bert-large-portuguese-cased"tokenizer_qa = AutoTokenizer.from_pretrained(model_checkpoint)
model_qa = AutoModelForQuestionAnswering.from_pretrained(model_checkpoint)

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_qa.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 = 'qa'
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_qa.active_adapters = Stack(task_mlm_load_as, task_name)
else:
model_qa.set_active_adapters(task_name)

Finalmente, podemos usar nosso modelo com lang e task adapters para encontrar as respostas às perguntas em um texto pelo código seguinte:

from transformers import pipelinenlp = pipeline("question-answering", model=model_qa, tokenizer=tokenizer_qa)

… com o texto seguinte:

text = """
A pandemia de COVID-19, também conhecida como pandemia de coronavírus, é uma pandemia em curso de COVID-19,
uma doença respiratória causada pelo coronavírus da síndrome respiratória aguda grave 2 (SARS-CoV-2).
O vírus tem origem zoonótica e o primeiro caso conhecido da doença remonta a dezembro de 2019 em Wuhan, na China.
Em 20 de janeiro de 2020, a Organização Mundial da Saúde (OMS) classificou o surto
como Emergência de Saúde Pública de Âmbito Internacional e, em 11 de março de 2020, como pandemia.
Em 18 de junho de 2021, 177 349 274 casos foram confirmados em 192 países e territórios,
com 3 840 181 mortes atribuídas à doença, tornando-se uma das pandemias mais mortais da história.
Os sintomas de COVID-19 são altamente variáveis, variando de nenhum a doenças com risco de morte.
O vírus se espalha principalmente pelo ar quando as pessoas estão perto umas das outras.
Ele deixa uma pessoa infectada quando ela respira, tosse, espirra ou fala e entra em outra pessoa pela boca, nariz ou olhos.
Ele também pode se espalhar através de superfícies contaminadas.
As pessoas permanecem contagiosas por até duas semanas e podem espalhar o vírus mesmo se forem assintomáticas.
"""

… e a questão seguinte:

question = "Onde foi descoberta a Covid-19?"result = nlp(question=question, context=context)

Aqui está o resultado:

Answer: 'Wuhan, na China'

Et voilà :-)

Nota: veja o nosso notebook para ter acesso ao código correspondente a essa parte.

Sobre o autor: Pierre Guillou é Head of AI na startup de HealthTech Laudite (Brasil), e consultor de IA no Brasil e na França. Entre em contato com ele por meio de seu perfil no LinkedIn.

--

--