Jeremy Howard Profile picture
Apr 3 25 tweets 7 min read Twitter logo Read on Twitter
There's a lot of folks under the misunderstanding that it's now possible to run a 30B param LLM in <6GB, based on this GitHub discussion.

This is not the case. Understanding why gives us a chance to learn a lot of interesting stuff! 🧵
github.com/ggerganov/llam…
The background is that the amazing @JustineTunney wrote this really cool commit for @ggerganov's llama.cpp, which modifies how llama models are loaded into memory to use mmap
github.com/ggerganov/llam…
Prior to this, llama.cpp (and indeed most deep learning frameworks) load the weights of a neural network by reading the file containing the weights and copying the contents into RAM. This is wasteful since a lot of bytes are moving around before you can even use the model
There's a *lot* of bytes to move and store, since a 30B model has (by definition!) around 30 billion parameters. If they've been squished down to just 4-bit ints, that's still 30*4/8=15 billion bytes just for the model. Then we need memory for the data and activations too!
mmap is a really nifty feature of modern operating systems which lets you not immediately read a file into memory, but instead just tell the OS you'd like to access some bits in that file sometime, and you can just grab the bits you need if/when you need them
The OS is pretty amazing at handling these requests. If you ask for the same bits twice, it won't re-read the disk, but instead will re-use the bits that are already in RAM, is possible. This is the "cache".
Early responses to the issue were under the mistaken impression that following the mmap commit, llama.cpp was now only "paging in" (i.e. reading from disk) a subset of the model, by grabbing only the parameters needed for a particular batch of data
This is based on a misunderstanding of how transformers models work. Transformers are very simple models. They are functions which apply the following two operations a bunch of times:
- An MLP with 1 hidden layer
- Attention
An MLP (multi-layer) perceptron with one hidden layer is a matrix multiplication followed by an activation function (an elementwise operation such as ReLU: `max(0,x)`), followed by another matrix multiplication.
Attention is the operation shown in this code snippet. This one does "self attention" (i.e q, k, and v are all applied to the same input); there's also "cross attention" that uses different inputs.
OK that was a slight simplification. Transformers actually use "multi-head" attention which groups channels first. But as you see from the implementation below, it's still just using some matrix multiplies and activation functions.
So every parameter is used, because they're just matrix multiplications and element-wise operations that they're used in. There's no true sparsity occurring here -- there's just some "soft attention" caused by the use of softmax.
Therefore, we don't really get to benefit fully from the magic of mmap, since we need all those parameters for every batch of data. It's still going to save some unnecessary memory copying so it's probably a useful thing to use here, but we still need RAM for all the parameters
The way mmap handles memory makes it a bit tricky for the OS to report on a per-process level how that memory is being used. So it generally will just show it as "cache" use. That's why (AFAICT) there was some initial misunderstanding regarding the memory savings
One interesting point though (mentioned in the GH issue) is that you can now have multiple processes all using the same model, and they'll share the memory -- pretty cool!
Note however that none of this helps us use the GPU better -- it's just for CPU use (or systems with integrated memory like Apple silicon).

By far the best speed is with an NVIDIA GPU, and that still requires copying all the params over to the card before using the model.
Hopefully you found that a useful overview of mmap and transformers. BTW these topics are covered in depth in our upcoming course (the above code is copied from it) which will be released in the next few days, so keep an eye out for that!
h/t @iScienceLuvr for encouraging me to write this thread.
Minor correction: the normalization layer I used here, Batchnorm2D, isn't what's used in a normal language model. I took the code from an image model we built for the course. In most language models we'd use Layernorm for normalization.
D'oh I meant to mention this and forgot!

This is a great point. The first layer of a language model is an "embedding" layer. Mathematically, it's matrix multiply by a bunch of one-hot encoded vectors. But it's implemented as an array index lookup.
Depending on how it's implemented, it's possible that this could avoid reading some of the embedding weights into memory. However, the OS has a minimum amount of stuff it reads at once around a location, so it might still end up reading most or all of the embeddings.
Having said that, the embedding weights are a fairly small proportion of the model parameters, so this won't generally make a big difference either way.
Oops another correction! I forgot to mention positional encoding. This is the layer after the embeddings. It can be implemented using sin/cos across a few freqs ("sinusoidal embeddings") or the code snippet below ("learnable embeddings").
Positional encoding is used to assign a unique vector to each position in the input token vector, so that the model can learn that the location of a words matters -- not just its presence/absence.

(They have few parameters do don't impact memory significantly.)
Heh turns out @amasad has already weighed in with his thoughts! :D

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Jeremy Howard

Jeremy Howard Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @jeremyphoward

Nov 21, 2022
Intriguing new study from the amazing Adriaan Bax and team suggests that most covid deaths resulted from (preventable) snoring droplets rather than (unpreventable) microaspiration. This could be a game changer.

No time for the paper? Then read this 🧵!
sciencedirect.com/science/articl…
Infection of the lung with SARS-CoV-2 is a two-step process: first the nose / throat, then the lungs. Postulated, but physically implausible, mechanism for step 2 involves “microaspiration” Image
Microaspiration during sleep is the accepted “hand-waving” mechanism for transfer of microbes from the oral cavity into the lung Image
Read 8 tweets
Oct 24, 2022
After just 2 weeks of the new @fastdotai course, our students are already making research advances in Stable Diffusion.

@sebderhy developed a novel yet simple modification to classifier-free guidance that gives better results (previous approach on left, new approach on right) Image
@fastdotai @sebderhy I think in this case there's room to improve the results even further. The basic idea being tackled is that the "old way" of doing guidance actually increased the scale of the update (especially if the difference between conditional and unconditional embeddings is large)
So the trick is to add the guidance without changing the scale.
Read 7 tweets
Oct 20, 2022
I got a special surprise for you all...

We just released the first 5.5 hours of our new course "From Deep Learning Foundations to Stable Diffusion", for free!
fast.ai/posts/part2-20…
Lesson 9 starts with a tutorial on how to use pipelines in the Diffusers library to generate images. We show some nifty tweaks like guidance scale and textual inversion.

The second half of the lesson shows the key concepts involved in Stable Diffusion.
Lesson 9A (by @johnowhitaker) shows what is happening behind the scenes, looking at the components and processes and how each can be modified for control over generation.
Read 8 tweets
Sep 27, 2022
Awesome news: 6 chapters of our (with @GuggerSylvain) fastai book are now freely available online, beautifully formatted thanks to @quarto_pub.

The chapters I've selected will give you a great understanding of the foundations of deep learning.🧵
fastai.github.io/fastbook2e/
Chapter 1 is an introduction to the amazing world of neural networks and deep learning, and shows how to train and use a neural net for many applications across vision, language, tabular analysis, and collaborative filtering.
fastai.github.io/fastbook2e/int…
Chapter 4 explains how things really work behind the scenes, using Stochastic Gradient Descent (SGD). We show how to create a complete digit classifier from scratch, using the famous MNIST dataset.
fastai.github.io/fastbook2e/mni…
Read 9 tweets
Sep 16, 2022
Big news: we're launching a new course in <4 weeks. "From Deep Learning Foundations to Stable Diffusion".

Bigger news: for this course, we're teaming up with @StabilityAI!

AFAIK, this is the 1st course that covers every method used in Stable Diffusion.
fast.ai/posts/part2-20…
To take stable diffusion to the next level, you need to deeply understand what’s under the hood. Then you can craft your own loss functions, initialization methods, multi-model mixups, and more, to create totally new applications that have never been seen before
Nearly every key technique in modern DL comes together in diffusion methods. Contrastive learning, transformer models, auto-encoders, CLIP embeddings, latent variables, u-nets, resnets, and much more are involved in creating a single image.

So we'll cover the whole lot!
Read 8 tweets
Aug 26, 2022
Have you ever tried to use @ProjectJupyter with git/@github? Did it drive you crazy because nothing worked right?

🔥It drove *us* crazy, so we fixed it.🔥
1/🧵
fast.ai/2022/08/25/jup…
Notebooks are a powerful tool-an ideal environment for exploring data and code, writing programs, and documenting the results.

But when collaborating with, this goes up in smoke, because git makes notebooks unusable. Literally.
The reason git breaks @ProjectJupyter stems from an incompatibility between the format Jupyter notebooks use (JSON) and the format that git conflict markers assume. git merges create invalid JSON, and therefore Jupyter can’t open the notebook.
Read 7 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(