olumideola commited on
Commit
aea694e
Β·
verified Β·
1 Parent(s): 0a5ac56

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -14
app.py CHANGED
@@ -1,29 +1,48 @@
1
  import gradio as gr
2
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
 
 
3
 
4
  # ---------------------------------------------------------------------------
5
  # Model registry β€” all LID models published under olaverse.
6
- # Lazy-loaded on first use so the Space doesn't need to hold all four in
7
- # memory (or pay startup time for all four) before anyone's clicked anything.
 
 
 
 
 
8
  # ---------------------------------------------------------------------------
9
  MODELS = {
10
  "lid-neural-5 (Nigerian, 4 langs)": {
 
11
  "repo": "olaverse/lid-neural-5",
12
  "note": "Yoruba, Hausa, Igbo, Nigerian Pidgin",
13
  },
14
  "lid-neural-5.1 (Nigerian, 4 langs, sentence-level)": {
 
15
  "repo": "olaverse/lid-neural-5.1",
16
  "note": "Hausa, Yoruba, Igbo, Nigerian Pidgin β€” built on mist-encoder-base-ng, tuned for short/sentence-level text (97.6% acc)",
17
  },
18
- "lid-lite-25 (fastText, 25 langs)": {
 
19
  "repo": "olaverse/lid-lite-25",
20
- "note": "CPU-only, sub-ms inference β€” trained on both long passages and short queries",
 
 
 
 
 
 
 
21
  },
22
  "lid-neural-25.1 (XLM-R, passages)": {
 
23
  "repo": "olaverse/lid-neural-25.1",
24
  "note": "25 languages, tuned for long-form text",
25
  },
26
  "lid-neural-25.2 (XLM-R, short queries)": {
 
27
  "repo": "olaverse/lid-neural-25.2",
28
  "note": "25 languages, tuned for short questions/queries",
29
  },
@@ -41,10 +60,29 @@ LANGUAGE_NAMES = {
41
 
42
  import gc
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  # Only ONE model is kept in memory at a time. Loading a new one evicts
45
  # whatever was previously cached. This trades re-download/reload time on
46
  # every model switch for a flat, predictable memory footprint β€” important
47
- # on a free/quota-limited CPU Space running four separate checkpoints.
48
  _CACHED_LABEL = None
49
  _CACHED_PIPELINE = None
50
 
@@ -67,10 +105,17 @@ def get_pipeline(model_label: str):
67
  # Evict whatever's currently loaded before loading the new one.
68
  _unload_current()
69
 
70
- repo = MODELS[model_label]["repo"]
71
- tok = AutoTokenizer.from_pretrained(repo)
72
- model = AutoModelForSequenceClassification.from_pretrained(repo)
73
- pipe = pipeline("text-classification", model=model, tokenizer=tok, top_k=5)
 
 
 
 
 
 
 
74
 
75
  _CACHED_LABEL = model_label
76
  _CACHED_PIPELINE = pipe
@@ -173,9 +218,9 @@ with gr.Blocks() as demo:
173
 
174
  with gr.Tab("Compare all models"):
175
  gr.Markdown(
176
- "Runs the same text through all five models and shows top-3 predictions from each. "
177
- "Only one model is kept in memory at a time, so this reloads each checkpoint in turn β€” "
178
- "expect it to take a few seconds longer than the single-model tab."
179
  )
180
  compare_input = gr.Textbox(
181
  label="Enter text",
@@ -193,9 +238,9 @@ with gr.Blocks() as demo:
193
  **Model notes:**
194
  - `lid-neural-5` β€” Nigerian-focused, 4 languages (Yoruba, Hausa, Igbo, Pidgin)
195
  - `lid-neural-5.1` β€” Nigerian-focused, same 4 languages, sentence-level tuned on `mist-encoder-base-ng` (97.6% acc; most residual error involves Pidgin, which shares vocabulary with the others)
196
- - `lid-lite-25` β€” fastText, CPU-only, 25 languages
197
  - `lid-neural-25.1` / `.2` β€” XLM-R fine-tunes, 25 languages, tuned for passages vs. short queries respectively.
198
- Known limitation across both: Zulu/Xhosa confusion on short text (see model cards).
199
  """)
200
 
201
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
3
+ from huggingface_hub import hf_hub_download
4
+ import fasttext
5
 
6
  # ---------------------------------------------------------------------------
7
  # Model registry β€” all LID models published under olaverse.
8
+ # Two different underlying formats:
9
+ # - "transformers": standard AutoTokenizer + AutoModelForSequenceClassification
10
+ # - "fasttext": a .bin file loaded directly with the fasttext library
11
+ # (lid-lite-25 is NOT a transformers model β€” it's a character-n-gram
12
+ # linear classifier, hence no tokenizer/config to load via AutoTokenizer)
13
+ # Lazy-loaded on first use so the Space doesn't need to hold all of these in
14
+ # memory (or pay startup time for all of them) before anyone's clicked anything.
15
  # ---------------------------------------------------------------------------
16
  MODELS = {
17
  "lid-neural-5 (Nigerian, 4 langs)": {
18
+ "type": "transformers",
19
  "repo": "olaverse/lid-neural-5",
20
  "note": "Yoruba, Hausa, Igbo, Nigerian Pidgin",
21
  },
22
  "lid-neural-5.1 (Nigerian, 4 langs, sentence-level)": {
23
+ "type": "transformers",
24
  "repo": "olaverse/lid-neural-5.1",
25
  "note": "Hausa, Yoruba, Igbo, Nigerian Pidgin β€” built on mist-encoder-base-ng, tuned for short/sentence-level text (97.6% acc)",
26
  },
27
+ "lid-lite-25 (fastText, passages)": {
28
+ "type": "fasttext",
29
  "repo": "olaverse/lid-lite-25",
30
+ "filename": "passages.bin",
31
+ "note": "25 languages, fastText character n-gram model, tuned for long-form passages",
32
+ },
33
+ "lid-lite-25 (fastText, short queries)": {
34
+ "type": "fasttext",
35
+ "repo": "olaverse/lid-lite-25",
36
+ "filename": "questions.bin",
37
+ "note": "25 languages, fastText character n-gram model, tuned for short questions/queries",
38
  },
39
  "lid-neural-25.1 (XLM-R, passages)": {
40
+ "type": "transformers",
41
  "repo": "olaverse/lid-neural-25.1",
42
  "note": "25 languages, tuned for long-form text",
43
  },
44
  "lid-neural-25.2 (XLM-R, short queries)": {
45
+ "type": "transformers",
46
  "repo": "olaverse/lid-neural-25.2",
47
  "note": "25 languages, tuned for short questions/queries",
48
  },
 
60
 
61
  import gc
62
 
63
+
64
+ class FastTextWrapper:
65
+ """Mimics the shape of a transformers text-classification pipeline output
66
+ ([[{'label': ..., 'score': ...}, ...]]) so downstream code doesn't need
67
+ to branch on model type."""
68
+
69
+ def __init__(self, ft_model):
70
+ self._model = ft_model
71
+
72
+ def __call__(self, text: str, top_k: int = 5):
73
+ clean = text.replace("\n", " ").strip()
74
+ labels, probs = self._model.predict(clean, k=top_k)
75
+ results = [
76
+ {"label": label.replace("__label__", ""), "score": float(prob)}
77
+ for label, prob in zip(labels, probs)
78
+ ]
79
+ return [results]
80
+
81
+
82
  # Only ONE model is kept in memory at a time. Loading a new one evicts
83
  # whatever was previously cached. This trades re-download/reload time on
84
  # every model switch for a flat, predictable memory footprint β€” important
85
+ # on a free/quota-limited CPU Space running several separate checkpoints.
86
  _CACHED_LABEL = None
87
  _CACHED_PIPELINE = None
88
 
 
105
  # Evict whatever's currently loaded before loading the new one.
106
  _unload_current()
107
 
108
+ entry = MODELS[model_label]
109
+
110
+ if entry["type"] == "fasttext":
111
+ local_path = hf_hub_download(repo_id=entry["repo"], filename=entry["filename"])
112
+ ft_model = fasttext.load_model(local_path)
113
+ pipe = FastTextWrapper(ft_model)
114
+ else:
115
+ repo = entry["repo"]
116
+ tok = AutoTokenizer.from_pretrained(repo)
117
+ model = AutoModelForSequenceClassification.from_pretrained(repo)
118
+ pipe = pipeline("text-classification", model=model, tokenizer=tok, top_k=5)
119
 
120
  _CACHED_LABEL = model_label
121
  _CACHED_PIPELINE = pipe
 
218
 
219
  with gr.Tab("Compare all models"):
220
  gr.Markdown(
221
+ "Runs the same text through all six model/checkpoint combinations and shows top-3 "
222
+ "predictions from each. Only one model is kept in memory at a time, so this reloads "
223
+ "each checkpoint in turn β€” expect it to take a bit longer than the single-model tab."
224
  )
225
  compare_input = gr.Textbox(
226
  label="Enter text",
 
238
  **Model notes:**
239
  - `lid-neural-5` β€” Nigerian-focused, 4 languages (Yoruba, Hausa, Igbo, Pidgin)
240
  - `lid-neural-5.1` β€” Nigerian-focused, same 4 languages, sentence-level tuned on `mist-encoder-base-ng` (97.6% acc; most residual error involves Pidgin, which shares vocabulary with the others)
241
+ - `lid-lite-25` β€” fastText (character n-gram, CPU-only), 25 languages, two checkpoints (passages / short queries)
242
  - `lid-neural-25.1` / `.2` β€” XLM-R fine-tunes, 25 languages, tuned for passages vs. short queries respectively.
243
+ Known limitation across both `-25` families: Zulu/Xhosa confusion on short text (see model cards).
244
  """)
245
 
246
  if __name__ == "__main__":