mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
46 lines
3.6 KiB
Markdown
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`.
|