<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://vishesh9131.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://vishesh9131.github.io/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-09-17T22:24:59+00:00</updated><id>https://vishesh9131.github.io/feed.xml</id><title type="html">Vishesh Yadav</title><subtitle>Data Scientist and researcher at IISc working on machine learning, language models, and defense-oriented AI. </subtitle><entry><title type="html">LLMs Count Digits, Not Store a Number Line</title><link href="https://vishesh9131.github.io/blog/2026/llms-counting-digits-not-storing-a-number-line/" rel="alternate" type="text/html" title="LLMs Count Digits, Not Store a Number Line"/><published>2026-06-11T00:00:00+00:00</published><updated>2026-06-11T00:00:00+00:00</updated><id>https://vishesh9131.github.io/blog/2026/llms-counting-digits-not-storing-a-number-line</id><content type="html" xml:base="https://vishesh9131.github.io/blog/2026/llms-counting-digits-not-storing-a-number-line/"><![CDATA[<p>I got stuck on a dumb sounding question: when a language model sees <code class="language-plaintext highlighter-rouge">4521</code>, what is actually in the vector?</p> <p>People say magnitude is linearly decodable. Ok fine. But does the model keep a real quantity like a number line? Or just rank order? Or digit symbols glued together? Everyone cites probes, nobody lines the stories up on the same stimuli.</p> <p>So I spent a long stretch building constraint tests across a bunch of models (small Qwen up to DeepSeek 70B, Llama, Phi, GPT-2, BERT, etc). Not to confirm my favorite theory. Mostly to break theories.</p> <p>This is my informal writeup of that work. Numbers live in <code class="language-plaintext highlighter-rouge">Experiment2/results/*_verdict.json</code> if you want the raw logs.</p> <h2 id="the-trap-that-fooled-me-early">the trap that fooled me early</h2> <p>If you sample integers uniformly from 1 to a million, value, log value, and rank all move together. Monotone.</p> <p>So a probe that only cares about ordering cant tell you if the model encoded cardinal size, ordinal rank, or digit pattern. I formalized that in the writeup as a non-identifiability thing. Practical fix: use <strong>gapped</strong> number sets where rank and log value disagree, plus cross val, shuffle nulls, bootstrap CIs. Dont trust single split R² from a uniform grid.</p> <p>Also intrinsic dimension on 100 points in 1500d looks “thin” for fake reasons. Small sample. I had to stop trusting my own earlier manifold plots until I reran with controls.</p> <h2 id="what-i-was-trying-to-kill">what I was trying to kill</h2> <p>Six rough accounts from the literature:</p> <ol> <li>Cardinal / linear value code</li> <li>Pure ordinal (only order matters)</li> <li>Symbolic digit code</li> <li>Log compressed magnitude manifold</li> <li>String + context entangled hybrid</li> <li>CCM (my synthesis name at the end)</li> </ol> <p>I wrote down 16 constraints any story has to survive. Things like: log decodable, no vector arithmetic, digit identity readable, magnitude weak vs total variance, no shared axis across domains, causal necessity, notation robustness, etc.</p> <p>The scorecard table in my notes is just a map. Experiments carry the weight, not the tick count.</p> <h2 id="headline-results-the-ones-that-survived">headline results (the ones that survived)</h2> <h3 id="magnitude-is-real-but-squashed">magnitude is real but squashed</h3> <p>Log value probes work across models and domains. R² often 0.94 to 1.00 on the setups I ran.</p> <p>But geometry is <strong>compressed</strong>. Between/within cluster ratios κ around 2 to 4.8. Isometry to log distance is moderate (ρ ~ 0.2 to 0.5). So yes metric-ish in log space, not a clean ruler.</p> <p>Partial distance tests on gapped sets: log value still beats pure rank in the large encoders (bootstrap CI excludes 0 for Llama3 / DeepSeek on several domains). Small effects on Qwen 7B integer and GPT-2 distance were marginal. I report those without pretending they’re huge.</p> <h3 id="order-of-magnitude--digit-count-length-read-positionally">order of magnitude ≈ digit count (length), read positionally</h3> <p>This was the mechanism result that stuck.</p> <p>Decompose log10(n):</p> <ul> <li>floor part (# digits / order of magnitude) probes insanely high (R² ~0.976 to 0.982 on Qwen/Llama/DeepSeek)</li> <li>fractional part / leading digit adds correction</li> <li>last digit depends on readout (pooling)</li> </ul> <p>So the model is mostly <strong>counting digits in the string</strong>, not holding an abstract scalar. Log compression falls out of positional notation.</p> <p>Notation test backed this: same value as plain digits, comma form, scientific, words. Log still decodable 0.90 to 0.99.</p> <p>Zero pad to fixed width (kills raw token length cue): R² drop ≤0.04, mean ~0.015. Magnitude still there. So it’s <strong>where significant digits sit</strong>, not raw token count per se.</p> <h3 id="no-shared-number-line-across-contexts">no shared number line across contexts</h3> <p>Same numeric value in different templates (population vs distance vs price vs weight, eight domains total).</p> <p>Probe <strong>directions</strong> for magnitude barely align. Cross domain cosine mean ~0.12 to 0.25. Above random noise in high D, far below “same axis.”</p> <p>Pooled leave-one-domain-out R² weak (up to ~0.46 on Qwen, negative on Llama3 in one setup). So you dont get one universal magnitude direction.</p> <p>But magnitude <strong>information</strong> still transfers somewhat (calibration free Spearman 0.53 to 0.97 depending model/domain). My read: context picks a new readout direction each time, order info is partly portable, not a shared register.</p> <h3 id="no-vector-space-arithmetic">no vector space arithmetic</h3> <p>Addition composition in embedding space doesnt work like vector add. Product from concat embeddings fails OOD. Group symmetries absent (that constraint is noisy but directionally right).</p> <p>So dont expect h(347)+h(892) ≈ h(1239).</p> <h3 id="causal-erasure-the-part-that-isnt-just-probes">causal erasure (the part that isnt just probes)</h3> <p>On Qwen2.5-1.5B comparison task (“is a &gt; b?”):</p> <table> <thead> <tr> <th>condition</th> <th>accuracy</th> </tr> </thead> <tbody> <tr> <td>baseline</td> <td>0.91</td> </tr> <tr> <td>erase magnitude subspace all layers</td> <td>0.53 (chance)</td> </tr> <tr> <td>erase random rank-8 subspace</td> <td>0.67 ± 0.15</td> </tr> </tbody> </table> <p>Erase <strong>length</strong> (#digits) subspace: same-order pairs mostly ok (0.90), cross-order hurt (0.62).<br/> Erase <strong>leading digit</strong> subspace: same-order collapses (~0.50).</p> <p>Magnitude subspace and length subspace overlap heavily (cos ~0.89). Leading digit more distinct (cos ~0.43). Double dissociation at 1.5B.</p> <p>Replicated magnitude collapse at 7B (0.55 vs baseline ~0.92). Length-only selective effect was cleaner at 1.5B; at 7B length erasure looked more redundant. I dont oversell that as universal.</p> <p>Point: the comparison behavior <strong>needs</strong> the magnitude/length directions. Geometry isnt decorative.</p> <h3 id="steering-experiment-failed-reporting-it-anyway">steering experiment failed (reporting it anyway)</h3> <p>I tried adding one domain’s magnitude direction into another domain’s residual stream mid layers. Hoped for weak cross domain shift.</p> <p>Within domain moved judgments. Cross domain looked smaller. Then random direction control moved things similarly. After correction, contrast unreliable. Generic perturbation bias. I dont use steering as evidence. Correlational orthogonality still stands.</p> <h2 id="the-synthesis-name-ccm">the synthesis name: CCM</h2> <p><strong>Contextual Compositional Magnitude</strong> is just my label for what didnt die:</p> <ul> <li>Numbers are built from <strong>notation tokens</strong> (digits etc)</li> <li>A weak log compressed magnitude summary is linearly readable on top</li> <li>Dominated by <strong>order of magnitude / digit count</strong>, with leading digit correction</li> <li>Encoded along <strong>context specific directions</strong> (no shared axis)</li> <li>Digit identity coexists</li> <li>No vector arithmetic</li> <li>Causal erasure supports length/magnitude link for comparisons</li> </ul> <p>CCM isnt claiming I discovered log compression or probing. Lot of that exists in 2025 papers. My bit is adjudication + identifiability caution + length mechanism with erasure + no-shared-direction result.</p> <p>On the internal scorecard CCM marks all 16 constraints. Closest competitor is the string/context hybrid account at 13. Take the table as organization, not proof.</p> <h2 id="stuff-i-am-not-saying">stuff I am not saying</h2> <ul> <li>Models have a human like number line in latent space</li> <li>One global magnitude neuron direction across all prompts</li> <li>Probes prove how arithmetic is implemented during reasoning</li> <li>CCM is final cognitive science of numeracy</li> <li>Steering negative means context doesnt matter (it does, correlationally)</li> </ul> <h2 id="methods-compressed">methods compressed</h2> <p>Integer templates, eight ordered domains, gapped geometries for identifiability, repeated CV probes, bootstrap where noted, twelve models total (nine core + three for notation battery), causal all-layer subspace projection on Qwen 1.5B and 7B.</p> <p>Code under <code class="language-plaintext highlighter-rouge">Experiment2/</code> experiments. Key json: <code class="language-plaintext highlighter-rouge">ablation_verdict.json</code>, <code class="language-plaintext highlighter-rouge">notation_verdict.json</code>, <code class="language-plaintext highlighter-rouge">domains_verdict.json</code>, <code class="language-plaintext highlighter-rouge">transfer_refine.json</code>, <code class="language-plaintext highlighter-rouge">bootstrap_ci.json</code>, <code class="language-plaintext highlighter-rouge">geometry_verdict.json</code>, <code class="language-plaintext highlighter-rouge">steering_verdict.json</code>.</p>]]></content><author><name></name></author><category term="research"/><category term="LLM"/><category term="representation learning"/><category term="latent space"/><summary type="html"><![CDATA[Constraint tests on how language models represent numerical magnitude.]]></summary></entry><entry><title type="html">When LLMs Multiply</title><link href="https://vishesh9131.github.io/blog/2026/when-llms-multiply/" rel="alternate" type="text/html" title="When LLMs Multiply"/><published>2026-06-07T00:00:00+00:00</published><updated>2026-06-07T00:00:00+00:00</updated><id>https://vishesh9131.github.io/blog/2026/when-llms-multiply</id><content type="html" xml:base="https://vishesh9131.github.io/blog/2026/when-llms-multiply/"><![CDATA[<p>When LLMs Multiply: Right Ballpark, Wrong Answer</p> <p>I was running multiply prompts on our local GPUs one evening. Same template every time, greedy decode, no chain of thought. And I kept getting annoyed at the answers.</p> <p>The model sounds sure of itself. The number looks fine at a glance. About the right length. Like someone who knows the answer is “big” but never did the multiplication.</p> <p>So I started saving outputs properly. Then I wondered what the internal state looks like right before it prints anything. That turned into a bunch of probe runs on the same box.</p> <p>Writing this down for myself mostly. If you read the verdict jsons later, this is the english version.</p> <h2 id="part-1-outputs-looked-wrong-in-a-specific-way">Part 1: outputs looked wrong in a specific way</h2> <h3 id="what-i-ran">what I ran</h3> <p>Prompt:</p> <blockquote> <p>Question: What is 347 times 892? Give only the number.<br/> Answer:</p> </blockquote> <p>No CoT. Greedy. Max 12 tokens. Mostly 2 to 3 digit operands. Few hundred pairs per model.</p> <p>Two scores:</p> <ul> <li><strong>Exact</strong>: is the number actually correct</li> <li><strong>OOM</strong> (order of magnitude): right ballpark, same digit count basically (same floor of log10)</li> </ul> <h3 id="numbers">numbers</h3> <p>Exact multiply is bad. Scale is oddly good.</p> <table> <thead> <tr> <th>Model</th> <th>Exact</th> <th>OOM (right scale)</th> </tr> </thead> <tbody> <tr> <td>Qwen2.5-1.5B</td> <td>7%</td> <td>93%</td> </tr> <tr> <td>Qwen2.5-7B</td> <td>22%</td> <td>100%</td> </tr> <tr> <td>Llama3-8B</td> <td>12%</td> <td>100%</td> </tr> <tr> <td>Phi-3-mini</td> <td>13%</td> <td>74%</td> </tr> <tr> <td>Mistral-7B</td> <td>3%</td> <td>79%</td> </tr> </tbody> </table> <p>Qwen 1.5B: 93% get the scale right. 7% get the product.</p> <p>I call it <strong>Fermi decoding</strong> bc its like a Fermi guess. Right size, wrong value.</p> <h3 id="sanity-checks-i-ran-bc-first-pass-felt-too-weird">sanity checks I ran bc first pass felt too weird</h3> <p><strong>Token limit?</strong><br/> Bumped max_new_tokens 12 to 48. Exact still ~9%. So not truncation.</p> <p><strong>All ops broken?</strong><br/> Same prompt style for <strong>addition</strong> on Qwen 1.5B: 92% exact, 99% OOM. Add is fine. This is mostly a multiply thing with this template.</p> <p><strong>Wrong answers shape</strong><br/> On 1.5B wrong multiply answers, 90.6% still OOM-correct. Usually right length, wrong digits. Not random garbage.</p> <p><strong>Scale in hidden state before decode?</strong><br/> Probed last prompt token. Linear probe on product scale R² ~0.82 to 0.85, about same as digit count probe. So scale info is often already there internally. Feels like the model fails at spitting out exact digits, not at having zero idea of size.</p> <p>If your benchmark only checks “did it output a plausible sized number” you will overrate these models on multiply.</p> <h2 id="part-2-probing-hidden-states">Part 2: probing hidden states</h2> <p>After logging outputs I wanted to know if multiply vs add look different inside when operands are the same.</p> <p>Linear probes on hidden states. Ridge regression, cross val, shuffle nulls (shuffle labels, probe should collapse). Mainly Qwen2.5-1.5B, some reruns on 7B and Phi-3.</p> <h3 id="times-vs-plus-is-decodable-but-vectors-are-almost-the-same">times vs plus is decodable, but vectors are almost the same</h3> <p>Binary probe for operation word: R² ~1.0 on three models. Shuffle nulls negative.</p> <p>Then cosine between mul and add last-token states for same (a,b): ~0.9999. Basically the same vector.</p> <p>So yeah you can read off times vs plus. But geometrically its not two separate clusters. More like a tiny shift on top of almost identical states.</p> <h3 id="log-product-readable-in-add-prompts-too-boring-reason">log product readable in add prompts too (boring reason)</h3> <p>Layer 4:</p> <ul> <li>mul prompt log10(a*b): R² ~0.987</li> <li>add prompt log10(a*b): R² ~0.985</li> <li>gap 0.002</li> </ul> <p>Both prompts still have a and b in the text. Probe can pull operands and combine. Dont read that as “add mode stores multiplication.”</p> <h3 id="operand-tokens-carry-most-of-it">operand tokens carry most of it</h3> <p>Operand digit hiddens -&gt; log10(product) R² ~0.98. Last token only adds ~0.01 on top.</p> <p>Bilinear h_a * h_b does worse than concat. So not some clever multiplicative geometry, mostly linear readout.</p> <p>Static embeddings of operands predict mul prompt state R² ~0.73. Context changes the vector. Magnitude still easy to read once youre in the prompt.</p> <h3 id="digit-tokens">digit tokens</h3> <p>Digit identity R² ~0.97, place R² ~0.95 on operand digit tokens in mul prompts.</p> <p>But token index on same rows: R² ~0.99. So “place” might just be where you are in the sequence. I wouldnt claim abstract place value from this alone.</p> <h3 id="templates-matter-a-lot">templates matter a lot</h3> <p>Static Integer:n vs mul prompt cosine ~0.32.</p> <p>Static vs dumb filler prompt (“summarize weather in Paris”) cosine ~0.21. So low cosine is partly just different prompts, not magic arithmetic geometry.</p> <p>Reword mul template, same numbers: cosine ~0.72. Wording changes the state.</p> <h3 id="nudging-add-toward-mul-doesnt-flip-magnitude-probes">nudging add toward mul doesnt flip magnitude probes</h3> <p>Shift add state along mean(mul - add). Classifies op fine. log10 product vs log10 sum probe scores basically dont move. Direction tags the op, doesnt act like a magnitude switch.</p> <h3 id="probes-vs-actual-output">probes vs actual output</h3> <p>Qwen 1.5B layer 2: log10(product) probe R² ~0.996<br/> Same setup greedy multiply: 7% exact, 93% OOM</p> <p>Hidden state looks informative. Output often wrong anyway. Decodable doesnt mean the model uses it correctly at decode time.</p> <h2 id="putting-the-two-halves-together">putting the two halves together</h2> <table> <thead> <tr> <th> </th> <th>output logging</th> <th>probes</th> </tr> </thead> <tbody> <tr> <td>exact multiply</td> <td>low on Qwen</td> <td>didnt focus on this</td> </tr> <tr> <td>scale / OOM</td> <td>high on Qwen</td> <td>log product R² ~0.99 in prompt</td> </tr> <tr> <td>where it fails</td> <td>generation</td> <td>not early scale readout</td> </tr> <tr> <td>mul vs add</td> <td>Fermi mostly on mul</td> <td>op readable, states nearly same</td> </tr> <tr> <td>causal</td> <td>no</td> <td>no, correlational</td> </tr> </tbody> </table> <p>How I explain it to someone in the lab:</p> <ol> <li>Before tokens come out, scale is often already linearly readable.</li> <li>When tokens come out, scale is right a lot, exact digits wrong (Fermi thing).</li> <li>Mul and add prompts for same numbers are almost the same vector; op is a small extra bit.</li> <li>Magnitude probes dont separate ops cleanly. Operands in the prompt dominate.</li> <li>R² 0.99 on log product is not “solved multiplication.” The 7% exact rate already said that.</li> </ol> <h2 id="stuff-i-am-not-saying">stuff I am not saying</h2> <ul> <li>found an arithmetic circuit inside the transformer</li> <li>mul and add live in different geometric worlds</li> <li>high product R² in add prompts means its doing mul secretly</li> <li>place probes prove positional notation (token index confound is too strong)</li> <li>decodable = used = causal</li> </ul> <h2 id="methods-in-one-breath">methods in one breath</h2> <p>Fixed templates. Forward pass for probes, greedy for outputs. Usually last prompt token. Ridge, 5-fold CV repeated, shuffle nulls. Numbers in <code class="language-plaintext highlighter-rouge">cursor-work/results/</code>, code in <code class="language-plaintext highlighter-rouge">cursor-work/experiments/</code>.</p> <h2 id="if-you-benchmark-this-stuff">if you benchmark this stuff</h2> <p>Split exact and OOM on multiply. Dont use probe R² as a competence score. If you care about operation understanding use filler prompts and paraphrases and position baselines. Add under same terse format is much easier, dont assume all ops look like mul.</p> <p>Started bc multiply answers looked like good guesses with wrong exact digits. Still does across the models I tried. Inside, scale probes easy, op word decodable but tiny on shared state, magnitude doesnt split clean by operation.</p> <p>Gap between probe R² ~0.99 and 7% exact is what stuck with me. Feels like readout/generation is where it breaks, not that magnitude is totally absent from representations.</p> <p>Wouldve helped me to read something like this before prompt 200.</p> <p>Vishesh</p>]]></content><author><name></name></author><category term="research"/><category term="LLM"/><category term="numerical reasoning"/><summary type="html"><![CDATA[Right ballpark, wrong answer - and what hidden states reveal.]]></summary></entry><entry><title type="html">Tokenizers Are All We Need</title><link href="https://vishesh9131.github.io/blog/2025/tokenizers-are-all-we-need/" rel="alternate" type="text/html" title="Tokenizers Are All We Need"/><published>2025-11-07T00:00:00+00:00</published><updated>2025-11-07T00:00:00+00:00</updated><id>https://vishesh9131.github.io/blog/2025/tokenizers-are-all-we-need</id><content type="html" xml:base="https://vishesh9131.github.io/blog/2025/tokenizers-are-all-we-need/"><![CDATA[<h1 id="sitting-outside-iisc-freezing-a-little-thinking-about-tokenizers">Sitting Outside IISc, Freezing a Little, Thinking About Tokenizers</h1> <p>I wrapped up my work and i am sitting in front of the main building of the Indian institute of science…its so soothing cold the winds of november are giving my mind thrills…</p> <p>Ok so we are about to talk about tokenizers today!!! Why does it come to mind??? As we go through reading foundational models …”How LLMs understand english is one of the many questions readers come around!”</p> <p>And tokenizer is what breaks sentences into tiny tokens, tokens are not words, not characters not syllables, tokens are subword units chosen to make the entire text space efficient to represent. The cleverness and strategy while tokenizing the corpus we take decides how well our model is able to grasp the context and generate the next token with a good tpc (tokens per character)(lower is better) ohhhh what’s tpc now!!!! …calm down we will talk about this now, it’s just a simple measure of how much total token your model can generate divided by the total number of characters in the text…</p> <p>For example : if the gpt-pro-max can generate 11 tokens for the sentence “Who is Ramanujan??” and on the other side gpt-potato generates 23 tokens for the same sentence..can you spot the time and space complexity which version of gpt will take more??? Yes you got it, that’s gpt-potato… because to represent a entity he is taking more chars then gpt-pro-max….</p> <p>Yeah moving forward while keeping the tone of discussion light we will talk and in between i will keep making you know the further concepts tokenizers are associated with or famous tokenizers how they cleverly make text space efficient.</p> <p>You must be wondering how they look, is there any pattern or symmetry between them…</p> <p>If you are not thinking this, okay be calm i will make you think. You see every tokenizer when get trained it makes a finite list of tokens that finite list of tokens we called vocabulary and using that we make every words which is in the text space so just like 26 alphabet is vocab of english lang…Tokenizers invent an alphabet, but the letters are allowed to be as big or as weird as they want, as long as the final reconstruction cost stays small.</p> <p>According to some notable papers , they reveal promising benchmarks on upgrading and working on optimization of tokenizers as we know earlier researchers were only interested in thinking about optimizing the architecture or inventing one… This is how impactful tokenizers can be!!!!!</p> <hr/> <h2 id="encode-decode-logic">Encode Decode Logic</h2> <p>Tokenizers are bound by a deterministic rule which is very senseful, just like when you translate a sentence in hindi , it should not get changed when you translate it back to english. Similarly when we tokenize the corpus of text we expect the same text corpus if we “"”detokenize”””” it in future. detokenize wired words right!!! that’s why we introduce encode and decode nomenclature … when you tokenize something you are encoding it and decoding it when you need your corpus back to its original state.</p> <p>Great now you become a geek who knows basis of toeknizers…lets take this article further and i will discuss you about some of the coolest topics, my friends who 1 year back sit on a placement they were telling me interviewers are really interested if one knows about modules which makes generative models work …everyone knows how gpt works right transformers transformers transformers but knowing what qkv scoring is , knowing how multi head attention is being computed or knowing the working of positional encoding is what keeps your answers and replies in placement healthy…</p> <p>Just like i told you about tpc…there are so many entities to judge these tokenizers we call it Tokenization cost metrics….you are sitting in a MAANG interview for gen ai JD and interviewer is not asking TCM….thats where your dream will break and you are not really giving an interview…lol</p> <hr/> <h2 id="tpc-tpw-entropy-oov">TPC, TPW, Entropy, OOV</h2> <p>Ok back to the topic! I told you how tpc can judge which tokenizer is efficient and cost effective similarly we are blessed with more TCMs like: Token Per Word (TPW), Tokenization Entropy, OOV Rate (Out-of-Vocabulary)…</p> <p>We will discuss one by one ; just like TPC tells us how expensive a tokenizer is for a language…TPW helps readers gauge efficiency quickly but according to me it’s less scientific. “WHYWHY VISHESH???” I dont know!!!! It just doesn’t feel scientific to me.</p> <p>I am so unpredictable lol..just like me there is a term to judge how unpredictable the token boundaries are for that language and tokenizer that is called Tokenization Entropy. And for domain specific writing like medicine or cook book to make veg food, How often tokenizers fail to represent a term and have to back off to characters is called its OOV Rate aks Out-of-Vocabulary Rate.</p> <hr/> <h2 id="some-under-the-hood-ideas">Some Under-the-hood Ideas</h2> <p>Now there are some more concepts which do matter in terms of tokenizers but works under the hood , i have written their definition you can read if you like:</p> <ul> <li><strong>Sub-word Segmentation</strong> : Every modern tokenizer relies on the idea..Instead of whole words, break text into the most useful word-pieces.</li> <li><strong>Merge Algorithms</strong> : How tokenizers decide which word-pieces deserve to become tokens.</li> <li><strong>Frequency-driven Compression</strong> : All common tokenizers are compression schemes pretending to be linguistic.</li> </ul> <hr/> <h2 id="main-tokenizer-families">Main Tokenizer Families</h2> <p>NOW NOW NOW We will talk …oh who switched my speaker off! Ok …. NOW NOW NOW WE WILL TALK ABOUT THE MAIN TOKENIZER FAMILIES AND THEIR WORKING..huh that was lowd.</p> <p>One of the earliest used tokenizers was Byte-Pair Encoding(BPE) used in GPT-2/3, BLOOM…and working on these will cost me a whole new article so I will give you an intuition!</p> <hr/> <h2 id="bpe-intuition">BPE Intuition</h2> <p>BPE starts with characters -&gt; counts which pair of characters appear together the most -&gt; merge those pairs and treat them as a single symbol(merge tables) -&gt; repeat 100000+ times -&gt;Final merges -&gt; become the vocabulary.</p> <p>Merge table is an ordered list of pair-merge decisions the tokenizer learned during training.</p> <p>It’s simple, deterministic, and compresses well, but it struggles with languages where words morph heavily.</p> <p>It looks like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0: ("e", "r") → "er"
1: ("pl", "ay") → "play"
2: ("play", "er") → "player"
3: ("player", "s") → "players"
</code></pre></div></div> <h3 id="example-of-how-encodings-uses-the-merge-table-in-bpe">Example of how Encodings uses the Merge Table in BPE:</h3> <p><strong>Start text</strong> = token</p> <p><strong>Merge table it formes:</strong></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1: ("t", "o") → "to"
7: ("k", "e") → "ke"
10: ("to", "k") → "tok"
52: ("ke", "n") → "ken"
100: ("tok", "en") → "token"
</code></pre></div></div> <p><strong>possible_doubt</strong> : why not (“e”,”n”) -&gt; “en”</p> <p>Because merging a pair in a merge table is not logical! BPE never decides merges based on logic.It only follows the statistics of the training corpus.</p> <p><strong>Encodings happens like:</strong></p> <ul> <li>First look for the earliest merge number that applies.</li> <li>Merge that pair</li> <li>Keep going</li> <li>Eventually, it might end up with the full token “token” if enough rules exist.</li> </ul> <hr/> <h2 id="sentencepiece--unigram-lm">SentencePiece / Unigram LM</h2> <p>Google has a famous library called Sentence piece where they have introduced Unigram Language Model Tokenizer, using which all the LLaMA family is trained on!!!</p> <p>So unlike BPE instead of merging it starts with a giant list of candidate sub-words and trains a probabilistic model. The goal of the model “what is the most likely set of subwords that explains all sentences???” and iteratively prunes the vocabulary.</p> <p>It handles multilingual and weird morphology better than BPE. It generates multiple possible tokenizations and picks the best.</p> <p>But google didn’t come up with sentence pieces in the first place Early google models like BERT, DistilBERT were trained on different tokenizers known as WordPiece. Its where Google was transitioning their aura form BPE to Unigram LM Tokenizer.</p> <p>So that transition development is what they call WordPiece. It’s very similar to BPE but with different scoring objectives, they asked “if I add this subword to vocabulary will it help me to explain my text better?????” and thats all maximize likelihood really meant.</p> <p>WordPiece aften ads “##” markers to show subword continuations. People still talk about this because it introduced the idea that tokenization can be tightly coupled with the LM’s training data.</p> <hr/> <h2 id="byte-level-bpe">Byte-Level BPE</h2> <p>I told you BPE was used in GPT-2 / 3…OpenAI really took tokenizers seriously and while hunting they found Byte-Level BPE they have used in GPT4 and Mistral also comes into account for using Byte-Level BPE.</p> <p>How does it work ?? same as bpe, but it starts from raw bytes(0-255) instead of characters.that means every piece of text is representable thus no OOVs. It became dominant because now it can handle emojis, accents, programming languages, and rare symbols effortlessly.</p> <hr/> <h2 id="tiktoken--gpt-4-encodings">TikToken / GPT-4 Encodings</h2> <p>But now OpenAI uses there own tokenizers they call it tiktoken / GPT-4’s Encodings As it introduces modern pretokenization rules, special tokens, optimized merges, extreme speed by memory mapped tables; i will talk about this now …</p> <p>People says tiktoken is nothing but “BPE but fast” that’s very surface level…because underneath, there are a few design moves that make these tokenizers behave cleaner, tighter, and more predictable than classical BPE.</p> <hr/> <h3 id="pretokenization-rules">Pretokenization Rules</h3> <p>Pretokenization Rules ie OpenAI tokenizers don’t treat raw text as-is. They apply collapsing weird whitespaces patterns into std ones, normalizing some unicode edge cases, treating punctuation in more consistent way, spitting boundaries around certain characters…its not like full normalization (like NFKC) it’s more like “Fix the obvious inconsistencies but don’t destroy meaning.”</p> <hr/> <h3 id="special-tokens">Special Tokens</h3> <p>Special Tokens : Gpt model rely on a fairly rich set of reserved tokens i.e. end-of-text, beginning-of-assistant message, beginning-of-user-message, system prompts, document seperators, bye-level fallbacks and some metadata tokens for chat formatting… It’s not at all impressive right, but together they let the model understand where a conversation turn begins, what role a segment plays, and how to differentiate data from instructions.</p> <p>Older tokenizers basically ignored structure, tiktoken has just baked structure into vocabulary itself</p> <hr/> <h3 id="optimized-merge-table">Optimized Merge Table</h3> <p>Optimized Merge Table : You know BPE generates very large, redundant, slow scan merge tables.OpenAI reworks this table into something extremely compact and efficiently indexable.Every merge is packed in a way that reduces cache misses and speeds up lookup time during encoding.</p> <hr/> <h3 id="memory-mapped-tables">Memory-Mapped Tables</h3> <p>Memory-Mapped Tables for Speed : I can say this is pure system engineering, Instead of loading merge rules into RAM and parsing them at runtime, tiktokenn uses memory mapped files: the OS loads the pages you actually touch, random access is extremely fast, zero copy overhead.</p> <hr/> <h3 id="soft-normalization">Soft Normalization</h3> <p>Soft Normalization : This is the part most people are not aware of. Older BPE tokenizers got wrecked by slight Unicode variations: smart quotes, accent marks, zero-width spaces, exotic whitespace… All these caused fragmentation, meaning the tokenizer produced way too many tokens for the same concept.</p>]]></content><author><name></name></author><category term="research"/><category term="tokenization"/><category term="LLM"/><category term="Mamba"/><summary type="html"><![CDATA[A grounded walkthrough of tokenization and its impact on model behavior.]]></summary></entry><entry><title type="html">Why India Needs Its Own LLMs</title><link href="https://vishesh9131.github.io/blog/2025/why-india-needs-its-own-llms/" rel="alternate" type="text/html" title="Why India Needs Its Own LLMs"/><published>2025-01-15T00:00:00+00:00</published><updated>2025-01-15T00:00:00+00:00</updated><id>https://vishesh9131.github.io/blog/2025/why-india-needs-its-own-llms</id><content type="html" xml:base="https://vishesh9131.github.io/blog/2025/why-india-needs-its-own-llms/"><![CDATA[<p><strong>Why India Needs Its Own LLMs</strong></p> <p>Let’s start with something obvious that somehow no one treats as obvious: language isn’t just communication. It’s compression. It’s the lossy encoding of an entire culture’s worldview into syntax, idioms, metaphors, jokes. When you train a large language model, you’re not just training it to predict the next word — you’re training it to predict <em>reality as seen through a particular civilization’s eyes.</em></p> <p>Now think about India. 1.4 billion people, hundreds of languages, thousands of dialects, infinite cultural contexts — all stacked on top of one another like some cosmic recursion of Babel. Every village, every caste, every generation has its own dataset. Yet our AI, our so-called “intelligent” systems, are trained mostly on English internet text, scraped from Reddit, Wikipedia, and Twitter. That means our models speak like Silicon Valley. They reason like Silicon Valley. They hallucinate like Silicon Valley.</p> <p>But India doesn’t think like Silicon Valley.</p> <p>Indian reasoning — in its philosophical, linguistic, and even mathematical roots — is nonlinear. Sanskrit grammar was formalized two thousand years ago by Pāṇini in what is effectively a programming language: recursive, compositional, modular. Indian logic, from Nyāya to Vedānta, doesn’t separate emotion from inference the way Western logic does. And the cadence of Indian languages — the way they intertwine context, relationship, and implication — is structurally richer than English tokenization ever captured.</p> <p>When you realize that, it becomes obvious: training India’s future on Western data is like trying to simulate the Vedas on a typewriter.</p> <p>India needs its own LLMs — not just translated, but <em>native-born.</em> Models that grew up on Indian text, learned from Indian discourse, and internalized Indian ways of thinking. Models that understand that “acha” can mean yes, no, maybe, or “I heard you, but I’m still deciding.” Models that don’t treat Hindi and Tamil and Bengali as “low-resource” languages, but as <em>primary</em> operating systems of thought.</p> <p>This isn’t just a matter of linguistic justice. It’s a matter of cognitive sovereignty. Whoever trains the models, trains the minds. The next billion users won’t read philosophy; they’ll chat with it. They won’t learn history; they’ll ask it questions. If the models answering those questions are trained on Western priorities, they’ll inherit Western biases — subtle, invisible, but deeply real.</p> <p>The danger is quiet. You won’t notice when a model starts preferring certain histories, certain heroes, certain tones of reasoning. You’ll just wake up one day in a digital world that speaks your language but not your soul.</p> <p>So yes, India needs its own LLMs — not as a nationalist project, but as a cultural survival mechanism. Imagine a model that can code-switch between Sanskrit’s precision and Hinglish’s chaos; one that understands the humor of Mumbai and the poetry of Madurai; one that can translate between languages not just semantically, but philosophically.</p> <p>The technical challenge is immense. We’ll need curated corpora from local sources, multilingual tokenizers that respect morphology, and training pipelines tuned for code-mixed text. We’ll need to rethink benchmarks — because why should “commonsense reasoning” be defined by American common sense?</p> <p>But the reward is equally immense: a model that’s not just <em>Indian in data,</em> but <em>Indian in cognition.</em> A system that embodies our way of seeing the world — plural, paradoxical, context-dependent, resilient.</p> <p>So if we build it right, India’s LLMs won’t just serve India. They’ll expand what AI itself can be. They’ll teach the machines that there are other ways to think — that the human mind isn’t a monolith, but a kaleidoscope.</p> <p>Because in the end, language isn’t just a tool we use to talk to AI. It’s the substrate through which AI learns what it means to be human. And humanity, in all its accents and contradictions, deserves to be represented.</p> <p>That’s why India needs its own LLMs. Not to compete with the West. To complete the story of intelligence.</p>]]></content><author><name></name></author><category term="research"/><category term="LLM"/><category term="AI for India"/><category term="Indian languages"/><summary type="html"><![CDATA[Why language models need cultural and linguistic grounding in India.]]></summary></entry><entry><title type="html">Diving Deep into the Mamba Model Implementation</title><link href="https://vishesh9131.github.io/blog/2023/diving-deep-into-the-mamba-model-implementation/" rel="alternate" type="text/html" title="Diving Deep into the Mamba Model Implementation"/><published>2023-10-25T00:00:00+00:00</published><updated>2023-10-25T00:00:00+00:00</updated><id>https://vishesh9131.github.io/blog/2023/diving-deep-into-the-mamba-model-implementation</id><content type="html" xml:base="https://vishesh9131.github.io/blog/2023/diving-deep-into-the-mamba-model-implementation/"><![CDATA[<h1 id="research-blog-diving-deep-into-the-mamba-model-implementation">Research Blog: Diving Deep into the Mamba Model Implementation</h1> <h2 id="introduction">Introduction</h2> <p>The Mamba model, introduced in the paper <em>Mamba: Linear-Time Sequence Modeling with Selective State Spaces</em> by Albert Gu and Tri Dao, represents a significant advancement in sequence modeling. Unlike traditional transformer-based architectures that scale quadratically with sequence length, Mamba achieves linear-time complexity using selective state space models (SSMs). This blog post explores the technical depth of implementing Mamba in PyTorch, as provided in the given <code class="language-plaintext highlighter-rouge">model.py</code> and <code class="language-plaintext highlighter-rouge">scan.py</code> files, breaking down the architecture, key components, and challenges encountered in the implementation.</p> <h2 id="background-state-space-models-and-mamba">Background: State Space Models and Mamba</h2> <p>State Space Models (SSMs) provide a framework for modeling sequences by representing them as a system of differential equations. Traditionally, SSMs like S4 (Structured State Space Sequence Models) use fixed parameters, limiting their adaptability to input data. Mamba introduces <em>selective</em> SSMs, where parameters like ( \Delta ), ( B ), and ( C ) are input-dependent, enabling the model to adapt dynamically to the sequence context. This selectivity, combined with a linear-time scanning mechanism, makes Mamba both efficient and expressive for long-sequence modeling tasks.</p> <p>The implementation provided is a minimal, single-file PyTorch version of Mamba, designed for clarity and ease of understanding. It includes the core components of the model, such as the Mamba block, selective scan, and RMS normalization, while also supporting pretrained model loading from HuggingFace.</p> <h2 id="key-components-of-the-implementation">Key Components of the Implementation</h2> <h3 id="1-model-configuration-with-modelargs">1. <strong>Model Configuration with <code class="language-plaintext highlighter-rouge">ModelArgs</code></strong></h3> <p>The <code class="language-plaintext highlighter-rouge">ModelArgs</code> dataclass defines the hyperparameters for the Mamba model, such as:</p> <ul> <li><code class="language-plaintext highlighter-rouge">d_model</code>: The hidden dimension of the model.</li> <li><code class="language-plaintext highlighter-rouge">n_layer</code>: The number of Mamba layers.</li> <li><code class="language-plaintext highlighter-rouge">vocab_size</code>: The size of the vocabulary for the embedding layer.</li> <li><code class="language-plaintext highlighter-rouge">d_state</code>: The latent state dimension (( N ) in the Mamba paper).</li> <li><code class="language-plaintext highlighter-rouge">expand</code>: The expansion factor to compute the inner dimension (( d<em>{\text{inner}} = d</em>{\text{model}} \times \text{expand} )).</li> <li><code class="language-plaintext highlighter-rouge">dt_rank</code>: The rank of the input-dependent step size (( \Delta )), with an “auto” option to set it as ( \lceil d_{\text{model}} / 16 \rceil ).</li> <li><code class="language-plaintext highlighter-rouge">d_conv</code>: The kernel size for the 1D convolution.</li> <li><code class="language-plaintext highlighter-rouge">scan_mode</code>: The mode for the selective scan algorithm (<code class="language-plaintext highlighter-rouge">cumsum</code> or <code class="language-plaintext highlighter-rouge">logcumsumexp</code>).</li> </ul> <p>The <code class="language-plaintext highlighter-rouge">__post_init__</code> method ensures that <code class="language-plaintext highlighter-rouge">d_inner</code> and <code class="language-plaintext highlighter-rouge">dt_rank</code> are computed appropriately and that <code class="language-plaintext highlighter-rouge">vocab_size</code> is padded to a multiple of <code class="language-plaintext highlighter-rouge">pad_vocab_size_multiple</code> for efficient processing.</p> <h3 id="2-mamba-model-architecture">2. <strong>Mamba Model Architecture</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">Mamba</code> class encapsulates the full model, consisting of:</p> <ul> <li><strong>Embedding Layer</strong>: An <code class="language-plaintext highlighter-rouge">nn.Embedding</code> layer maps input tokens to dense vectors of size <code class="language-plaintext highlighter-rouge">d_model</code>.</li> <li><strong>Residual Blocks</strong>: A stack of <code class="language-plaintext highlighter-rouge">n_layer</code> <code class="language-plaintext highlighter-rouge">ResidualBlock</code> modules, each containing a normalization layer and a <code class="language-plaintext highlighter-rouge">MambaBlock</code>.</li> <li><strong>Normalization</strong>: An <code class="language-plaintext highlighter-rouge">RMSNorm</code> layer applied before the final output projection.</li> <li><strong>Language Model Head</strong>: A linear layer (<code class="language-plaintext highlighter-rouge">lm_head</code>) that projects the hidden states back to the vocabulary size, with tied weights to the embedding layer for efficiency (as described in the “Weight Tying” paper).</li> </ul> <p>The <code class="language-plaintext highlighter-rouge">forward</code> method processes input token IDs through the embedding layer, applies the residual blocks, normalizes the output, and projects it to logits over the vocabulary.</p> <h3 id="3-residualblock">3. <strong>ResidualBlock</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">ResidualBlock</code> wraps a <code class="language-plaintext highlighter-rouge">MambaBlock</code> with a normalization layer (<code class="language-plaintext highlighter-rouge">RMSNorm</code>) and a residual connection. The forward pass follows the structure: [ \text{output} = \text{MambaBlock}(\text{RMSNorm}(x)) + x ] This differs from the official Mamba implementation, which uses a fused Add-Norm-Mamba structure for performance. The provided implementation prioritizes simplicity and numerical equivalence, applying normalization before the Mamba block and adding the residual connection afterward.</p> <h3 id="4-mambablock">4. <strong>MambaBlock</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">MambaBlock</code> is the core of the model, implementing the selective SSM as described in Figure 3 of the Mamba paper. Its components include:</p> <ul> <li><strong>Input Projection</strong>: A linear layer (<code class="language-plaintext highlighter-rouge">in_proj</code>) projects the input from <code class="language-plaintext highlighter-rouge">d_model</code> to <code class="language-plaintext highlighter-rouge">2 * d_inner</code>, splitting the output into <code class="language-plaintext highlighter-rouge">x</code> and a residual (<code class="language-plaintext highlighter-rouge">res</code>).</li> <li><strong>1D Convolution</strong>: A grouped 1D convolution (<code class="language-plaintext highlighter-rouge">conv1d</code>) with kernel size <code class="language-plaintext highlighter-rouge">d_conv</code> processes the input sequence, introducing local context.</li> <li><strong>SSM Parameters</strong>: <ul> <li>The <code class="language-plaintext highlighter-rouge">x_proj</code> linear layer generates input-dependent parameters ( \Delta ), ( B ), and ( C ).</li> <li>The <code class="language-plaintext highlighter-rouge">dt_proj</code> layer projects ( \Delta ) from <code class="language-plaintext highlighter-rouge">dt_rank</code> to <code class="language-plaintext highlighter-rouge">d_inner</code>.</li> <li>( A ) is parameterized as <code class="language-plaintext highlighter-rouge">A_log</code> (logarithm of the state transition matrix) to ensure stability, and ( D ) is a learnable vector.</li> </ul> </li> <li><strong>Selective Scan</strong>: The <code class="language-plaintext highlighter-rouge">ssm</code> method computes the state space dynamics using the <code class="language-plaintext highlighter-rouge">selective_scan</code> function.</li> <li><strong>Output Projection</strong>: A linear layer (<code class="language-plaintext highlighter-rouge">out_proj</code>) maps the SSM output back to <code class="language-plaintext highlighter-rouge">d_model</code>.</li> </ul> <p>The forward pass applies the convolution, SiLU activation, the selective SSM, and a gated residual connection before the final projection.</p> <h3 id="5-selective-scan-scanpy">5. <strong>Selective Scan (<code class="language-plaintext highlighter-rouge">scan.py</code>)</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">selective_scan</code> function implements Algorithm 2 from the Mamba paper, computing the SSM output given input ( u ), step size ( \Delta ), and parameters ( A ), ( B ), ( C ), and ( D ). It supports two modes:</p> <ul> <li><strong>Cumsum Mode</strong>: Uses cumulative summation to compute the SSM recurrence. This is straightforward but can suffer from numerical instability for long sequences.</li> <li><strong>Logcumsumexp Mode</strong>: A more numerically stable “Heisen sequence” approach, using complex logarithms to compute the recurrence in log space, reducing overflow risks.</li> </ul> <p>The provided <code class="language-plaintext highlighter-rouge">scan.py</code> includes a test script that compares the two modes, showing that the mismatch between them grows with sequence length due to numerical precision differences.</p> <h3 id="6-rmsnorm">6. <strong>RMSNorm</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">RMSNorm</code> class implements Root Mean Square Normalization, a variant of layer normalization that scales the input by the inverse of its root mean square value. It is used in both the <code class="language-plaintext highlighter-rouge">ResidualBlock</code> and the final normalization step of the <code class="language-plaintext highlighter-rouge">Mamba</code> model.</p> <h3 id="7-pretrained-model-loading">7. <strong>Pretrained Model Loading</strong></h3> <p>The <code class="language-plaintext highlighter-rouge">from_pretrained</code> method in the <code class="language-plaintext highlighter-rouge">Mamba</code> class enables loading pretrained weights from HuggingFace models (e.g., <code class="language-plaintext highlighter-rouge">state-spaces/mamba-2.8b</code>). It loads the model configuration and state dictionary, mapping weights to the corresponding model parameters while handling differences in naming conventions (e.g., removing the <code class="language-plaintext highlighter-rouge">backbone.</code> prefix).</p> <h2 id="challenges-and-considerations">Challenges and Considerations</h2> <p>Implementing Mamba in PyTorch involves several challenges:</p> <ul> <li><strong>Numerical Stability</strong>: The selective scan algorithm requires careful handling to avoid numerical overflow, especially for long sequences. The <code class="language-plaintext highlighter-rouge">logcumsumexp</code> mode addresses this by operating in log space, but it introduces additional complexity.</li> <li><strong>Selective Parameters</strong>: Unlike traditional SSMs, Mamba’s input-dependent ( \Delta ), ( B ), and ( C ) require careful tensor manipulation to align dimensions and ensure efficient computation.</li> <li><strong>Convolution Padding</strong>: The 1D convolution uses padding to maintain sequence length, requiring precise configuration to avoid information loss.</li> <li><strong>Pretrained Weight Compatibility</strong>: Loading pretrained weights involves mapping between the official implementation’s state dictionary and the custom implementation, handling potential mismatches in parameter names or shapes.</li> </ul> <h2 id="insights-from-the-implementation">Insights from the Implementation</h2> <ul> <li><strong>Modularity</strong>: The code is structured for clarity, with separate classes for <code class="language-plaintext highlighter-rouge">Mamba</code>, <code class="language-plaintext highlighter-rouge">ResidualBlock</code>, <code class="language-plaintext highlighter-rouge">MambaBlock</code>, and <code class="language-plaintext highlighter-rouge">RMSNorm</code>. This makes it easier to understand and extend compared to a monolithic implementation.</li> <li><strong>Flexibility</strong>: The <code class="language-plaintext highlighter-rouge">scan_mode</code> parameter allows switching between <code class="language-plaintext highlighter-rouge">cumsum</code> and <code class="language-plaintext highlighter-rouge">logcumsumexp</code>, enabling experimentation with numerical stability trade-offs.</li> <li><strong>Efficiency</strong>: Weight tying and grouped convolutions reduce memory usage and computational cost, making the implementation suitable for resource-constrained environments.</li> <li><strong>Extensibility</strong>: The <code class="language-plaintext highlighter-rouge">from_pretrained</code> method facilitates integration with pretrained models, allowing researchers to leverage existing weights for fine-tuning or evaluation.</li> </ul> <h2 id="potential-improvements">Potential Improvements</h2> <ul> <li><strong>Performance Optimization</strong>: Fusing the Add-Norm-Mamba structure, as done in the official implementation, could improve runtime performance.</li> <li><strong>Parallel Scan</strong>: The current selective scan is sequential, but parallel implementations (e.g., using associative scan techniques) could further reduce latency.</li> <li><strong>Additional Features</strong>: Supporting bidirectional processing or integrating attention mechanisms could enhance the model’s capabilities for specific tasks.</li> <li><strong>Robustness Testing</strong>: Extending the test script in <code class="language-plaintext highlighter-rouge">scan.py</code> to cover edge cases (e.g., very long sequences or extreme values) would ensure robustness.</li> </ul> <h2 id="conclusion">Conclusion</h2> <p>The provided Mamba implementation is a concise yet powerful demonstration of selective state space modeling in PyTorch. By breaking down the architecture into modular components and addressing numerical stability, it offers a clear entry point for researchers and practitioners interested in exploring linear-time sequence models. The ability to load pretrained weights further enhances its utility, making it a valuable tool for advancing research in efficient sequence modeling.</p> <p>For further reading, refer to:</p> <ul> <li>Mamba paper: <a href="https://arxiv.org/abs/2312.00752">arXiv:2312.00752</a></li> <li>The Annotated S4: <a href="https://srush.github.io/annotated-s4">srush.github.io/annotated-s4</a></li> </ul>]]></content><author><name></name></author><category term="research"/><category term="Mamba"/><category term="PyTorch"/><category term="sequence modeling"/><summary type="html"><![CDATA[A technical exploration of implementing Mamba in PyTorch.]]></summary></entry></feed>