hacktricks/src/AI/AI-llm-architecture/7.2.-fine-tuning-to-follow-instructions.md

105 lines
7.7 KiB
Markdown

# 7.2. Ottimizzazione per seguire istruzioni
{{#include ../../banners/hacktricks-training.md}}
> [!TIP]
> L'obiettivo di questa sezione è mostrare come **ottimizzare un modello già pre-addestrato per seguire istruzioni** piuttosto che generare semplicemente testo, ad esempio, rispondendo a compiti come un chatbot.
## Dataset
Per ottimizzare un LLM per seguire istruzioni è necessario avere un dataset con istruzioni e risposte per ottimizzare il LLM. Ci sono diversi formati per addestrare un LLM a seguire istruzioni, ad esempio:
- L'esempio dello stile di prompt Apply Alpaca:
```csharp
Below is an instruction that describes a task. Write a response that appropriately completes the request.
### Instruction:
Calculate the area of a circle with a radius of 5 units.
### Response:
The area of a circle is calculated using the formula \( A = \pi r^2 \). Plugging in the radius of 5 units:
\( A = \pi (5)^2 = \pi \times 25 = 25\pi \) square units.
```
- Esempio di Stile Prompt Phi-3:
```vbnet
<|User|>
Can you explain what gravity is in simple terms?
<|Assistant|>
Absolutely! Gravity is a force that pulls objects toward each other.
```
Addestrare un LLM con questo tipo di set di dati invece di semplici testi grezzi aiuta il LLM a capire che deve fornire risposte specifiche alle domande che riceve.
Pertanto, una delle prime cose da fare con un set di dati che contiene richieste e risposte è modellare quei dati nel formato di prompt desiderato, come:
```python
# Code from https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/ch07.ipynb
def format_input(entry):
instruction_text = (
f"Below is an instruction that describes a task. "
f"Write a response that appropriately completes the request."
f"\n\n### Instruction:\n{entry['instruction']}"
)
input_text = f"\n\n### Input:\n{entry['input']}" if entry["input"] else ""
return instruction_text + input_text
model_input = format_input(data[50])
desired_response = f"\n\n### Response:\n{data[50]['output']}"
print(model_input + desired_response)
```
Poi, come sempre, è necessario separare il dataset in set per l'addestramento, la validazione e il test.
## Batching & Data Loaders
Poi, è necessario raggruppare tutti gli input e gli output attesi per l'addestramento. Per questo, è necessario:
- Tokenizzare i testi
- Aggiungere padding a tutti i campioni alla stessa lunghezza (di solito la lunghezza sarà grande quanto la lunghezza del contesto utilizzato per pre-addestrare il LLM)
- Creare i token attesi spostando di 1 l'input in una funzione di collate personalizzata
- Sostituire alcuni token di padding con -100 per escluderli dalla perdita di addestramento: Dopo il primo token `endoftext`, sostituire tutti gli altri token `endoftext` con -100 (perché usare `cross_entropy(...,ignore_index=-100)` significa che ignorerà i target con -100)
- \[Opzionale] Mascherare usando -100 anche tutti i token appartenenti alla domanda in modo che il LLM impari solo a generare la risposta. Nello stile Apply Alpaca questo significherà mascherare tutto fino a `### Response:`
Con questo creato, è tempo di creare i data loader per ciascun dataset (addestramento, validazione e test).
## Load pre-trained LLM & Fine tune & Loss Checking
È necessario caricare un LLM pre-addestrato per affinarlo. Questo è già stato discusso in altre pagine. Poi, è possibile utilizzare la funzione di addestramento precedentemente utilizzata per affinare il LLM.
Durante l'addestramento è anche possibile vedere come la perdita di addestramento e la perdita di validazione variano durante le epoche per vedere se la perdita si sta riducendo e se si sta verificando overfitting.\
Ricorda che l'overfitting si verifica quando la perdita di addestramento si sta riducendo ma la perdita di validazione non si sta riducendo o addirittura aumentando. Per evitare questo, la cosa più semplice da fare è fermare l'addestramento all'epoca in cui inizia questo comportamento.
## Response Quality
Poiché questo non è un fine-tuning di classificazione in cui è possibile fidarsi maggiormente delle variazioni di perdita, è anche importante controllare la qualità delle risposte nel set di test. Pertanto, è consigliato raccogliere le risposte generate da tutti i set di test e **controllare manualmente la loro qualità** per vedere se ci sono risposte sbagliate (nota che è possibile per il LLM creare correttamente il formato e la sintassi della frase di risposta ma fornire una risposta completamente errata. La variazione della perdita non rifletterà questo comportamento).\
Nota che è anche possibile eseguire questa revisione passando le risposte generate e le risposte attese a **altri LLM e chiedere loro di valutare le risposte**.
Altri test da eseguire per verificare la qualità delle risposte:
1. **Measuring Massive Multitask Language Understanding (**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU valuta le conoscenze e le capacità di problem-solving di un modello in 57 soggetti, comprese le scienze umane, le scienze e altro. Utilizza domande a scelta multipla per valutare la comprensione a vari livelli di difficoltà, dall'elementare all'avanzato professionale.
2. [**LMSYS Chatbot Arena**](https://arena.lmsys.org): Questa piattaforma consente agli utenti di confrontare le risposte di diversi chatbot fianco a fianco. Gli utenti inseriscono un prompt e più chatbot generano risposte che possono essere confrontate direttamente.
3. [**AlpacaEval**](https://github.com/tatsu-lab/alpaca_eval)**:** AlpacaEval è un framework di valutazione automatizzato in cui un LLM avanzato come GPT-4 valuta le risposte di altri modelli a vari prompt.
4. **General Language Understanding Evaluation (**[**GLUE**](https://gluebenchmark.com/)**):** GLUE è una raccolta di nove compiti di comprensione del linguaggio naturale, tra cui analisi del sentiment, implicazione testuale e risposta a domande.
5. [**SuperGLUE**](https://super.gluebenchmark.com/)**:** Basandosi su GLUE, SuperGLUE include compiti più impegnativi progettati per essere difficili per i modelli attuali.
6. **Beyond the Imitation Game Benchmark (**[**BIG-bench**](https://github.com/google/BIG-bench)**):** BIG-bench è un benchmark su larga scala con oltre 200 compiti che testano le capacità di un modello in aree come ragionamento, traduzione e risposta a domande.
7. **Holistic Evaluation of Language Models (**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM fornisce una valutazione completa attraverso vari metriche come accuratezza, robustezza e equità.
8. [**OpenAI Evals**](https://github.com/openai/evals)**:** Un framework di valutazione open-source di OpenAI che consente di testare modelli AI su compiti personalizzati e standardizzati.
9. [**HumanEval**](https://github.com/openai/human-eval)**:** Una raccolta di problemi di programmazione utilizzati per valutare le capacità di generazione di codice dei modelli di linguaggio.
10. **Stanford Question Answering Dataset (**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD consiste in domande su articoli di Wikipedia, dove i modelli devono comprendere il testo per rispondere accuratamente.
11. [**TriviaQA**](https://nlp.cs.washington.edu/triviaqa/)**:** Un dataset su larga scala di domande e risposte trivia, insieme a documenti di prova.
e molti altri
## Follow instructions fine-tuning code
Puoi trovare un esempio del codice per eseguire questo fine-tuning in [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/gpt_instruction_finetuning.py](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/gpt_instruction_finetuning.py)
## References
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
{{#include ../../banners/hacktricks-training.md}}