Top
Best
New

Posted by dev-experiments 1 day ago

Good results fine tuning a local LLM like Qwen 3:0.6B to categorize questions(www.teachmecoolstuff.com)
210 points | 49 comments
nl 1 day ago|
If you are going to go to the bother of fine tuning for trivial problems like subject classification then I think you'll find Scikit Learn with a SGDClassifier on 2-grams will do probably just as well and be under 1MB for the trained classifier.

You can train it in under a minute, and it will work perfectly well on embedded devices.

Small LLMs are good choices for text classification in two cases:

- If you next to provide in-context examples and classifier based on them.

- Your classification goes beyond simple subject-type classifiers. For example, multiple choice question answering is classification where small LLM will work but traditional ML methods won't/

djsjajah 1 day ago||
Not with 800 examples. If you are going to consider an ngram model, I think you are better off getting a frontier llm to write you an absurd regex.
nl 1 day ago|||
Hmm maybe. Turns out the author trained a logistic-regression classifier on the embeddings too, but didn't report the results:

https://github.com/thelgevold/fine-tuned-classifier/blob/mai...

dev-experiments 1 day ago||
Expanding on this experiment using logistic regression is an interesting continuation, detailed here: https://www.teachmecoolstuff.com/viewarticle/using-logistic-...

In summary: Using logistic regression actually improves accuracy, but also performance during both runtime and during training.

nl 22 hours ago||
Is that overfitted?

Do 5-fold cross validation, maybe stratified.

dev-experiments 20 hours ago||
It's the same dataset as the original experiment, but could be interesting to dig into it more.
IanCal 1 day ago|||
I would also recommend the approach of using an llm to create the examples, and then train from there.

You can even get fancy and do things like active learning with the llm taking the role of the human annotator and sending in trial statements (and you can use a cheap one for larger gen and a more expensive one for the classification).

I’d be interested in seeing how well LLMs work with writing things like code for what snorkel AI used to have (there was open source code a while back that I assume is still around somewhere, you wrote code that was a low quality set of classifiers and it trained a model around those)

zubiaur 1 day ago|||
A small transformer like BERT or variants is a better fit. It only takes a few examples, which can be generated synthetically using an LLM.

Trains quickly and classifies speedily on modern hardware.

Had a lot of fun doing stuff like this years ago, before LLMs were a thing.

brokensegue 1 day ago||
there are models between 2-grams and 600m param models that would be good options. i don't expect a 2-gram to do very well here. also i'm not sure why this model isn't a fine choice if it solves their problem
throwa356262 1 day ago||
What would you suggest instead?
stephantul 1 day ago||
A non-autoregressive transformer trained with a classification objective.
all2 1 day ago||
These are absurdly effective for this kind of task. Training is fast and straight forward. Packaging for deployment as ONNX is pretty simple as well.
dev-experiments 1 day ago||
As a follow up to the original article, I added a new experiment using Logistic Regression and the results are very good. It actually improves on the accuracy by a few points.

More details here: https://www.teachmecoolstuff.com/viewarticle/using-logistic-...

deepsquirrelnet 1 day ago||
If you want to go deeper on language models, try these project ideas:

- Zero-shot encoders like tasksource or GliNER

- Natural language inference: https://huggingface.co/blog/dleemiller/nli-xenc-ways-to-use

- GRPO training

- GEPA prompt tuning Qwen 0.6B (or GEPA, then GRPO)

- Use an embedding model and train a classifier (MLP, logistic, svm)

- Use a larger LLM to generate a synthetic dataset (beware of lack of diversity, mine "seed text" from real sources first)

- Synthetically generate "hard examples" where more than one category may be valid and DPO tune your preferred responses

throwaw12 1 day ago|
may I ask where did you get the list? I am looking for ways to get involved in going little more deeper on LLMs (I have very high level understanding, but my direct work doesn't involve them, hence I am not familiar with deeper details)
deepsquirrelnet 1 day ago||
I'd been working with language models for several years before LLMs were a solution to this kind of problem. These are some ideas "off the top of my head" about how you can do classification in various ways. There's really a lot of ways to tackle it now, and a lot of trade-offs you can learn by experimenting with them.

There's even more options still, especially if you go further back toward more traditional methods. Static word vectors like GloVe or fasttext (optionally more modern equivalents like WordLlama or Model2Vec). Then there's sklearn-style stuff too. Those can be really small/fast but have more accuracy-level tradeoffs.

mickael-kerjean 1 day ago||
If you are interested in small language model to fine tune, gemma3:270m is quite interesting for its size
nextaccountic 1 day ago||
> The model invents new categories (e.g. apartments) and doesn’t stick to the provided list of allowed categories

Can this specific failure mode be solved by providing a grammar that the output must adhere to? (Not sure if Qwen has this feature, it's used for eg. to ensure the output is parseable json)

nl 1 day ago||
It can.

It's something that is implemented by the thing that runs the model - eg Llama.cpp - rather than the model itself.

Note that it is hard to make work if you turn thinking on because the grammar gets complicated quickly (I don't recall if Qwen 0.6B can do thinking).

nextaccountic 19 hours ago|||
Just one question. If I'm running a local model, can I do something other than just a context free grammar? Does it makes sense to have something more general, or it would be just too slow?

I guess the only hard constraint is to not have backtracking, right? To not waste previously emitted tokens

aesthesia 1 day ago|||
Thinking shouldn't be too hard to deal with---just let the model generate freely until it hits a </think> token, then do constrained decoding, right?
stymaar 1 day ago||
Sure, but does llama-cpp support that?
nl 22 hours ago||
It does and this is how I did it.

But actually getting that grammar right as well as actually making it work with the correct Jinja template to correctly enable thinking mode and parse it out was a lot more work than I expected.

thomascountz 1 day ago|||
Yes, you can use constrained decoding like logit masking to force all invalid tokens in the vocabulary to -inf, and effectively be removed from selection. I believe llama.cpp exposes this by accepting a formatted grammar.
mijoharas 1 day ago||
This was my thought as well. I'm surprised that it's not being used here (afaict)
doubtfuluser 1 day ago||
But why using an encoder model instead of a BERT based model? For a pure classification that should be easier to train and work quite well
zwaps 1 day ago||
Has anyone compared recently doing something like ModernBERT plus classifier vs. full or lora FT of a small LM like qwen?
kamranjon 1 day ago|
I have! I recently compared Gemma 1b to ModernBERT Large for a binary classification task and ModernBERT was the clear winner. It learned faster and performed the task better by a significant margin by the end of training. It seems the bidirectional encoder only architecture works really well for classification tasks, and I think it is related to being bidirectional whereas decoder only models like Gemma (or Qwen) can only “look backwards”. I used a mixture of FFT and LoRA as well as a mixture of CE Loss and SupCon Loss.
vb7132 15 hours ago||
Isn’t a cosine similarity over the text embeddings a much more effective way to handle categorization?

The whole reason why embeddings work so well is because they encode the underlying meaning of the texts

pj_mukh 1 day ago||
“As an example, the question “When did we replace our pool pump?” will be mapped to a category called “pool” before querying the Index database.”

Cool write up! Really appreciate it but incidentally how does this categorization help you get better retrieval results?

mettamage 1 day ago|
Categorization allows for retrieval strategy
all2 1 day ago|||
In a general sense, you see this crop up in SKILLS.md files and other places, as LLMs have to deal with broad contexts. People try and drill into some taxonomy in a naive fashion using plaintext as a directive, which is not particularly optimal.

I wonder if one could build a 'mixture of experts' at the model level that leveraged a variety of small models "within" a larger model...

pj_mukh 1 day ago|||
because you have a different vector store for each categorization?

What if the question crosses categories?

electroglyph 1 day ago||
existing embedding models like alibaba's modernbert tune or one of the jina v5s would probably map query to category automatically. (i.e. store embeddings of each category and calculate cosine sim for each incoming query vs. categories and pick the closest)

also, you could stick a classifier head on a BERT model as another option.

GardenLetter27 1 day ago|
If you're gonna fine-tune for a closed set classification problem like this, you could just fine-tune BERT and get a faster model with better performance.
More comments...