Jeppcode commited on
Commit
eca64ae
·
verified ·
1 Parent(s): a8f20e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -147
app.py CHANGED
@@ -7,61 +7,57 @@ SUBFOLDER = "merged-model-fp16"
7
 
8
  print(f"Loading model {MODEL_ID}/{SUBFOLDER} ...")
9
 
10
- # Load tokenizer
11
  tokenizer = AutoTokenizer.from_pretrained(
12
  MODEL_ID,
13
  subfolder=SUBFOLDER,
14
  )
15
 
16
- # Load model (fp16 on CPU to fit in HF Space)
17
  model = AutoModelForCausalLM.from_pretrained(
18
  MODEL_ID,
19
  subfolder=SUBFOLDER,
20
- dtype=torch.float16, # use dtype (torch_dtype is deprecated)
21
  low_cpu_mem_usage=True,
22
- device_map="cpu",
23
  )
24
  model.eval()
25
 
26
- # Predefined “styles” as system prompts
27
- STYLE_SYSTEM_PROMPTS = {
28
- "Default": "You are a helpful, polite assistant.",
29
- "Short answer": (
30
- "You are a helpful assistant. Answer as concisely as possible, usually in 1–3 sentences."
31
- ),
32
- "Detailed explanation": (
33
- "You are a helpful teaching assistant. Give clear, structured and detailed explanations, "
34
- "often with bullet points or numbered steps when useful."
35
- ),
36
- "Step-by-step reasoning": (
37
- "You are a careful problem solver. Think step by step and explain your reasoning clearly "
38
- "before giving the final answer."
39
- ),
40
- }
41
 
42
-
43
- def build_prompt(message, history, style):
44
  """
45
- history is a list of [user, bot] pairs (Gradio's default Chatbot format).
46
- We convert it into a list of role/content messages for the chat template.
 
 
 
 
 
47
  """
48
  messages = []
49
 
50
- # Add system / style message
51
- system_prompt = STYLE_SYSTEM_PROMPTS.get(style, STYLE_SYSTEM_PROMPTS["Default"])
52
- messages.append({"role": "system", "content": system_prompt})
53
-
54
- # Add previous conversation
55
- for user_msg, bot_msg in history:
56
- if user_msg is not None:
57
- messages.append({"role": "user", "content": user_msg})
58
- if bot_msg is not None:
59
- messages.append({"role": "assistant", "content": bot_msg})
60
-
61
- # Current user message
 
 
 
 
 
 
 
 
62
  messages.append({"role": "user", "content": message})
63
 
64
- # Use chat_template from your tokenizer
65
  prompt = tokenizer.apply_chat_template(
66
  messages,
67
  tokenize=False,
@@ -70,130 +66,38 @@ def build_prompt(message, history, style):
70
  return prompt
71
 
72
 
73
- def chat_fn(message, history, max_new_tokens, temperature, top_p, repetition_penalty, style):
74
- # Build full prompt including history + style
75
- prompt = build_prompt(message, history, style)
76
 
77
  inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
78
 
79
- gen_kwargs = {
80
- **inputs,
81
- "max_new_tokens": int(max_new_tokens),
82
- "pad_token_id": tokenizer.eos_token_id,
83
- "eos_token_id": tokenizer.eos_token_id,
84
- "repetition_penalty": float(repetition_penalty),
85
- }
86
-
87
- # Deterministic if temperature == 0, otherwise sampling
88
- if temperature <= 0.0:
89
- gen_kwargs.update(
90
- dict(
91
- do_sample=False,
92
- temperature=None,
93
- top_p=None,
94
- )
95
- )
96
- else:
97
- gen_kwargs.update(
98
- dict(
99
- do_sample=True,
100
- temperature=float(temperature),
101
- top_p=float(top_p),
102
- )
103
- )
104
-
105
  with torch.no_grad():
106
- outputs = model.generate(**gen_kwargs)
 
 
 
 
 
 
 
 
107
 
108
  generated = tokenizer.decode(
109
  outputs[0][inputs["input_ids"].shape[1]:],
110
  skip_special_tokens=True,
111
  ).strip()
112
 
113
- # Update history in the default (user, bot) format
114
- history = history + [[message, generated]]
115
-
116
- # Return empty textbox + updated chat history
117
- return "", history
118
 
119
 
120
- with gr.Blocks() as demo:
121
- gr.Markdown(
122
- "# Lab 2 – Fine-tuned merged model (fp16)\n"
 
123
  "Chat with our fine-tuned Llama-based model, merged to fp16 and "
124
- "loaded from `Jeppcode/ScalableLab2/merged-model-fp16`.\n\n"
125
- "Use the controls on the right like a DJ board to see how decoding "
126
- "settings change the behaviour of the model."
127
- )
128
-
129
- with gr.Row():
130
- # Left side: chatbot
131
- with gr.Column(scale=3):
132
- chatbot = gr.Chatbot(label="Chat") # no 'type' argument
133
- msg = gr.Textbox(
134
- label="Your message",
135
- placeholder="Ask the model something...",
136
- lines=3,
137
- )
138
- send_btn = gr.Button("Send")
139
- clear_btn = gr.Button("Clear chat")
140
-
141
- # Right side: generation settings (DJ board)
142
- with gr.Column(scale=1):
143
- gr.Markdown("### Generation controls")
144
-
145
- max_new_tokens = gr.Slider(
146
- minimum=16,
147
- maximum=256,
148
- value=64,
149
- step=8,
150
- label="Max new tokens (response length)",
151
- )
152
- temperature = gr.Slider(
153
- minimum=0.0,
154
- maximum=1.5,
155
- value=0.0,
156
- step=0.1,
157
- label="Temperature (0 = deterministic, higher = more random)",
158
- )
159
- top_p = gr.Slider(
160
- minimum=0.1,
161
- maximum=1.0,
162
- value=0.9,
163
- step=0.05,
164
- label="Top-p (nucleus sampling)",
165
- )
166
- repetition_penalty = gr.Slider(
167
- minimum=0.8,
168
- maximum=1.3,
169
- value=1.0,
170
- step=0.05,
171
- label="Repetition penalty",
172
- )
173
-
174
- style = gr.Radio(
175
- choices=[
176
- "Default",
177
- "Short answer",
178
- "Detailed explanation",
179
- "Step-by-step reasoning",
180
- ],
181
- value="Detailed explanation",
182
- label="Answer style",
183
- )
184
-
185
- # Hook up buttons / enter key
186
- send_btn.click(
187
- chat_fn,
188
- inputs=[msg, chatbot, max_new_tokens, temperature, top_p, repetition_penalty, style],
189
- outputs=[msg, chatbot],
190
- )
191
- msg.submit(
192
- chat_fn,
193
- inputs=[msg, chatbot, max_new_tokens, temperature, top_p, repetition_penalty, style],
194
- outputs=[msg, chatbot],
195
- )
196
- clear_btn.click(lambda: [], None, chatbot)
197
 
198
  if __name__ == "__main__":
199
  demo.launch()
 
7
 
8
  print(f"Loading model {MODEL_ID}/{SUBFOLDER} ...")
9
 
10
+ # Tokenizer
11
  tokenizer = AutoTokenizer.from_pretrained(
12
  MODEL_ID,
13
  subfolder=SUBFOLDER,
14
  )
15
 
16
+ # Modell fp16 och snålare CPU
17
  model = AutoModelForCausalLM.from_pretrained(
18
  MODEL_ID,
19
  subfolder=SUBFOLDER,
20
+ dtype=torch.float16, # samma som torch_dtype men utan varningen
21
  low_cpu_mem_usage=True,
22
+ device_map="cpu", # var explicit, allt på CPU
23
  )
24
  model.eval()
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ def build_prompt(message, history):
 
28
  """
29
+ I Gradio 6 är history en lista av dicts:
30
+ [
31
+ {"role": "user", "content": [...]},
32
+ {"role": "assistant", "content": [...]},
33
+ ...
34
+ ]
35
+ Vi plockar ut texten och mappar till {role, content}.
36
  """
37
  messages = []
38
 
39
+ for msg in history:
40
+ role = msg.get("role")
41
+ content = msg.get("content", "")
42
+
43
+ # content kan vara en lista av blocks eller en sträng
44
+ if isinstance(content, list):
45
+ texts = []
46
+ for block in content:
47
+ if isinstance(block, dict) and block.get("type") == "text":
48
+ texts.append(block.get("text", ""))
49
+ else:
50
+ texts.append(str(block))
51
+ text = "\n".join(t for t in texts if t)
52
+ else:
53
+ text = str(content)
54
+
55
+ if text:
56
+ messages.append({"role": role, "content": text})
57
+
58
+ # nuvarande användarmeddelande
59
  messages.append({"role": "user", "content": message})
60
 
 
61
  prompt = tokenizer.apply_chat_template(
62
  messages,
63
  tokenize=False,
 
66
  return prompt
67
 
68
 
69
+ def chat_fn(message, history):
70
+ prompt = build_prompt(message, history)
 
71
 
72
  inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  with torch.no_grad():
75
+ outputs = model.generate(
76
+ **inputs,
77
+ max_new_tokens=64, # kortare svar för snabbare CPU
78
+ do_sample=False, # deterministiskt
79
+ temperature=None,
80
+ top_p=None,
81
+ pad_token_id=tokenizer.eos_token_id,
82
+ eos_token_id=tokenizer.eos_token_id,
83
+ )
84
 
85
  generated = tokenizer.decode(
86
  outputs[0][inputs["input_ids"].shape[1]:],
87
  skip_special_tokens=True,
88
  ).strip()
89
 
90
+ return generated
 
 
 
 
91
 
92
 
93
+ demo = gr.ChatInterface(
94
+ fn=chat_fn,
95
+ title="Lab 2 – Fine-tuned merged model (fp16)",
96
+ description=(
97
  "Chat with our fine-tuned Llama-based model, merged to fp16 and "
98
+ "loaded from Jeppcode/ScalableLab2/merged-model-fp16."
99
+ ),
100
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  if __name__ == "__main__":
103
  demo.launch()