Spaces:
Running
Running
Commit History
-
Make short page links work Running
b16d906 -
Short page links and never cache not-found pages
9394c1b -
Add chat box: floating chat, full chat page, talk to the team
ec9b3d8
-
Add security headers and self-host Supabase library
613c65d
-
Production front end: design system, legal pages, SEO, a11y, 404; hash API keys
260cc43 -
Fix verdict: DistilBERT does not accept token_type_ids
75daaa5 -
Surface verdict errors in the response while debugging
edbe45a -
Add /verdict endpoint: three-state ensemble of v1 and v2
2144ece
-
Add usage metering: background logging per API key and a /usage endpoint
79e1060 -
Add in-memory rate limiting middleware with per-key and per-IP buckets
79a0e7b
-
Day 17: Add API key validation to FastAPI service
- Validates Bearer tokens against Supabase api_keys table on /classify and /classify/batch - Anonymous access still allowed (backward compatible for landing page demo) - Updates last_used_at on each successful key use - Reads SUPABASE_URL and SUPABASE_SERVICE_KEY from environment (set as HF Space secrets) - Returns 401 for invalid/revoked keys342363d
-
Configure HF Space deployment with models loaded from Hub
- Models served from winifred12/wilma-distilbert (separate model repo, bypassing HF Spaces 1GB storage limit) - ModelBundle accepts subfolder argument for multi-model repos - Dockerfile stays slim: code only, no model artifacts copied - API loads both binary and multi-class models from Hub at startup0eb8707 -
Day 12: HTML visualization of token attributions
- Add src/wilma/inference/visualize.py: standalone HTML output with token highlighting, three-tier attribution intensity, light/dark mode toggle (with localStorage persistence and prefers-color-scheme fallback), Inter font from rsms.me, punctuation-aware tokenization, hover tooltips with exact scores - CLI: python -m wilma.inference.visualize '<text>' [--multiclass] - Note: visualization is a development/inspection tool. Production users receive structured JSON via the API (see Day 13).043a496 -
Day 11: token-level explainability via Integrated Gradients
- Add src/wilma/inference/explain.py: WilmaExplainer wrapping trained DistilBERT models with Captum LayerIntegratedGradients on the embedding layer, 50 integration steps, zero baseline - Subword merging: BERT-style ##fragments combined into whole words for human-readable output (URGENT/BUSINESS/ASSISTANCE instead of B/##R/##GE/##NT, etc.) - CLI: python -m wilma.inference.explain '<text>' [--multiclass] - Add tests/test_explain.py with structural validity + subword merging checks (skip if model not trained) - Pin captum==0.7.0 in requirements.txt - Note: explanations run on CPU due to Captum/MPS float64 incompatibility; prediction inference still uses MPS Verified findings: - Token 'transfer' has NEGATIVE attribution on 419 messages (-0.1762), demonstrating contextual rather than keyword-based classification - 'pharmacy' dominates commercial_spam attribution (+1.27) - Family vocabulary ('mum') is a learned anti-scam signal25e61f9 -
Day 10: multi-class DistilBERT trained (test F1_macro=0.9761)
- Add src/wilma/models/train_distilbert_multiclass.py: 4-class fine-tune on legitimate, scam_other, advance_fee_419, commercial_spam categories (rare categories <50 examples deferred to V1.5) - 3 epochs, batch 16, lr 2e-5, max_length 256, early stopping on f1_macro - Validation: F1_macro=0.9699 | Test: F1_macro=0.9761, accuracy=98.22% - Per-class test F1: legitimate=0.9926, scam_other=0.9709, advance_fee_419=0.9747, commercial_spam=0.9660 - Strongest result: 419 recall=0.9838 (only 7 missed out of 431), validating the Nigerian-context moat hypothesis - Update notebooks/01_eda.ipynb with executed cell outputs5ff83cc
-
Recover Days 6-8 model code (gitignore was hiding src/wilma/models)
- Fix .gitignore pattern: models/ -> /models/ so it only matches the top-level trained-artifacts folder, not the source code folder - Add src/wilma/models/__init__.py (was untracked) - Add baseline_tfidf.py from Day 6 (TF-IDF + Logistic Regression, validation F1=0.9837) - Add baseline_fasttext.py from Day 7 (fastText with character n-grams, validation F1=0.9835) - Add train_distilbert.py from Day 8 (binary DistilBERT fine-tuning, validation F1=0.9906, test F1=0.9921, ROC-AUC=0.9995) This commit recovers code that was correctly written and run during Days 6-8 but silently ignored by an over-broad gitignore rule. The trained model artifacts and metrics remain gitignored.57a6700 -
Day 9: rule-based scam categorization
- Add src/wilma/data/categorize.py: priority-ordered regex/keyword rules for 8 fine-grained scam categories plus commercial_spam - Add tests/test_categorize.py with 19 hand-crafted edge cases (all passing); fixed widow + late-spouse edge case via 419 priority - Add src/wilma/data/recategorize.py applying rules to all splits - Recategorization results (full dataset, 39,465 rows): legitimate 20,426 (51.8%) scam_other 12,072 (30.6%) unmatched residual advance_fee_419 4,158 (10.5%) commercial_spam 2,711 ( 6.9%) impersonation/phishing/crypto/romance/loan/otp: <50 each - Findings: rare modern categories (fake_otp, fake_loan, crypto, etc.) have insufficient training data due to corpus age (Enron 2002, SpamAssassin 2003, Kaggle 419 ~2002). Deferred to V1.5 pending collection of contemporary Nigerian SMS data.8744c81 -
Day 4: clean all datasets and produce unified train/val/test splits
- Add HTML stripping to cleaners.py (with 2 new tests, 8 total passing) - Add email_utils.py with RFC-822 multipart parsing - Add cleaners for Enron-Spam, SpamAssassin, and Kaggle 419 corpus - Add merge_datasets.py producing stratified 80/10/10 splits - Pin scikit-learn in requirements.txt - Document processed dataset schema and reproduction steps Final dataset: 39,465 rows, 48.24% scam, balanced across all splits2aa5ce2 -
Day 3: text cleaning pipeline with unified schema
- Add wilma.data.cleaners with PII anonymization (phones, emails, URLs, money) - Add wilma.data.schema defining unified row format used by all datasets - Add wilma.data.clean_sms_spam producing data/interim/sms_spam.csv - Add tests/test_cleaners.py with 6 unit tests covering core cleaning logic - Add pyproject.toml configuring pytest, ruff, black, and editable install - 5,169 SMS messages cleaned: 4,516 legitimate / 653 scame1a4bda -
Initialize Wilma project structure and dependencies
bbd7f6a