--- language: en license: mit library_name: transformers tags: - text-classification - onnx - freelance - intent-classification base_model: sentence-transformers/all-MiniLM-L6-v2 pipeline_tag: text-classification widget: - text: "I offer web scraping and automation services" example_title: "Offer example" - text: "Need a copywriter for email sequences" example_title: "Request example" - text: "Hi everyone, hope you're doing well today" example_title: "Neither example" --- # Freelance offer/request classifier Fine-tuned `all-MiniLM-L6-v2` (22M params) that classifies short freelance-community messages into one of three categories: - **offer** — the sender is offering their own service/skill - **request** — the sender is looking to hire / needs someone else's service - **neither** — general chat, unrelated to offering/requesting a service ## Performance Evaluated on a held-out validation split (15% of training data, not seen during training): | Class | Precision | Recall | F1 | |----------|-----------|--------|------| | offer | 0.74 | 0.87 | 0.80 | | request | 0.93 | 0.88 | 0.90 | | neither | 0.86 | 0.78 | 0.82 | | **accuracy** | | | **0.85** | | **macro avg** | 0.84 | 0.84 | **0.84** | Trained on 2,614 messages collected from freelance-community Telegram groups. ## Known limitation The model still struggles with the phrasing pattern "I'm looking for [role] opportunities" when the speaker is actually **offering** their own skill (it tends to predict "request" instead of "offer" for this pattern with high confidence). If your use case is sensitive to this, consider a post-processing rule for this specific phrasing, or contribute additional labeled examples. ## Usage (ONNX, recommended — fast, CPU-only) ```python from optimum.onnxruntime import ORTModelForSequenceClassification from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("ademchaoua/freelance-offer-request-classifier", subfolder="onnx") model = ORTModelForSequenceClassification.from_pretrained("ademchaoua/freelance-offer-request-classifier", subfolder="onnx") inputs = tokenizer("I offer web scraping services", return_tensors="pt") outputs = model(**inputs) pred = outputs.logits.argmax(-1).item() print(model.config.id2label[pred]) ``` ## Usage (PyTorch) ```python from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch tokenizer = AutoTokenizer.from_pretrained("ademchaoua/freelance-offer-request-classifier") model = AutoModelForSequenceClassification.from_pretrained("ademchaoua/freelance-offer-request-classifier") inputs = tokenizer("Need a copywriter for email sequences", return_tensors="pt") with torch.no_grad(): logits = model(**inputs).logits pred = logits.argmax(-1).item() print(model.config.id2label[pred]) ``` ## Training details - Base model: `sentence-transformers/all-MiniLM-L6-v2` - Method: end-to-end fine-tuning (full model, classification head included) - Max sequence length: 96 tokens - Class-weighted loss (balanced) to counter class imbalance - Early stopping on macro-F1 - Trained on ~2,600 messages collected from freelance-community Telegram groups, labeled with an LLM (DeepSeek) and manually reviewed - Exported to ONNX + INT8 quantized for fast CPU inference (~2ms/text)