Image of eBits Academy computing illustration

Så bygger du din egen AI-språkmodell (LLM)

  • October 13, 2024
  • |
  • Teofil Corad

Inom artificiell intelligens har stora språkmodeller (LLM:er) som GPT (Generative Pretrained Transformers) hamnat i centrum. Du har säkert använt ChatGPT, Bard eller annan textgenererande magi för att fråga om allt från programmering till cocktailrecept. Men bakom magin finns en komplex arkitektur driven av djupinlärning, neurala nätverk och enorma textdataset. Låt oss gå igenom det, och samtidigt visar jag hur du programmerar och bygger en egen LLM från grunden.

Guiden går igenom vad en LLM är, hur du bygger och tränar den och, viktigast av allt, hur du gör det medan du njuter av en varm kopp te.

1. Vad är en LLM?

Föreställ dig en robot som är riktigt bra på att förstå och generera text. Det är en stor språkmodell. Den är som vännen som kan avsluta dina meningar, men mindre irriterande eftersom den drivs av miljarder parametrar som förutsäger nästa ord i en sekvens. LLM:er är tekniken bakom textgenerering, översättning, sammanfattning och mer. De bygger på djupa neurala nätverk, tränade på enorma mängder textdata för att fånga nyanser, samband och sammanhang i mänskligt språk.

LLM:er bygger på en arkitektur som kallas Transformers, introducerad i artikeln från 2017 Attention Is All You Need. Transformers låter modeller fokusera på olika delar av indata (kallat self-attention) och generera sammanhängande text. Och nej, de ”förstår” inte språk som människor, utan gör mycket kvalificerade gissningar utifrån statistiska mönster i data.

2. Bygga en LLM: stegen

Steg 1: datainsamling och förbehandling

Innan du börjar programmera behöver du ett dataset. En LLM tränas på enorma mängder textdata. GPT-3 tränades till exempel på ungefär 570GB text från CommonCrawl-datasetet, böcker, Wikipedia med mera. För att hålla det enkelt (och din GPU intakt) kan du börja smått med en textsamling som The Verdict av Edith Wharton.

Tokenisering: Modellen förstår inte råtext. Den behöver tal. Där kommer tokenisering in: text delas upp i hanterbara delar (ord, delord eller tecken) och omvandlas till tal (ID:n). Det görs med tokeniserare som Byte Pair Encoding (BPE) och med 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)

Steg 2: Transformer-arkitekturen

Ryggraden i de flesta LLM:er är Transformer, men GPT använder en decoder-only-arkitektur. Decoder-only-modeller kan också översätta; arkitekturen begränsar dem inte till uppgifter utan översättning.

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

Steg 3: förträna modellen

Att träna en LLM som GPT från grunden är dyrt (tänk miljontals dollar för molnberäkningar). Men vi kan implementera en förenklad träningsloop med PyTorch.

Först behöver du träna modellen på en textsamling där uppgiften är att förutsäga nästa ord. Det kallas förutsägelse av nästa 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 träningsloopen lär modellen sig att förutsäga nästa ord i målsekvensen utifrån källsekvensen. Du behöver en lämplig datasetinläsare (se PyTorchs DataLoader) för att mata modellen med omgångar av tokeniserad text.

Steg 4: finjustering

När grundmodellen har tränats är det dags att finjustera den för specifika uppgifter. Det kan vara allt från att besvara frågor till att översätta språk. Du tar den förtränade modellen och fortsätter träna den på ett mindre, uppgiftsspecifikt dataset.

Finjustering kräver ett dataset med indata-utdata-par, exempelvis frågor och svar. Modellen justeras för att minimera fel när den förutsäger rätt utdata för varje indata.

Steg 5: använd förtränade modeller

Om du vill ladda ner en förtränad modell kan du använda GPT-2. Till skillnad från GPT-3, som inte har modellvikter för nedladdning, kan GPT-2 laddas med bibliotek som Hugging Faces Transformers. Så laddar du en modell för textgenerering:

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 bara några rader har du en textgenererande maskin som kan fortsätta på vilken prompt som helst.

3. Så tränar du en LLM

Förträning

Förträning innebär att mata modellen med enorma mängder text för att förutsäga nästa ord i en sekvens. Det är dyrt men avgörande för att lära sig allmänna språkmönster.

  • Självövervakad inlärning: Modellen skapar egna etiketter (nästa ord) från indatasekvensen, vilket gör detta till en självövervakad uppgift.
  • Enorma dataset: GPT-3 tränades på 300 miljarder token. För utbildningsändamål kan du börja med mindre dataset.

Finjustering

Finjustering innebär att träna modellen vidare för en specifik uppgift. Du kan exempelvis finjustera en LLM så att den blir särskilt bra på textsammanfattning eller att besvara frågor.

# 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. Avslutande tankar

Att bygga en LLM från grunden är en spännande resa genom djupinlärningens värld. Det är som att konstruera ett sinne som kan prata, skriva och (nästan) tänka. Med guiden har du en plan för att bygga en enkel LLM, finjustera den eller använda förtränade modeller. Oavsett om du skapar en egen AI-assistent eller en textgenererande bot är möjligheterna oändliga.

Artikeln gick igenom mina reflektioner kring ”Build an Large Language Model from Scratch” skriven av Sebastian Raschka. Kodsnuttarna är förenklade för att din GPU inte ska fatta eld, men begreppen hjälper dig att skala upp om du vill fördjupa dig.

Lycka till med kodningen, och må dina LLM:er alltid vara vältaliga!

Lämna en kommentar

Observera att kommentarer måste godkännas innan de publiceras.