Justin commited on
Commit
09898d7
·
1 Parent(s): db4d3df

Removed requirements ... more pt 3

Browse files
Files changed (1) hide show
  1. app.py +131 -0
app.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from pydantic import BaseModel
4
+ from typing import List, Optional
5
+ import torch
6
+ from transformers import AutoModelForCausalLM, AutoTokenizer
7
+ import re
8
+ import os
9
+
10
+ app = FastAPI()
11
+
12
+ # Enable CORS for frontend access
13
+ app.add_middleware(
14
+ CORSMiddleware,
15
+ allow_origins=["*"], # Or specify your frontend domain
16
+ allow_credentials=True,
17
+ allow_methods=["*"],
18
+ allow_headers=["*"],
19
+ )
20
+
21
+ # Hugging Face model config
22
+ REPO_NAME = "jaydatech/phi3-finetuned-project"
23
+ HF_TOKEN = os.getenv("HF_TOKEN") # Load from Render environment variable
24
+
25
+ device = "cuda" if torch.cuda.is_available() else "cpu"
26
+
27
+ tokenizer = AutoTokenizer.from_pretrained(REPO_NAME, token=HF_TOKEN)
28
+ model = AutoModelForCausalLM.from_pretrained(
29
+ REPO_NAME,
30
+ token=HF_TOKEN,
31
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
32
+ device_map="auto"
33
+ )
34
+
35
+ # Message and request models
36
+ class ChatMessage(BaseModel):
37
+ role: str
38
+ text: str
39
+
40
+ class ChatRequest(BaseModel):
41
+ message: str
42
+ history: Optional[List[ChatMessage]] = []
43
+
44
+ def is_farewell(message: str) -> bool:
45
+ farewells = ["bye", "goodbye", "see you", "farewell", "exit", "quit", "end"]
46
+ message_lower = message.lower().strip()
47
+ return any(farewell in message_lower for farewell in farewells)
48
+
49
+ @app.post("/chat")
50
+ async def chat(request: ChatRequest):
51
+ try:
52
+ history = request.history
53
+ user_message = request.message
54
+
55
+ if is_farewell(user_message):
56
+ return {
57
+ "response": "Goodbye! Feel free to chat again if you have more questions.",
58
+ "terminate": True
59
+ }
60
+
61
+ conversation = (
62
+ "<|system|>\nYou are an AI assistant for the Federal Reserve Bank of St. Louis. "
63
+ "Answer questions based ONLY on your knowledge of the Federal Reserve Bank of St. Louis. "
64
+ "If the answer is NOT in the training data, respond with: 'I don't think this information is available. Maybe rephrase for me!'. "
65
+ "Answer ONLY what the user asks. Do not volunteer information unless specifically requested. "
66
+ "Do NOT ask: 'How can I assist you today?' after every response you give. "
67
+ "Provide concise answers to the exact question asked and nothing more.\n"
68
+ )
69
+
70
+ seen_messages = set()
71
+ for msg in history:
72
+ if msg.role == "user" and msg.text.strip() not in seen_messages:
73
+ conversation += f"<|user|>\n{msg.text.strip()}\n"
74
+ seen_messages.add(msg.text.strip())
75
+ elif msg.role == "model":
76
+ conversation += f"<|assistant|>\n{msg.text.strip()}\n"
77
+
78
+ conversation += f"<|user|>\n{user_message.strip()}\n<|assistant|>"
79
+
80
+ inputs = tokenizer(conversation, return_tensors="pt", padding=True, truncation=True, max_length=4096).to(device)
81
+
82
+ with torch.no_grad():
83
+ outputs = model.generate(
84
+ **inputs,
85
+ max_new_tokens=130,
86
+ do_sample=True,
87
+ temperature=0.1,
88
+ top_k=5,
89
+ pad_token_id=tokenizer.eos_token_id
90
+ )
91
+
92
+ full_response = tokenizer.decode(outputs[0], skip_special_tokens=False)
93
+ assistant_response = ""
94
+
95
+ if "<|assistant|>" in full_response:
96
+ assistant_sections = full_response.split("<|assistant|>")
97
+ for section in reversed(assistant_sections):
98
+ cleaned = section.strip()
99
+ if cleaned:
100
+ cleaned = re.split(
101
+ r"(<\|user\|>|<\|system\|>|<\|assistant\|>|\nuser[:\s]|<\|endoftext\|>)",
102
+ cleaned
103
+ )[0]
104
+ cleaned = re.sub(r"\n?(User|Assistant)\s*[::\-–]\s*.*", "", cleaned, flags=re.IGNORECASE).strip()
105
+ assistant_response = cleaned
106
+ break
107
+
108
+ if not assistant_response:
109
+ assistant_response = "⚠️ Sorry, I couldn't generate a response."
110
+
111
+ assistant_response = re.sub(r'\*\* Instruction \*\*:.*?(?=\n\n|\n$|$)', '', assistant_response, flags=re.DOTALL)
112
+ assistant_response = re.sub(r'\*\* Instruction \*\*.*?(?=\n\n|\n$|$)', '', assistant_response, flags=re.DOTALL)
113
+ assistant_response = re.sub(r'\n{3,}', '\n\n', assistant_response).strip()
114
+ assistant_response = re.sub(r"(How can I assist you today\?|What else can I help you with\?|How can I help you today\?)", "", assistant_response, flags=re.IGNORECASE).strip()
115
+
116
+ def remove_repeated_sentences(response):
117
+ sentences = response.split(". ")
118
+ seen = set()
119
+ cleaned = []
120
+ for sentence in sentences:
121
+ if sentence not in seen:
122
+ cleaned.append(sentence)
123
+ seen.add(sentence)
124
+ return ". ".join(cleaned)
125
+
126
+ assistant_response = remove_repeated_sentences(assistant_response)
127
+
128
+ return {"response": assistant_response}
129
+
130
+ except Exception as e:
131
+ raise HTTPException(status_code=500, detail=str(e))