QLoRA: Estratégias e práticas eficientes de ajuste fino para LLM quantitativo

Se você estiver interessado neste artigo e quiser aprender mais sobre habilidades práticas na área de IA, siga a conta pública "Technology Frenzy AI" . Aqui você pode ver os artigos mais recentes e interessantes e tutoriais de casos práticos na área de AIGC.

I. Introdução

No campo dos grandes modelos de linguagem (LLMs), o ajuste fino é um processo fundamental para melhorar o desempenho e ajustar o comportamento. No entanto, o ajuste fino para modelos grandes pode ser muito caro devido aos enormes requisitos de memória. Recentemente, a Universidade de Washington publicou uma solução inovadora para este problema – QLoRA (Quantized Low-Rank Adapter).

QLoRA é um novo método para ajuste fino de modelos de linguagem grande (LLM) que economiza memória enquanto mantém a velocidade. O princípio de funcionamento é primeiro quantizar o LLM em 4 bits, reduzindo significativamente o consumo de memória do modelo. Em seguida, o LLM quantizado é ajustado usando o método do adaptador de baixa ordem (LoRA). LoRA permite que o modelo aprimorado retenha a maior parte da precisão do LLM original, sendo menor e mais rápido.

O texto acima é uma breve introdução ao QLoRA, e seus princípios e aplicações serão discutidos mais detalhadamente abaixo.

2. Introdução ao QLoRA

QLoRA é um método eficiente de ajuste fino que reduz significativamente o uso de memória ao retropropagar gradientes em um adaptador de ordem inferior (LoRA). Ele pode ajustar um modelo de 65 bilhões de parâmetros em uma única GPU de 48 GB e manter o desempenho completo das tarefas de ajuste fino de 16 bits.

Também foi lançada uma nova família de modelos chamada Guanaco, que teve bom desempenho no benchmark Vicuna, atingindo 99,3% do nível de desempenho ChatGPT. O que é surpreendente é que resultados tão excelentes podem ser alcançados com apenas 24 horas de ajuste fino em uma única GPU. Estas inovações permitem o ajuste fino do modelo de forma mais eficiente com recursos limitados e alcançam resultados muito satisfatórios.

QLoRA é um método LLM inovador e aprimorado que foi verificado em diversas tarefas, incluindo classificação de texto, resposta a perguntas e geração de linguagem natural, comprovando sua eficácia em vários campos. O surgimento deste método fornece uma maneira mais conveniente de aplicar o LLM a uma gama mais ampla de usuários e aplicações, e espera-se que promova ainda mais a aplicação do LLM em diferentes campos.

2.1. Principais inovações

LoRA tradicional (adaptador de classificação baixa) e QLoRA (LoRA quantizado) são métodos para ajustar modelos de linguagem grandes e reduzir os requisitos de memória. No entanto, o QLoRA apresenta diversas inovações para reduzir ainda mais o uso de memória e, ao mesmo tempo, manter o desempenho. Aqui está uma comparação dos dois métodos:

LoRA:

  • - Use um pequeno conjunto de parâmetros treináveis ​​(adaptadores) enquanto mantém fixos os parâmetros completos do modelo.

  • - Os gradientes durante a descida do gradiente estocástico são passados ​​através de pesos fixos de modelo pré-treinados para o adaptador, que é atualizado para otimizar a função de perda.

  • - Mais eficiente em termos de memória do que o ajuste fino completo, mas ainda requer precisão de 16 bits para treinamento.

QLoRA:

  • - Retropropagação de gradientes em um adaptador de ordem inferior (LoRA) por meio de um modelo de linguagem pré-treinado quantizado e congelado de 4 bits.

  • - Apresentando NormalFloat (NF4) de 4 bits, um tipo de dados quantizados teoricamente ideal para dados normalmente distribuídos que produz melhores resultados empíricos do que números inteiros de 4 bits e ponto flutuante de 4 bits.

  • - A aplicação da quantização dupla, um método de quantização de constantes de quantização, economiza em média cerca de 0,37 bits por parâmetro.

  • - Use o otimizador de paginação com memória unificada NVIDIA para evitar picos de memória durante pontos de verificação de gradiente ao processar minilotes com sequências longas.

  • - Requisitos de memória significativamente reduzidos em comparação com a linha de base totalmente ajustada de 16 bits, permitindo o ajuste fino de um modelo de parâmetros de 65B em uma única GPU de 48GB sem degradar o tempo de execução ou o desempenho de previsão.

Em resumo, o QLoRA baseia-se no LoRA tradicional e introduz quantização de 4 bits, tipo de dados NormalFloat de 4 bits, quantização dupla e otimizador de paginação para reduzir ainda mais o uso de memória, mantendo o desempenho comparável aos métodos de ajuste fino de 16 bits.

2.2 Análise de desempenho

Um estudo aprofundado do tamanho do modelo e do desempenho do chatbot revelou alguns resultados interessantes. Devido às limitações de sobrecarga de memória, os métodos convencionais de ajuste fino não podem ser usados. Portanto, um método especial de ajuste fino de instruções foi usado para treinar vários conjuntos de dados, diferentes arquiteturas de modelos e números de parâmetros, com um total de mais de 1000 modelos treinados.

Os resultados mostram que mesmo usando modelos menores do que os modelos de última geração anteriores, o ajuste fino com QLoRA em pequenos conjuntos de dados de alta qualidade pode alcançar resultados de última geração. Isto mostra que a qualidade dos dados tem um impacto muito maior no desempenho do modelo do que o tamanho do conjunto de dados. Esta descoberta tem um significado orientador importante para otimizar o desempenho dos chatbots.

A avaliação foi realizada no modelo Guanaco 65B, que foi ajustado para variantes do OASST1 usando QLORA. Os resultados mostram que é o modelo de chatbot de código aberto com melhor desempenho e seu desempenho é comparável ao ChatGPT. Comparado ao GPT-4, o Guanaco 65B e 33B têm uma probabilidade de vitória esperada de 30%.

  • No benchmark Vicuna, o Guanaco 65B apresenta melhor desempenho após o GPT-4, alcançando 99,3% de desempenho em relação ao ChatGPT. Apesar de ter mais parâmetros, o modelo Guanaco 33B é mais eficiente em termos de memória que o modelo Vicuna 13B porque os pesos utilizam apenas 4 dígitos de precisão. Além disso, o Guanaco 7B pode ser instalado em telefones modernos, superando o Alpaca 13B em quase 20 pontos percentuais.

  • Embora os resultados sejam impressionantes, muitos modelos apresentam desempenhos sobrepostos com amplos intervalos de confiança. Os autores atribuem esta incerteza à falta de especificações claras de escala. Para resolver este problema, eles propõem a utilização do método de classificação Elo, que se baseia nos julgamentos pareados de anotadores humanos e GPT-4.

  • As classificações Elo mostram que os modelos Guanaco 33B e 65B superam todos os modelos, exceto GPT-4, nos benchmarks Vicuna e OA, e têm desempenho equivalente ao ChatGPT. No entanto, a escolha do conjunto de dados de ajuste fino afeta muito o desempenho, indicando a importância da adequação do conjunto de dados.

3. Use QLoRA para ajustar o modelo GPT

3.1. Requisitos de hardware para QLoRA:

  • GPU: Para modelos com menos de 20 bilhões de parâmetros, como GPT-J, recomenda-se uma GPU com pelo menos 12 GB de VRAM. Por exemplo, uma GPU RTX 3060 de 12 GB está disponível. Se você tiver uma GPU maior e 24 GB de VRAM, poderá usar um modelo com 20 bilhões de parâmetros, como o GPT-NeoX-20b.

  • RAM: Recomenda-se que você tenha pelo menos 6 GB de RAM. A maioria dos computadores hoje atende a esse critério.

  • Disco rígido: como GPT-J e GPT-NeoX-20b são modelos grandes, você precisa de pelo menos 80 GB de espaço livre em seu disco rígido.

Se o seu sistema não atender a esses critérios, você poderá usar uma instância gratuita do Google Colab.

3.2. Requisitos de software QLoRA:

  • CUDA : Certifique-se de que CUDA esteja instalado em seu computador.

  • Dependências : dependências:

  • bitsandbytes : esta biblioteca contém todas as ferramentas necessárias para quantificar grandes modelos de linguagem (LLMs).

  • Hugging Face Transformers e Accelerate : essas bibliotecas padrão são usadas para treinamento de modelo eficiente do Hugging Face Hub.

  • PEFT : Esta biblioteca fornece implementações de vários métodos para ajustar um pequeno número de parâmetros adicionais do modelo. LoRA exige isso.

  • Conjunto de dados : embora não seja obrigatório, uma biblioteca de conjunto de dados pode ser usada para obter um conjunto de dados para ajuste fino. Como alternativa, você pode fornecer seu próprio conjunto de dados.

Certifique-se de instalar todas as dependências de software necessárias antes de prosseguir com o ajuste fino do modelo GPT baseado em QLoRA.

4. Demonstração QLoRA

Guanaco é um sistema projetado para fins de pesquisa e pode ser experimentado através do seguinte endereço de demonstração.

  1. Visite a demonstração do Guanaco Playground [4], esta é uma demonstração do modelo 33B, o modelo 65B será demonstrado posteriormente.

  2. Se você quiser hospedar sua própria demonstração do Guanaco grdio, você pode usar isto[5]. Para os modelos 7B e 13B, funciona com GPU gratuita.

  3. Quanto à diferença entre ChatGPT e guanaco, as respostas do modelo podem ser comparadas em [6]. Na dica Vicuna você pode ver a comparação entre ChatGPT e guanaco 65B.

5. Instalação do QLoRA

Para usar Transformer e BitsandBytes para carregar modelos de 4 bits, você deve instalar o acelerador e o Transformer da fonte e instalar a versão atual da biblioteca BitsandBytes (0.39.0). Você pode usar o seguinte comando para atingir o propósito acima:

pip install -q -U bitsandbytes
pip install -q -U git+https://github.com/huggingface/transformers.git
pip install -q -U git+https://github.com/huggingface/peft.git
pip install -q -U git+https://github.com/huggingface/accelerate.git

6. Primeiros passos com QLoRA

qlora.pyAs funções podem ser usadas para ajustar e inferir sobre uma variedade de conjuntos de dados. Aqui estão os comandos básicos para ajustar um modelo de linha de base no conjunto de dados Alpaca:

python qlora.py --model_name_or_path <path_or_name>

Para modelos maiores que 13B, recomendamos ajustar a taxa de aprendizagem:

python qlora.py –learning_rate 0.0001 --model_name_or_path <path_or_name>

6.1. Quantificação

Os parâmetros de quantização são BitsandbytesConfigcontrolados da seguinte forma:

  • load_in_4bitHabilite o carregamento de 4 bits via .

  • bnb_4bit_compute_dtypeTipo de dados usado para cálculos de camada linear.

  • A quantização aninhada é bnb_4bit_use_double_quanthabilitada via .

  • bnb_4bit_quant_typeEspecifica o tipo de dados usado para quantificação. Dois tipos de dados quantizados são suportados: fp4(ponto flutuante de quatro bits) e nf4(ponto flutuante regular de quatro bits). Defendemos seu uso nf4porque é teoricamente ideal para pesos normalmente distribuídos.

model = AutoModelForCausalLM.from_pretrained(
        model_name_or_path='/name/or/path/to/your/model',
        load_in_4bit=True,
        device_map='auto',
        max_memory=max_memory,
        torch_dtype=torch.bfloat16,
        quantization_config=BitsAndBytesConfig(
            load_in_4bit=True,
            bnb_4bit_compute_dtype=torch.bfloat16,
            bnb_4bit_use_double_quant=True,
            bnb_4bit_quant_type='nf4'
        ),
    )

6.2. Otimizador de paginação

Para lidar com situações ocasionais em que a GPU fica sem memória, o QLoRA usa um otimizador de paginação que aproveita o recurso Memória Unificada da NVIDIA, que realiza transferências automáticas página a página entre a CPU e a GPU e funciona de forma semelhante à memória normal entre a CPU RAM e a GPU. A paginação é muito semelhante. disco. Este recurso é usado para alocar memória paginada para o estado do otimizador e, em seguida, movê-la para a RAM da CPU quando a memória da GPU estiver baixa e movê-la de volta para a memória da GPU quando necessário.

Podemos acessar o otimizador de paginação usando os seguintes parâmetros.

--optim paged_adamw_32bit

7. Use QLoRA para ajustar o LLaMA 2

A seguir, descrevemos como ajustar o modelo mais recente do Llama-2-7b em um único Google Colab e transformá-lo em um chatbot. Usaremos a biblioteca PEFT no ecossistema Hugging Face, bem como QLoRA para obter um ajuste fino de memória mais eficiente.

7.1. PEFT ou ajuste fino eficiente de parâmetros

PEFT (Parameter Efficient Fine-Tuning) é uma nova biblioteca de código aberto da Hugging Face que adapta com eficiência modelos de linguagem pré-treinados (PLM) a uma variedade de aplicativos downstream sem a necessidade de ajustar todos os parâmetros do modelo. PEFT atualmente inclui as seguintes tecnologias:

  • LoRA: Adaptação de baixo nível de grandes modelos de linguagem [8]

  • Ajuste de prefixo: P-Tuning v2: ajuste rápido comparável ao ajuste fino universal em escalas e tarefas

  • P-Tuning: GPT também pode entender [9]

  • Ajuste instantâneo: O poder da escala permite o ajuste rápido e eficiente dos parâmetros [10]

7.2. Configure o ambiente de desenvolvimento

Primeiro você precisa instalar as dependências necessárias , precisaremos instalar as bibliotecas accelerate, peft, e TRL para aproveitar as vantagens do . Quantize o modelo base para 4 bits usando . Também será instalado porque é uma biblioteca necessária para carregar o modelo Falcon.transformersdatasetsSFTTrainerbitsandbyteseinops

pip install -q -U trl transformers accelerate git+https://github.com/huggingface/peft.git
pip install -q datasets bitsandbytes einops wandb

7.3. Preparar conjunto de dados

Carregamos a divisão do conjunto de dados do trem do conjunto de dados AlexanderDoria/novel17_test. Este conjunto de dados contém dados de texto de alguns romances franceses e é usado para treinamento e avaliação de tarefas de processamento de linguagem natural. O texto neste conjunto de dados será usado para treinar o modelo para realizar o processamento de linguagem natural em romances franceses.

from datasets import load_dataset

#dataset_name = "timdettmers/openassistant-guanaco" ###Human ,.,,,,,, ###Assistant

dataset_name = 'AlexanderDoria/novel17_test' #french novels
dataset = load_dataset(dataset_name, split="train")

7.4. Modelo de carga

Carregou o modelo pré-treinado e definiu a configuração de quantização usando a função BitsAndBytesConfig, carregando o modelo como 4 bits e usando o tipo de dados de cálculo torch.float16. Carregue o modelo pré-treinado na variável do modelo por meio da função from_pretrained e passe a configuração de quantização para o modelo.

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, AutoTokenizer

model_name = "TinyPixel/Llama-2-7B-bf16-sharded"

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16,
)

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    trust_remote_code=True
)
model.config.use_cache = False

Carregue o tokenizer do modelo pré-treinado e configure-o para adicionar marcadores de preenchimento no final da sequência para processamento em lote ao usar o modelo para inferência.

tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token

Crie um objeto de configuração PEFT para usar ao treinar e avaliar o modelo.

from peft import LoraConfig, get_peft_model

lora_alpha = 16
lora_dropout = 0.1
lora_r = 64

peft_config = LoraConfig(
    lora_alpha=lora_alpha,
    lora_dropout=lora_dropout,
    r=lora_r,
    bias="none",
    task_type="CAUSAL_LM"
)

7.5. Carregue o treinador

Usaremos a biblioteca TRL SFTTrainer, que fornece Trainerwrappers em torno de transformadores para ajustar facilmente modelos em conjuntos de dados baseados em instruções usando adaptadores PEFT. Vamos primeiro carregar os parâmetros de treinamento abaixo.

from transformers import TrainingArguments

output_dir = "./results"
per_device_train_batch_size = 4
gradient_accumulation_steps = 4
optim = "paged_adamw_32bit"
save_steps = 100
logging_steps = 10
learning_rate = 2e-4
max_grad_norm = 0.3
max_steps = 100
warmup_ratio = 0.03
lr_scheduler_type = "constant"

training_arguments = TrainingArguments(
    output_dir=output_dir,
    per_device_train_batch_size=per_device_train_batch_size,
    gradient_accumulation_steps=gradient_accumulation_steps,
    optim=optim,
    save_steps=save_steps,
    logging_steps=logging_steps,
    learning_rate=learning_rate,
    fp16=True,
    max_grad_norm=max_grad_norm,
    max_steps=max_steps,
    warmup_ratio=warmup_ratio,
    group_by_length=True,
    lr_scheduler_type=lr_scheduler_type,
)

Finalmente, passe tudo para o treinador, criando um objeto de treinamento para treinar o modelo de linguagem especificado.

from trl import SFTTrainer

max_seq_length = 512

trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    peft_config=peft_config,
    dataset_text_field="text",
    max_seq_length=max_seq_length,
    tokenizer=tokenizer,
    args=training_arguments,
)

Também pré-processaremos o modelo atualizando a especificação da camada no float 32 para um treinamento mais estável

for name, module in trainer.model.named_modules():
    if "norm" in name:
        module = module.to(torch.float32)

7.6. Modelo de treinamento

A seguir, inicia-se o processo de treinamento do modelo para atualizar os parâmetros do modelo por meio do algoritmo de retropropagação para melhorar o desempenho do modelo.

trainer.train()

Durante o treinamento, o modelo deve convergir perfeitamente, conforme mostrado abaixo:

Salve o modelo treinado no sistema de arquivos local para uso posterior. SFTTrainerApenas o adaptador é salvo corretamente, e não o modelo inteiro.

model_to_save = trainer.model.module if hasattr(trainer.model, 'module') else trainer.model  # Take care of distributed/parallel training
model_to_save.save_pretrained("outputs")

Use a classe LoraConfig para carregar as informações de configuração de um modelo pré-treinado e combiná-las com um modelo existente para obter um novo modelo.

lora_config = LoraConfig.from_pretrained('outputs')
model = get_peft_model(model, lora_config)

Use o modelo pré-treinado para gerar um novo trecho de texto para testar os recursos de geração do modelo.

text = "Écrire un texte dans un style baroque sur la glace et le feu ### Assistant: Si j'en luis éton"
device = "cuda:0"

inputs = tokenizer(text, return_tensors="pt").to(device)
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

Envie o modelo para o Hugging Face Hub, onde ele pode ser compartilhado e acessado com outras pessoas.

from huggingface_hub import login
login()

model.push_to_hub("llama2-qlora-finetunined-french")

8. Limitações do QLoRA

QLoRA é um modelo de raciocínio baseado em LoRA (Logical Reasoning Architecture), que apresenta algumas limitações em alguns aspectos. A seguir estão algumas limitações conhecidas:

  1. Velocidade de inferência lenta: a velocidade de inferência do QLoRA é relativamente lenta ao usar inferência de quatro dígitos. Atualmente, o sistema de inferência de quatro bits do QLoRA ainda não está conectado à multiplicação de matrizes de quatro bits, o que pode afetar seu desempenho e velocidade.

  2. Falha no treinamento de recuperação do instrutor: ao usar o Trainer para retomar as corridas de treinamento LoRA, você pode encontrar falhas. Isso pode ser devido a algum problema interno ou configuração incorreta e exigirá mais investigação e resolução.

  3. Instabilidade com bnb 4bit compute type='fp16' : atualmente, usar bnb 4bit compute type='fp16' pode causar instabilidade. Especialmente para a tarefa 7B LLaMA, apenas 80% do ajuste fino é executado sem problemas. Embora existam soluções, elas ainda não foram implementadas em bits e bytes.

  4. Defina o ID do token tokenizer.bos como 1: Para evitar dificuldades, é recomendado definir o ID do token tokenizer.bos como 1. Provavelmente, isso é para garantir que, ao usar QLoRA, o ID da tag inicial (BOS) seja definido corretamente como 1 para evitar possíveis problemas.

9. Resumo

QLoRA é um método de ajuste fino de modelo de linguagem baseado em quantização que quantiza modelos de linguagem pré-treinados em um formato de baixa precisão, aumentando assim a velocidade de inferência e reduzindo o espaço de armazenamento do modelo, mantendo o desempenho do modelo.

Neste artigo, exploramos como usar o método QLoRA para ajustar o modelo LLaMA 2, incluindo carregar o modelo pré-treinado, definir a configuração de quantização, usar a classe SFTTrainer para criar um objeto de treinamento e treinar o modelo. Também discutimos como usar a função BitsAndBytesConfig para quantizar o modelo em 4 bits e usar o tipo de dados de cálculo torch.float16 para cálculos. Essas operações podem nos ajudar a aumentar a velocidade de inferência e reduzir o espaço de armazenamento do modelo, mantendo o desempenho do modelo, permitindo assim a implantação e aplicação de modelos de linguagem em ambientes com recursos limitados.

10. Referências

[1]. QLoRA GitHub:

https://github.com/artidoro/qlora

[2]. Pager QLoRA:

https://arxiv.org/abs/2305.14314

[3]. Bits e Bytes (para treinamento de 4 bits):

https://github.com/TimDettmers/bitsandbytes

[4]. Parque Guanaco HF:

https://huggingface.co/spaces/uwnlp/guanaco-playground-tgi

[5]. Guanaco Gradio Colab:

https://colab.research.google.com/drive/17XEqL1JcmVWjHkT-WczdYkJlNINacwG7?usp=sharing

[6]. Colaboração Guanaco vs ChatGPT:

https://colab.research.google.com/drive/1kK6xasHiav9nhiRUJjPMZb4fAED4qRHb?usp=sharing

[7]. PEFT GitHub:

https://github.com/huggingface/peft

[8]. Pager LoRA:

https://arxiv.org/pdf/2106.09685.pdf

[9]. Pager P-Tuning:

https://arxiv.org/pdf/2103.10385.pdf

[10]. Pager de ajuste de prompt :

https://arxiv.org/pdf/2104.08691.pdf

[11]. SFTTrainer HF:

https://huggingface.co/docs/trl/main/en/sft_trainer

Se você estiver interessado neste artigo e quiser aprender mais sobre habilidades práticas na área de IA, siga a conta pública "Technology Frenzy AI" . Aqui você pode ver os artigos mais recentes e interessantes e tutoriais de casos práticos na área de AIGC.

Acho que você gosta

Origin blog.csdn.net/FrenzyTechAI/article/details/132686051
Recomendado
Clasificación