1 पॉइंट द्वारा GN⁺ 2024-02-25 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • केवल PostgreSQL और pgvector से GPT-2 inference flow को SQL में उतारकर, tokenization से लेकर Transformer blocks और next-token generation तक को फिर से बनाया गया
  • Generative LLM लगभग एक deterministic function जैसा होता है, जो समान input पर समान candidate token probabilities देता है; response अलग होने की जगह candidate token चुनने वाले probabilistic selection step में होती है
  • implementation में GPT-2 के BPE tokenizer, 50257 tokens, 768-dimensional embeddings, 1024-token context, 12 blocks, 12 attention heads, और GELU-based feedforward को SQL queries और tables के रूप में व्यक्त किया गया
  • PostgreSQL regex में Unicode properties support न होना और EXP में बहुत छोटे values handle करने की सीमा जैसी वजहों से database environment के अनुसार व्यावहारिक workarounds की जरूरत पड़ी
  • उदाहरण में "Happy New Year! I wish you" से 10 tokens generate करके "Happy New Year! I wish you all the best in your new year!" output किया गया, और लेखक के environment में इसमें 2 मिनट 44 सेकंड लगे

SQL से GPT-2 inference pipeline बनाना

  • ChatGPT ने जवाब दिया कि SQL large language model implementation के लिए उपयुक्त नहीं है, लेकिन PostgreSQL SQL से GPT-2 inference pipeline implement की गई
  • संदर्भ के रूप में Jay Mody की GPT in 60 Lines of NumPy implementation explanation ली गई, और उन्हीं components को database tables और queries में उतारा गया
  • Generative LLM को llm(prompt: str) -> list[tuple[str, float]] रूप वाले function की तरह देखा जा सकता है
    • input text prompt है
    • output अगली आने वाली string candidates और probabilities की array है
    • अगर internal math और parameters समान हों, तो समान input पर समान result लौटाता है
  • ChatGPT जैसे products के समान सवाल पर अलग जवाब दे पाने की वजह model खुद से ज्यादा next token selection step में probabilistic selection है

Text generation loop

  • Generation process prompt को token array में बदलने के बाद model को बार-बार call करके next token चुनता है और उसे prompt के पीछे जोड़ता है
  • basic flow इन steps से बना है
    • tokenize(prompt) से string को token ID array में convert करना
    • gpt2(tokens) 50257 tokens के लिए probabilities calculate करता है
    • select_next_token(candidates) अगला token चुनता है
    • चुने गए token को array में add करना
    • तय token count, timeout, stopword जैसी conditions पर रोकना
    • detokenize(tokens) से token array को string में restore करना
  • इस तरह accumulated token sequence grammar, syntax, meaning और reasoning जैसी दिखने वाली विशेषताओं वाला natural language text बन सकता है

BPE tokenizer को SQL में implement करना

  • Neural network input से पहले text को numbers की list में बदलना पड़ता है, लेकिन Unicode codepoints को सीधे इस्तेमाल करने पर token space और length inefficient हो जाते हैं
  • GPT-2 Byte pair encoding का एक variant इस्तेमाल करता है
    • token dictionary 50257 codepoints का उपयोग करती है
    • इसमें UTF-8 byte sequences और “end of text” token शामिल हैं
    • शुरुआत 256 byte tokens से होती है, फिर अक्सर आने वाले adjacent token pairs को नए token के रूप में जोड़ा जाता है
    • इस merge को 50000 बार repeat करके 50256 tokens बनाए जाते हैं, और अंत में end-of-text token जोड़ा जाता है
  • GPT-2 tokenizer में bytes को string characters पर map करने वाली एक अतिरिक्त layer है, और यह mapping OpenAI GPT-2 के encoder.py में define है
  • SQL implementation में OpenAI से download की गई token dictionary को tokenizer table में डाला गया, और byte-character mapping को encoder table में store किया गया
  • "Mississippilessly" example recursive CTE से single bytes से शुरू होकर merge किए जा सकने वाले best adjacent pair को बार-बार merge करता है
    • example में token count 17 से घटकर 5 हो जाता है
    • Unicode के करीब 150k codepoint space के बजाय GPT-2 का करीब 50k token space इस्तेमाल होता है
  • कई words process करते समय GPT-2 regex से text को split करके हर word के अंदर merge करता है
    • PostgreSQL regex में Unicode character properties support नहीं करता, इसलिए original GPT-2 regex को कुछ modify किया गया
    • संभव है कि इस modification ने सही Unicode support को नुकसान पहुंचाया हो
  • "PostgreSQL is great" SQL tokenizer में [6307, 47701, 318, 1049] में convert होता है
    • token clusters हैं Post, greSQL, Ġis, Ġgreat
    • Ġ space को दर्शाता है

Embedding और context window

  • Token ID सीधे model calculations में इस्तेमाल नहीं होते, बल्कि embedding vectors में convert होते हैं
  • GPT-2 tokens और positions को अलग-अलग embed करता है
    • WTE word token embedding है और 50257×768 matrix है
    • WPE word position embedding है और 1024×768 matrix है
  • हर token position पर WTE vector और WPE vector को जोड़कर next step का input vector बनाया जाता है
  • क्योंकि WPE में सिर्फ 1024 positions हैं, GPT-2 prompt में इस्तेमाल किए जा सकने वाले tokens की maximum संख्या 1024 है
    • यही संख्या LLM की context window के बराबर है
    • यह model design के समय तय hyperparameter है और training से नहीं बदलता
  • SQL implementation pgvector का उपयोग करता है
    • arrays पर vector operations खुद define करके pure SQL से भी संभव है, लेकिन performance कम हो जाती है
    • शुरुआती version pure SQL functions से चलता था, लेकिन धीमा था

self-attention को SQL query में विस्तार देना

  • Transformer का core self-attention mechanism है, और यह 2017 के paper Attention is all you need पर आधारित है
  • attention token vectors को एक-दूसरे को प्रभावित करने देता है, ताकि prompt के शुरुआती हिस्से की information आखिरी vector तक पहुंच सके
  • GPT-2 implementation Q, K, V matrices के 12 sets का उपयोग करता है
    • हर set एक attention head है
    • हर head 64-dimensional है
    • c_attn 768×2304 linear transformation है, और result Q, K, V को horizontally stack करके बना 2304-dimensional vector है
    • weights और bias c_attn_w, c_attn_b tables में store होते हैं
  • attention calculation से पहले layer normalization apply होती है
    • scale और shift parameters ln_1_g, ln_1_b tables में store होते हैं
  • causal self-attention में बाद के tokens को पहले के tokens को प्रभावित करने से रोकने के लिए causal mask apply किया जाता है
    • model का next token candidate अंततः last embedding से तय होता है
    • information flow last vector की ओर होना चाहिए, और last vector की intermediate value को previous vectors को प्रभावित नहीं करना चाहिए
  • SQL implementation में softmax calculation के दौरान PostgreSQL EXP के बहुत छोटे numbers पर fail होने की समस्या से बचने के लिए input -745.13 से छोटा हो तो उसे 0 माना जाता है
  • causal mask की वजह से नए token को prompt में जोड़ने पर भी previous tokens के calculation results नहीं बदलते
    • original GPT-2 implementation इसी property का उपयोग करता है
    • SQL implementation simplicity के लिए इस reuse का उपयोग नहीं करता

multi-head attention और residual connection

  • 12 heads के attention results हर एक 64-dimensional होते हैं, जिन्हें horizontally stack करके फिर 768-dimensional बनाया जाता है
  • इसके बाद c_proj_w, c_proj_b में stored trained linear transformation से attention output को project किया जाता है
  • multi-headed attention result में original input फिर से add किया जाता है
    • यह residual connection original Transformer paper में शामिल technique है
    • इसे training के दौरान vanishing gradient और exploding gradient problems को कम करने वाली design के रूप में introduce किया गया था

feedforward step और Transformer block

  • attention के बाद feedforward neural network आता है
  • GPT-2 का feedforward step 3-layer multi-layer perceptron से बना है
    • dimensions 768 → 3072 → 768 हैं
    • activation function GELU इस्तेमाल होता है
  • linear transformation parameters इन tables में store हैं
    • mlp_c_fc_w, mlp_c_fc_b
    • mlp_c_proj_w, mlp_c_proj_b
  • feedforward input भी पहले ln_2 parameters से normalize होता है
    • ln_2_g, ln_2_b scale और shift store करते हैं
  • feedforward output में भी input को फिर से add करने वाला residual connection apply होता है
  • attention + feedforward का यह combination एक block है, और GPT-2 12 blocks को pipeline की तरह connect करता है
    • हर block के अपने trained parameter sets होते हैं
    • SQL में blocks को recursive CTE से connect किया जाता है
  • last block output को ln_f parameters से फिर normalize किया जाता है

वापस next token में बदलना

  • final output में last position का 768-dimensional vector next token की embedding है
  • इस vector को फिर token में बदलने के लिए initial token embedding में इस्तेमाल हुआ WTE matrix फिर इस्तेमाल किया जाता है
  • exact inverse transformation आम तौर पर संभव नहीं है
    • predicted embedding WTE की किसी specific row के बिल्कुल समान नहीं हो सकती
    • इसलिए हर token embedding के साथ dot product calculate करके करीब token खोजा जाता है
  • WTE और predicted embedding के dot product results 50257 scores, यानी logits बनते हैं
  • ये scores softmax से गुजरकर probabilities में बदलते हैं
    • top candidate count top_n है
    • probability distribution को adjust करने वाली value temperature है
    • temperature जितना अधिक होगा, rank 1 के अलावा tokens के चुने जाने की संभावना उतनी बढ़ेगी, और inference कम predictable होगा
  • "PostgreSQL is great" example में top 5 next token candidates ये हैं
    • Ġfor
    • ,
    • .
    • Ġat
    • Ġto
  • temperature 0.5, 1, 2 में बदलने पर समान candidates की softmax probability distribution बदल जाती है

वास्तविक inference result और code

  • final SQL tokens को probability के अनुसार चुनने और prompt में जोड़ने की process को repeat करता है
  • model खुद deterministic है, और non-deterministic element सिर्फ token selection में शामिल random numbers हैं
  • example settings इस प्रकार हैं
    • prompt: "Happy New Year! I wish you"
    • generated token count: 10
    • temperature: 2
    • top_n: 1
    • SETSEED(0.20231231) का उपयोग
  • लेखक के environment में query 2 मिनट 44 सेकंड चली
  • output result "Happy New Year! I wish you all the best in your new year!" है
  • query और installation code GitHub repository quassnoi/explain-extended-2024 में हैं

1 टिप्पणियां

 
GN⁺ 2024-02-25
Hacker News टिप्पणियाँ
  • बहुत सुंदर। मैं भी SQLite में कुछ ऐसा ही rabbit hole खोद रहा था, लेकिन अभी तक neural network तक नहीं पहुँच पाया था
    makemore lecture series[0] से प्रेरणा मिली थी, और लगभग 1 घंटे बाद वह counting approach से neural network पर चली जाती है; मैं भी लगभग वहीं तक पहुँचा था
    इसे relational model में तोड़कर देखना वाकई बहुत अच्छा अभ्यास है
    [0] https://www.youtube.com/watch?v=PaCmpygFfXo

    • आगे देखते रहें तो neural network ठीक वही tables निकालता है जो counting approach में निकलते हैं, और generation के समय भी बिल्कुल वही result देता है
  • डेमो अच्छा है, लेकिन लेख में causal masking की व्याख्या training और inference को मिलाती हुई लगती है
    causal masking का उद्देश्य training के दौरान future tokens को “झाँकने” से रोकना होता है, और GPT-शैली की architectures में inference के दौरान autoregressiveness को लागू करना भी इसका उद्देश्य है
    inference में वैसे भी सिर्फ आख़िरी token का उपयोग होता है, इसलिए वह token पूरे input sequence पर attention देता है; इसीलिए अगला token सिर्फ आख़िरी token की embedding से तय नहीं होता

  • मुझे जिज्ञासा है कि क्या यह GPT के driver loop को सही तरह से दिखाता है: prompt को tokenize करना, gpt2(tokens) से 50257 tokens की probabilities लेना, अगला token चुनना, उसे token list में जोड़ना, stop condition जाँचना, और अंत में detokenize करना — कुछ ऐसा दिख रहा है
    लेकिन यह state machine Shlemiel the painter algorithm लागू करती हुई लगती है, इसलिए generation task की मूल computational cost को लेकर सवाल उठता है

    • लोगों के large language models में context window कहने का मतलब मैं यह समझता हूँ कि रखे जाने वाले tokens की अधिकतम संख्या होती है, और सबसे पुराने tokens हटते जाते हैं
      वह window एक sliding window होती है
    • हाँ, वही loop है, और सारा जादू gpt2 function के अंदर है
    • यह algorithm का बहुत छोटा हिस्सा है
      यह ज़्यादा से ज़्यादा generated tokens को एक वाक्य में इकट्ठा करने का तरीका दिखाता है
  • संबंधित सामग्री: A GPT in 60 Lines of NumPy - https://news.ycombinator.com/item?id=34726115 - फ़रवरी 2023, 146 टिप्पणियाँ

    • यह सामग्री लेख की शुरुआत में पहले से ही दी गई है
  • इसी तरह के संदर्भ में, मैंने GPT को पूरी तरह spreadsheet functions में implement किया था, और साथ में देखने लायक video tutorial भी बनाया था
    https://spreadsheets-are-all-you-need.ai/

    • पहला वीडियो शानदार है
      मुझे LLM काफ़ी कमाल का लगता है, लेकिन उसके असली काम करने के तरीके को पेशेवर रूप से सीखने की ज़रूरत कभी नहीं पड़ी; ऐसे में 10 मिनट के उस वीडियो ने उलझी हुई HN टिप्पणियाँ और सतही mainstream media लेख कई साल पढ़ने से ज़्यादा सिखा दिया
      floating-point numbers की भारी मात्रा को computation के इंतज़ार में जमा हुआ देखकर यह भी कहीं ज़्यादा सहज रूप से समझ आया कि यह तकनीक GPU इतनी ज़्यादा क्यों खाती है
    • spreadsheets, LLM को समझाने का एक स्वाभाविक तरीका हैं
      अगर हर training example में हर parameter का derivative निकाला जाए और साफ़ दिखाया जाए कि वह उस parameter पर कैसे map होता है, तो training process भी अच्छी तरह समझाई जा सकती है
  • बढ़िया। जो चीज़ सिर्फ 1 साल पहले तक किसी तरह के जादू जैसी लगती थी, अब उसे इतने अच्छे से, लगभग इस हद तक समझाया जा रहा है कि बच्चे भी उसका पीछा कर सकें

    • यह जादू 1 साल पहले शुरू नहीं हुआ था
      लेख में समझाया गया model GPT-2 है, जो 2019 की शुरुआत में जारी किया गया था
    • “इतना कि बच्चे भी समझ सकें” कहना ठीक नहीं होगा
      इस लेख को ठीक से समझने के लिए computer science की पृष्ठभूमि काफ़ी मज़बूत होनी चाहिए, और शीर्षक भी अपने-आप में मानवता के 99% लोगों के लिए कम सुलभ है
  • मैं अब तक GPT और LLM से पूरी तरह बचता आया हूँ, लेकिन यह तरीका text output में कुछ हद तक fluency तो पैदा कर सकता है, पर सवाल समझकर जवाब देने की क्षमता तक पहुँचता हुआ नहीं लगता
    मैं सोच रहा हूँ कि क्या कोई सरल blog post या course है जो बताए कि यह वास्तव में कैसे काम करता है, या Python जैसी toy engine दिखाए
    अब तक मैंने जो शैक्षिक सामग्री देखी है, वह platforms का उपयोग कैसे करें इस पर ज़्यादा केंद्रित थी, अंदरूनी कामकाज पर नहीं

  • दिलचस्प बात यह है कि आधुनिक machine learning को Turing completeness की ज़रूरत नहीं होती
    फिर भी हम AGI की संभावना पर विचार कर रहे हैं, इसलिए अगर निष्कर्ष यह निकले कि Turing completeness ज़रूरी नहीं है, तो वह काफ़ी रोचक होगा

    • Turing completeness ज़रूरी लगती है
      सीधी वजह यह है कि मैं अपने दिमाग़ में Turing-complete code के execution का पीछा कर सकता हूँ
    • token inference अपने-आप में Turing-complete नहीं है, लेकिन अगर output side effects पैदा कर सके — जैसे अगले iteration के prompt को बदल सके — तो बात पूरी तरह अलग हो जाती है
  • लेख शानदार था, और हर component की व्याख्या साफ़ और काफ़ी thorough थी, इसलिए पढ़ना अच्छा लगा
    बस गलती से “+ expand source” दबा दिया, और उस चौंकाने वाले monster को देखने के बाद मुझे ChatGPT की यह बात माननी पड़ी कि “SQL large language models को implement करने के लिए उपयुक्त नहीं है”

    • मैंने भी दबा दिया था और उसे फिर से collapse करने का तरीका नहीं मिला
  • “साधारण Unicode neural networks के साथ अच्छी तरह काम नहीं करता” — यह बात सही नहीं है। उदाहरण के लिए ByT5 को देखिए
    लेख में जिसे “alphabet” कहा गया है, उसे आम तौर पर vocabulary कहा जाता है, और अगर UTF-8 bytes को vocabulary बनाया जाए तो tokens 149186 नहीं बल्कि 256 होंगे
    ByT5 ठीक यही करता है

    • बात यह नहीं है कि यह बिल्कुल काम नहीं करता, बल्कि यह कि हमारे पास मौजूद दूसरे approaches की तुलना में यह उतना अच्छा काम नहीं करता
      बाज़ार में सबसे अच्छा performance देने वाले models सभी tokenization का उपयोग करते हैं; यही इसका सबूत है
      यह कोई रहस्य नहीं कि tokenization मूल रूप से एक तरह का hack है, और आदर्श रूप में लोग चाहते हैं कि किसी न किसी तरह इसे कभी हटाया जा सके (https://twitter.com/karpathy/status/1657949234535211009)
      सिद्धांत रूप में byte-level tokenization की कमियों की भरपाई बड़े models और बड़े context से की जा सकती है, लेकिन व्यवहार में उसी स्तर की intelligence वाला model train करने के लिए कहीं ज़्यादा resources लगते हैं
      हाँ, कुछ खास tasks — जैसे किसी शब्द में अक्षरों की संख्या गिनना — ऐसे भी हैं जहाँ tokenization उल्टा intelligence को नुकसान पहुँचाती है