oddadmix commited on
Commit
5dd4d67
ยท
verified ยท
1 Parent(s): a112f99

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +10 -11
app.py CHANGED
@@ -4,9 +4,8 @@ Nawah-Reasoning-v1 โ€” Gradio demo.
4
  The prompt rendering (ChatML + BOS prepend) is IDENTICAL to train_reasoning.py. A 51M model
5
  is very sensitive to format drift, so do not change render_prompt() without changing training.
6
 
7
- Runs on CPU: the model is ~52M parameters, so a full answer takes a couple of seconds without
8
- a GPU. That is the point of the model, so the Space is deliberately CPU-only โ€” no `spaces`
9
- import, no ZeroGPU quota.
10
 
11
  The model emits <think>โ€ฆ</think> before its answer, so the stream is split live into two
12
  panels: the reasoning trace and the final answer.
@@ -19,6 +18,7 @@ import os
19
  import re
20
  import threading
21
 
 
22
  import gradio as gr
23
  import torch
24
  from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
@@ -32,18 +32,16 @@ HF_TOKEN = os.environ.get("MODEL_HF_TOKEN") or os.environ.get("HF_TOKEN")
32
 
33
  IM_START, IM_END = "<|im_start|>", "<|im_end|>"
34
  THINK_OPEN, THINK_CLOSE = "<think>", "</think>"
35
- MAX_NEW_TOKENS_CAP = 1500
36
 
37
  # โ”€โ”€ Load (once, at startup) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
 
39
- torch.set_num_threads(os.cpu_count() or 2)
40
-
41
  print("[*] token env vars present:",
42
  [k for k in ("MODEL_HF_TOKEN", "HF_TOKEN") if os.environ.get(k)] or "NONE")
43
  print(f"[*] Loading {MODEL_ID} ...")
44
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, token=HF_TOKEN)
45
- model = AutoModelForCausalLM.from_pretrained(MODEL_ID, dtype=torch.float32, token=HF_TOKEN)
46
- model.eval()
47
 
48
  CTX = getattr(model.config, "max_position_embeddings", 2048)
49
 
@@ -78,6 +76,7 @@ def split_stream(text: str):
78
 
79
  # โ”€โ”€ Generate โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
80
 
 
81
  def solve(question, max_new_tokens, temperature, repetition_penalty):
82
  question = (question or "").strip()
83
  if not question:
@@ -87,7 +86,7 @@ def solve(question, max_new_tokens, temperature, repetition_penalty):
87
  ids = tokenizer(render_prompt(question), add_special_tokens=False)["input_ids"]
88
  if tokenizer.bos_token_id is not None:
89
  ids = [tokenizer.bos_token_id] + ids # match training's explicit BOS
90
- input_ids = torch.tensor([ids])
91
 
92
  # skip_special_tokens must stay False โ€” <think>/</think> are real special tokens
93
  # in this tokenizer, and stripping them would destroy the split.
@@ -131,8 +130,8 @@ DESCRIPTION = """
131
  ุซู… ูŠุนุทูŠ ุงู„ุฅุฌุงุจุฉ ุงู„ู†ู‡ุงุฆูŠุฉ.<br>
132
  A ~52M-parameter Arabic reasoning model that thinks step by step inside
133
  <code>&lt;think&gt;</code> before answering.</p>
134
- <p><i>ูŠุนู…ู„ ุนู„ู‰ ุงู„ู…ุนุงู„ุฌ (CPU) ุจุฏูˆู† ูƒุฑุช ุฑุณูˆู…ุงุช โ€” ู‡ุฐุง ู‡ูˆ ุจูŠุช ุงู„ู‚ุตูŠุฏ.<br>
135
- Runs on CPU, no GPU needed โ€” that is the whole point.</i></p>
136
  </div>
137
  """
138
 
 
4
  The prompt rendering (ChatML + BOS prepend) is IDENTICAL to train_reasoning.py. A 51M model
5
  is very sensitive to format drift, so do not change render_prompt() without changing training.
6
 
7
+ Runs on ZeroGPU. The model is only ~52M parameters and works on CPU too, but ZeroGPU keeps
8
+ responses snappy. `import spaces` must come BEFORE torch so it can patch the CUDA calls.
 
9
 
10
  The model emits <think>โ€ฆ</think> before its answer, so the stream is split live into two
11
  panels: the reasoning trace and the final answer.
 
18
  import re
19
  import threading
20
 
21
+ import spaces # import BEFORE torch so it can patch CUDA calls
22
  import gradio as gr
23
  import torch
24
  from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
 
32
 
33
  IM_START, IM_END = "<|im_start|>", "<|im_end|>"
34
  THINK_OPEN, THINK_CLOSE = "<think>", "</think>"
35
+ MAX_NEW_TOKENS_CAP = 512
36
 
37
  # โ”€โ”€ Load (once, at startup) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
 
 
 
39
  print("[*] token env vars present:",
40
  [k for k in ("MODEL_HF_TOKEN", "HF_TOKEN") if os.environ.get(k)] or "NONE")
41
  print(f"[*] Loading {MODEL_ID} ...")
42
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, token=HF_TOKEN)
43
+ model = AutoModelForCausalLM.from_pretrained(MODEL_ID, dtype=torch.bfloat16, token=HF_TOKEN)
44
+ model.to("cuda").eval()
45
 
46
  CTX = getattr(model.config, "max_position_embeddings", 2048)
47
 
 
76
 
77
  # โ”€โ”€ Generate โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
78
 
79
+ @spaces.GPU(duration=60)
80
  def solve(question, max_new_tokens, temperature, repetition_penalty):
81
  question = (question or "").strip()
82
  if not question:
 
86
  ids = tokenizer(render_prompt(question), add_special_tokens=False)["input_ids"]
87
  if tokenizer.bos_token_id is not None:
88
  ids = [tokenizer.bos_token_id] + ids # match training's explicit BOS
89
+ input_ids = torch.tensor([ids], device=model.device)
90
 
91
  # skip_special_tokens must stay False โ€” <think>/</think> are real special tokens
92
  # in this tokenizer, and stripping them would destroy the split.
 
130
  ุซู… ูŠุนุทูŠ ุงู„ุฅุฌุงุจุฉ ุงู„ู†ู‡ุงุฆูŠุฉ.<br>
131
  A ~52M-parameter Arabic reasoning model that thinks step by step inside
132
  <code>&lt;think&gt;</code> before answering.</p>
133
+ <p><i>ู†ู…ูˆุฐุฌ ุตุบูŠุฑ ุจู…ุง ูŠูƒููŠ ู„ูŠุนู…ู„ ุญุชู‰ ุนู„ู‰ ุงู„ู…ุนุงู„ุฌ (CPU).<br>
134
+ Small enough to run on a CPU โ€” this Space uses ZeroGPU for snappier responses.</i></p>
135
  </div>
136
  """
137