Spaces:
Running on Zero
Running on Zero
Daryl Lim Claude Opus 4.8 (1M context) commited on
Commit Β·
9fdec8c
1
Parent(s): 42772e1
fix: remove invalid Textbox clear button and tighten model/tokenizer types
Browse filesty surfaced that buttons=["clear"] is not a valid gradio Textbox
built-in (only "copy" is), so the input's clear button silently did
nothing β remove it and update CLAUDE.md.
Annotate the loaders with PreTrainedTokenizerBase/PreTrainedModel
instead of the Auto* factory classes, resolving the get_vocab/device/
decode/callable warnings. With decode now typed as str, the dead
isinstance guard in translate() is removed. The remaining
model.generate warning is an irreducible transformers stub gap,
already downgraded to warn in ty.toml.
Verified: ty 6->1, 38 fast tests pass, ruff clean, app imports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLAUDE.md
CHANGED
|
@@ -35,7 +35,7 @@ uv run scripts/generate_langmap.py <path-to-paper.pdf>
|
|
| 35 |
|
| 36 |
## Architecture
|
| 37 |
|
| 38 |
-
**`app.py`** β Single-file application with a Google Translate-style layout: top row has two symmetric, filterable, region-sorted language dropdowns (source defaults to "English (en)", target defaults to "French (fr)") with a swap button ("β") between them; below that, input textbox
|
| 39 |
|
| 40 |
**`langmap/`** β Package with `langid_mapping.py`, mapping 418 language tokens to `{"name": ..., "region": ...}` dicts. Auto-generated by `scripts/generate_langmap.py` from Table 9 (Section A.1) of the MADLAD-400 paper. Available languages at runtime are the intersection of this mapping and the model's vocabulary.
|
| 41 |
|
|
|
|
| 35 |
|
| 36 |
## Architecture
|
| 37 |
|
| 38 |
+
**`app.py`** β Single-file application with a Google Translate-style layout: top row has two symmetric, filterable, region-sorted language dropdowns (source defaults to "English (en)", target defaults to "French (fr)") with a swap button ("β") between them; below that, input textbox and output textbox with copy button side by side. The Translate button spans full width below both textboxes (shows "Translating..." during processing). Ctrl+Enter submits from the input. The model auto-detects source language; the source dropdown is for user reference and the swap button only. Uses `@lru_cache` for lazy loading of the `google/madlad400-3b-mt` tokenizer and model (no download on import). Uses `float16` on CUDA, `float32` on CPU. MPS is not supported (produces garbage output with T5 models). Translation prepends a target language token with a space to the input text (e.g., `<2fr> Hello`) before tokenization and generation. The `@spaces.GPU` decorator allocates GPU on HF Spaces infrastructure.
|
| 39 |
|
| 40 |
**`langmap/`** β Package with `langid_mapping.py`, mapping 418 language tokens to `{"name": ..., "region": ...}` dicts. Auto-generated by `scripts/generate_langmap.py` from Table 9 (Section A.1) of the MADLAD-400 paper. Available languages at runtime are the intersection of this mapping and the model's vocabulary.
|
| 41 |
|
app.py
CHANGED
|
@@ -10,7 +10,7 @@ from functools import lru_cache
|
|
| 10 |
import gradio as gr
|
| 11 |
import spaces
|
| 12 |
import torch
|
| 13 |
-
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
|
| 14 |
|
| 15 |
from langmap.langid_mapping import langid_to_language
|
| 16 |
|
|
@@ -25,7 +25,7 @@ def _get_device() -> torch.device:
|
|
| 25 |
|
| 26 |
|
| 27 |
@lru_cache(maxsize=1)
|
| 28 |
-
def _load_tokenizer() ->
|
| 29 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
|
| 30 |
if tokenizer is None:
|
| 31 |
raise RuntimeError(f"Failed to load tokenizer for {MODEL_NAME}")
|
|
@@ -33,7 +33,7 @@ def _load_tokenizer() -> AutoTokenizer:
|
|
| 33 |
|
| 34 |
|
| 35 |
@lru_cache(maxsize=1)
|
| 36 |
-
def _load_model() ->
|
| 37 |
device = _get_device()
|
| 38 |
dtype = torch.float16 if device.type == "cuda" else torch.float32
|
| 39 |
return AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME, dtype=dtype).to(device)
|
|
@@ -85,10 +85,7 @@ def translate(
|
|
| 85 |
generate_kwargs["temperature"] = temperature
|
| 86 |
|
| 87 |
outputs = model.generate(**generate_kwargs)
|
| 88 |
-
|
| 89 |
-
if not isinstance(result, str):
|
| 90 |
-
raise TypeError(f"Expected str from decode, got {type(result)}")
|
| 91 |
-
return result
|
| 92 |
|
| 93 |
|
| 94 |
def _translate_with_loading(
|
|
@@ -131,7 +128,6 @@ def _build_demo() -> gr.Blocks:
|
|
| 131 |
lines=6,
|
| 132 |
max_length=2000,
|
| 133 |
show_label=False,
|
| 134 |
-
buttons=["clear"],
|
| 135 |
)
|
| 136 |
output_text = gr.Textbox(
|
| 137 |
placeholder="Translation",
|
|
|
|
| 10 |
import gradio as gr
|
| 11 |
import spaces
|
| 12 |
import torch
|
| 13 |
+
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, PreTrainedModel, PreTrainedTokenizerBase
|
| 14 |
|
| 15 |
from langmap.langid_mapping import langid_to_language
|
| 16 |
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
@lru_cache(maxsize=1)
|
| 28 |
+
def _load_tokenizer() -> PreTrainedTokenizerBase:
|
| 29 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
|
| 30 |
if tokenizer is None:
|
| 31 |
raise RuntimeError(f"Failed to load tokenizer for {MODEL_NAME}")
|
|
|
|
| 33 |
|
| 34 |
|
| 35 |
@lru_cache(maxsize=1)
|
| 36 |
+
def _load_model() -> PreTrainedModel:
|
| 37 |
device = _get_device()
|
| 38 |
dtype = torch.float16 if device.type == "cuda" else torch.float32
|
| 39 |
return AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME, dtype=dtype).to(device)
|
|
|
|
| 85 |
generate_kwargs["temperature"] = temperature
|
| 86 |
|
| 87 |
outputs = model.generate(**generate_kwargs)
|
| 88 |
+
return tokenizer.decode(outputs[0], skip_special_tokens=True)
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
|
| 91 |
def _translate_with_loading(
|
|
|
|
| 128 |
lines=6,
|
| 129 |
max_length=2000,
|
| 130 |
show_label=False,
|
|
|
|
| 131 |
)
|
| 132 |
output_text = gr.Textbox(
|
| 133 |
placeholder="Translation",
|