Ask HN: Most efficient way to fine-tune an LLM in 2024?
In Apr 2024 what is the most efficient way to fine-tune an LLM?
In particular we are trying to understand performance vs. cost trade-offs. We don't have a budget to train from scratch.
We are working with a proprietary data set on the order of 100M tokens and are looking to fine-tune a general purpose language model and also create task-specific models based on the same corpus.
Any help would be appreciated!
51 comments
[ 3.8 ms ] story [ 108 ms ] threadhttps://github.com/OpenAccess-AI-Collective/axolotl
Someone from one of the cloud GPU vendors wrote a guide: https://brev.dev/blog/fine-tuning-mistral
https://fortune.com/2024/03/11/adaptive-startup-funding-falc...
[1] https://arxiv.org/pdf/2305.11206.pdf
You would fine-tune, certainly, for domain-specific tasks, and would curate a subset of the 100M tokens. Total tokens in alignment study references is 1,000,000.
RAG is a hacky way to interpolate new knowledge with a base model. Not always reliable nor easy to integrate into task-specific workflows.
We’re building some “smart search” functionality for some teams and I start to wonder if a traditional search results list (i.e. sans the LLM, or used only to rewrite the user query) with the document chunks wouldn’t be better than blindly taking the top N and feeding them to the LLM to produce some response.
E.g. we have some docs about specific supermarket chains, but the word “supermarket” might not appear at all in them, but the user query might be “show me what we have about supermarkets”. Now the embeddings hopefully will place the word “supermarket” close to, say, “Costco”, but they might also place it closer to “shopping center”, and we might have docs about shopping centers that could rank higher. So we might take the top 5 docs and send them to the LLM, but the docs the user was after might have been in 7th and 9th position, nowhere to be seen by the LLM nor the user.
Yep, it's a pretty common pattern: query -> embeddings -> vector db -> records -> context -> LLM -> result.
The LLM doesn’t even get the full docs most of the time, just chunks. It has a very narrow view so its full power is not used.
Vector retrieval that isn’t contextualized in the domain is usually bad (RAG solutions call this “naive rag” … and make up for it with funky chunking and retrieval ensembles). Training custom retrievers and reranker is often key but quite an effort and still hard to generalize in a domain with broad knowledge.
Lexical based searching provides nice guarantees and deterministic control in results (depending on how you index). Certainly useful here is advanced querying capability. Constructing/enriching queries with transformers is cool.
Reranking is often nice ensemble additions, albeit can be done with smaller models.
If your documents repeat the same information several different ways then you actually might get something out of LoRA on raw documents. But you need a way to measure it and you have to verify that RAG won't work with real tests first.
To do effective training with LoRA though and expect it to pick up most of the information reliably then you need to cover the knowledge and skills with multiple question answer pairs for each item you expect it to learn. Which you can then use QA pairs to validate that it learned those things.
But it's a lot of QA pair generation.
what is the preferred way to feed documents / knowledge into a model so that the primary retrieval is done by the llm, and perhaps use vector db only for information enhancement (a la onebox)?
LIMA demonstrated that instruction-tuning and output formatting could be trained with a limited number of samples, not that finetuning was incapable of adding new information to the model.
It may be sub-optimal in most cases to RAG, but it does work.
I've had trouble finding high quality sources of information about successful applications of fine-tuning to add knowledge to a model.
Anecdotally, I literally "added knowledge" to a model via fine-tuning earlier today.
Fine tuning can do extremely well given a specific question and answer, the tuned model "knows" how to answer that question much more accurately.
I gave it a specific question, and a good answer as a fine tuning input. (Literally 2 data points as the input, 2 questions/answer sets.)
I asked it that question, and the tuned model blows the base model away, for answering that specific question.
Validating on training data...What could possibly go wrong?
However: we were allowed to pick any base model in a given repo. All of the teams that “won” did so for the same reason: they had all picked the same base model (whereas a majority of teams picked the given default), presumably the one that had at some point been trained on the most favorable data for this particular challenge.
It was quite silly. Had everyone had the same base model we’d have a bit more of an interesting problem (more around NLP and alignment than picking the ‘best’ model).
Theres no one size fits all answer yet, but if you just want to test it out there are many commercial offerings on which you should be able to get some results for under $10k.
https://arxiv.org/abs/2106.09685
A single A100 or H100 with 80GB VRAM can fine tune 70B open models (and obviously scaling out to many nodes/GPUs is faster, or can use much cheaper GPUs for fine tuning smaller models.)
The localllama Reddit sub at https://www.reddit.com/r/LocalLLaMA/ is also an awesome community for the GPU poor :)
Have you seen benchmarks
If you do end up wanting to fine tune then use qlora with axolotl or unsloth to prove your hypothesis on a smaller model and then evaluate if you want the marginal gains you get from full precision training.
After you fine tune it with 100m token dataset, use DPO to polish it off. You need to create a DPO dataset for that but it can be relatively small to get some great gains.
After that, look at applying grammars during inference if you are expecting structured results like json.
You should be able to run the experiments on 4090s from vast.ai or runpod or similar service.
It can cost less than $100 depending on your requirements.
I'd like to add that if you don't have pairwise preference data (A > B) but do have binary data (A is good for x_1, B is good for x_2, etc.), then Kahneman-Tversky Optimization (KTO) might be a better fit. Despite learning with a weaker signal, it works as well or better than dpo in practice.
Blazing fast compared to out-of-the-box transformers, also make sure to use flash attention if you have A100s or better and context length >= 2k
Add FAISS (https://github.com/facebookresearch/faiss) if you need fast local RAG
could you give a high level way to think about how to use dspy for something like this?
and since your dataset is large, the longest context windows are insufficient.
* [Example 1](https://www.mongodb.com/developer/products/atlas/rag_with_cl...) (Claude and MongoDB's vector database)
* [Example 2](https://docs.mistral.ai/guides/basic-RAG/) (Mistral and the Faiss vector database or other embedding frameworks)
Mistral 7b is 2x faster than HuggingFace + Flash Attention 2. Gemma 7b is 2.4x faster than HF + FA2.
Check out https://github.com/unslothai/unsloth for full benchmarks!