VoltageVagabond commited on
Commit
082b339
·
verified ·
1 Parent(s): c425d05

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +9 -4
  2. app.py +31 -1
  3. requirements.txt +1 -0
README.md CHANGED
@@ -66,14 +66,19 @@ Liquid AI's LFM2.5-1.2B-Instruct model fine-tuned with LoRA adapters using Huggi
66
  | Training examples | 3,200 |
67
  | Test examples | 800 |
68
  | Epochs | 3 |
69
- | Batch size | 4 |
70
  | Learning rate | 2e-4 |
71
- | Gradient checkpointing | Enabled |
 
 
 
 
 
72
  | LoRA rank | 8 |
73
  | LoRA alpha | 16 |
74
  | LoRA dropout | 0.1 |
75
  | Target modules | 8 (q_proj, k_proj, v_proj, out_proj, w1, w2, w3, in_proj) |
76
- | Training time | ~2–2.5 hours |
77
 
78
  ### Hardware
79
 
@@ -121,7 +126,7 @@ It is **not** intended for production spam filtering.
121
 
122
  ## Limitations
123
 
124
- - **Binary classification only** (spam/ham) no multi-class or severity ranking (v1)
125
  - Model is too large for free HuggingFace Spaces deployment
126
  - May misclassify legitimate marketing emails as spam
127
  - Trained on **English emails only** — not suitable for other languages
 
66
  | Training examples | 3,200 |
67
  | Test examples | 800 |
68
  | Epochs | 3 |
69
+ | Batch size | 1 (effective 4 with gradient accumulation steps = 4) |
70
  | Learning rate | 2e-4 |
71
+ | Max sequence length | 256 |
72
+ | Optimizer | adamw_torch (bitsandbytes 8-bit not supported on MPS) |
73
+ | Weight dtype | bfloat16 |
74
+ | Device | MPS (Apple Silicon) |
75
+ | Gradient checkpointing | Enabled (use_reentrant=False) |
76
+ | Max gradient norm | 0.3 |
77
  | LoRA rank | 8 |
78
  | LoRA alpha | 16 |
79
  | LoRA dropout | 0.1 |
80
  | Target modules | 8 (q_proj, k_proj, v_proj, out_proj, w1, w2, w3, in_proj) |
81
+ | Training time | ~1–1.5 hours (per fine_tune.py; earlier docs listed ~2–2.5 hours before the v0.4.3 memory optimization) |
82
 
83
  ### Hardware
84
 
 
126
 
127
  ## Limitations
128
 
129
+ - **Three-class classification** (SPAM / HAM / PHISHING) as of v0.4.0 earlier versions were binary
130
  - Model is too large for free HuggingFace Spaces deployment
131
  - May misclassify legitimate marketing emails as spam
132
  - Trained on **English emails only** — not suitable for other languages
app.py CHANGED
@@ -90,6 +90,31 @@ tokenizer = None
90
 
91
  adapter_exists = Path(ADAPTER_PATH).exists() and any(Path(ADAPTER_PATH).iterdir())
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  if adapter_exists:
94
  print("Loading Liquid AI model and LoRA adapters...")
95
  base_model = AutoModelForCausalLM.from_pretrained(
@@ -143,6 +168,8 @@ def generate_response(messages, max_tokens=750):
143
  max_new_tokens=max_tokens,
144
  do_sample=True,
145
  temperature=0.1,
 
 
146
  )
147
 
148
  # Decode only the NEW tokens (skip the input prompt)
@@ -370,6 +397,8 @@ TOPBAR_HTML = """
370
 
371
  with gr.Blocks(
372
  title="Liquid AI Spam Classifier",
 
 
373
  ) as demo:
374
 
375
  gr.HTML(TOPBAR_HTML)
@@ -378,6 +407,7 @@ with gr.Blocks(
378
  chatbot = gr.Chatbot(
379
  label="Chat",
380
  height=450,
 
381
  )
382
 
383
  # Message input row
@@ -476,4 +506,4 @@ with gr.Blocks(
476
  # ---------------------------------------------------------------------------
477
 
478
  if __name__ == "__main__":
479
- demo.launch(theme=theme, css=custom_css)
 
90
 
91
  adapter_exists = Path(ADAPTER_PATH).exists() and any(Path(ADAPTER_PATH).iterdir())
92
 
93
+ # If local adapters are missing (e.g. running on HuggingFace Spaces),
94
+ # download them from the HF model repo instead.
95
+ HF_ADAPTER_REPO = "VoltageVagabond/spam-classifier-liquid"
96
+
97
+ if not adapter_exists:
98
+ print(f"Local adapters not found. Downloading from {HF_ADAPTER_REPO}...")
99
+ try:
100
+ import os
101
+ from huggingface_hub import snapshot_download
102
+ snapshot_path = snapshot_download(
103
+ repo_id=HF_ADAPTER_REPO,
104
+ repo_type="model",
105
+ allow_patterns=["adapters_fast/adapter_config.json",
106
+ "adapters_fast/adapter_model.safetensors",
107
+ "adapters_fast/chat_template.jinja",
108
+ "adapters_fast/tokenizer.json",
109
+ "adapters_fast/tokenizer_config.json"],
110
+ token=os.environ.get("HF_TOKEN"),
111
+ )
112
+ ADAPTER_PATH = str(Path(snapshot_path) / "adapters_fast")
113
+ adapter_exists = True
114
+ print(f"Adapters downloaded to {ADAPTER_PATH}")
115
+ except Exception as e:
116
+ print(f"ERROR: Could not download adapters: {e}")
117
+
118
  if adapter_exists:
119
  print("Loading Liquid AI model and LoRA adapters...")
120
  base_model = AutoModelForCausalLM.from_pretrained(
 
168
  max_new_tokens=max_tokens,
169
  do_sample=True,
170
  temperature=0.1,
171
+ cache_implementation="quantized",
172
+ cache_config={"backend": "hqq", "nbits": 8},
173
  )
174
 
175
  # Decode only the NEW tokens (skip the input prompt)
 
397
 
398
  with gr.Blocks(
399
  title="Liquid AI Spam Classifier",
400
+ theme=theme,
401
+ css=custom_css,
402
  ) as demo:
403
 
404
  gr.HTML(TOPBAR_HTML)
 
407
  chatbot = gr.Chatbot(
408
  label="Chat",
409
  height=450,
410
+ type='messages',
411
  )
412
 
413
  # Message input row
 
506
  # ---------------------------------------------------------------------------
507
 
508
  if __name__ == "__main__":
509
+ demo.launch()
requirements.txt CHANGED
@@ -3,6 +3,7 @@ transformers>=5.0.0
3
  torch>=2.6.0
4
  accelerate>=1.0.0
5
  peft>=0.14.0
 
6
  gradio>=5.0
7
  numpy>=1.24.0
8
  pandas>=2.0.0
 
3
  torch>=2.6.0
4
  accelerate>=1.0.0
5
  peft>=0.14.0
6
+ hqq>=0.2.0
7
  gradio>=5.0
8
  numpy>=1.24.0
9
  pandas>=2.0.0