Yoel125 commited on
Commit
e3e85f6
·
verified ·
1 Parent(s): b8c3f18

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -29
app.py CHANGED
@@ -7,15 +7,14 @@ import re
7
  from datasets import load_dataset
8
  from sentence_transformers import SentenceTransformer
9
  import faiss
10
- from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
11
  import spaces # <--- Import the Hugging Face spaces library for Free GPU
12
 
13
  # =========================================================================
14
  # 1. LAZY LOADING ARCHITECTURE (The Ultimate Fix for Smart AI)
15
- # To get a truly "smart" pitch, we MUST use the heavier 'flan-t5-base' model.
16
- # But loading heavy models during startup crashes Hugging Face.
17
- # The solution: We load the app instantly, and only load the heavy AI into
18
- # memory when you click Search for the first time!
19
  # =========================================================================
20
 
21
  # Load the dataset globally so the UI Dropdown knows what sectors exist
@@ -50,58 +49,66 @@ def get_ai_models():
50
  faiss_index_cache.add(np.array(embeddings).astype('float32'))
51
 
52
  if gen_model_cache is None:
53
- print("Lazy-loading Smarter GenAI Model (flan-t5-base)...")
54
- # UPGRADED back to the much smarter 'base' model!
55
- gen_tokenizer_cache = AutoTokenizer.from_pretrained("google/flan-t5-base")
56
- gen_model_cache = AutoModelForSeq2SeqLM.from_pretrained("google/flan-t5-base")
57
  gen_model_cache.eval()
58
 
59
  return embedding_model_cache, faiss_index_cache, gen_tokenizer_cache, gen_model_cache
60
 
61
 
62
  def generate_sales_pitch(user_query, company_name, sector, theme, description, tokenizer, model):
63
- # Now that we have the smarter 'base' model, we give it a strict prompt
64
- # forcing it to act like an aggressive, smart Wall Street analyst.
65
- prompt = (
66
- f"Task: Write a creative, aggressive sales pitch explaining why this company is the ultimate investment for the '{user_query}' market. Do not summarize the company.\n"
67
- f"Company Name: {company_name}\n"
68
- f"Industry: {theme}\n"
69
- f"Profile: {description[:200]}\n"
70
- f"Pitch:"
71
- )
 
72
 
73
  try:
74
- device = "cuda" if torch.cuda.is_available() else "cpu"
75
  model.to(device)
76
- inputs = tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True).to(device)
77
 
 
78
  torch.manual_seed(42)
 
 
 
 
79
 
80
  with torch.no_grad():
81
  outputs = model.generate(
82
  **inputs,
83
  max_new_tokens=75,
84
  do_sample=False,
85
- num_beams=4,
86
- repetition_penalty=1.5,
87
- early_stopping=True
88
  )
89
- pitch = tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
 
90
 
91
- pitch = pitch.replace("Pitch:", "").replace("Sales Pitch:", "").strip()
92
  if pitch and pitch[0] == '"' and pitch[-1] == '"':
93
  pitch = pitch[1:-1]
94
 
95
- # Ultimate fallback just in case it still tries to copy
96
- if len(pitch.split()) < 6 or pitch.lower() in description.lower():
97
- pitch = f"By leveraging their advanced {theme} capabilities, {company_name} is perfectly positioned to capture explosive growth and completely dominate the '{user_query}' space."
 
98
 
99
  if pitch:
100
  pitch = pitch[0].upper() + pitch[1:]
101
 
102
  return pitch
103
 
104
- except Exception:
 
105
  return f"By leveraging their advanced {theme} capabilities, {company_name} is perfectly positioned to capture explosive growth and completely dominate the '{user_query}' space."
106
 
107
 
 
7
  from datasets import load_dataset
8
  from sentence_transformers import SentenceTransformer
9
  import faiss
10
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForCausalLM
11
  import spaces # <--- Import the Hugging Face spaces library for Free GPU
12
 
13
  # =========================================================================
14
  # 1. LAZY LOADING ARCHITECTURE (The Ultimate Fix for Smart AI)
15
+ # To get a truly "smart" pitch, we MUST use a modern State-of-the-Art LLM.
16
+ # We are upgrading from the ancient 'flan-t5' to the brilliant 'Qwen2.5' model.
17
+ # By lazy loading, we ensure Hugging Face never crashes during startup!
 
18
  # =========================================================================
19
 
20
  # Load the dataset globally so the UI Dropdown knows what sectors exist
 
49
  faiss_index_cache.add(np.array(embeddings).astype('float32'))
50
 
51
  if gen_model_cache is None:
52
+ print("Lazy-loading State-of-the-Art GenAI Model (Qwen2.5-0.5B-Instruct)...")
53
+ # UPGRADED to a massively smarter, modern Causal LLM (ChatGPT equivalent for small models)
54
+ gen_tokenizer_cache = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
55
+ gen_model_cache = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct", torch_dtype="auto")
56
  gen_model_cache.eval()
57
 
58
  return embedding_model_cache, faiss_index_cache, gen_tokenizer_cache, gen_model_cache
59
 
60
 
61
  def generate_sales_pitch(user_query, company_name, sector, theme, description, tokenizer, model):
62
+ device = "cuda" if torch.cuda.is_available() else "cpu"
63
+
64
+ # Modern ChatML format used by state-of-the-art models like Qwen and Llama
65
+ messages = [
66
+ {"role": "system", "content": "You are a brilliant, aggressive Wall Street investment analyst. Your job is to write a single, highly persuasive, creative sentence explaining why a company is a massive investment opportunity."},
67
+ {"role": "user", "content": f"Company: {company_name}\nIndustry: {theme}\nWhat they do: {description[:300]}\n\nWrite a 1-sentence sales pitch explaining why this company is the ultimate strategic investment for someone focused on '{user_query}'. Do not just summarize what they do. Be creative and aggressive."}
68
+ ]
69
+
70
+ # Apply the exact chat template the model was trained on
71
+ prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
72
 
73
  try:
 
74
  model.to(device)
75
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
76
 
77
+ # 100% STRICT DETERMINISM: Forces the exact same brilliant output every time!
78
  torch.manual_seed(42)
79
+ if torch.cuda.is_available():
80
+ torch.cuda.manual_seed_all(42)
81
+ torch.backends.cudnn.deterministic = True
82
+ torch.backends.cudnn.benchmark = False
83
 
84
  with torch.no_grad():
85
  outputs = model.generate(
86
  **inputs,
87
  max_new_tokens=75,
88
  do_sample=False,
89
+ repetition_penalty=1.1,
 
 
90
  )
91
+
92
+ # Causal LMs output the prompt + generation. We slice off the prompt.
93
+ input_length = inputs.input_ids.shape[1]
94
+ pitch = tokenizer.decode(outputs[0][input_length:], skip_special_tokens=True).strip()
95
 
96
+ # Clean up quotes
97
  if pitch and pitch[0] == '"' and pitch[-1] == '"':
98
  pitch = pitch[1:-1]
99
 
100
+ # Just in case the AI gets chatty, force it to 1-2 sentences max
101
+ sentences = pitch.split(". ")
102
+ if len(sentences) > 2:
103
+ pitch = ". ".join(sentences[:2]) + "."
104
 
105
  if pitch:
106
  pitch = pitch[0].upper() + pitch[1:]
107
 
108
  return pitch
109
 
110
+ except Exception as e:
111
+ print(f"GenAI Generation Error: {e}")
112
  return f"By leveraging their advanced {theme} capabilities, {company_name} is perfectly positioned to capture explosive growth and completely dominate the '{user_query}' space."
113
 
114