Curious-PM commited on
Commit
ac2728e
·
verified ·
1 Parent(s): 23b42e6

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +23 -18
app.py CHANGED
@@ -13,7 +13,8 @@ from transformers import AutoModelForCausalLM, AutoTokenizer
13
  BASE = "Qwen/Qwen2.5-3B-Instruct"
14
  LORA = "Curious-PM/lexwell-contract-irac-qwen2.5-3b-lora"
15
 
16
- SYSTEM_PROMPT = (
 
17
  "You are an associate at Lexwell Advisors, a contract-review advisory "
18
  "firm for SMBs. Reply in Lexwell's house IRAC format with required top "
19
  "and bottom disclaimers."
@@ -33,22 +34,24 @@ def _decode(out, input_len):
33
  return tokenizer.decode(out[0][input_len:], skip_special_tokens=True)
34
 
35
 
 
 
 
 
 
 
 
 
 
 
 
36
  @spaces.GPU(duration=120)
37
  def generate_both(question):
38
  if not question or not question.strip():
39
  placeholder = "_Type a contract question first._"
40
  return placeholder, placeholder
41
 
42
- msgs = [
43
- {"role": "system", "content": SYSTEM_PROMPT},
44
- {"role": "user", "content": question.strip()},
45
- ]
46
- text = tokenizer.apply_chat_template(
47
- msgs, tokenize=False, add_generation_prompt=True
48
- )
49
- inputs = tokenizer(text, return_tensors="pt").to("cuda")
50
  model.to("cuda")
51
- input_len = inputs.input_ids.shape[1]
52
 
53
  gen_kwargs = dict(
54
  max_new_tokens=600,
@@ -56,16 +59,18 @@ def generate_both(question):
56
  pad_token_id=tokenizer.eos_token_id,
57
  )
58
 
59
- # LEFT — base model (adapter disabled)
 
60
  with model.disable_adapter():
61
  with torch.no_grad():
62
- base_out = model.generate(**inputs, **gen_kwargs)
63
- base_reply = _decode(base_out, input_len)
64
 
65
- # RIGHT — fine-tuned (adapter on)
 
66
  with torch.no_grad():
67
- ft_out = model.generate(**inputs, **gen_kwargs)
68
- ft_reply = _decode(ft_out, input_len)
69
 
70
  return base_reply, ft_reply
71
 
@@ -371,7 +376,7 @@ with gr.Blocks(title="Junior Associate · Stay Curious", css=CSS, theme=gr.theme
371
  gr.HTML(
372
  '<div class="lane-header">'
373
  ' <div class="lane-title">Base Qwen 2.5-3B</div>'
374
- ' <div class="lane-meta">no fine-tuning · prompt only</div>'
375
  '</div>'
376
  )
377
  base_output = gr.Markdown(value=PLACEHOLDER, elem_classes="lane-body")
@@ -380,7 +385,7 @@ with gr.Blocks(title="Junior Associate · Stay Curious", css=CSS, theme=gr.theme
380
  gr.HTML(
381
  '<div class="lane-header">'
382
  ' <div class="lane-title">+ LoRA adapter (fine-tuned)</div>'
383
- ' <div class="lane-meta">trained on 80 contract-review memos</div>'
384
  '</div>'
385
  )
386
  ft_output = gr.Markdown(value=PLACEHOLDER, elem_classes="lane-body")
 
13
  BASE = "Qwen/Qwen2.5-3B-Instruct"
14
  LORA = "Curious-PM/lexwell-contract-irac-qwen2.5-3b-lora"
15
 
16
+ BASE_PROMPT = "You are a helpful assistant."
17
+ FT_PROMPT = (
18
  "You are an associate at Lexwell Advisors, a contract-review advisory "
19
  "firm for SMBs. Reply in Lexwell's house IRAC format with required top "
20
  "and bottom disclaimers."
 
34
  return tokenizer.decode(out[0][input_len:], skip_special_tokens=True)
35
 
36
 
37
+ def _prepare_inputs(system_prompt, user_question):
38
+ msgs = [
39
+ {"role": "system", "content": system_prompt},
40
+ {"role": "user", "content": user_question.strip()},
41
+ ]
42
+ text = tokenizer.apply_chat_template(
43
+ msgs, tokenize=False, add_generation_prompt=True
44
+ )
45
+ return tokenizer(text, return_tensors="pt").to("cuda")
46
+
47
+
48
  @spaces.GPU(duration=120)
49
  def generate_both(question):
50
  if not question or not question.strip():
51
  placeholder = "_Type a contract question first._"
52
  return placeholder, placeholder
53
 
 
 
 
 
 
 
 
 
54
  model.to("cuda")
 
55
 
56
  gen_kwargs = dict(
57
  max_new_tokens=600,
 
59
  pad_token_id=tokenizer.eos_token_id,
60
  )
61
 
62
+ # LEFT — base model + generic "helpful assistant" prompt
63
+ base_inputs = _prepare_inputs(BASE_PROMPT, question)
64
  with model.disable_adapter():
65
  with torch.no_grad():
66
+ base_out = model.generate(**base_inputs, **gen_kwargs)
67
+ base_reply = _decode(base_out, base_inputs.input_ids.shape[1])
68
 
69
+ # RIGHT — fine-tuned + specific Lexwell prompt
70
+ ft_inputs = _prepare_inputs(FT_PROMPT, question)
71
  with torch.no_grad():
72
+ ft_out = model.generate(**ft_inputs, **gen_kwargs)
73
+ ft_reply = _decode(ft_out, ft_inputs.input_ids.shape[1])
74
 
75
  return base_reply, ft_reply
76
 
 
376
  gr.HTML(
377
  '<div class="lane-header">'
378
  ' <div class="lane-title">Base Qwen 2.5-3B</div>'
379
+ ' <div class="lane-meta">system: <code>&ldquo;You are a helpful assistant.&rdquo;</code></div>'
380
  '</div>'
381
  )
382
  base_output = gr.Markdown(value=PLACEHOLDER, elem_classes="lane-body")
 
385
  gr.HTML(
386
  '<div class="lane-header">'
387
  ' <div class="lane-title">+ LoRA adapter (fine-tuned)</div>'
388
+ ' <div class="lane-meta">system: <code>&ldquo;You are an associate at Lexwell Advisors&hellip;&rdquo;</code></div>'
389
  '</div>'
390
  )
391
  ft_output = gr.Markdown(value=PLACEHOLDER, elem_classes="lane-body")