LLM in a Flash: Efficient LLM Inference with Limited Memory
huggingface.co
huggingface.co
- First, the Deja Vu paper observes that models with low weight sparsity have what they call high "contextual sparsity". Basically, the matrix multiplications will produce vectors with lots of zeros in them, but where the zeros are depends on the input.
- The paper notes that you can use that sparsity to skip loading some rows of your matrices.
- However, to get good performance benefits, you can to predict in advance which rows you're going to skip. You can do that with a low-rank matrix.
The Apple paper then suggests these findings can not just improve your performance loading from RAM, but even allow you to load from flash memory without sacrificing bandwidth:
- The paper notes that attention matrices are rather light; the FFNs are the ones you want to load sparsely.
- The paper notes that you can get much better sparsity by predicting the output of the ReLU layer rather than the input of the FFN. Basically saying "if you can predict that after matmul this slot of the vector will have a negative value before ReLU, you can skip loading the matrix column and output zero".
- The paper suggests that you don't need to load most rows of the FFN at all; you can just keep a cache of recently used FFN rows for each FFN, and update it from flash memory on-demand.
There's a bunch more about chunk loading and the correlation between projection layers, but the above is where I think the main insights are.
(FFN = Feed Forward Network; in the context of transformers they're the biggest blocks.)
Let’s say you want to maintain 90% of everything-in-RAM performance.
Can you get away with only using half the memory? Do you need 90% of the memory? Maybe 95%?
Basically how fast do you lose performance compared to the maximum by cutting RAM. The charts are comparing their algorithm vs a basic one for the less RAM case, which is a different (but good!) question.
If you can get good performance by NOT loading an entire eight gig model into memory of a cell phone that’s obviously a very useful thing.
The paper is worth a read in full as what they are doing is pretty cool:
https://arxiv.org/pdf/2312.11514
Highlight from the paper...
"Then, we introduce two complementary techniques to minimize data transfer and maximize flash memory throughput:
• Windowing: We load parameters for only the past few tokens, reusing activations from recently computed tokens. This sliding window approach reduces the number of IO requests to load weights.
• Row-column bundling: We store a concatenated row and column of the up-projection and down-projection layers to read bigger contiguous chunks from flash memory. This increases throughput by reading larger chunks."
They are targeting limited gpu memory and limit cpu to gpu memory transfer. I don't know how it could be useful on Macs because MacBooks have a unified memory and you don't need to do that transfer necessarily.
p.s: The window size in the paper is showing how many token's feed forward layer is in the memory.
Theoretically, the time consumed to inference a single token with part of the model stored in flash should be equal to the time to inference that token if the whole model was in RAM, plus the time required to load the part of the model stored in flash memory.
I assume we do not need to write back to flash, but I'm not an LLM expert so I could be wrong.
I assume we have many (more than 10) layers so we can leave a fairly small amount of our RAM available to load one layer after another. Most nontrivial LLMs have many dozens of layers, so this seems plausible.
If we are not bottlenecking on our RAM during inferencing then we might be able to load the next layer from flash into RAM through a DMA transfer while inferencing our current layer. I don't think that would work on single-processor systems due to us always bottlenecking on RAM.
Maybe a dual-processor system could load one layer into RAM on one processor while inferencing on the previous layer on the other processor, and thus run really big LLMs in a small amount of RAM?
I'm sitting next to a pile of parts to build a new LLM AI machine. (z840, dual processor) and I look forward to playing with this stuff.
"Mixture of Experts (Yiet al., 2023) have a sparse structure in their feed forward layer. This property can be used to combine with our method for enabling larger MoEs on device."
Assuming this implementation would allow for running Mixtral 8x7b on a 16Gb M1, I'm happy.
Q4 should be well below the 32GB (2x 16GB).
I am wondering if the same implementation could be done for RAM to CPU, too. Those are said to be data transfer limited, so minimizing the RAM to CPU cache transfer should help there, too?
Unless you use this hack [2].
[1] https://developer.apple.com/forums/thread/732035
[2] https://github.com/ggerganov/llama.cpp/discussions/2182#disc...
As for why it's not the default, it's mostly because wiring all your memory will crash the computer pretty fast.
Part of that is that Apples software team uses more efficient languages like (eg. Objective-C vs Java). Part of that is that applications on iOS don't have to target a huge variety of screen resolutions (and therefore are frequently loading then downscaling high res textures). Part of that is that RAM doesn't get much cheaper if you buy at Apple-scale - so a RAM bump represents a bigger hit to margins than adding other features.
But all of that comes back to bite when using LLM's, which inherently gobble RAM. And any memory saving techniques used will simply allow a competitor with more RAM to squeeze in an even bigger better smarter model.
I want to buy a Mac soon, and I'm really struggling to decide how much RAM I should order. Unfortunately, my budget is limited. If it wasn't, I would probably go for at least 32GB. I'm still hoping Apple might change their RAM pricing, but probably in vain.
I'd recommend getting at least 32GB if you're on the fence. Not being able to upgrade it is a bummer, and your future self will thank you for getting the most you possibly can.
For my most recent upgrade I went for 64GB (previously 32GB) and I'm really glad I did, especially since llama.cpp became a thing shortly after getting it.
Now I wish I’d bought 4tb rather than 2tb hard drive lol but that’s just me being lazy - that upgrade definitely felt like a step too far.
Here's Mixtral-8x7B-Instruct: https://huggingface.co/TheBloke/Mixtral-8x7B-Instruct-v0.1-G...
64GB of memory will struggle on 65-70B (or bigger) models, and you'll be limited to running 70B on Q3 or Q4 if you want to use it somewhat comfortably.
1 - https://www.lifewire.com/understanding-compressed-memory-os-... : Apple devices have support for memory compression, see https://opensource.apple.com/source/xnu/xnu-2050.18.24/libke...
2 - Apple devices support something called "jetsam", which basically frees up memory from unused/background apps by killing them in order to keep high priority apps running smoothly: https://developer.apple.com/documentation/xcode/identifying-...
I also do not know if Android combines system libraries into one big file for the savings, something Apple devices do.
E.g. there was a GH Discussion about running LLMs on Apple A-series chips (iPhone) posted here yesterday: https://news.ycombinator.com/item?id=38703161
edit: Seems like this is an extension along two different mechanisms within the flash framework. Title of paper could be better, but it is within the first few pages.
[0]: https://www.geekwire.com/2020/exclusive-apple-acquires-xnor-...
From what I understand, FlashAttention is about using access patterns that better leverage local memory, and especially SRAM. Eg, it about keeping data in CPU L1 cache, or in whatever the GPU equivalent is.
(In other words: FlashAttention is concerned about the part that's faster than DRAM, this is about better offloading to the part that's slower than DRAM)
Does anyone here know what exactly that metric refers to? Does it mean the layer has 97% 0 values? That it can be compressed to 3% of its size?
1. It's not as easy to change the controller, even if you do it was not obvious for me if we need for software updates at system level. In current way it is a standalone project.
2. I guess for a LLM scale flash controller chip might not be strong enough for computation. Additional hardware inside flash might be required for that.