maxafanasiev commited on
Commit
098a562
·
verified ·
1 Parent(s): 5795ff9

Document offline usage

Browse files
Files changed (1) hide show
  1. README.md +44 -0
README.md CHANGED
@@ -56,6 +56,50 @@ print(classify([
56
 
57
  Classify in batches of 16–32 articles; `max_len=256` is about twice as fast at a small quality cost (see Results).
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  ## Results (gold set, CPU Apple M4 Pro, fp32)
60
 
61
  | Max tokens | micro-F1 (random gold, 163) | exact set match | CPU latency |
 
56
 
57
  Classify in batches of 16–32 articles; `max_len=256` is about twice as fast at a small quality cost (see Results).
58
 
59
+ ## Download once, use without Hugging Face
60
+
61
+ 1. Download the files (needs access to this private repo once), with any of:
62
+ - CLI: `hf auth login`, then `hf download maxafanasiev/news-topic-classifier-e5-base --local-dir ./news-topic-classifier-e5-base`
63
+ - git: `git lfs install && git clone https://huggingface.co/maxafanasiev/news-topic-classifier-e5-base` (use a token as the password)
64
+ - browser: the "Files and versions" tab, download every file into one folder
65
+ 2. Keep these files together: `model.safetensors`, `config.json`, `tokenizer.json`, `tokenizer_config.json`, `thresholds.json`.
66
+ 3. Load from the folder; `HF_HUB_OFFLINE=1` makes sure nothing is fetched from the internet:
67
+
68
+ ```python
69
+ import json
70
+ import os
71
+ from pathlib import Path
72
+
73
+ os.environ["HF_HUB_OFFLINE"] = "1"
74
+
75
+ import torch
76
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
77
+
78
+ MODEL_DIR = Path("./news-topic-classifier-e5-base")
79
+ PREFIX = "passage: "
80
+ PARENTS = {"Theft": "Crime", "Assault": "Crime"}
81
+
82
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR)
83
+ model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR).eval()
84
+ thresholds = json.loads((MODEL_DIR / "thresholds.json").read_text())
85
+ categories = list(thresholds)
86
+
87
+
88
+ @torch.no_grad()
89
+ def classify(articles: list[dict], max_len: int = 512) -> list[list[str]]:
90
+ texts = [f"{PREFIX}{a['title']}\n{a['content']}" for a in articles]
91
+ batch = tokenizer(texts, truncation=True, max_length=max_len, padding=True, return_tensors="pt")
92
+ probs = torch.sigmoid(model(**batch).logits)
93
+ results = []
94
+ for row in probs:
95
+ labels = [c for c, p in zip(categories, row.tolist()) if p >= thresholds[c]]
96
+ labels += [PARENTS[c] for c in labels if c in PARENTS and PARENTS[c] not in labels]
97
+ results.append(labels or ["Other"])
98
+ return results
99
+ ```
100
+
101
+ Requirements: `torch` and `transformers` (no `huggingface_hub` login needed at this point).
102
+
103
  ## Results (gold set, CPU Apple M4 Pro, fp32)
104
 
105
  | Max tokens | micro-F1 (random gold, 163) | exact set match | CPU latency |