Slothwolf commited on
Commit
4131912
·
verified ·
1 Parent(s): a40fcfd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -52
app.py CHANGED
@@ -1,69 +1,116 @@
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
 
4
 
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
 
19
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
20
 
21
- messages.extend(history)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- messages.append({"role": "user", "content": message})
 
 
 
 
24
 
 
25
  response = ""
 
 
26
 
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
 
33
  ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
 
39
- response += token
40
- yield response
 
 
 
 
 
 
 
41
 
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
  additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
  ],
 
 
 
 
 
 
60
  )
61
 
62
- with gr.Blocks() as demo:
63
- with gr.Sidebar():
64
- gr.LoginButton()
65
- chatbot.render()
66
-
67
-
68
  if __name__ == "__main__":
69
- demo.launch()
 
1
+ """
2
+ Gradio chat interface for nanochat models on Hugging Face Spaces.
3
+ Downloads the model from HF Hub and serves a streaming chat UI.
4
+ """
5
+
6
+ import os
7
+ import json
8
+ import random
9
+ import torch
10
  import gradio as gr
11
+ from huggingface_hub import snapshot_download
12
+
13
+ # ---------------------------------------------------------------------------
14
+ # Configuration
15
+ # ---------------------------------------------------------------------------
16
+ MODEL_REPO = os.environ.get("MODEL_REPO", "Slothwolf/MiniChat-0.9B")
17
+ MODEL_STEP = int(os.environ.get("MODEL_STEP", "486"))
18
+ DEFAULT_TEMPERATURE = float(os.environ.get("DEFAULT_TEMPERATURE", "0.8"))
19
+ DEFAULT_MAX_TOKENS = int(os.environ.get("DEFAULT_MAX_TOKENS", "1024"))
20
+ DEFAULT_TOP_K = int(os.environ.get("DEFAULT_TOP_K", "50"))
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Download and load model
24
+ # ---------------------------------------------------------------------------
25
+ print(f"Downloading model from {MODEL_REPO}...")
26
+ model_dir = snapshot_download(MODEL_REPO)
27
+
28
+ # Point nanochat at the downloaded directory so get_tokenizer() finds tokenizer/
29
+ os.environ["NANOCHAT_BASE_DIR"] = model_dir
30
 
31
+ from nanochat.checkpoint_manager import build_model
32
+ from nanochat.engine import Engine
33
 
34
+ print(f"Loading model (step {MODEL_STEP}) on CPU...")
35
+ device = torch.device("cpu")
36
+ model, tokenizer, meta = build_model(model_dir, MODEL_STEP, device, "eval")
37
+ engine = Engine(model, tokenizer)
38
+ print("Model loaded and ready!")
 
 
 
 
 
 
 
 
39
 
40
+ # Grab special token ids once
41
+ bos_id = tokenizer.get_bos_token_id()
42
+ user_start = tokenizer.encode_special("<|user_start|>")
43
+ user_end = tokenizer.encode_special("<|user_end|>")
44
+ assistant_start = tokenizer.encode_special("<|assistant_start|>")
45
+ assistant_end = tokenizer.encode_special("<|assistant_end|>")
46
 
47
+ # ---------------------------------------------------------------------------
48
+ # Chat function (streaming)
49
+ # ---------------------------------------------------------------------------
50
+ def chat(message, history, temperature, max_tokens, top_k):
51
+ """Generate a streaming response for the chat interface."""
52
+ # Build the full token sequence from conversation history
53
+ # history is a list of [user_msg, assistant_msg] tuples
54
+ tokens = [bos_id]
55
+ for user_msg, assistant_msg in history:
56
+ tokens.append(user_start)
57
+ tokens.extend(tokenizer.encode(user_msg))
58
+ tokens.append(user_end)
59
+ if assistant_msg:
60
+ tokens.append(assistant_start)
61
+ tokens.extend(tokenizer.encode(assistant_msg))
62
+ tokens.append(assistant_end)
63
 
64
+ # Add the current user message and prime the assistant
65
+ tokens.append(user_start)
66
+ tokens.extend(tokenizer.encode(message))
67
+ tokens.append(user_end)
68
+ tokens.append(assistant_start)
69
 
70
+ # Generate tokens with streaming
71
  response = ""
72
+ accumulated_tokens = []
73
+ last_clean_text = ""
74
 
75
+ for token_column, token_masks in engine.generate(
76
+ tokens,
77
+ num_samples=1,
78
+ max_tokens=int(max_tokens),
79
+ temperature=float(temperature),
80
+ top_k=int(top_k) if int(top_k) > 0 else None,
81
+ seed=random.randint(0, 2**31 - 1),
82
  ):
83
+ token = token_column[0]
84
+ if token == assistant_end or token == bos_id:
85
+ break
 
86
 
87
+ # Accumulate tokens and decode, handling multi-byte UTF-8
88
+ accumulated_tokens.append(token)
89
+ current_text = tokenizer.decode(accumulated_tokens)
90
+ if not current_text.endswith("\ufffd"):
91
+ new_text = current_text[len(last_clean_text):]
92
+ if new_text:
93
+ response += new_text
94
+ last_clean_text = current_text
95
+ yield response
96
 
97
+ # ---------------------------------------------------------------------------
98
+ # Gradio UI
99
+ # ---------------------------------------------------------------------------
100
+ demo = gr.ChatInterface(
101
+ chat,
 
102
  additional_inputs=[
103
+ gr.Slider(0.0, 2.0, value=DEFAULT_TEMPERATURE, step=0.1, label="Temperature"),
104
+ gr.Slider(1, 2048, value=DEFAULT_MAX_TOKENS, step=1, label="Max Tokens"),
105
+ gr.Slider(0, 200, value=DEFAULT_TOP_K, step=1, label="Top-K (0 = disabled)"),
 
 
 
 
 
 
 
106
  ],
107
+ title="MiniChat",
108
+ description=(
109
+ "Chat with a **0.9B parameter** GPT-like model trained with "
110
+ "[nanochat](https://github.com/karpathy/nanochat) by Andrej Karpathy. "
111
+ "Running on CPU — generation will be slow."
112
+ ),
113
  )
114
 
 
 
 
 
 
 
115
  if __name__ == "__main__":
116
+ demo.launch()