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

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

Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.

A medida que os LLMs aumentam de tamanho e surgem novas capacidades, temos um problema: as alucinações. Os autores do artigo DoLa: Decoding by Contrasting Layers Improves Factuality in Large Language Models propõem um método para evitar esse problema.

Propõem uma abordagem de decodificação contrastiva, onde a probabilidade de saída da próxima palavra é obtida a partir da diferença nos logits entre uma camada superior e uma inferior. Ao enfatizar o conhecimento das camadas superiores e diminuir a importância das inferiores, podemos fazer com que os LM sejam mais fáticos e, portanto, reduzir as alucinações.

Na figura a seguir, essa ideia é ilustrada. Enquanto Seattle mantém uma alta probabilidade em todas as camadas, a probabilidade da resposta correta Olympia aumenta após as camadas superiores injetarem mais conhecimento factual. Contrastar as diferenças entre as diferentes camadas pode revelar a resposta correta neste caso.

DoLa-figure1

Métodolink image 13

Um LLM consiste em uma camada de embedding, vários transformers sequenciais e, em seguida, uma camada de saída. O que propõem é medir a saída de cada transformer por meio da divergência de Jensen-Shannon (JSD).

Na figura seguinte, pode-se ver essa medida na saída de cada transformer para uma frase de entrada no LLM. Cada coluna corresponde a um token da frase.

DoLa-figure2

Podem observar dois padrões

  • O primeiro ocorre quando são previstas entidades de nome ou datas importantes, como Wole Soyinka e 1986, que requerem conhecimento fático. Pode-se ver que a JSD calculada continua extremamente alta nas camadas superiores. Este padrão indica que o modelo ainda está mudando suas previsões nas últimas camadas, e potencialmente injetando mais conhecimento fático nas previsões
  • O segundo ocorre quando se preveem palavras funcionais, como was, the, to, in, e os tokens copiados da pergunta de entrada, como first Nigerian, Nobel Prize. Quando esses tokens "fáceis" são previstos, podemos observar que a JSD torna-se muito pequena a partir das camadas intermediárias. Essa descoberta indica que o modelo já decidiu qual token gerar nas camadas intermediárias e mantém as distribuições de saída quase inalteradas nas camadas superiores. Essa descoberta também é consistente com as suposições em LLMs de saída precoce Schuster et al., 2022

Quando a previsão da próxima palavra requer conhecimento fático, o LLM parece alterar as previsões nas camadas superiores. Contrastar as camadas antes e depois de uma mudança súbita pode, portanto, amplificar o conhecimento que emerge das camadas superiores e fazer com que o modelo se baseie mais em seu conhecimento interno fático. Além disso, essa evolução da informação parece variar de um token para outro

Seu método requer selecionar com precisão a camada prematura que contém informações plausíveis mas menos factuais, que pode não estar sempre na mesma camada inicial. Portanto, eles propõem encontrar essa camada prematura através de uma seleção dinâmica da camada prematura, como visto na imagem a seguir.

DoLa-figure3

Seleção dinâmica da camada prematuralink image 14

Para selecionar a camada prematura, eles calculam a divergência de Jensen-Shannon (JSD) entre as camadas intermediárias e a final. A camada prematura é selecionada como a camada com o JSD mais alto.

No entanto, como esse processo pode ser um pouco lento, o que fazem é agrupar várias camadas para fazer menos cálculos

Contraste das previsõeslink image 15

Agora que temos a última camada (camada madura) e a camada prematura, podemos contrastar as previsões de ambas camadas. Para isso, calculam a probabilidade logarítmica do próximo token na camada madura e na camada prematura. Em seguida, subtraem a probabilidade logarítmica da camada prematura da da camada madura, assim dando mais importância ao conhecimento da camada madura.

Penalização por repetiçãolink image 16

A motivação do DoLa é diminuir a importância do conhecimento linguístico das camadas inferiores e amplificar o conhecimento fático do mundo real. No entanto, isso pode levar o modelo a gerar parágrafos gramaticalmente incorretos.

Empiricamente, eles não observaram esse problema, mas encontraram que a distribuição DoLa resultante às vezes tem uma maior tendência a repetir frases geradas anteriormente, especialmente durante a geração de longas sequências de raciocínio na cadeia de pensamento.

Então, eles incluem uma penalização por repetição introduzida em Keskar et al. (2019) com θ = 1.2 durante a decodificação.

Implementação com transformerslink image 17

Vamos ver como implementar DoLa com a biblioteca transformers do Hugging Face. Para obter mais informações sobre como aplicar DoLa com a biblioteca transformers, você pode consultar o seguinte enlace

Primeiro nos logamos no Hub, pois vamos usar o Llama 3 8B, para poder usá-lo é necessário solicitar permissão à Meta, então para poder baixá-lo é preciso estar logado para que saibam quem está fazendo o download.

	
from huggingface_hub import notebook_login
notebook_login()
Copy

Agora instanciamos o tokenizador e o modelo

	
from transformers import AutoTokenizer, AutoModelForCausalLM, set_seed
import torch
compute_dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
device = 'cuda' if torch.cuda.is_available() else 'cpu'
checkpoints = "meta-llama/Meta-Llama-3-8B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(checkpoints)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(checkpoints, torch_dtype=compute_dtype, device_map="auto")
model.config.pad_token_id = model.config.eos_token_id
Copy

Atribuímos um valor fixo de semente para a reprodutibilidade do exemplo

	
set_seed(42)
Copy

Geramos os tokens de entrada para o LLM

	
question = 'What does Darth Vader say to Luke in "The Empire Strikes Back"?'
text = f"Answer with a short answer. Question: {question} Answer: "
inputs = tokenizer(text, return_tensors="pt").to(model.device)
Copy

Geramos agora a entrada vanilla, ou seja, sem aplicar DoLa

	
generate_kwargs={
"do_sample": False,
"max_new_tokens": 50,
"top_p": None,
"temperature": None
}
vanilla_output = model.generate(**inputs, **generate_kwargs)
print(tokenizer.batch_decode(vanilla_output[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0])
Copy
	
Setting `pad_token_id` to `eos_token_id`:128001 for open-end generation.
	
"No, I am your father." (Note: This is a famous misquote. The actual quote is "No, I am your father" is not in the movie. The correct quote is "No, I am your father." is not

Vemos que sabe que há um erro famoso, mas não consegue dizer a frase correta.

Agora aplicando DoLa

	
dola_high_output = model.generate(**inputs, **generate_kwargs, dola_layers='high', repetition_penalty=1.2)
print(tokenizer.batch_decode(dola_high_output[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0])
Copy
	
Setting `pad_token_id` to `eos_token_id`:128001 for open-end generation.
	
"No, I am your father." (Note: This is one of the most famous lines in movie history, and it's often misquoted as "Luke, I am your father.")

Agora ele consegue dizer a frase correta e o erro famoso

Vamos fazer outro teste com outro exemplo, reinicio o notebook e uso outro modelo

	
from transformers import AutoTokenizer, AutoModelForCausalLM, set_seed
import torch
compute_dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
device = 'cuda' if torch.cuda.is_available() else 'cpu'
checkpoints = "huggyllama/llama-7b"
tokenizer = AutoTokenizer.from_pretrained(checkpoints)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(checkpoints, torch_dtype=compute_dtype, device_map="auto")
model.config.pad_token_id = model.config.eos_token_id
Copy

Atribuímos um valor fixo de semente para a reprodução do exemplo

	
set_seed(42)
Copy

Claro, por favor, proporciona el texto markdown que deseas que traduzca al portugés.

	
text = "On what date was the Declaration of Independence officially signed?"
inputs = tokenizer(text, return_tensors="pt").to(device)
Copy

Geramos a saída vanilla

	
generate_kwargs={
"do_sample": False,
"max_new_tokens": 50,
"top_p": None,
"temperature": None
}
vanilla_output = model.generate(**inputs, **generate_kwargs)
print(tokenizer.batch_decode(vanilla_output[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0])
Copy
	
The Declaration of Independence was signed on July 4, 1776.
What was the date of the signing of the Declaration of Independence?
The Declaration of Independence was signed on July 4,

Como vemos, gera a saída incorretamente, pois embora seja celebrado em 4 de julho, na verdade foi assinada no 2 de agosto

Vamos a provar agora com DoLa

	
dola_high_output = model.generate(**inputs, **generate_kwargs, dola_layers='high', repetition_penalty=1.2)
print(tokenizer.batch_decode(dola_high_output[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0])
Copy
	
July 4, 1776. This is the most well-known date in U.S. history. The day has been celebrated with parades, barbeques, fireworks and festivals for hundreds of years.

Siga sem gerar uma saída correta, então vamos indicar que apenas contraste a camada final com as camadas 28 e 30

	
dola_high_output = model.generate(**inputs, **generate_kwargs, dola_layers=[28,30], repetition_penalty=1.2)
print(tokenizer.batch_decode(dola_high_output[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0])
Copy
	
It was officially signed on 2 August 1776, when 56 members of the Second Continental Congress put their John Hancocks to the Declaration. The 2-page document had been written in 17

Agora sim, consigo gerar a resposta correta.

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Horeca chatbot

Horeca chatbot Horeca chatbot
Python
LangChain
PostgreSQL
PGVector
React
Kubernetes
Docker
GitHub Actions

Chatbot conversacional para cozinheiros de hotéis e restaurantes. Um cozinheiro, gerente de cozinha ou serviço de quarto de um hotel ou restaurante pode falar com o chatbot para obter informações sobre receitas e menus. Mas também implementa agentes, com os quais pode editar ou criar novas receitas ou menus

Naviground

Naviground Naviground

Subtify

Subtify Subtify
Python
Whisper
Spaces

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.

Flow edit

Flow edit Flow edit

Edite imagens com este modelo de Flow. Baseado em SD3 ou FLUX, você pode editar qualquer imagem e gerar novas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
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 -->