Upload folder using huggingface_hub
Browse files- README.md +16 -11
- __pycache__/app.cpython-314.pyc +0 -0
- app.py +36 -36
README.md
CHANGED
|
@@ -7,7 +7,7 @@ sdk: gradio
|
|
| 7 |
sdk_version: 6.30.0
|
| 8 |
app_file: app.py
|
| 9 |
python_version: "3.12"
|
| 10 |
-
short_description:
|
| 11 |
license: apache-2.0
|
| 12 |
models:
|
| 13 |
- Sandroeth/cali-id-en-translate
|
|
@@ -16,22 +16,27 @@ models:
|
|
| 16 |
|
| 17 |
# cali
|
| 18 |
|
| 19 |
-
|
| 20 |
|
| 21 |
-
|
|
|
|
| 22 |
|
| 23 |
-
|
| 24 |
|
| 25 |
-
|
| 26 |
|
| 27 |
-
|
| 28 |
|
| 29 |
-
|
| 30 |
|
| 31 |
-
|
| 32 |
|
| 33 |
-
|
| 34 |
|
| 35 |
-
|
| 36 |
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
sdk_version: 6.30.0
|
| 8 |
app_file: app.py
|
| 9 |
python_version: "3.12"
|
| 10 |
+
short_description: Indonesian-English translation and CALI text generation
|
| 11 |
license: apache-2.0
|
| 12 |
models:
|
| 13 |
- Sandroeth/cali-id-en-translate
|
|
|
|
| 16 |
|
| 17 |
# cali
|
| 18 |
|
| 19 |
+
Explore two lightweight language models by Sandroeth in an English-language interface.
|
| 20 |
|
| 21 |
+
- **Translation:** translate everyday sentences between Indonesian and English.
|
| 22 |
+
- **Explore CALI:** continue a text prompt with the experimental CALI-0.1B base model.
|
| 23 |
|
| 24 |
+
## Inference
|
| 25 |
|
| 26 |
+
Translation follows the [official model README](https://huggingface.co/Sandroeth/cali-id-en-translate/blob/main/README.md): `[idβen]\n{text}\nβ` or `[enβid]\n{text}\nβ`, deterministic decoding, `repetition_penalty=1.5`, `no_repeat_ngram_size=3`, `use_cache=False`, and 64 output tokens by default. The first-sentence option matches the official example; disable it to inspect the complete generated output.
|
| 27 |
|
| 28 |
+
The base model receives a plain text prompt without a chat template. Both models use their custom architecture code at the revisions pinned in `app.py`. Float32 preserves compatibility with the translation model's RoPE implementation. Transformers 5.9.0 matches the translation checkpoint configuration.
|
| 29 |
|
| 30 |
+
The combined input and output budget is 1024 tokens, with up to 256 output tokens. Translation inputs are limited to 200 words.
|
| 31 |
|
| 32 |
+
## Hosting and API
|
| 33 |
|
| 34 |
+
This Gradio Space uses ZeroGPU. Both models are loaded once at startup, and the inference handlers use `@spaces.GPU`. CPU execution is also supported when available. Spaces manages Gradio, PyTorch, `spaces`, and `huggingface_hub`.
|
| 35 |
|
| 36 |
+
Gradio API endpoints: `/translate` and `/complete`. MCP is enabled. Examples are cached lazily after first use. Each response includes token counts and inference time.
|
| 37 |
|
| 38 |
+
## Limitations
|
| 39 |
+
|
| 40 |
+
Translation works best on everyday sentences. Very short inputs, technical topics, and long passages may be unreliable. CALI-0.1B is an experimental base model trained on limited data; continuations can repeat, drift off-topic, or be inconsistent.
|
| 41 |
+
|
| 42 |
+
Both models are released under Apache 2.0 by Sandroeth.
|
__pycache__/app.cpython-314.pyc
CHANGED
|
Binary files a/__pycache__/app.cpython-314.pyc and b/__pycache__/app.cpython-314.pyc differ
|
|
|
app.py
CHANGED
|
@@ -27,7 +27,7 @@ def run_model(key: str, prompt: str, max_new_tokens: int, **options) -> tuple[st
|
|
| 27 |
inputs = tokenizer(prompt, return_tensors="pt", return_token_type_ids=False).to(DEVICE)
|
| 28 |
input_length = inputs["input_ids"].shape[1]
|
| 29 |
if input_length + max_new_tokens > model.config.seq_len:
|
| 30 |
-
raise gr.Error("
|
| 31 |
start = time.perf_counter()
|
| 32 |
with torch.inference_mode():
|
| 33 |
output = model.generate(
|
|
@@ -38,23 +38,23 @@ def run_model(key: str, prompt: str, max_new_tokens: int, **options) -> tuple[st
|
|
| 38 |
text = tokenizer.decode(generated, skip_special_tokens=True).strip()
|
| 39 |
elapsed = time.perf_counter() - start
|
| 40 |
print(f"{key}: input={input_length}, output={len(generated)}, seconds={elapsed:.2f}", flush=True)
|
| 41 |
-
return text, f"{input_length}
|
| 42 |
|
| 43 |
|
| 44 |
@spaces.GPU(duration=60)
|
| 45 |
-
def translate(text: str, direction: str = "
|
| 46 |
first_sentence: bool = True) -> tuple[str, str]:
|
| 47 |
"""Translate a short sentence between Indonesian and English using CALI's trained prompt format."""
|
| 48 |
if not text or not text.strip():
|
| 49 |
-
raise gr.Error("
|
| 50 |
-
if direction not in ("
|
| 51 |
-
raise gr.Error("
|
| 52 |
max_new_tokens = int(max_new_tokens)
|
| 53 |
if not 16 <= max_new_tokens <= 256:
|
| 54 |
-
raise gr.Error("
|
| 55 |
if len(text.split()) > 200:
|
| 56 |
-
raise gr.Error("
|
| 57 |
-
tag = "[idβen]" if direction == "
|
| 58 |
result, stats = run_model("translate", f"{tag}\n{text.strip()}\nβ", max_new_tokens,
|
| 59 |
do_sample=False, repetition_penalty=1.5, no_repeat_ngram_size=3)
|
| 60 |
if first_sentence:
|
|
@@ -67,10 +67,10 @@ def complete(prompt: str, max_new_tokens: int = 96, temperature: float = 0.7,
|
|
| 67 |
top_p: float = 0.9) -> tuple[str, str]:
|
| 68 |
"""Continue an Indonesian or English text prompt with the experimental CALI base language model."""
|
| 69 |
if not prompt or not prompt.strip():
|
| 70 |
-
raise gr.Error("
|
| 71 |
max_new_tokens = int(max_new_tokens)
|
| 72 |
if not 16 <= max_new_tokens <= 256 or not 0 <= temperature <= 1.5 or not 0.1 <= top_p <= 1:
|
| 73 |
-
raise gr.Error("
|
| 74 |
options = {"do_sample": temperature > 0, "repetition_penalty": 1.1}
|
| 75 |
if temperature > 0:
|
| 76 |
options.update(temperature=float(temperature), top_p=float(top_p))
|
|
@@ -78,41 +78,41 @@ def complete(prompt: str, max_new_tokens: int = 96, temperature: float = 0.7,
|
|
| 78 |
|
| 79 |
|
| 80 |
with gr.Blocks(title="cali") as demo:
|
| 81 |
-
gr.Markdown("# cali\
|
| 82 |
-
with gr.Tab("
|
| 83 |
-
gr.Markdown("###
|
| 84 |
-
direction = gr.Radio(["
|
| 85 |
with gr.Row():
|
| 86 |
-
source = gr.Textbox(label="
|
| 87 |
-
translated = gr.Textbox(label="
|
| 88 |
-
with gr.Accordion("
|
| 89 |
-
tokens = gr.Slider(16, 256, value=64, step=1, label="
|
| 90 |
-
first = gr.Checkbox(value=True, label="
|
| 91 |
-
translate_button = gr.Button("
|
| 92 |
-
translation_stats = gr.Textbox(label="
|
| 93 |
translate_button.click(translate, [source, direction, tokens, first], [translated, translation_stats], api_name="translate")
|
| 94 |
gr.Examples([
|
| 95 |
-
["Dia pergi ke pasar setiap pagi.", "
|
| 96 |
-
["Saya makan nasi.", "
|
| 97 |
-
["The weather is very cold today.", "English β
|
| 98 |
-
["She is happy.", "English β
|
| 99 |
], inputs=[source, direction], outputs=[translated, translation_stats], fn=translate,
|
| 100 |
cache_examples=True, cache_mode="lazy")
|
| 101 |
-
with gr.Tab("
|
| 102 |
-
gr.Markdown("###
|
| 103 |
-
prompt = gr.Textbox(label="
|
| 104 |
-
continuation = gr.Textbox(label="
|
| 105 |
-
with gr.Accordion("
|
| 106 |
-
base_tokens = gr.Slider(16, 256, value=96, step=1, label="
|
| 107 |
-
temperature = gr.Slider(0, 1.5, value=0.7, step=0.05, label="Temperature (0 =
|
| 108 |
top_p = gr.Slider(0.1, 1, value=0.9, step=0.05, label="Top-p")
|
| 109 |
-
generate_button = gr.Button("
|
| 110 |
-
base_stats = gr.Textbox(label="
|
| 111 |
generate_button.click(complete, [prompt, base_tokens, temperature, top_p], [continuation, base_stats], api_name="complete")
|
| 112 |
gr.Examples([["Indonesia adalah negara yang"], ["The sun rises in the"]],
|
| 113 |
inputs=[prompt], outputs=[continuation, base_stats], fn=complete,
|
| 114 |
cache_examples=True, cache_mode="lazy")
|
| 115 |
-
gr.Markdown("Model: [CALI Translate](https://huggingface.co/Sandroeth/cali-id-en-translate) Β· [CALI-0.1B](https://huggingface.co/Sandroeth/cali-0.1B) Β·
|
| 116 |
|
| 117 |
if __name__ == "__main__":
|
| 118 |
demo.queue(max_size=20, default_concurrency_limit=1).launch(mcp_server=True)
|
|
|
|
| 27 |
inputs = tokenizer(prompt, return_tensors="pt", return_token_type_ids=False).to(DEVICE)
|
| 28 |
input_length = inputs["input_ids"].shape[1]
|
| 29 |
if input_length + max_new_tokens > model.config.seq_len:
|
| 30 |
+
raise gr.Error("Text is too long. Shorten the input or reduce the output limit (1024 tokens total).")
|
| 31 |
start = time.perf_counter()
|
| 32 |
with torch.inference_mode():
|
| 33 |
output = model.generate(
|
|
|
|
| 38 |
text = tokenizer.decode(generated, skip_special_tokens=True).strip()
|
| 39 |
elapsed = time.perf_counter() - start
|
| 40 |
print(f"{key}: input={input_length}, output={len(generated)}, seconds={elapsed:.2f}", flush=True)
|
| 41 |
+
return text, f"{input_length} input tokens Β· {len(generated)} output tokens Β· {elapsed:.2f} seconds"
|
| 42 |
|
| 43 |
|
| 44 |
@spaces.GPU(duration=60)
|
| 45 |
+
def translate(text: str, direction: str = "Indonesian β English", max_new_tokens: int = 64,
|
| 46 |
first_sentence: bool = True) -> tuple[str, str]:
|
| 47 |
"""Translate a short sentence between Indonesian and English using CALI's trained prompt format."""
|
| 48 |
if not text or not text.strip():
|
| 49 |
+
raise gr.Error("Enter the text you want to translate.")
|
| 50 |
+
if direction not in ("Indonesian β English", "English β Indonesian"):
|
| 51 |
+
raise gr.Error("Invalid translation direction.")
|
| 52 |
max_new_tokens = int(max_new_tokens)
|
| 53 |
if not 16 <= max_new_tokens <= 256:
|
| 54 |
+
raise gr.Error("Choose between 16 and 256 output tokens.")
|
| 55 |
if len(text.split()) > 200:
|
| 56 |
+
raise gr.Error("Use up to 200 words; this model is designed for short texts.")
|
| 57 |
+
tag = "[idβen]" if direction == "Indonesian β English" else "[enβid]"
|
| 58 |
result, stats = run_model("translate", f"{tag}\n{text.strip()}\nβ", max_new_tokens,
|
| 59 |
do_sample=False, repetition_penalty=1.5, no_repeat_ngram_size=3)
|
| 60 |
if first_sentence:
|
|
|
|
| 67 |
top_p: float = 0.9) -> tuple[str, str]:
|
| 68 |
"""Continue an Indonesian or English text prompt with the experimental CALI base language model."""
|
| 69 |
if not prompt or not prompt.strip():
|
| 70 |
+
raise gr.Error("Enter a text prompt to continue.")
|
| 71 |
max_new_tokens = int(max_new_tokens)
|
| 72 |
if not 16 <= max_new_tokens <= 256 or not 0 <= temperature <= 1.5 or not 0.1 <= top_p <= 1:
|
| 73 |
+
raise gr.Error("Generation settings are outside the supported range.")
|
| 74 |
options = {"do_sample": temperature > 0, "repetition_penalty": 1.1}
|
| 75 |
if temperature > 0:
|
| 76 |
options.update(temperature=float(temperature), top_p=float(top_p))
|
|
|
|
| 78 |
|
| 79 |
|
| 80 |
with gr.Blocks(title="cali") as demo:
|
| 81 |
+
gr.Markdown("# cali\nTwo lightweight models by **Sandroeth** for exploring Indonesian and English.")
|
| 82 |
+
with gr.Tab("Translation"):
|
| 83 |
+
gr.Markdown("### From one language to another\nBest for everyday sentences. Very short inputs (1β2 words), technical terms, and long passages may produce less accurate translations.")
|
| 84 |
+
direction = gr.Radio(["Indonesian β English", "English β Indonesian"], value="Indonesian β English", label="Translation direction")
|
| 85 |
with gr.Row():
|
| 86 |
+
source = gr.Textbox(label="Source text", lines=5, placeholder="Dia pergi ke pasar setiap pagi.", max_length=6000)
|
| 87 |
+
translated = gr.Textbox(label="Translation", lines=5, interactive=False)
|
| 88 |
+
with gr.Accordion("Settings", open=False):
|
| 89 |
+
tokens = gr.Slider(16, 256, value=64, step=1, label="Maximum output tokens")
|
| 90 |
+
first = gr.Checkbox(value=True, label="Return the first sentence only (matches the official example)")
|
| 91 |
+
translate_button = gr.Button("Translate", variant="primary")
|
| 92 |
+
translation_stats = gr.Textbox(label="Stats", interactive=False)
|
| 93 |
translate_button.click(translate, [source, direction, tokens, first], [translated, translation_stats], api_name="translate")
|
| 94 |
gr.Examples([
|
| 95 |
+
["Dia pergi ke pasar setiap pagi.", "Indonesian β English"],
|
| 96 |
+
["Saya makan nasi.", "Indonesian β English"],
|
| 97 |
+
["The weather is very cold today.", "English β Indonesian"],
|
| 98 |
+
["She is happy.", "English β Indonesian"],
|
| 99 |
], inputs=[source, direction], outputs=[translated, translation_stats], fn=translate,
|
| 100 |
cache_examples=True, cache_mode="lazy")
|
| 101 |
+
with gr.Tab("Explore CALI"):
|
| 102 |
+
gr.Markdown("### Continue a piece of text\nCALI-0.1B is an experimental base model. Start a sentence or paragraph and let it continue. Outputs may repeat or become inconsistent.")
|
| 103 |
+
prompt = gr.Textbox(label="Prompt", lines=4, placeholder="Indonesia adalah negara yang")
|
| 104 |
+
continuation = gr.Textbox(label="Generated continuation", lines=6, interactive=False)
|
| 105 |
+
with gr.Accordion("Settings", open=False):
|
| 106 |
+
base_tokens = gr.Slider(16, 256, value=96, step=1, label="Maximum output tokens")
|
| 107 |
+
temperature = gr.Slider(0, 1.5, value=0.7, step=0.05, label="Temperature (0 = deterministic)")
|
| 108 |
top_p = gr.Slider(0.1, 1, value=0.9, step=0.05, label="Top-p")
|
| 109 |
+
generate_button = gr.Button("Generate continuation", variant="primary")
|
| 110 |
+
base_stats = gr.Textbox(label="Stats", interactive=False)
|
| 111 |
generate_button.click(complete, [prompt, base_tokens, temperature, top_p], [continuation, base_stats], api_name="complete")
|
| 112 |
gr.Examples([["Indonesia adalah negara yang"], ["The sun rises in the"]],
|
| 113 |
inputs=[prompt], outputs=[continuation, base_stats], fn=complete,
|
| 114 |
cache_examples=True, cache_mode="lazy")
|
| 115 |
+
gr.Markdown("Model: [CALI Translate](https://huggingface.co/Sandroeth/cali-id-en-translate) Β· [CALI-0.1B](https://huggingface.co/Sandroeth/cali-0.1B) Β· Apache 2.0 license")
|
| 116 |
|
| 117 |
if __name__ == "__main__":
|
| 118 |
demo.queue(max_size=20, default_concurrency_limit=1).launch(mcp_server=True)
|