Ottimizza Multimodel LLM:IDEFICS 9B utilizzando A100
Introduzione
In questo articolo impareremo come eseguire l'inferenza utilizzando la versione quantizzata di IDEFICS e ottimizzare IDEFICS-9b utilizzando una GPU A100. Metteremo a punto anche IDEFICS 9B, una variante dell'innovativo modello di linguaggio visivo. Questo processo di messa a punto coinvolge tecniche come LoRa, che sono specificamente progettate per migliorare le prestazioni del modello in determinate aree.
Quando si tratta di eseguire l'inferenza e ottimizzare IDEFICS-9 b, l'elevata potenza di elaborazione delle GPU A100 può accelerare significativamente il processo, consentendoti di iterare e sperimentare più rapidamente.
Cos'è IDEFICS?
IDEFICS (Image-aware Decoder Enhanced à la Flamingo with Interleaved Cross-attentionS) è un modello di linguaggio visivo ad accesso aperto in grado di elaborare sequenze di immagini e testo per produrre output di testo, simili a GPT-4.
Il modello si basa sul modello Flamingo di DeepMind, che non è disponibile pubblicamente. IDEFICS utilizza dati e modelli disponibili pubblicamente, in particolare LLaMA v1 e OpenCLIP, ed è offerto in due versioni: una versione base e una versione istruita, ciascuna disponibile in 9 miliardi e 80 miliardi di dimensioni dei parametri.
Recentemente è stato rilasciato IDEFICS2. Il modello è addestrato a rispondere a domande sulle immagini, come "Di che colore è l'auto?" o "Quante persone ci sono nella foto?" '. Può anche descrivere contenuti visivi, creare storie basate su più immagini, estrarre informazioni da documenti ed eseguire operazioni aritmetiche di base.
Cos'è la messa a punto?
L'ottimizzazione è un processo che implica prendere un modello pre-addestrato e addestrarlo per un'attività specifica utilizzando un set di dati specifico. Questo processo prevede l’aggiornamento dei pesi del modello in base ai dati della nuova attività, in genere con un tasso di apprendimento inferiore, per apportare lievi modifiche senza alterare drasticamente la conoscenza pre-addestrata.
I modelli pre-addestrati vengono in genere addestrati su set di dati grandi e diversificati e acquisiscono molte funzionalità. Sono formati per eseguire bene un compito specifico, come l'analisi del sentiment, la classificazione delle immagini o qualsiasi applicazione specifica del dominio. Utilizzando dati specifici per la nuova attività, il modello può apprendere le sfumature e le specificità di tali dati, migliorando accuratezza e prestazioni.
La messa a punto richiede risorse di calcolo e tempo significativamente inferiori rispetto all'addestramento di un modello da zero.
In questo caso, utilizzeremo "TheFusion21/PokemonCards" per mettere a punto il modello. Ecco la struttura dei dati di questo set di dati.
{
"id": "pl1-1",
"image_url": "https://images.pokemontcg.io/pl1/1_hires.png",
"caption": "A Stage 2 Pokemon Card of type Lightning with the title ""Ampharos"" and 130 HP of rarity ""Rare Holo"" evolved from Flaaffy from the set Platinum and the flavor text: ""None"". It has the attack ""Gigavolt"" with the cost Lightning, Colorless, the energy cost 2 and the damage of 30+ with the description: ""Flip a coin. If heads, this attack does 30 damage plus 30 more damage. If tails, the Defending Pokemon is now Paralyzed."". It has the attack ""Reflect Energy"" with the cost Lightning, Colorless, Colorless, the energy cost 3 and the damage of 70 with the description: ""Move an Energy card attached to Ampharos to 1 of your Benched Pokemon."". It has the ability ""Damage Bind"" with the description: ""Each Pokemon that has any damage counters on it (both yours and your opponent's) can't use any Poke-Powers."". It has weakness against Fighting +30. It has resistance against Metal -20.",
"name": "Ampharos",
"hp": "130",
"set_name": "Platinum"
}
Installazione
Inizieremo installando alcuni pacchetti necessari. Consigliamo ai nostri utenti di fare clic sul collegamento fornito con l'articolo per avviare il notebook e iniziare a lavorare.
!pip install -q datasets
!pip install -q git+https://github.com/huggingface/transformers.git
!pip install -q bitsandbytes sentencepiece accelerate loralib
!pip install -q -U git+https://github.com/huggingface/peft.git
!pip install accelerate==0.27.2
Installeremo la libreria dataset
. Questa libreria fornisce strumenti per l'accesso e la gestione dei set di dati per l'addestramento e la valutazione dei modelli di machine learning. Stiamo anche installando trasformatori e bitsandbyte per una messa a punto efficiente.
Bitsandbytes è un'incredibile libreria che consente di caricare modelli con precisione a 4 bit, rendendola estremamente utile per mettere a punto modelli linguistici di grandi dimensioni con Qlora.
Una volta installati con successo questi pacchetti, importeremo le librerie necessarie.
#import the libraries
import torch
from datasets import load_dataset
from peft import LoraConfig, get_peft_model
from PIL import Image
from transformers import IdeficsForVisionText2Text, AutoProcessor, Trainer, TrainingArguments, BitsAndBytesConfig
import torchvision.transforms as transforms
Carica il modello quantizzato
Successivamente, caricheremo la versione quantizzata del modello, quindi carichiamo il modello. Selezioneremo il dispositivo come "CUDA"; se "CUDA" non è disponibile utilizzeremo la CPU.
device = "cuda" if torch.cuda.is_available() else "cpu"
checkpoint = "HuggingFaceM4/idefics-9b"
#load the model in 4-bit precision
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
llm_int8_skip_modules=["lm_head", "embed_tokens"],
)
processor = AutoProcessor.from_pretrained(checkpoint, use_auth_token=True)
Caricheremo il modello con una precisione a 4 bit, che riduce l'utilizzo della memoria e può accelerare l'elaborazione. Inoltre utilizzeremo una tecnica chiamata doppia quantizzazione, una tecnica che può migliorare la precisione del modello quantizzato a 4 bit. Successivamente, viene inizializzato un processore per gestire gli input e gli output del modello utilizzando il checkpoint pre-addestrato.
model = IdeficsForVisionText2Text.from_pretrained(checkpoint, quantization_config=bnb_config, device_map="auto")
Questo codice inizializza il modello IdeficsForVisionText2Text
caricando una versione pre-addestrata dal checkpoint specificato. Successivamente, applicheremo le impostazioni di quantizzazione definite in bnb_config
per caricare il modello in un formato efficiente con precisione a 4 bit.
Inoltre, il codice utilizza la mappatura automatica dei dispositivi per distribuire i componenti del modello sull'hardware disponibile, ottimizzando le prestazioni e l'utilizzo delle risorse.
Una volta terminati i download, stamperemo il modello.
print(model)
Questo stampa l'intera pipeline del modello con il livello e i dettagli di incorporamento.
Inferenza
Utilizzeremo questo modello per l'inferenza e testeremo il modello.
def model_inference(model, processor, prompts, max_new_tokens=50):
tokenizer = processor.tokenizer
bad_words = ["<image>", "<fake_token_around_image>"]
if len(bad_words) > 0:
bad_words_ids = tokenizer(bad_words, add_special_tokens=False).input_ids
eos_token = "</s>"
eos_token_id = tokenizer.convert_tokens_to_ids(eos_token)
inputs = processor(prompts, return_tensors="pt").to(device)
generated_ids = model.generate(**inputs, eos_token_id=[eos_token_id], bad_words_ids=bad_words_ids, max_new_tokens=max_new_tokens, early_stopping=True)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(generated_text)
La funzione elabora le richieste di input, genera testo utilizzando il modello filtrando i token indesiderati e stampa il testo risultante. La funzione utilizza il tokenizzatore e il processore per gestire la tokenizzazione del testo e la decodifica a sua volta garantisce che il testo generato aderisca ai vincoli specificati.
url = "https://hips.hearstapps.com/hmg-prod/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg?crop=0.752xw:1.00xh;0.175xw,0&resize=1200:*"
prompts = [
# "Instruction: provide an answer to the question. Use the image to answer.\n",
url,
"Question: What's on the picture? Answer:",
]
model_inference(model, processor, prompts, max_new_tokens=5)
Fonte
Domanda: cosa c'è nella foto? Risposta: un cucciolo.
Prepareremo il set di dati che utilizzeremo per il nostro compito di perfezionamento.
def convert_to_rgb(image):
# `image.convert("RGB")` would only work for .jpg images, as it creates a wrong background
# for transparent images. The call to `alpha_composite` handles this case
if image.mode == "RGB":
return image
image_rgba = image.convert("RGBA")
background = Image.new("RGBA", image_rgba.size, (255, 255, 255))
alpha_composite = Image.alpha_composite(background, image_rgba)
alpha_composite = alpha_composite.convert("RGB")
return alpha_composite
def ds_transforms(example_batch):
image_size = processor.image_processor.image_size
image_mean = processor.image_processor.image_mean
image_std = processor.image_processor.image_std
image_transform = transforms.Compose([
convert_to_rgb,
transforms.RandomResizedCrop((image_size, image_size), scale=(0.9, 1.0), interpolation=transforms.InterpolationMode.BICUBIC),
transforms.ToTensor(),
transforms.Normalize(mean=image_mean, std=image_std),
])
prompts = []
for i in range(len(example_batch['caption'])):
# We split the captions to avoid having very long examples, which would require more GPU ram during training
caption = example_batch['caption'][i].split(".")[0]
prompts.append(
[
example_batch['image_url'][i],
f"Question: What's on the picture? Answer: This is {example_batch['name'][i]}. {caption}</s>",
],
)
inputs = processor(prompts, transform=image_transform, return_tensors="pt").to(device)
inputs["labels"] = inputs["input_ids"]
return inputs
load and prepare dataset
ds = load_dataset("TheFusion21/PokemonCards")
ds = ds["train"].train_test_split(test_size=0.002)
train_ds = ds["train"]
eval_ds = ds["test"]
train_ds.set_transform(ds_transforms)
eval_ds.set_transform(ds_transforms)
La funzione convert_to_rgb
garantisce che le immagini siano in formato RGB, per gestire diversi tipi di immagini. La funzione ds_transforms
elabora una serie di esempi trasformando immagini, preparando istruzioni di testo e convertendo il tutto in un formato adatto per l'addestramento o l'inferenza del modello. La funzione aiuta ad applicare le trasformazioni necessarie, tokenizza i prompt e imposta gli input e le etichette per il modello.
Caricheremo "TheFusion21/PokemonCards" come suggerito abbracciando il viso per mettere a punto il modello. Tuttavia, non esitate a utilizzare qualsiasi set di dati con il formato corretto.
LoRA
L'adattamento di basso rango (LoRA) è una tecnica PEFT che riduce una matrice di grandi dimensioni in due matrici più piccole di basso rango all'interno degli strati di attenzione, riducendo significativamente il numero di parametri che necessitano di messa a punto.
model_name = checkpoint.split("/")[1]
config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
)
model = get_peft_model(model, config)
Questo codice configura e applica l'adattamento di basso rango (LoRA) al nostro modello IDEFICS9b:
- Estrai il nome del modello: dal punto di controllo, estrai il modello.
- Configura LoRA: imposta i parametri LoRA, incluso il rango delle matrici di basso rango su 16, i moduli target, il dropout e la gestione dei bias.
- Imposta abbandono: imposta un tasso di abbandono del 5% per LoRA. Il dropout è una tecnica di regolarizzazione per prevenire l'overfitting impostando casualmente alcune unità di input su zero durante l'addestramento.
- Applica LoRA al modello: modifica il modello per includere LoRA nei livelli specificati con la configurazione fornita.
model.print_trainable_parameters()
parametri addestrabili: 19.750.912 || tutti i parametri: 8.949.430.544 || % addestrabile: 0,2206946230030432
Formazione
Successivamente, perfezioneremo il modello,
training_args = TrainingArguments(
output_dir=f"{model_name}-pokemon",
learning_rate=2e-4,
fp16=True,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=8,
dataloader_pin_memory=False,
save_total_limit=3,
evaluation_strategy="steps",
save_strategy="steps",
save_steps=40,
eval_steps=20,
logging_steps=20,
max_steps=20,
remove_unused_columns=False,
push_to_hub=False,
label_names=["labels"],
load_best_model_at_end=True,
report_to=None,
optim="paged_adamw_8bit",
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_ds,
eval_dataset=eval_ds,
)
trainer.train()
Fare un passo
Perdita di allenamento
Perdita di convalida
20
1.450000
0.880157
40
0.702000
0.675355
Out[23]:TrainOutput(global_step=40, training_loss=1.0759869813919067, metrics={'train_runtime': 403.1999, 'train_samples_per_second': 1.587, 'train_steps_per_second': 0.099, 'total_flos': 1445219210656320.0, 'train_loss': 1.0759869813919067, 'epoch': 0.05})
Questo codice avvierà il processo di addestramento in base ai parametri specificati, quali velocità di apprendimento, precisione, dimensioni dei batch, accumulo del gradiente e strategia di check point. Utilizziamo una precisione in virgola mobile a 16 bit per un addestramento più rapido ed efficiente e utilizzeremo l'ottimizzatore per una precisione a 8 bit.
# check generation after finetuning
url = "https://images.pokemontcg.io/pop6/2_hires.png"
prompts = [
url,
"Question: What's on the picture? Answer:",
]
# check generation again after finetuning
check_inference(model, processor, prompts, max_new_tokens=100)
Domanda: cosa c'è nella foto? Risposta: Questo è Lucario. Una carta Pokemon Fase 2 di tipo Lotta con il titolo Lucario e 90 HP di rarità Rara evoluta da Pikachu dal set Neo Destiny e il testo narrativo: Può usare la coda come una frusta
Conclusione
Con questo siamo arrivati alla fine dell’articolo. Siamo stati in grado di mettere a punto con successo il nostro modello utilizzando il set di dati Pokemon. Possiamo spingere il nostro modello ad abbracciare i volti e utilizzare il modello per l'inferenza.
La messa a punto dei modelli multimodali richiede un attento bilanciamento delle risorse computazionali e delle strategie di formazione per ottenere i migliori risultati.
La GPU NVIDIA A100 è una scelta eccellente per la messa a punto di modelli multimodali grazie alle sue prestazioni elevate, all'ampia capacità di memoria e alla scalabilità. Queste funzionalità consentono una gestione efficiente di attività complesse e su larga scala coinvolte nell'integrazione di dati visivi e testuali, portando a una formazione e un'implementazione del modello più rapida ed efficace.
Ci auguriamo che l'articolo ti sia piaciuto!
Riferimenti
- Il taccuino è stato contribuito da Léo Tronchon, Younes Belkada e Stas Bekman, inoltre, il modello IDEFICS è stato contribuito da: Lucile Saulnier, Léo Tronchon, Hugo Laurençon, Stas Bekman, Amanpreet Singh, Siddharth Karamcheti e Victor Sanh Codice di riferimento
- Presentazione di Idefics2: un potente modello di linguaggio visivo 8B per la comunità
- Set di dati utilizzato