File size: 7,697 Bytes
8aceec0 8c2c9df 8aceec0 1fe24dd 8aceec0 06ceb89 8aceec0 1fe24dd 8aceec0 ec1a12b 8aceec0 1fe24dd ec1a12b 8aceec0 8c2c9df 1fe24dd ec1a12b 1fe24dd 561281d 1fe24dd 561281d 1fe24dd 8c2c9df ec1a12b b16a1fc 8c2c9df 8aceec0 1fe24dd 8aceec0 1fe24dd 8aceec0 1fe24dd 8aceec0 8c2c9df 8aceec0 8c2c9df 8aceec0 8c2c9df 1fe24dd b16a1fc 1fe24dd ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b b16a1fc 1fe24dd ec1a12b 8aceec0 561281d 8aceec0 1fe24dd 8aceec0 ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b b16a1fc ec1a12b 1fe24dd ec1a12b b16a1fc 8c2c9df 8aceec0 1fe24dd 8aceec0 ec1a12b 8aceec0 1fe24dd b16a1fc 8aceec0 8c2c9df 8aceec0 1fe24dd 8aceec0 8c2c9df 8aceec0 1fe24dd 8c2c9df 1fe24dd 8aceec0 1fe24dd 8aceec0 8c2c9df ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b 1fe24dd ec1a12b 8aceec0 561281d ec1a12b 561281d 8aceec0 ec1a12b 1fe24dd ec1a12b b16a1fc ec1a12b 1fe24dd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
import gradio as gr
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
import torch
import time
# =======================================================
# Load Model
# =======================================================
model_name = "augtoma/qCammel-13"
print("Loading tokenizer and model...")
tokenizer = AutoTokenizer.from_pretrained(model_name)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto",
torch_dtype=torch.float16,
trust_remote_code=True,
low_cpu_mem_usage=True
)
model.eval()
print("β
Model loaded successfully!")
print(f"Device map: {model.hf_device_map}")
print(f"Model device: {next(model.parameters()).device}")
# =======================================================
# Generate Doctor Response (Refined for natural tone)
# =======================================================
def generate_doctor_response(history):
user_message = history[-1]["content"]
if not user_message.strip():
history.append({"role": "assistant", "content": "β οΈ Please describe your symptoms or ask a question."})
yield history
return
# π©Ί Refined, Doctor-Like Prompt
prompt = f"""
You are Dr. Aiden, a compassionate, calm, and experienced medical doctor.
You speak naturally, like in a real consultation, providing medical reasoning and empathy.
You should:
- Greet the patient kindly and acknowledge their concern.
- Offer a likely cause in simple medical terms.
- Suggest possible medicines (with safe dosage and common over-the-counter names).
- Recommend home remedies, foods, and hydration advice.
- Share short lifestyle or rest tips to aid recovery.
- End with reassurance and a disclaimer.
Keep your tone friendly yet professional β like an experienced doctor talking directly to the patient.
Avoid using headings, bullet points, or medical jargon unless necessary.
Keep your response under 180 words.
Patient says: "{user_message}"
Dr. Aiden:
"""
# Tokenize input
inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048).to(model.device)
gen_config = GenerationConfig(
temperature=0.7,
top_p=0.9,
do_sample=True,
max_new_tokens=600,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
repetition_penalty=1.15,
)
input_len = inputs["input_ids"].shape[1]
with torch.no_grad():
output_ids = model.generate(**inputs, generation_config=gen_config)
generated_ids = output_ids[0][input_len:]
response = tokenizer.decode(generated_ids, skip_special_tokens=True).strip()
# Clean up the response
response = clean_medical_response(response)
# Stream response (simulated)
history.append({"role": "assistant", "content": ""})
for i in range(0, len(response), 5):
history[-1]["content"] = response[:i + 5] + "β"
yield history.copy()
time.sleep(0.01)
history[-1]["content"] = response
yield history
# =======================================================
# Clean the response
# =======================================================
def clean_medical_response(response: str) -> str:
remove_prefixes = ["assistant:", "doctor:", "dr. aiden:", "response:", "patient:"]
for p in remove_prefixes:
if response.lower().startswith(p):
response = response[len(p):].strip()
response = response.replace("Dr. Aiden:", "").strip()
# Ensure punctuation
if response and response[-1] not in ".!?":
response += "."
# Add disclaimer if missing
if "βοΈ" not in response and "consult" not in response.lower():
response += "\n\nβοΈ *Please note: This is AI-generated medical guidance, not a substitute for a licensed healthcare provider. Always consult a doctor for personal medical care.*"
return response.strip()
# =======================================================
# Gradio UI
# =======================================================
with gr.Blocks(theme=gr.themes.Soft(), css="""
.medical-header {
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
padding: 20px;
border-radius: 12px;
color: white;
text-align: center;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
""") as demo:
gr.HTML("""
<div class="medical-header">
<h1>π₯ Dr. Aiden β AI Medical Consultation</h1>
<p>Friendly β’ Professional β’ Science-Backed Guidance</p>
</div>
""")
chatbot = gr.Chatbot(
label="π¬ Your Consultation with Dr. Aiden",
type='messages',
avatar_images=(
"https://cdn-icons-png.flaticon.com/512/706/706830.png", # Patient
"https://cdn-icons-png.flaticon.com/512/3774/3774299.png" # Doctor
),
height=550,
show_copy_button=True
)
with gr.Row():
user_input = gr.Textbox(
placeholder="Describe your symptoms or ask a question (e.g., 'I have a fever and sore throat for two days')...",
label="π§ Describe Your Symptoms",
lines=3,
scale=4
)
with gr.Row():
send_btn = gr.Button("π¬ Ask Dr. Aiden", variant="primary", size="lg")
clear_btn = gr.Button("π§Ή New Consultation", size="lg")
gr.Markdown("### π‘ Example Questions")
gr.Examples(
examples=[
"I have a fever and headache for two days. What should I take?",
"I feel tired all day and have trouble sleeping. What could be wrong?",
"I have mild chest tightness when I exercise. Should I worry?",
"I'm feeling anxious and stressed. Any natural remedies?",
"I have stomach pain after eating. What can I do?",
"I caught a cold and sore throat. What treatment do you recommend?",
],
inputs=user_input,
)
# =======================================================
# Respond Function (stateless model, persistent chat)
# =======================================================
def respond(message, history):
user_message = message.strip()
if not user_message:
return "", history
# Show user input
history.append({"role": "user", "content": user_message})
# Model sees only current input (no memory)
temp_history = [{"role": "user", "content": user_message}]
for updated_history in generate_doctor_response(temp_history):
if len(history) == 0 or history[-1]["role"] != "assistant":
history.append({"role": "assistant", "content": updated_history[-1]["content"]})
else:
history[-1]["content"] = updated_history[-1]["content"]
yield "", history
# =======================================================
# Button Bindings
# =======================================================
send_btn.click(respond, [user_input, chatbot], [user_input, chatbot])
user_input.submit(respond, [user_input, chatbot], [user_input, chatbot])
clear_btn.click(lambda: [], None, chatbot, queue=False)
# =======================================================
# Launch App
# =======================================================
if __name__ == "__main__":
print("="*60)
print("π₯ Dr. Aiden β AI Medical Doctor is starting...")
print("="*60)
demo.queue(max_size=20)
demo.launch(
share=True,
show_error=True,
server_name="0.0.0.0"
)
|