5-linjers GPT-stil tekstgenerering i Python med TensorFlow/Keras

Transformers, selv om de ble utgitt i 2017, har bare begynt å få betydelig trekkraft de siste par årene. Med spredningen av teknologien gjennom plattformer som HuggingFace, NLP og Store språkmodeller (LLMs) har blitt mer tilgjengelig enn noen gang.

Likevel – selv med all hypen rundt dem og med mange teoriorienterte guider, det er ikke mange tilpassede implementeringer på nettet, og ressursene er ikke like lett tilgjengelige som med noen andre nettverkstyper som har eksistert lenger. Selv om du kan forenkle arbeidssyklusen din ved å bruke en forhåndsbygd transformator fra HuggingFace (emnet i en annen guide) – kan du komme til føler hvordan det fungerer ved å bygge en selv, før du abstraherer den bort gjennom et bibliotek. Vi vil fokusere på bygging, i stedet for teori og optimalisering her.

I denne veiledningen skal vi bygge en Autoregressiv språkmodell til generere tekst. Vi vil fokusere på de praktiske og minimalistiske/konsise aspektene ved å laste data, dele dem, vektorisere dem, bygge en modell, skrive en tilpasset tilbakeringing og opplæring/slutning. Hver av disse oppgavene kan deles ut til mer detaljerte veiledninger, så vi beholder implementeringen som en generisk, og gir rom for tilpasning og optimalisering avhengig av ditt eget datasett.

Typer LLM og GPT-Fyodor

Selv om kategorisering kan bli mye mer intrikat - kan du bredt kategoriser transformatorbaserte språkmodeller i tre kategorier:

  • Enkoder-baserte modeller – ALBERT, BERT, DistilBERT, ROBERTa
  • Dekoderbasert – GPT, GPT-2, GPT-3, TransformerXL
  • Seq2Seq-modeller – BART, mBART, T5

Enkoderbasert Modeller bruker bare en transformatorkoder i arkitekturen deres (vanligvis stablet) og er gode for å forstå setninger (klassifisering, navngitt enhetsgjenkjenning, spørsmålssvar).

Dekoderbasert Modeller bruker bare en Transformer-dekoder i arkitekturen (også vanligvis stablet) og er gode for fremtidig prediksjon, noe som gjør dem egnet for tekstgenerering.

Seq2Seq Modeller kombinerer både kodere og dekodere og er gode på tekstgenerering, oppsummering og viktigst av alt – oversettelse.

GPT-familien av modeller, som har fått mye grep de siste par årene, er dekoderbaserte transformatormodeller, og er gode på å produsere menneskelignende tekst, trent på store datakorpus og får en melding som en ny startfrø for generasjon. For eksempel:

generate_text('the truth ultimately is')

Som under panseret mater denne meldingen inn i en GPT-lignende modell, og produserer:

'the truth ultimately is really a joy in history, this state of life through which is almost invisible, superfluous  teleological...'

Dette er faktisk en liten spoiler fra slutten av guiden! En annen liten spoiler er arkitekturen som produserte den teksten:

inputs = layers.Input(shape=(maxlen,))
embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
transformer_block = keras_nlp.layers.TransformerDecoder(embed_dim, num_heads)(embedding_layer)
outputs = layers.Dense(vocab_size, activation='softmax')(transformer_block)
    
model = keras.Model(inputs=inputs, outputs=outputs)

5 linjer er alt som trengs for å bygge en transformatormodell som bare er dekoder – simulerer en liten GPT. Siden vi skal trene modellen på Fjodor Dostoyevskys romaner (som du kan erstatte med alt annet, fra Wikipedia til Reddit-kommentarer) – vil vi foreløpig kalle modellen GPT-Fyodor.

KerasNLP

Trikset til en 5-linjers GPT-Fyodor ligger i KerasNLP, som er utviklet av det offisielle Keras-teamet, som en horisontal utvidelse til Keras, som på ekte Keras-vis tar sikte på å bringe bransjestyrke NLP til fingertuppene dine, med nye lag (kodere, dekodere, token-innbygging, posisjonsinnbygging, metrikk, tokenizere, etc.).

KerasNLP er ikke en modelldyrehage. Det er en del av Keras (som en egen pakke), som senker inngangsbarrieren for NLP-modellutvikling, akkurat som den senker inngangsbarrieren for generell dyp læringsutvikling med hovedpakken.

OBS: I skrivende stund produseres KerasNLP fortsatt, og i tidlige stadier. Subtile forskjeller kan være tilstede i fremtidige versjoner. Oppskriften bruker versjonen 0.3.0.

For å kunne bruke KerasNLP, må du installere den via pip:

$ pip install keras_nlp

Og du kan bekrefte versjonen med:

keras_nlp.__version__

Implementering av en GPT-stilmodell med Keras

La oss starte med å importere bibliotekene vi skal bruke – TensorFlow, Keras, KerasNLP og NumPy:

import tensorflow as tf
from tensorflow import keras
import keras_nlp
import numpy as np

Laster inn data

La oss laste inn noen av Dostojevskijs romaner – en ville være altfor kort til at en modell passer, uten en god del overfitting fra de tidlige stadiene og fremover. Vi kommer til å bruke de rå tekstfilene fra Project Gutenberg, på grunn av det enkle å jobbe med slike data:

crime_and_punishment_url = 'https://www.gutenberg.org/files/2554/2554-0.txt'
brothers_of_karamazov_url = 'https://www.gutenberg.org/files/28054/28054-0.txt'
the_idiot_url = 'https://www.gutenberg.org/files/2638/2638-0.txt'
the_possessed_url = 'https://www.gutenberg.org/files/8117/8117-0.txt'

paths = [crime_and_punishment_url, brothers_of_karamazov_url, the_idiot_url, the_possessed_url]
names = ['Crime and Punishment', 'Brothers of Karamazov', 'The Idiot', 'The Possessed']
texts = ''
for index, path in enumerate(paths):
    filepath = keras.utils.get_file(f'{names[index]}.txt', origin=path)
    text = ''
    with open(filepath, encoding='utf-8') as f:
        text = f.read()
        
        
        
        texts += text[10000:]

Vi har ganske enkelt lastet ned alle filene, gått gjennom dem og satt dem sammen på toppen av den andre. Dette inkluderer et visst mangfold i språket som brukes, mens det fortsatt holder det tydelig Fyodor! For hver fil har vi hoppet over de første 10 500 tegnene, som er rundt gjennomsnittslengden på forordet og Gutenberg-introen, så vi sitter igjen med en stort sett intakt hoveddel av boken for hver iterasjon. La oss ta en titt på noen tilfeldige XNUMX tegn i texts streng nå:


texts[25000:25500]
'nd that was whynI addressed you at once. For in unfolding to you the story of my life, Indo not wish to make myself a laughing-stock before these idle listeners,nwho indeed know all about it already, but I am looking for a mannof feeling and education. Know then that my wife was educated in anhigh-class school for the daughters of noblemen, and on leaving shendanced the shawl dance before the governor and other personages fornwhich she was presented with a gold medal and a certificate of merit.n'

La oss dele strengen i setninger før vi gjør noen annen behandling:

text_list = texts.split('.')
len(text_list) 

Vi har 69 XNUMX setninger. Når du bytter ut n tegn med mellomrom og tell ordene:

len(texts.replace('n', ' ').split(' ')) 

OBS: Du vil vanligvis ha minst en million ord i et datasett, og ideelt sett mye mye mer enn det. Vi jobber med noen få megabyte data (~5MB) mens språkmodeller er mer vanlig trent på titalls gigabyte med tekst. Dette vil naturligvis gjøre det veldig enkelt å overpasse tekstinndataene og vanskelig å generalisere (høy forvirring uten overtilpasning, eller lav forvirring med mye overtilpasning). Ta resultatene med en klype salt.

Ikke desto mindre, la oss dele disse inn i en trening, test og validering sett. Først, la oss fjerne de tomme strengene og blande setningene:


text_list = list(filter(None, text_list))

import random
random.shuffle(text_list)

Deretter vil vi gjøre en 70/15/15-deling:

length = len(text_list)
text_train = text_list[:int(0.7*length)]
text_test = text_list[int(0.7*length):int(0.85*length)]
text_valid = text_list[int(0.85*length):]

Dette er en enkel, men effektiv måte å utføre en tog-test-valideringsdeling. La oss ta en titt på text_train:

[' It was a dull morning, but the snow had ceased',
 'nn"Pierre, you who know so much of what goes on here, can you really havenknown nothing of this business and have heard nothing about it?"nn"What? What a set! So it's not enough to be a child in your old age,nyou must be a spiteful child too! Varvara Petrovna, did you hear what hensaid?"nnThere was a general outcry; but then suddenly an incident took placenwhich no one could have anticipated', ...

Tid for standardisering og vektorisering!

Tekstvektorisering

Nettverk forstår ikke ord – de forstår tall. Vi ønsker å symbolisere ordene:

...
sequence = ['I', 'am', 'Wall-E']
sequence = tokenize(sequence)
print(sequence) # [4, 26, 472]
...

Siden setninger er forskjellige i lengde – legges det vanligvis til utfylling til venstre eller høyre for å sikre samme form på tvers av setninger som mates inn. Si at vår lengste setning er 5-ord (tokens) lang. I så fall vil Wall-E-setningen bli polstret med to nuller, slik at vi sikrer samme inngangsform:

sequence = pad_sequence(sequence)
print(sequence) # [4, 26, 472, 0, 0]

Tradisjonelt ble dette gjort ved hjelp av en TensorFlow Tokenizer og Keras' pad_sequences() metoder - imidlertid et mye mer praktisk lag, TextVectorization, kan brukes, som symboliserer og fyller innspillene dine, slik at du kan trekke ut ordforrådet og dets størrelse, uten å kjenne til ordforrådet på forhånd!

Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!

La oss tilpasse og tilpasse en TextVectorization lag:

from tensorflow.keras.layers import TextVectorization

def custom_standardization(input_string):
    sentence = tf.strings.lower(input_string)
    sentence = tf.strings.regex_replace(sentence, "n", " ")
    return sentence

maxlen = 50



vectorize_layer = TextVectorization(
    standardize = custom_standardization,
    output_mode="int",
    output_sequence_length=maxlen + 1,
)

vectorize_layer.adapt(text_list)
vocab = vectorize_layer.get_vocabulary()

De custom_standardization() metoden kan bli mye lengre enn dette. Vi har ganske enkelt redusert alle inndata og erstattet n med " ". Det er her du virkelig kan legge inn det meste av forhåndsbehandlingen din for tekst – og levere den til vektoriseringslaget gjennom den valgfrie standardize argument. Med en gang du adapt() laget til teksten (NumPy-array eller liste over tekster) – du kan få ordforrådet, så vel som størrelsen derfra:

vocab_size = len(vocab)
vocab_size 

Til slutt, for å de-tokenisere ord, vil vi lage en index_lookup ordbok:

index_lookup = dict(zip(range(len(vocab)), vocab))    
index_lookup[5] 

Den kartlegger alle tokens ([1, 2, 3, 4, ...]) til ord i vokabularet (['a', 'the', 'i', ...]). Ved å sende inn en nøkkel (token index) kan vi enkelt få ordet tilbake. Du kan nå kjøre vectorize_layer() på alle inndata og observer de vektoriserte setningene:

vectorize_layer(['hello world!'])

Som resulterer i:

<tf.Tensor: shape=(1, 51), dtype=int64, numpy=
array([[   1, 7509,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0]], dtype=int64)>

Hei har indeksen på 1 mens verden har indeksen på 7509! Resten er polstringen til maxlen vi har regnet ut.

Vi har midler til å vektorisere tekst – la oss nå lage datasett fra text_train, text_test og text_valid, ved å bruke vårt vektoriseringslag som et konverteringsmedium mellom ord og vektorer som kan mates inn i GPT-Fyodor.

Datasettoppretting

Vi skal lage en tf.data.Dataset for hvert av våre sett, ved hjelp av from_tensor_slices() og gi en liste over, vel, tensorskiver (setninger):

batch_size = 64

train_dataset = tf.data.Dataset.from_tensor_slices(text_train)
train_dataset = train_dataset.shuffle(buffer_size=256)
train_dataset = train_dataset.batch(batch_size)

test_dataset = tf.data.Dataset.from_tensor_slices(text_test)
test_dataset = test_dataset.shuffle(buffer_size=256)
test_dataset = test_dataset.batch(batch_size)

valid_dataset = tf.data.Dataset.from_tensor_slices(text_valid)
valid_dataset = valid_dataset.shuffle(buffer_size=256)
valid_dataset = valid_dataset.batch(batch_size)

Når den er opprettet og blandet (igjen, for godt mål) – kan vi bruke en forbehandlingsfunksjon (vektorisering og sekvensdeling):

def preprocess_text(text):
    text = tf.expand_dims(text, -1)
    tokenized_sentences = vectorize_layer(text)
    x = tokenized_sentences[:, :-1]
    y = tokenized_sentences[:, 1:]
    return x, y


train_dataset = train_dataset.map(preprocess_text)
train_dataset = train_dataset.prefetch(tf.data.AUTOTUNE)

test_dataset = test_dataset.map(preprocess_text)
test_dataset = test_dataset.prefetch(tf.data.AUTOTUNE)

valid_dataset = valid_dataset.map(preprocess_text)
valid_dataset = valid_dataset.prefetch(tf.data.AUTOTUNE)

De preprocess_text() funksjonen utvides ganske enkelt med den siste dimensjonen, vektoriserer teksten ved hjelp av vår vectorize_layer og oppretter inngangene og målene, motvirket av et enkelt symbol. Modellen vil bruke [0..n] å antyde n+1, som gir en prediksjon for hvert ord, og står for alle ordene før det. La oss ta en titt på en enkelt oppføring i et av datasettene:

for entry in train_dataset.take(1):
    print(entry)

Ved å undersøke de returnerte inngangene og målene, i partier på 64 (med en lengde på 30 hver), kan vi tydelig se hvordan de er kompensert med ett:

(<tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[17018,   851,     2, ...,     0,     0,     0],
       [  330,    74,     4, ...,     0,     0,     0],
       [   68,   752, 30273, ...,     0,     0,     0],
       ...,
       [    7,    73,  2004, ...,     0,     0,     0],
       [   44,    42,    67, ...,     0,     0,     0],
       [  195,   252,   102, ...,     0,     0,     0]], dtype=int64)>, <tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[  851,     2,  8289, ...,     0,     0,     0],
       [   74,     4,    34, ...,     0,     0,     0],
       [  752, 30273,  7514, ...,     0,     0,     0],
       ...,
       [   73,  2004,    31, ...,     0,     0,     0],
       [   42,    67,    76, ...,     0,     0,     0],
       [  252,   102,  8596, ...,     0,     0,     0]], dtype=int64)>)

Endelig – det er på tide å bygge modellen!

Modelldefinisjon

Vi vil bruke KerasNLP-lag her. Etter en Input, koder vi inndataene gjennom en TokenAndPositionEmbedding lag, passerer i vår vocab_size, maxlen og embed_dim. Det samme embed_dim at dette laget mater ut og går inn i TransformerDecoder vil være beholdes i dekoderen. I skrivende stund opprettholder dekoderen automatisk inngangsdimensjonaliteten, og lar deg ikke projisere den inn i en annen utgang, men den lar deg definere de latente dimensjonene gjennom intermediate_dim argument.

Vi multipliserer innbyggingsdimensjonene med to for den latente representasjonen, men du kan beholde den den samme eller bruke et tall løsrevet fra de innebygde dimmene:

embed_dim = 128
num_heads = 4

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    decoder = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim, 
                                                            num_heads=num_heads, 
                                                            dropout=0.5)(embedding_layer)
    
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(decoder)
    
    model = keras.Model(inputs=inputs, outputs=outputs)
    
    model.compile(
        optimizer="adam", 
        loss='sparse_categorical_crossentropy',
        metrics=[keras_nlp.metrics.Perplexity(), 'accuracy']
    )
    return model

model = create_model()
model.summary()

På toppen av dekoderen har vi en Dense lag for å velge neste ord i sekvensen, med en softmax aktivering (som produserer sannsynlighetsfordelingen for hvert neste token). La oss ta en titt på sammendraget av modellen:

Model: "model_5"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_6 (InputLayer)        [(None, 30)]              0         
                                                                 
 token_and_position_embeddin  (None, 30, 128)          6365824   
 g_5 (TokenAndPositionEmbedd                                     
 ing)                                                            
                                                                 
 transformer_decoder_5 (Tran  (None, 30, 128)          132480    
 sformerDecoder)                                                 
                                                                 
 dense_5 (Dense)             (None, 30, 49703)         6411687   
                                                                 
=================================================================
Total params: 13,234,315
Trainable params: 13,234,315
Non-trainable params: 0
_________________________________________________________________

GPT-2 stabler mange dekodere – GPT-2 Small har 12 stablede dekodere (117M paramer), mens GPT-2 Extra Large har 48 stablede dekodere (1.5B paramer). Vår enkeltdekodermodell med ydmyke 13M parametere bør fungere godt nok for pedagogiske formål. Med LLM-er – oppskalering har vist seg å være en svært god strategi, og Transformers gir mulighet for god skalering, noe som gjør det mulig å trene ekstremt store modeller.

GPT-3 har en "mager" 175B parametere. Google Brains team trente en 1.6T-parametermodell for å utføre sparsomhetsundersøkelser samtidig som beregningene ble holdt på samme nivå som mye mindre modeller.

Faktisk, hvis vi økte antallet dekodere fra 1 til 3:

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    x = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    for i in range(4):
        x = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim*2, num_heads=num_heads,                                                             dropout=0.5)(x)
    do = keras.layers.Dropout(0.4)(x)
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(do)
    
    model = keras.Model(inputs=inputs, outputs=outputs)

Vårt parameterantall vil økes med 400k:

Total params: 13,631,755
Trainable params: 13,631,755
Non-trainable params: 0

De fleste parametrene i nettverket vårt kommer fra TokenAndPositionEmbedding og Dense lag!

Prøv ut forskjellige dybder på dekoderen – fra 1 til hele måten maskinen din kan håndtere og notere resultatene. Uansett – vi er nesten klare til å lære opp modellen! La oss lage en tilpasset tilbakeringing som produserer et eksempel på tekst for hver epoke, slik at vi kan se hvordan modellen lærer å danne setninger gjennom trening.

Tilpasset tilbakeringing

class TextSampler(keras.callbacks.Callback):
    def __init__(self, start_prompt, max_tokens):
        self.start_prompt = start_prompt
        self.max_tokens = max_tokens
        
    
    
    def sample_token(self, logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

    def on_epoch_end(self, epoch, logs=None):
        decoded_sample = self.start_prompt
        
        for i in range(self.max_tokens-1):
            tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
            predictions = self.model.predict([tokenized_prompt], verbose=0)
            
            
            
            
            sample_index = len(decoded_sample.strip().split())-1
            
            sampled_token = self.sample_token(predictions[0][sample_index])
            sampled_token = index_lookup[sampled_token]
            decoded_sample += " " + sampled_token
            
        print(f"nSample text:n{decoded_sample}...n")


random_sentence = ' '.join(random.choice(text_valid).replace('n', ' ').split(' ')[:4])
sampler = TextSampler(random_sentence, 30)
reducelr = keras.callbacks.ReduceLROnPlateau(patience=10, monitor='val_loss')

Trening av modellen

Endelig tid for å trene! La oss kaste inn vår train_dataset og validation_dataset med tilbakeringingene på plass:

model = create_model()
history = model.fit(train_dataset, 
                    validation_data=valid_dataset,
                    epochs=10, 
                    callbacks=[sampler, reducelr])

Prøvetakeren valgte en uheldig setning som starter med sluttsitatet og startsitatet, men det gir fortsatt interessante resultater mens han trener:

# Epoch training
Epoch 1/10
658/658 [==============================] - ETA: 0s - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711
# on_epoch_end() sample generation
Sample text:
”  “What do you had not been i had been the same man was not be the same eyes to been a whole man and he did a whole man to the own...
# Validation
658/658 [==============================] - 158s 236ms/step - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711 - val_loss: 2.2130 - val_perplexity: 9.1434 - val_accuracy: 0.6864 - lr: 0.0010
...
Sample text:
”  “What do you know it is it all this very much as i should not have a great impression  in the room to be  able of it in my heart...

658/658 [==============================] - 149s 227ms/step - loss: 1.7753 - perplexity: 5.9019 - accuracy: 0.7183 - val_loss: 2.0039 - val_perplexity: 7.4178 - val_accuracy: 0.7057 - lr: 0.0010

Det starter med:

"Hva hadde du ikke vært jeg hadde vært den samme"...

Noe som egentlig ikke gir mye mening. Ved slutten av de ti korte epokene produserer den noe i retning av:

"Hva mener du at det er den mest vanlige mannen av en mann selvfølgelig"...

Selv om den andre setningen fortsatt ikke gir så mye mening - er den mye mer fornuftig enn den første. Lengre trening på mer data (med mer intrikate forbehandlingstrinn) vil gi bedre resultater. Vi har bare trent det på 10 epoker med høyt frafall for å bekjempe den lille datasettstørrelsen. Hvis den ble latt trene mye lenger, ville den produsert veldig Fyodor-lignende tekst, fordi den ville ha husket store biter av den.

OBS: Siden utgangen er ganske detaljert, kan du justere verbose argument mens du tilpasser modellen for å redusere mengden tekst på skjermen.

Modellinferens

For å utføre slutninger, vil vi replikere grensesnittet til TextSampler – en metode som aksepterer et frø og en response_length (max_tokens). Vi bruker de samme metodene som i sampleren:

def sample_token(logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

def generate_text(prompt, response_length=20):
    decoded_sample = prompt
    for i in range(response_length-1):
        tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
        predictions = model.predict([tokenized_prompt], verbose=0)
        sample_index = len(decoded_sample.strip().split())-1

        sampled_token = sample_token(predictions[0][sample_index])
        sampled_token = index_lookup[sampled_token]
        decoded_sample += " " + sampled_token
    return decoded_sample

Nå kan du kjøre metoden på nye prøver:

generate_text('the truth ultimately is')


generate_text('the truth ultimately is')

Forbedre resultater?

Så hvordan kan du forbedre resultatene? Det er noen ganske handlingsrettede ting du kan gjøre:

  • Datarensing (rens inndataene mer omhyggelig, vi trimmet bare et omtrentlig tall fra starten og fjernet nye linjetegn)
  • Få mer data (vi jobbet bare med noen få megabyte tekstdata)
  • Skaler modellen sammen med dataene (stabling av dekodere er ikke vanskelig!)

konklusjonen

Selv om forbehandlingsrørledningen er minimalistisk og kan forbedres – produserte rørledningen som er skissert i denne veiledningen en anstendig GPT-modell, med bare 5 linjer med kode som kreves for å bygge en tilpasset dekoder-bare transformator, ved å bruke Keras!

Transformatorer er populære og allment anvendelige for generisk sekvensmodellering (og mange ting kan uttrykkes som sekvenser). Så langt var hovedbarrieren for inngang en tungvint implementering, men med KerasNLP – utøvere av dyp læring kan utnytte implementeringene til å bygge modeller raskt og enkelt.

Tidstempel:

Mer fra Stackabuse