5 पॉइंट द्वारा GN⁺ 2024-01-04 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Transformer inference प्रक्रिया को Hello World → Hola Mundo अनुवाद उदाहरण तक सीमित करके, tokenization से लेकर encoder·decoder और अगले token की probability calculation तक हाथ से follow करने लायक बनाया गया है
  • मूल paper की बड़ी settings के बजाय 4-dimensional embedding, 2 attention heads, और 8-dimensional feedforward layer का उपयोग करके matrix multiplication और softmax flow को छोटा किया गया है
  • Encoder token embedding में positional encoding जोड़ने के बाद, multi-head self-attention और feedforward layer से गुजरकर input sequence का contextual representation बनाता है
  • Decoder SOS से शुरू होता है और पिछले generated tokens तथा encoder output दोनों का उपयोग करता है; encoder-decoder attention में query decoder से, और key/value encoder output से calculate होते हैं
  • आखिरी decoder embedding linear layer और softmax से गुजरकर अगले token की probabilities बनती है, लेकिन उदाहरण में random weights हैं, इसलिए वास्तविक translation quality की उम्मीद नहीं की जाती

लक्ष्य और आधारभूत मान्यताएँ

  • Transformer model के अंदर inference के समय गणित कैसे end-to-end आगे बढ़ता है, इसे एक उदाहरण से देखना
  • calculation को हाथ से follow करना आसान बनाने के लिए model size को काफी कम किया गया है
    • मूल paper के embedding dimension 512 के बजाय उदाहरण में 4 dimensions का उपयोग
    • attention heads मूल paper के 8 के बजाय 2 उपयोग किए गए
    • feedforward dimension मूल paper के 2048 के बजाय 8 dimensions उपयोग किया गया
  • आवश्यक आधारभूत ज्ञान basic linear algebra है, और अधिकतर calculation matrix multiplication से होती है
  • Transformer “क्या है” से ज़्यादा, असल calculation कैसे आगे बढ़ती है इस पर focus है
  • intuitive explanation के लिए The Illustrated Transformer के साथ पढ़ना अच्छा है, और मूल paper Attention is all you need है

Encoder input बनाना

  • Tokenization

    • Machine learning model text नहीं, numbers process करते हैं, इसलिए input text को token IDs में बदला जाता है
    • उदाहरण को सरल बनाने के लिए "Hello World" को "Hello" और "World" दो word tokens में बांटा गया है
    • असली tokenization तरीक़े word-based, character-based, और subword-based हो सकते हैं
    • word-based तरीके में बड़ा vocabulary चाहिए और "dog" तथा "dogs" को अलग tokens माना जाता है
    • character-based में vocabulary छोटा होता है, लेकिन semantic information कम हो सकती है
    • subword tokenization, word और character तरीके के बीच का रास्ता है, और statistical process से tokenizer को train करता है
  • Token embedding

    • Token ID अपने आप में अर्थ नहीं रखता, इसलिए हर token को fixed-size vector यानी embedding में बदला जाता है
    • उदाहरण embeddings में arbitrary values उपयोग की गई हैं
      • Hello -> [1, 2, 3, 4]
      • World -> [2, 3, 4, 5]
    • वास्तविक Transformer में embedding mapping भी train होती है, और model task के हिसाब से token representations सीखता है
    • दोनों embeddings को एक matrix में जोड़ा जाता है और आगे matrix multiplication में उपयोग किया जाता है
  • Positional encoding

    • केवल embedding से शब्द की sentence में position पता नहीं चलती, इसलिए positional encoding जोड़ी जाती है
    • मूल paper fixed sine/cosine positional encoding उपयोग करता है, और उदाहरण भी वही तरीका अपनाता है
    • उदाहरण की positional encoding इस तरह calculate होती है
      • Hello -> [0, 1, 0, 1]
      • World -> [0.84, 0.99, 0, 1]
    • token embedding और positional encoding को जोड़कर encoder input matrix बनाया जाता है
      • Hello -> [1, 3, 3, 5]
      • World -> [2.84, 3.99, 4, 6]

Self-attention calculation

  • Q, K, V बनाना

    • self-attention input embedding से query(Q), key(K), value(V) calculate करता है
    • उदाहरण में 2 attention heads हैं, और हर head के पास अलग WQ, WK, WV matrices हैं
    • हर weight matrix 4-dimensional embedding को 3-dimensional query/key/value में बदलता है
    • पहले head में input matrix को WK1, WV1, WQ1 से multiply करके K1, V1, Q1 मिलते हैं
  • Attention formula

    • attention score चार steps में calculate होता है
      • query और हर key का dot product calculate करना
      • key dimension के square root से divide करना
      • softmax से इसे positive weights में बदलना जिनका sum 1 हो
      • weights से value vectors का weighted sum लेना
    • यह प्रक्रिया मूल paper के formula में संक्षेपित है
    • [
    • Attention(Q,K,V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V
    • ]
    • उदाहरण में छोटे dimension और random initial values की वजह से softmax result लगभग 0 और 1 की तरफ झुक जाता है
    • बड़े dot product values softmax में और strongly amplify हो सकते हैं, इसलिए key dimension के square root से divide करने वाली scaling ज़रूरी है
    • explanation के लिए अस्थायी रूप से sqrt(3) के बजाय 30 से divide करने वाला variation भी उपयोग किया गया है, लेकिन यह long-term समाधान नहीं है
  • Multi-head attention output

    • हर head के attention result को concatenate करने के बाद, train होने वाले weight matrix से multiply करके फिर embedding dimension में वापस बदला जाता है
    • उदाहरण में दोनों head results को मिलाकर 6-dimensional matrix बनाया जाता है, और इसे 4-dimensional output में transform किया जाता है
    • यह output encoder block के अगले step, feedforward layer, में भेजा जाता है

Feedforward layer और encoder block

  • Feedforward layer

    • self-attention के बाद feedforward neural network(FFN) आता है
    • FFN दो linear transformations और उनके बीच ReLU activation से बना होता है
    • पहली linear layer dimension बढ़ाती है, और दूसरी linear layer dimension को original size में घटाती है
    • ReLU negative values को 0 बनाता है और positive values को जस का तस रखता है, जिससे non-linearity जुड़ती है
    • उदाहरण में 4-dimensional input को 8 dimensions तक expand करके फिर 4 dimensions में घटाया जाता है
    • [
    • \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2
    • ]
  • Encoder block

    • एक encoder block multi-head attention और FFN से बना होता है
    • मूल paper 6 encoders stack करता है, और example code भी n=6 से encoders repeat करता है
    • कई encoder blocks से सीधे गुजारने पर values बहुत बड़ी हो जाती हैं, softmax calculation में overflow हो सकता है और nan आ सकता है

Residual connection और layer normalization

  • Values के अनियंत्रित बढ़ने की समस्या

    • उदाहरण में 6 encoders से गुजरने पर overflow encountered in exp और invalid value encountered in divide warnings आती हैं और output nan हो जाता है
    • values का बहुत बड़ा होना और next layer में और बड़ा होना deep neural networks में आम समस्या है
    • backpropagation के दौरान gradient बहुत बड़ा हो जाए तो इसे gradient explosion कहते हैं
  • Residual connection

    • residual connection layer input को layer output में जोड़ने का तरीका है
    • [
    • \text{Residual}(x) = x + \text{Layer}(x)
    • ]
    • उदाहरण में attention output और FFN output दोनों पर residual connection apply किया गया है
    • residual connection vanishing gradient problem को कम करने के लिए उपयोग होता है
  • Layer normalization

    • layer normalization हर embedding dimension के लिए mean 0 और standard deviation 1 बनाने के लिए normalize करता है
    • formula इस प्रकार है
    • [
    • \text{LayerNorm}(x) = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} \times \gamma + \beta
    • ]
    • (\epsilon) एक छोटी value है ताकि standard deviation 0 होने पर 0 से divide करने की समस्या से बचा जा सके
    • (\gamma) और (\beta) learning parameters हैं जो scaling और shifting control करते हैं
    • residual connection और layer normalization जोड़ने के बाद 6 encoders से गुजरने पर भी nan के बिना normal values आती हैं

Decoder structure

  • Decoder input और generation method

    • decoder encoder output और अब तक generated output sequence को input के रूप में लेता है
    • inference के दौरान यह SOS(start-of-sequence) token से शुरू होता है
    • decoder autoregressive तरीके से एक बार में एक token generate करता है
      • पहला iteration: SOS को input लेकर "hola" generate करता है
      • दूसरा iteration: SOS + hola को input लेकर "mundo" generate करता है
      • तीसरा iteration: SOS + hola + mundo को input लेकर EOS generate करता है
    • EOS(end-of-sequence) token generate होते ही decoding रुक जाती है
    • encoder एक forward pass में representation बना सकता है, लेकिन decoder को कई forward passes करने पड़ते हैं, इसलिए यह धीमा होता है
  • Decoder block composition

    • decoder block encoder block से अधिक complex है और निम्न क्रम में बना होता है
      • masked self-attention
      • residual connection और layer normalization
      • encoder-decoder attention
      • residual connection और layer normalization
      • feedforward layer
      • residual connection और layer normalization
    • inference example में SOS embedding में positional encoding जोड़कर [1, 1, 0, 1] उपयोग किया गया है
    • training के दौरान future tokens न दिखें, इसके लिए attention score को -inf से mask करने वाला masked self-attention उपयोग होता है

Encoder-decoder attention

  • encoder-decoder attention वह step है जो decoder को input sentence के relevant parts पर focus करने देता है
  • calculation method self-attention जैसा ही है, लेकिन Q/K/V बनाने वाले inputs अलग होते हैं
    • query पिछले decoder layer output से calculate होती है
    • key और value encoder output से calculate होते हैं
  • इस structure की वजह से decoder की हर position input sequence की सभी positions को reference कर सकती है
  • translation जैसे tasks में उपयोगी है, जहां output token input sentence की relevant position पर निर्भर होना चाहिए

Output token generation

  • Linear layer और softmax

    • decoder output सीधे word नहीं होता, इसलिए आखिरी embedding को linear layer से गुजारकर vocabulary size का logits vector बनाया जाता है
    • example vocabulary size 10 है, और अगले token candidates ये हैं
      • hello, mundo, world, how, ?, EOS, SOS, a, hola, c
    • logits softmax से गुजरकर हर token की probability distribution बनते हैं
    • example probabilities में "hola" की probability सबसे अधिक है, इसलिए उसे अगले token के रूप में चुना जाता है
    • हमेशा highest probability वाला token चुनने की method greedy decoding है, और यह हमेशा best नहीं होती
    • generation techniques के बारे में Hugging Face article में और detail मिल सकती है
  • Complete generation loop

    • पूरा generation process इस flow का पालन करता है
      • input sequence को embedding में बदलना
      • encoder input के पूरे context का representation generate करता है
      • decoder SOS से शुरू होकर previous generated tokens और encoder output दोनों का उपयोग करता है
      • आखिरी decoder embedding पर linear layer और softmax apply करना
      • सबसे probable next token चुनकर sequence में जोड़ना
      • EOS आने या maximum length तक पहुंचने तक repeat करना
    • example run hello world input के लिए SOS hola mundo world generate करता है
    • सभी weights और embeddings random हैं, इसलिए result अच्छा translation नहीं है; यह expected behavior है

निष्कर्ष और दायरा

  • उदाहरण Transformer के core components — embedding, positional encoding, self-attention, multi-head attention, FFN, residual connection, layer normalization, encoder-decoder attention, softmax output — को एक flow में जोड़ता है
  • आधुनिक Transformer architectures कई techniques जोड़ते हैं, लेकिन core mathematics इस उदाहरण में बताए गए structure पर आधारित है
  • task type के आधार पर उपयोग होने वाला stack अलग हो सकता है
    • classification जैसे understanding-centric tasks में encoder stack के ऊपर linear layer रखी जा सकती है
    • translation जैसे generation-centric tasks में encoder और decoder stacks साथ उपयोग किए जा सकते हैं
    • ChatGPT या Mistral जैसे free generation tasks में केवल decoder stack उपयोग हो सकता है
  • training process को cover नहीं किया गया है; focus existing model इस्तेमाल करते समय inference mathematics समझने पर है
  • अधिक formal math material के लिए यह PDF देख सकते हैं

1 टिप्पणियां

 
GN⁺ 2024-01-04
Hacker News की टिप्पणियाँ
  • Transformer का “रहस्य” यह है कि हर layer में static weights और values को linear क्रम में multiply करने के बजाय, वही input trained weights से multiply करके 3 matrices बनाता है और फिर उन matrices को आपस में multiply करता है
    इससे parallelism बढ़ता है और यह अच्छी तरह काम करता है, लेकिन attention formula खुद fixed है, इसलिए यह बहुत सीमित है
    आगे बढ़ने के लिए शायद computation graph को ही learnable parameters के रूप में generalize करने का तरीका चाहिए। छोटे बदलावों से performance में बड़े बदलाव आने वाले chaotic effect की वजह से पता नहीं traditional gradient methods से यह संभव है या नहीं; internally genetic algorithm या particle swarm optimization जैसी कोई form चाहिए हो सकती है

    • यह व्याख्या बिल्कुल सही नहीं है। Transformer की खास बात यह है कि sequence का हर element बाकी सभी elements में से अपने लिए महत्वपूर्ण हिस्से चुनकर उन्हें निकालकर compute कर सकता है
      RNN की तुलना में बड़ा theoretical फायदा यह है कि यह इसे lossless तरीके से support करता है। क्योंकि हर element sequence के बाकी सभी elements, या time order में पहले आए elements की पूरी जानकारी तक access कर सकता है
      इसके उलट RNN और “linear Transformer” past values को compress करते हैं, इसलिए लंबे sequence के आखिरी element के लिए पहले element की सारी जानकारी तक access करना आम तौर पर मुश्किल होता है, और जब तक internal state इतनी बड़ी न हो कि कोई जानकारी discard न हो, यह असंभव है
    • “और आगे बढ़ने के लिए computation graph को learnable parameters में generalize करना होगा” कहना काफ़ी bold है। क्योंकि computation graph सीखे बिना भी पहले ही बहुत बड़ी प्रगति हो चुकी है
    • यह तरीका मूल रूप से कुछ paths को ignore करना और अधिक important चीज़ों को amplify करना सीख सकता है, और फिर जिन paths को हटाने पर quality loss बड़ा नहीं होता उन्हें prune किया जा सकता है
      समस्या यह है कि इससे बहुत कुछ हासिल नहीं होता। matrix multiplication के अलावा operations शायद धीमे होंगे या लगभग उसी speed के होंगे
    • computation graph को learnable parameters में generalize करने वाली बात से मैं सहमत हूँ। LLM से जिन समस्याओं को हल करवाना चाहते हैं—यानी Transformer जिस “language processing” में अच्छा है उससे आगे, real reasoning जैसी समस्याएँ—वे इंसानी mental processes के हल करने के तरीके जैसी लगती हैं
      लेकिन flow control जोड़ने पर असल में Turing machine बन जाने का जोखिम है, और तब, जैसा कहा गया, learning समस्या बन जाती है। फिर भी यह पूरी तरह intractable समस्या न भी हो सकती है
    • hyperparameter tuning भी computation graph सीखने की दिशा में कुछ हद तक बढ़ रही है। हालांकि यह बहुत limited है और कहीं ज़्यादा training की जरूरत होती है
  • अगर आप ज्यादा dry, formal और concise explanation चाहते हैं, तो John Thickstun की “The Transformer Model in Equations” [0] है
    standard mathematical notation में पूरी चीज़ एक page में आ जाती है
    [0] https://johnthickstun.com/docs/transformers.pdf

    • आखिरकार ऐसी explanation देखकर अच्छा लगा। मुझे लगता है mathematical notation की 7 lines qualitative गपशप के कई pages से कहीं बेहतर हैं
      कई बार लगता है कि machine learning researchers ने math बिल्कुल पढ़ा ही नहीं है
    • papers पढ़ते समय मुझे ऐसी चीज़ों को कई बार अपनी personal notes में जोड़-जोड़कर लिखना पड़ा, और हमेशा भरोसा नहीं होता था कि कहीं कुछ छूट तो नहीं गया
  • “NaN आता है, values बहुत बड़ी होने से next encoder में जाते हुए explode हो जाती हैं, यही gradient explosion है” वाली explanation, मेरी समझ के अनुसार, गलत है
    यहाँ किसी भी point पर gradient compute नहीं किया जा रहा, इसलिए यह gradient explosion नहीं है
    समस्या softmax implementation की लगती है, और numerically stable softmax implementation का तरीका यहाँ [0] में समझाया गया है
    [0]: https://jaykmody.com/blog/stable-softmax/

    • सही। common training problems यानी gradient explosion और gradient vanishing को softmax के बड़े values के प्रति sensitive होने की समस्या से जोड़ने की कोशिश की थी, लेकिन मैं मानता हूँ कि इससे गलतफहमी होती है या यह inaccurate है, इसलिए उस हिस्से को फिर से लिखूँगा
      हालांकि neural network कुल मिलाकर बड़े values के प्रति sensitive होता है, इसलिए सिर्फ numerically stable softmax से यह हल नहीं होता। network के काम करने के लिए normalization key है
  • Transformer tutorials शायद नए Monad tutorials बन जाएँ। concept समझना मुश्किल है, लेकिन examples पर practice करते हुए जूझना पड़ता है, तभी समझ आता है
    computer science के बहुत-से हिस्सों की तरह

    • जिस पल आप Transformer समझ लेते हैं, आप उसे explain नहीं कर पाते
    • Monad कोई मुश्किल concept है? Monad तो बस endofunctor category में monoid है, इसमें दिक्कत क्या है?
    • “You could have invented transformers” title वाले blog post का इंतज़ार कर रहा हूँ
  • मैंने सिर्फ छह paragraphs पढ़े हैं और अभी से सवाल आ गया
    Hello -> [1,2,3,4] World -> [2,3,4,5] में vectors random बताए गए हैं, लेकिन pattern जैसा दिख रहा है। दोनों vectors में मौजूद 2 का कोई मतलब है, या पूरी set मिलकर uniqueness बनाती है—यह जानना चाहता हूँ

    • numbers reuse होना बस इतना है कि author ने थोड़ा आलस किया। आप देख सकते हैं कि दोनों vectors similar direction में point कर रहे हैं या angle compute करके similarity estimate कर सकते हैं
      यहाँ वे लगभग 60 degrees दूर हैं और कुछ हद तक same direction में हैं, लेकिन example में negative numbers न डालने की कोशिश की वजह से vectors असल से ज्यादा similar दिख रहे हैं
      numbers reuse होने का fact खुद meaningful नहीं है। पहली position का 1, दूसरी position के 1 से लगभग unrelated है। क्योंकि इन vectors पर convolution नहीं किया जा रहा
    • यह अच्छा example नहीं है। हर token का vector अपने elements को normal distribution से लेकर randomly initialized होता है
      training के बाद similar words में कुछ हद तक cosine similarity होगी, लेकिन [1,2,3,4] और [2,3,4,5] जितनी ऊँची cosine similarity शायद ही कभी होगी
  • पूरी तरह संबंधित सवाल नहीं है, लेकिन मैं ऐसा लेख या पेपर खोज रहा हूँ जो यह समझाए कि Transformer सिर्फ “अगला token predictor” की तरह काम करते हुए भी नीचे जैसे सवालों को कैसे संभाल पाता है

    1. training dataset में न देखे गए अज्ञात शब्द, subword या token को संभालना। उदाहरण: pandas में "sdsfs_ff", "fsdf_value" को columns के रूप में रखकर table बनाना
    2. training data में न मौजूद उदाहरण बनाना और LLM से वैसा ही output मांगना
      यह आम सवाल लगता है, लेकिन search करने के keywords नहीं मिल रहे। positional embeddings पर गहराई से बात करने वाले links भी मिल जाएँ तो अच्छा होगा, और sine/cosine क्यों इस्तेमाल होते हैं तथा multiplication बनाम addition पर भी अभी तक संतोषजनक जवाब नहीं मिला
    • मेरा अनुमान है कि एकल अक्षर भी token के रूप में encode हो सकते हैं, लेकिन model के अंदर उन्हें process करने में अधिक bandwidth लगती है, और किसी विशिष्ट word token की तुलना में उनमें मूल रूप से मौजूद अर्थ कम होता है
      अगर model को ज़रूरी लगे, तो वह अज्ञात sequence को single-character tokens copy करके फिर से बना सकता है, या context में समझ में आए तो नया बना सकता है
    • P(X_1=x_1, X_2=x_2, X_3=x_3) = P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_1=x_1, X_2=x_2)
      = P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_2=x_2 | X_1=x_1) • P(X_1=x_1)
      यानी यदि पिछले tokens दिए होने पर अगले token के लिए सही conditional probability distribution हो, तो पूरे token sequence के लिए भी सही probability distribution बन जाता है
      “token sequence के लिए सही probability distribution”, या किसी condition के दिए होने पर token sequence का सही conditional probability distribution, असल में लगभग हर तरह के input/output व्यवहार को इसी तरह बयान कर सकता है
      इसलिए “अगले token की भविष्यवाणी करके काम करता है” सिद्धांततः इस पर कोई बड़ी पाबंदी नहीं लगाता कि वह किस तरह का input/output behavior कर सकता है
      वह कोई भी प्रभावशाली काम करे, उसका output P(X_{n+1}=x_{n+1} | X_1=x_1, ..., X_n=x_n) से आता है, यानी “next token prediction” है—इस तथ्य से कोई टकराव नहीं होता
    • यह training data की exact strings को reproduce करना नहीं है, बल्कि patterns और patterns के patterns को reproduce करना है
      next token prediction सुनने में जितना लगता है, उससे कहीं अधिक intelligent task है
  • “complexity steps की संख्या और parameters की संख्या से आती है” वाली बात से सहमत हूँ
    जो Transformer model हमारे समझने लायक simple है, वह दिलचस्प काम नहीं करता, और जो Transformer दिलचस्प काम करने लायक complex है, वह हमारे समझने के लिए बहुत complex दिखता है
    ऐसा मध्यम आकार का model study करना चाहूँगा जो समझने लायक simple भी हो और दिलचस्प काम करने लायक complex भी

    • अगर पहले से परिचित नहीं हैं, तो mechanistic interpretability के क्षेत्र की research आपको दिलचस्प लग सकती है। Neel Nanda ने इस topic पर बहुत से accessible resources डाले हैं: https://www.neelnanda.io/mechanistic-interpretability
    • लगता है कि दोनों तरफ की boundaries असल में कुछ ऐसी ही होंगी। बीच वाला क्षेत्र शायद पहले ही इंसानों के ठीक से समझने के लिए बहुत complex है, लेकिन साथ ही दिलचस्प काम करने के लिए अभी बहुत छोटा भी है
  • concepts को define या introduce किए बिना इस्तेमाल किया जाए तो समझना मुश्किल होता है। Encoder section बिना यह बताए सीधे शुरू हो जाता है कि वह क्या है और पूरी प्रक्रिया में कहाँ आता है
    लेखक क्या करना चाहते हैं, यह समझ आता है, लेकिन पहले idea introduce करना, फिर explain करना और उसके बाद use करना—लेखन की यह basic structure गायब है
    अगर कोई इस topic को पहले से पढ़ रहा हो और आधा समझ चुका हो, तभी ठीक; वरना पूरा लेख उलझाने वाला लगता है

  • मैंने ANN शुरू से लिखा है और TensorFlow इस्तेमाल नहीं किया, फिर भी यह explanation अब भी confusing है
    मैंने ChatGPT से कहा कि Matrix या Vector शब्दों का इस्तेमाल किए बिना बताए कि basic ANN को self-attention implement करने के लिए कैसे बदला जाए, तो उसने काफी simple explanation दी। हालांकि मैंने अभी implement करके नहीं देखा
    मेरे लिए सब कुछ nodes, weights और layers के नजरिए से सोचना बेहतर है। matrices और vectors ANN के अंदर सच में क्या हो रहा है, उससे जोड़ना और मुश्किल बना देते हैं
    ANN लिखने के familiar तरीके में हर input node scalar होता है, लेकिन forward propagation algorithm हर input node को weight से multiply करके add करता है, इसलिए वह vector-matrix multiplication जैसा दिखता है। लगता है मैं इन explanations को गलत mindset से approach कर रहा हूँ, और शायद मेरे पास जरूरी background knowledge कम है