paint-brush
Hur man bygger en liten språkmodell (TLM) i Ruby: En steg-för-steg-guideförbi@davidesantangelo
528 avläsningar
528 avläsningar

Hur man bygger en liten språkmodell (TLM) i Ruby: En steg-för-steg-guide

förbi Davide Santangelo10m2025/02/03
Read on Terminal Reader

För länge; Att läsa

I den här artikeln kommer vi att gå igenom hur man skapar en mycket enkel språkmodell med hjälp av Ruby. Vi kommer att bygga en grundläggande Markov Chain-modell som "lär sig" från inmatad text och sedan genererar ny text baserat på mönstren den observerade.
featured image - Hur man bygger en liten språkmodell (TLM) i Ruby: En steg-för-steg-guide
Davide Santangelo HackerNoon profile picture
0-item

I den här artikeln kommer vi att gå igenom hur man skapar en mycket enkel språkmodell med hjälp av Ruby. Även om sanna stora språkmodeller (LLM) kräver enorma mängder data och beräkningsresurser, kan vi skapa en leksaksmodell som visar många av kärnkoncepten bakom språkmodellering. I vårt exempel kommer vi att bygga en grundläggande Markov Chain-modell som "lär sig" från inmatad text och sedan genererar ny text baserat på mönstren den observerade.


Obs: Denna handledning är avsedd för utbildningsändamål och illustrerar en förenklad metod för språkmodellering. Det är inte en ersättning för moderna djuplärande LLMs som GPT-4 utan snarare en introduktion till de underliggande idéerna.


Innehållsförteckning

  1. Förstå grunderna i språkmodeller
  2. Konfigurera din Ruby-miljö
  3. Datainsamling och förbearbetning
  4. Bygger Markov Chain Model
  5. Utbildning av modellen
  6. Generera och testa text
  7. Slutsats

Förstå grunderna i språkmodeller

En språkmodell är ett system som tilldelar sannolikheter till sekvenser av ord. I sin kärna är det utformat för att fånga språkets statistiska struktur genom att lära sig sannolikheten för att en viss sekvens inträffar i ett givet sammanhang. Detta innebär att modellen analyserar stora textkroppar för att förstå hur ord vanligtvis följer varandra, vilket gör att den kan förutsäga vilket ord eller fras som kan komma härnäst i en följd. Sådana funktioner är centrala inte bara för uppgifter som textgenerering och autokomplettering utan också för en mängd olika applikationer för naturlig språkbehandling (NLP), inklusive översättning, sammanfattning och sentimentanalys.

Moderna storskaliga språkmodeller (LLM) som GPT-4 använder djupinlärningstekniker och massiva datauppsättningar för att fånga komplexa mönster i språk. De fungerar genom att bearbeta inmatad text genom många lager av artificiella neuroner, vilket gör det möjligt för dem att förstå och generera människoliknande text med anmärkningsvärt flyt. Men bakom dessa sofistikerade system ligger samma grundläggande idé: att förstå och förutsäga ordsekvenser baserat på inlärda sannolikheter.

En av de enklaste metoderna att modellera språk är genom en Markov-kedja . En Markov-kedja är en statistisk modell som arbetar utifrån antagandet att sannolikheten för att ett ord inträffar bara beror på en begränsad uppsättning föregående ord, snarare än hela textens historia. Detta koncept är känt som Markov-egendomen. I praktiska termer antar modellen att nästa ord i en sekvens kan förutsägas enbart genom att titta på det eller de senaste orden - en förenkling som gör problemet beräkningsmässigt mer löst samtidigt som det fångar användbara mönster i data.

I en Markov Chain-baserad språkmodell:

  • Det framtida tillståndet (nästa ord) beror bara på det aktuella tillståndet (tidigare ord): Det betyder att när vi känner till de sista orden (bestämda av modellens ordning), har vi tillräckligt med sammanhang för att förutsäga vad som kan komma härnäst. Hela historien om samtalet eller texten behöver inte beaktas, vilket minskar komplexiteten.
  • Vi bygger en sannolikhetsfördelning av vilket ord som kommer härnäst givet föregående ord: Eftersom modellen tränas på en korpus av text lär den sig sannolikheten för att olika ord följer en given sekvens. Denna sannolikhetsfördelning används sedan under genereringsfasen för att välja nästa ord i sekvensen, typiskt med användning av en slumpmässig samplingsprocess som respekterar de lärda sannolikheterna.

I vår implementering kommer vi att använda en konfigurerbar "ordning" för att bestämma hur många tidigare ord som ska beaktas när vi gör förutsägelser. En högre ordning ger mer sammanhang, vilket potentiellt kan resultera i mer sammanhängande och kontextuellt relevant text, eftersom modellen har mer information om vad som kom innan. Omvänt introducerar en lägre ordning mer slumpmässighet och kan leda till mer kreativa, om än mindre förutsägbara, ordsekvenser. Denna avvägning mellan koherens och kreativitet är en central faktor i språkmodellering.

Genom att förstå dessa grundläggande principer kan vi uppskatta både enkelheten i Markov Chain-modeller och de grundläggande idéerna som ligger till grund för mer komplexa neurala språkmodeller. Denna utökade vy hjälper inte bara till att förstå den statistiska mekaniken bakom språkförutsägelse utan lägger också grunden för att experimentera med mer avancerade tekniker inom naturlig språkbehandling.


Konfigurera din Ruby-miljö

Innan du börjar, se till att du har Ruby installerat på ditt system. Du kan kontrollera din Ruby-version genom att köra:

 ruby -v

Om Ruby inte är installerad kan du ladda ner den från ruby-lang.org .

För vårt projekt kanske du vill skapa en dedikerad katalog och fil:

 mkdir tiny_llm cd tiny_llm touch llm.rb

Nu är du redo att skriva din Ruby-kod.


Datainsamling och förbearbetning

Samla utbildningsdata

För en språkmodell behöver du en textkorpus. Du kan använda vilken textfil som helst för träning. För vårt enkla exempel kan du använda ett litet exempel på text, till exempel:

 sample_text = <<~TEXT Once upon a time in a land far, far away, there was a small village. In this village, everyone knew each other, and tales of wonder were told by the elders. The wind whispered secrets through the trees and carried the scent of adventure. TEXT

Förbearbetning av data

Innan träning är det användbart att förbehandla texten:

  • Tokenisering: Dela upp text i ord.
  • Normalisering: Valfritt konvertera text till gemener, ta bort skiljetecken, etc.

För våra syften fungerar Rubys String#split -metod tillräckligt bra för tokenisering.


Bygger Markov Chain Model

Vi kommer att skapa en Ruby-klass vid namn MarkovChain för att kapsla in modellens beteende. Klassen kommer att innehålla:

  • En initialiserare för att ställa in ordningen (antal föregående ord) för kedjan.
  • En train som bygger kedjan från inmatad text.
  • En generate som producerar ny text genom sampling från kedjan.

Nedan är den fullständiga koden för modellen:

 class MarkovChain def initialize(order = 2) @order = order # The chain is a hash that maps a sequence of words (key) to an array of possible next words. @chain = Hash.new { |hash, key| hash[key] = [] } end # Train the model using the provided text. def train(text) # Optionally normalize the text (eg, downcase) processed_text = text.downcase.strip words = processed_text.split # Iterate over the words using sliding window technique. words.each_cons(@order + 1) do |words_group| key = words_group[0...@order].join(" ") next_word = words_group.last @chain[key] << next_word end end # Generate new text using the Markov chain. def generate(max_words = 50, seed = nil) # Choose a random seed from the available keys if none is provided or if the seed is invalid. if seed.nil? || [email protected]?(seed) seed = @chain.keys.sample end generated = seed.split while generated.size < max_words # Form the key from the last 'order' words. key = generated.last(@order).join(" ") possible_next_words = @chain[key] break if possible_next_words.nil? || possible_next_words.empty? # Randomly choose the next word from the possibilities. next_word = possible_next_words.sample generated << next_word end generated.join(" ") end end

Förklaring av koden


  • **Initiering:** initialize ställer in ordningen (standard är 2) och skapar en tom hash för vår kedja. Hashen ges ett standardblock så att varje ny nyckel börjar som en tom array.


  • **Träna modellen:** train tar en textsträng, normaliserar den och delar upp den i ord. Genom att använda each_cons skapar den på varandra följande grupper av ord av längdordningen order + 1 . Orden av första order fungerar som nyckeln, och det sista ordet läggs till raden av möjliga fortsättningar för den nyckeln.


  • **Generera text:** generate börjar med en frönyckel. Om ingen tillhandahålls, väljs en slumpmässig nyckel. Den bygger sedan iterativt en sekvens genom att slå upp de sista order och sampla nästa ord tills det maximala antalet ord har uppnåtts.


Utbildning av modellen

Nu när vi har vår MarkovChain klass, låt oss träna den på lite textdata.

 # Sample text data for training sample_text = <<~TEXT Once upon a time in a land far, far away, there was a small village. In this village, everyone knew each other, and tales of wonder were told by the elders. The wind whispered secrets through the trees and carried the scent of adventure. TEXT # Create a new MarkovChain instance with order 2 model = MarkovChain.new(2) model.train(sample_text) puts "Training complete!"

När du kör ovanstående kod (till exempel genom att spara den i llm.rb och köra ruby llm.rb ), kommer modellen att tränas med hjälp av den medföljande exempeltexten.


Generera och testa text

När modellen är tränad kan du generera ny text. Låt oss lägga till lite kod för att generera och skriva ut en exempeltext:

 # Generate new text using the trained model. generated_text = model.generate(50) puts "Generated Text:" puts generated_text

Du kan också prova att tillhandahålla ett frö för textgenerering. Om du till exempel känner till en av nycklarna i modellen (som "once upon" ), kan du göra:

 seed = "once upon" generated_text_with_seed = model.generate(50, seed) puts "\nGenerated Text with seed '#{seed}':" puts generated_text_with_seed

Genom att experimentera med olika frön och parametrar (som ordning och maximalt antal ord) kan du se hur resultatet varierar.


Komplett exempel: Utbildning och testning av en liten LLM

Här är det kompletta Ruby-skriptet som kombinerar alla ovanstående steg:

 #!/usr/bin/env ruby # llm.rb # Define the MarkovChain class class MarkovChain def initialize(order = 2) @order = order @chain = Hash.new { |hash, key| hash[key] = [] } end def train(text) processed_text = text.downcase.strip words = processed_text.split words.each_cons(@order + 1) do |words_group| key = words_group[0...@order].join(" ") next_word = words_group.last @chain[key] << next_word end end def generate(max_words = 50, seed = nil) if seed.nil? || [email protected]?(seed) seed = @chain.keys.sample end generated = seed.split while generated.size < max_words key = generated.last(@order).join(" ") possible_next_words = @chain[key] break if possible_next_words.nil? || possible_next_words.empty? next_word = possible_next_words.sample generated << next_word end generated.join(" ") end end # Sample text data for training sample_text = <<~TEXT Once upon a time in a land far, far away, there was a small village. In this village, everyone knew each other, and tales of wonder were told by the elders. The wind whispered secrets through the trees and carried the scent of adventure. TEXT # Create and train the model model = MarkovChain.new(2) model.train(sample_text) puts "Training complete!" # Generate text without a seed generated_text = model.generate(50) puts "\nGenerated Text:" puts generated_text # Generate text with a specific seed seed = "once upon" generated_text_with_seed = model.generate(50, seed) puts "\nGenerated Text with seed '#{seed}':" puts generated_text_with_seed

Kör skriptet

  1. Spara skriptet som llm.rb .
  2. Öppna din terminal och navigera till katalogen som innehåller llm.rb
  3. Kör skriptet med:
 ruby llm.rb

Du bör se utdata som indikerar att modellen har tränats och sedan två exempel på genererad text.


Benchmark

Följande tabell sammanfattar några benchmarkmått för olika versioner av våra Tiny LLM-implementeringar. Varje mätvärde förklaras nedan:

  • Modell: Namnet eller versionsidentifieraren för språkmodellen.
  • Ordning: Antalet tidigare ord som används i Markov-kedjan för att förutsäga nästa ord. En högre ordning innebär generellt att mer sammanhang används, vilket potentiellt ökar koherensen.
  • Träningstid (ms): Den ungefärliga tiden det tar att träna modellen på den tillhandahållna textdata, mätt i millisekunder.
  • Genereringstid (ms): Den tid som krävs för att generera ett exempel på textutdata, mätt i millisekunder.
  • Minnesanvändning (MB): Mängden minne som konsumeras av modellen under träning och generering.
  • Koherensbetyg: Ett subjektivt betyg (av 5) som anger hur koherent eller kontextuellt lämplig den genererade texten är.

Nedan är nedräkningstabellen med referensdata:

Modell

Beställa

Träningstid (ms)

Generationstid (ms)

Minnesanvändning (MB)

Koherensbetyg

Tiny LLM v1

2

50

10

10

3/5

Tiny LLM v2

3

70

15

12

3,5/5

Tiny LLM v3

4

100

20

15

4/5

Dessa riktmärken ger en snabb översikt över avvägningarna mellan olika modellkonfigurationer. När beställningen ökar tenderar modellen att ta något längre tid att träna och generera text, och den använder mer minne. Dessa ökningar av resursförbrukning åtföljs dock ofta av förbättringar i den genererade textens sammanhållning.

Slutsats

I den här handledningen demonstrerade vi hur man skapar en mycket enkel språkmodell med Ruby. Genom att utnyttja Markov Chain-tekniken byggde vi ett system som:

  • Tränar på exempeltext genom att lära sig ordövergångar.
  • Genererar ny text baserat på inlärda mönster.

Även om denna leksaksmodell är långt ifrån produktionsnivå LLM, fungerar den som en språngbräda för att förstå hur språkmodeller fungerar på en grundläggande nivå. Du kan utöka denna idé genom att införliva mer avancerade tekniker, hantera skiljetecken bättre eller till och med integrera Ruby med maskininlärningsbibliotek för mer sofistikerade modeller.

Glad kodning!

L O A D I N G
. . . comments & more!

About Author

Davide Santangelo HackerNoon profile picture
Davide Santangelo@davidesantangelo
Software Engineer - dad. APIs specialist, In love with #ruby, #go and #python - developer at sevio.it

HÄNG TAGGAR

DENNA ARTIKEL PRESENTERAS I...