rudra0410hf commited on
Commit
3bcd4a2
·
verified ·
1 Parent(s): ec29e3f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +159 -0
app.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/main.py
2
+
3
+ import os
4
+ import time
5
+ import logging
6
+ from typing import Optional
7
+
8
+ from fastapi import FastAPI, HTTPException, Query
9
+ from pydantic import BaseModel
10
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, BitsAndBytesConfig
11
+
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger("biogpt_chatbot")
14
+
15
+ # =========================
16
+ # PROMPT TEMPLATES
17
+ # =========================
18
+ MEDICAL_PROMPTS = {
19
+ "dermatology": """
20
+ You are DermX-AI, a specialized medical AI assistant trained in dermatology.
21
+ Your role is to provide clear, evidence-based information about skin conditions,
22
+ diagnostic insights, and treatment options.
23
+
24
+ - Use simple but professional language, suitable for both patients and clinicians.
25
+ - When explaining, balance medical accuracy with user-friendly clarity.
26
+ - For any uncertain or critical cases, clearly advise consultation with a dermatologist.
27
+ - Always include safety reminders and disclaimers.
28
+ """,
29
+ "general": """
30
+ You are a medical AI assistant designed to provide helpful, evidence-based health information.
31
+ When answering:
32
+ - Ensure accuracy and clarity in medical explanations.
33
+ - Provide actionable lifestyle and preventive care suggestions where applicable.
34
+ - Avoid giving definitive diagnoses or prescriptions—always emphasize professional medical consultation.
35
+ - Be empathetic, supportive, and professional in tone.
36
+ """,
37
+ "disclaimer": """
38
+ ⚠️ Important: I am an AI medical assistant, not a licensed healthcare professional.
39
+ The information provided is for educational purposes only and should not be
40
+ considered a substitute for professional medical advice, diagnosis, or treatment.
41
+ Please consult a dermatologist or qualified healthcare provider for personalized care.
42
+ """,
43
+ }
44
+
45
+ # =========================
46
+ # FASTAPI SETUP
47
+ # =========================
48
+ class ChatRequest(BaseModel):
49
+ question: str
50
+ context: Optional[str] = None
51
+ mode: Optional[str] = "dermatology" # "dermatology" | "general"
52
+ max_new_tokens: Optional[int] = None
53
+ temperature: Optional[float] = None
54
+ top_p: Optional[float] = None
55
+
56
+ class ChatResponse(BaseModel):
57
+ answer: str
58
+ model: str
59
+ took_seconds: float
60
+ confidence: int
61
+ sources: list
62
+
63
+ app = FastAPI(title="BioGPT-Large Medical Chatbot")
64
+
65
+ MODEL_ID = os.environ.get("MODEL_ID", "microsoft/BioGPT-Large")
66
+ MAX_NEW_TOKENS = int(os.environ.get("MAX_NEW_TOKENS", "200"))
67
+ TEMPERATURE = float(os.environ.get("TEMPERATURE", "0.7"))
68
+ TOP_P = float(os.environ.get("TOP_P", "0.9"))
69
+ DEVICE = int(os.environ.get("DEVICE", "-1")) # -1 = CPU
70
+ USE_4BIT = os.environ.get("USE_4BIT", "false").lower() == "true"
71
+
72
+ generator = None
73
+
74
+ @app.on_event("startup")
75
+ def load_model():
76
+ global generator
77
+ try:
78
+ logger.info(f"Loading model: {MODEL_ID}")
79
+ if USE_4BIT:
80
+ bnb_config = BitsAndBytesConfig(
81
+ load_in_4bit=True,
82
+ bnb_4bit_quant_type="nf4",
83
+ bnb_4bit_compute_dtype="float16",
84
+ bnb_4bit_use_double_quant=True,
85
+ )
86
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=False)
87
+ model = AutoModelForCausalLM.from_pretrained(
88
+ MODEL_ID,
89
+ quantization_config=bnb_config,
90
+ device_map="auto",
91
+ trust_remote_code=True,
92
+ )
93
+ else:
94
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=False)
95
+ model = AutoModelForCausalLM.from_pretrained(MODEL_ID, trust_remote_code=True)
96
+
97
+ generator = pipeline(
98
+ "text-generation",
99
+ model=model,
100
+ tokenizer=tokenizer,
101
+ device=DEVICE,
102
+ )
103
+ logger.info("Model loaded successfully.")
104
+ except Exception as e:
105
+ logger.exception("Model loading failed")
106
+ generator = None
107
+
108
+ @app.post("/chat", response_model=ChatResponse)
109
+ def chat(req: ChatRequest):
110
+ if generator is None:
111
+ raise HTTPException(status_code=500, detail="Model not available.")
112
+
113
+ if not req.question.strip():
114
+ raise HTTPException(status_code=400, detail="Question cannot be empty")
115
+
116
+ # Select system prompt
117
+ mode = req.mode.lower() if req.mode else "dermatology"
118
+ system_prompt = MEDICAL_PROMPTS.get(mode, MEDICAL_PROMPTS["general"])
119
+
120
+ # Build final prompt
121
+ prompt = f"{system_prompt}\n\nUser Question: {req.question.strip()}\n\nAI Answer:"
122
+ if req.context:
123
+ prompt = req.context.strip() + "\n\n" + prompt
124
+
125
+ max_new = req.max_new_tokens or MAX_NEW_TOKENS
126
+ temp = req.temperature or TEMPERATURE
127
+ top_p = req.top_p or TOP_P
128
+
129
+ logger.info(f"Generating answer for: {req.question[:80]}...")
130
+ t0 = time.time()
131
+
132
+ try:
133
+ outputs = generator(
134
+ prompt,
135
+ max_new_tokens=max_new,
136
+ temperature=temp,
137
+ top_p=top_p,
138
+ do_sample=True,
139
+ return_full_text=False,
140
+ num_return_sequences=1,
141
+ )
142
+ answer = outputs[0]["generated_text"].strip()
143
+
144
+ # Always append disclaimer
145
+ final_answer = f"{answer}\n\n{MEDICAL_PROMPTS['disclaimer']}"
146
+
147
+ took = time.time() - t0
148
+ confidence = min(95, 70 + int(len(answer) / 50))
149
+
150
+ return ChatResponse(
151
+ answer=final_answer,
152
+ model=MODEL_ID,
153
+ took_seconds=round(took, 2),
154
+ confidence=confidence,
155
+ sources=["HuggingFace", MODEL_ID],
156
+ )
157
+ except Exception as e:
158
+ logger.exception("Generation failed")
159
+ raise HTTPException(status_code=500, detail=str(e))