hacktricks/todo/llm-training.md
2024-09-14 17:16:23 +00:00

46 lines
3.6 KiB
Markdown

# LLM Training
## Tokenizing
Tokenizing consiste nel separare i dati in specifici chunk e assegnare loro ID specifici (numeri).\
Un tokenizer molto semplice per i testi potrebbe semplicemente prendere ogni parola di un testo separatamente, e anche i simboli di punteggiatura e rimuovere gli spazi.\
Pertanto, `"Hello, world!"` sarebbe: `["Hello", ",", "world", "!"]`
Poi, per assegnare a ciascuna delle parole e simboli un token ID (numero), è necessario creare il **vocabolario** del tokenizer. Se stai tokenizzando, ad esempio, un libro, questo potrebbe essere **tutte le diverse parole del libro** in ordine alfabetico con alcuni token extra come:
* `[BOS] (Inizio della sequenza)`: Posizionato all'inizio di un testo, indica l'inizio di un testo (usato per separare testi non correlati).
* `[EOS] (Fine della sequenza)`: Posizionato alla fine di un testo, indica la fine di un testo (usato per separare testi non correlati).
* `[PAD] (padding)`: Quando una dimensione del batch è maggiore di uno (di solito), questo token è usato per aumentare la lunghezza di quel batch per essere grande come gli altri.
* `[UNK] (sconosciuto)`: Per rappresentare parole sconosciute.
Seguendo l'esempio, avendo tokenizzato un testo assegnando a ciascuna parola e simbolo del testo una posizione nel vocabolario, la frase tokenizzata `"Hello, world!"` -> `["Hello", ",", "world", "!"]` sarebbe qualcosa come: `[64, 455, 78, 467]` supponendo che `Hello` sia alla posizione 64, "`,"` sia alla posizione `455`... nell'array del vocabolario risultante.
Tuttavia, se nel testo usato per generare il vocabolario la parola `"Bye"` non esistesse, questo risulterebbe in: `"Bye, world!"` -> `["[UNK]", ",", "world", "!"]` -> `[987, 455, 78, 467]` supponendo che il token per `[UNK]` sia a 987.
### BPE - Byte Pair Encoding
Per evitare problemi come la necessità di tokenizzare tutte le possibili parole per i testi, i LLM come GPT utilizzano BPE che fondamentalmente **codifica coppie di byte frequenti** per ridurre la dimensione del testo in un formato più ottimizzato fino a quando non può essere ridotto ulteriormente (controlla [**wikipedia**](https://en.wikipedia.org/wiki/Byte\_pair\_encoding)). Nota che in questo modo non ci sono parole "sconosciute" per il vocabolario e il vocabolario finale sarà tutti i set scoperti di byte frequenti raggruppati il più possibile mentre i byte che non sono frequentemente collegati con lo stesso byte saranno un token a sé.
## Data Sampling
I LLM come GPT funzionano prevedendo la parola successiva basata su quelle precedenti, quindi per preparare alcuni dati per l'addestramento è necessario preparare i dati in questo modo.
Ad esempio, usando il testo "Lorem ipsum dolor sit amet, consectetur adipiscing elit,"
Per preparare il modello ad apprendere a prevedere la parola successiva (supponendo che ogni parola sia un token usando il tokenizer molto basilare), e usando una dimensione massima di 4 e una finestra mobile di 1, questo è come il testo dovrebbe essere preparato:
```javascript
Input: [
["Lorem", "ipsum", "dolor", "sit"],
["ipsum", "dolor", "sit", "amet,"],
["dolor", "sit", "amet,", "consectetur"],
["sit", "amet,", "consectetur", "adipiscing"],
],
Target: [
["ipsum", "dolor", "sit", "amet,"],
["dolor", "sit", "amet,", "consectetur"],
["sit", "amet,", "consectetur", "adipiscing"],
["amet,", "consectetur", "adipiscing", "elit,"],
["consectetur", "adipiscing", "elit,", "sed"],
]
```
Nota che se la finestra scorrevole fosse stata 2, significa che la prossima voce nell'array di input inizierà 2 token dopo e non solo uno, ma l'array target continuerà a prevedere solo 1 token. In pytorch, questa finestra scorrevole è espressa nel parametro `stride`.