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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -15
app.py CHANGED
@@ -23,8 +23,24 @@ model = AutoModelForCausalLM.from_pretrained(
23
  )
24
  model.eval()
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- def build_prompt(message, history):
28
  """
29
  I Gradio 6 är history en lista av dicts:
30
  [
@@ -32,10 +48,16 @@ def build_prompt(message, history):
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", "")
@@ -52,7 +74,7 @@ def build_prompt(message, history):
52
  else:
53
  text = str(content)
54
 
55
- if text:
56
  messages.append({"role": role, "content": text})
57
 
58
  # nuvarande användarmeddelande
@@ -66,37 +88,107 @@ def build_prompt(message, history):
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__":
 
23
  )
24
  model.eval()
25
 
26
+ # Några stil-lägen som systemprompter
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
  I Gradio 6 är history en lista av dicts:
46
  [
 
48
  {"role": "assistant", "content": [...]},
49
  ...
50
  ]
51
+ Vi plockar ut texten och mappar till {role, content}, och lägger till en systemprompt
52
+ baserat på vald 'style'.
53
  """
54
  messages = []
55
 
56
+ # Lägg till system / style prompt
57
+ system_prompt = STYLE_SYSTEM_PROMPTS.get(style, STYLE_SYSTEM_PROMPTS["Default"])
58
+ messages.append({"role": "system", "content": system_prompt})
59
+
60
+ # Tidigare historik
61
  for msg in history:
62
  role = msg.get("role")
63
  content = msg.get("content", "")
 
74
  else:
75
  text = str(content)
76
 
77
+ if text and role in ("user", "assistant", "system"):
78
  messages.append({"role": role, "content": text})
79
 
80
  # nuvarande användarmeddelande
 
88
  return prompt
89
 
90
 
91
+ def chat_fn(message, history, max_new_tokens, temperature, top_p, repetition_penalty, style):
92
+ # Bygg prompt med historik + stil
93
+ prompt = build_prompt(message, history, style)
94
 
95
  inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
96
 
97
+ gen_kwargs = {
98
+ **inputs,
99
+ "max_new_tokens": int(max_new_tokens),
100
+ "pad_token_id": tokenizer.eos_token_id,
101
+ "eos_token_id": tokenizer.eos_token_id,
102
+ "repetition_penalty": float(repetition_penalty),
103
+ }
104
+
105
+ # Deterministisk om temperature == 0, annars sampling
106
+ if temperature <= 0.0:
107
+ gen_kwargs.update(
108
+ dict(
109
+ do_sample=False,
110
+ temperature=None,
111
+ top_p=None,
112
+ )
113
+ )
114
+ else:
115
+ gen_kwargs.update(
116
+ dict(
117
+ do_sample=True,
118
+ temperature=float(temperature),
119
+ top_p=float(top_p),
120
+ )
121
  )
122
 
123
+ with torch.no_grad():
124
+ outputs = model.generate(**gen_kwargs)
125
+
126
  generated = tokenizer.decode(
127
  outputs[0][inputs["input_ids"].shape[1]:],
128
  skip_special_tokens=True,
129
  ).strip()
130
 
131
+ # ChatInterface sköter history själv, vi returnerar bara svaret
132
  return generated
133
 
134
 
135
+ # DJ-reglagen (extra inputs till ChatInterface)
136
+ max_new_tokens_slider = gr.Slider(
137
+ minimum=16,
138
+ maximum=256,
139
+ value=64,
140
+ step=8,
141
+ label="Max new tokens (response length)",
142
+ )
143
+ temperature_slider = gr.Slider(
144
+ minimum=0.0,
145
+ maximum=1.5,
146
+ value=0.0,
147
+ step=0.1,
148
+ label="Temperature (0 = deterministic, higher = more random)",
149
+ )
150
+ top_p_slider = gr.Slider(
151
+ minimum=0.1,
152
+ maximum=1.0,
153
+ value=0.9,
154
+ step=0.05,
155
+ label="Top-p (nucleus sampling)",
156
+ )
157
+ repetition_penalty_slider = gr.Slider(
158
+ minimum=0.8,
159
+ maximum=1.3,
160
+ value=1.0,
161
+ step=0.05,
162
+ label="Repetition penalty",
163
+ )
164
+ style_radio = gr.Radio(
165
+ choices=[
166
+ "Default",
167
+ "Short answer",
168
+ "Detailed explanation",
169
+ "Step-by-step reasoning",
170
+ ],
171
+ value="Detailed explanation",
172
+ label="Answer style",
173
+ )
174
+
175
  demo = gr.ChatInterface(
176
  fn=chat_fn,
177
  title="Lab 2 – Fine-tuned merged model (fp16)",
178
  description=(
179
  "Chat with our fine-tuned Llama-based model, merged to fp16 and "
180
+ "loaded from Jeppcode/ScalableLab2/merged-model-fp16.\n\n"
181
+ "Use the controls in the accordion below like a DJ board to tweak "
182
+ "response length, randomness and style."
183
  ),
184
+ additional_inputs=[
185
+ max_new_tokens_slider,
186
+ temperature_slider,
187
+ top_p_slider,
188
+ repetition_penalty_slider,
189
+ style_radio,
190
+ ],
191
+ additional_inputs_accordion="Generation controls",
192
  )
193
 
194
  if __name__ == "__main__":