Image of eBits Academy computing illustration

Sådan bygger du din egen AI-sprogmodel (LLM)

  • October 13, 2024
  • |
  • Teofil Corad

Inden for kunstig intelligens har store sprogmodeller (LLM’er) som GPT (Generative Pretrained Transformers) fået en central rolle. Du har sikkert brugt ChatGPT, Bard eller anden tekstgenererende trolddom til at spørge om alt fra programmering til cocktailopskrifter. Men bag magien ligger en kompleks arkitektur drevet af deep learning, neurale netværk og enorme tekstdatasæt. Lad os gennemgå det, og undervejs viser jeg dig, hvordan du programmerer og bygger din egen LLM fra bunden.

Denne guide gennemgår de vigtigste elementer i, hvad en LLM er, hvordan man bygger og træner den, og vigtigst af alt: hvordan du gør det, mens du nyder en varm kop te.

1. Hvad er en LLM?

Forestil dig en robot, som er rigtig god til at forstå og generere tekst. Det er en stor sprogmodel. Den er som den ven, der kan afslutte dine sætninger, men mindre irriterende, fordi den drives af milliarder af parametre, som forudsiger det næste ord i en sekvens. LLM’er er teknologien bag tekstgenerering, oversættelse, opsummering og mere. De bygger på dybe neurale netværk, som er trænet på enorme mængder tekstdata for at opfange nuancer, sammenhænge og kontekst i menneskeligt sprog.

LLM’er bygger på en arkitektur kaldet Transformers, introduceret i artiklen fra 2017 Attention Is All You Need. Transformers lader modeller fokusere på forskellige dele af et input (kaldet self-attention) og generere sammenhængende tekst. Og nej, de ”forstår” ikke sproget som mennesker; de laver meget kvalificerede gæt ud fra statistiske mønstre i data.

2. Byg en LLM: trinene

Trin 1: dataindsamling og forbehandling

Inden du går i gang med programmeringen, skal du have et datasæt. En LLM trænes på enorme mængder tekstdata. GPT-3 blev eksempelvis trænet på omkring 570GB tekst fra CommonCrawl-datasættet, bøger, Wikipedia og mere. For at holde det enkelt (og din GPU intakt) kan du begynde i det små med et tekstkorpus som The Verdict af Edith Wharton.

Tokenisering: Modellen kan ikke forstå rå tekst. Den behøver tal. Her kommer tokenisering ind: Tekst opdeles i håndterbare dele (ord, delord eller tegn), som omdannes til tal (ID’er). Det gøres med tokenizere som Byte Pair Encoding (BPE) og brug af PyTorch-biblioteket.

import re

def simple_tokenizer(text):
    tokens = re.findall(r'\b\w+\b', text.lower())
    return tokens

text = "Hello, I am building an LLM!"
tokens = simple_tokenizer(text)
print(tokens)

Trin 2: Transformer-arkitekturen

Rygraden i de fleste LLM’er er Transformer, men GPT bruger en decoder-only-arkitektur. Decoder-only-modeller kan også oversætte; arkitekturen begrænser dem ikke til opgaver uden oversættelse.

import torch
import torch.nn as nn

class SimpleTransformer(nn.Module):
    def __init__(self, vocab_size, d_model, nhead, num_layers):
        super(SimpleTransformer, self).__init__()
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.transformer = nn.Transformer(d_model, nhead, num_layers)
        self.fc = nn.Linear(d_model, vocab_size)
    
    def forward(self, src, tgt):
        src_emb = self.embedding(src)  # Embed the input
        tgt_emb = self.embedding(tgt)
        transformer_out = self.transformer(src_emb, tgt_emb)
        output = self.fc(transformer_out)
        return output

Trin 3: fortræn modellen

At træne en LLM som GPT fra bunden er dyrt (tænk millioner af dollars til cloudberegning). Men vi kan implementere en forenklet træningsløkke med PyTorch.

Først skal modellen trænes på et tekstkorpus, hvor opgaven er at forudsige næste ord. Det kaldes forudsigelse af næste ord:

import torch.optim as optim

def train(model, data, epochs=10):
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)

    for epoch in range(epochs):
        for batch in data:
            src, tgt = batch
            optimizer.zero_grad()
            output = model(src, tgt[:-1])
            loss = criterion(output.view(-1, model.fc.out_features), tgt[1:].view(-1))
            loss.backward()
            optimizer.step()

        print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

# Assuming `data` is a DataLoader that provides batches of (source, target) pairs.
train(model, data)

I denne træningsløkke lærer modellen at forudsige næste ord i målsekvensen ud fra kildesekvensen. Du skal bruge en passende datasætindlæser (se PyTorchs DataLoader) til at sende portioner af tokeniseret tekst ind i modellen.

Trin 4: finjustering

Når grundmodellen er trænet, er det tid til at finjustere den til særlige opgaver. Det kan være alt fra at besvare spørgsmål til at oversætte sprog. Du tager den fortrænede model og fortsætter træningen på et mindre, opgavespecifikt datasæt.

Finjustering kræver et datasæt med input-output-par, som spørgsmål og svar. Modellen justeres for at minimere fejl i forudsigelsen af det korrekte output til hvert input.

Trin 5: brug fortrænede modeller

Hvis du vil downloade en fortrænet model, kan du bruge GPT-2. I modsætning til GPT-3, som ikke har modelvægte til download, kan GPT-2 indlæses med biblioteker som Hugging Faces Transformers. Sådan indlæser du en model til tekstgenerering:

from transformers import GPT2LMHeadModel, GPT2Tokenizer

tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
model = GPT2LMHeadModel.from_pretrained("gpt2")

input_text = "Once upon a time"
input_ids = tokenizer.encode(input_text, return_tensors="pt")
output = model.generate(input_ids, max_length=50)

print(tokenizer.decode(output[0], skip_special_tokens=True))

Med få linjer har du en tekstgenererende maskine, der kan fortsætte enhver prompt.

3. Sådan træner du en LLM

Fortræning

Fortræning betyder at give modellen enorme mængder tekst, så den kan forudsige det næste ord i en sekvens. Det er dyrt, men afgørende for at lære generelle sprogmønstre.

  • Selvovervåget læring: Modellen laver sine egne etiketter (det næste ord) fra inputsekvensen, hvilket gør dette til en selvovervåget opgave.
  • Enorme datasæt: GPT-3 blev trænet på 300 milliarder tokens. Til undervisningsformål kan du begynde med mindre datasæt.

Finjustering

Finjustering betyder at træne modellen videre til en bestemt opgave. Du kan eksempelvis finjustere en LLM til at være særligt god til tekstopsummering eller besvarelse af spørgsmål.

# Fine-tuning code using a smaller dataset
model.train()
for epoch in range(5):
    for batch in fine_tune_data:
        inputs, labels = batch
        optimizer.zero_grad()
        outputs = model(inputs, labels=labels)
        loss = outputs.loss
        loss.backward()
        optimizer.step()

4. Afsluttende tanker

At bygge en LLM fra bunden er en spændende rejse gennem deep learning-land. Det er som at konstruere et sind, der kan tale, skrive og (næsten) tænke. Med denne guide har du en plan til at bygge en enkel LLM, finjustere den eller blot bruge fortrænede modeller. Uanset om du laver din egen AI-assistent eller en tekstgenererende bot, er mulighederne uendelige.

Denne artikel gennemgik mine refleksioner over ”Build an Large Language Model from Scratch” skrevet af Sebastian Raschka. Kodestykkerne er forenklede, så din GPU ikke bryder i brand, men begreberne hjælper dig med at skalere op, hvis du vil gå mere i dybden.

God fornøjelse med kodningen, og må dine LLM’er altid være velformulerede!

Efterlad en kommentar

Bemærk venligst, at kommentarer skal godkendes, før de offentliggøres.