Update model references to Qwen2.5-1.5B-Instruct; adjust download and preload functions accordingly
Browse files- download_models.py +4 -2
- main.py +65 -91
- preload_models.py +12 -18
download_models.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
| 1 |
from huggingface_hub import snapshot_download
|
| 2 |
import os
|
| 3 |
|
|
|
|
|
|
|
|
|
|
| 4 |
MODELS = [
|
| 5 |
"yasserrmd/GemmaECG-Vision",
|
| 6 |
"google/tabfm-1.0.0-pytorch",
|
| 7 |
-
"Qwen/
|
| 8 |
-
"BioMistral/BioMistral-7B"
|
| 9 |
]
|
| 10 |
|
| 11 |
def download():
|
|
|
|
| 1 |
from huggingface_hub import snapshot_download
|
| 2 |
import os
|
| 3 |
|
| 4 |
+
# Keep the download set aligned with the active inference pipeline.
|
| 5 |
+
# The app now uses the lighter Qwen2.5-1.5B-Instruct path for reasoning/report synthesis
|
| 6 |
+
# to minimize latency on small GPU instances.
|
| 7 |
MODELS = [
|
| 8 |
"yasserrmd/GemmaECG-Vision",
|
| 9 |
"google/tabfm-1.0.0-pytorch",
|
| 10 |
+
"Qwen/Qwen2.5-1.5B-Instruct",
|
|
|
|
| 11 |
]
|
| 12 |
|
| 13 |
def download():
|
main.py
CHANGED
|
@@ -2,7 +2,7 @@ import torch
|
|
| 2 |
from fastapi import FastAPI, UploadFile, File, Form
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from typing import Optional
|
| 5 |
-
from transformers import AutoProcessor, AutoModelForMultimodalLM, AutoTokenizer,
|
| 6 |
from PIL import Image
|
| 7 |
import io
|
| 8 |
import uvicorn
|
|
@@ -80,6 +80,21 @@ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
|
| 80 |
|
| 81 |
models = {}
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
def load_models():
|
| 84 |
if models:
|
| 85 |
return
|
|
@@ -123,23 +138,14 @@ def load_models():
|
|
| 123 |
print(f"Warning: Could not load TabFM model: {e}. Using mock for pipeline demonstration.")
|
| 124 |
models['tabfm_clf'] = None
|
| 125 |
|
| 126 |
-
print("Loading
|
| 127 |
-
models['
|
| 128 |
-
|
| 129 |
-
"Qwen/
|
|
|
|
| 130 |
device_map="auto",
|
| 131 |
-
quantization_config=quant_config,
|
| 132 |
-
low_cpu_mem_usage=True
|
| 133 |
)
|
| 134 |
|
| 135 |
-
print("Loading BioMistral-7B...")
|
| 136 |
-
models['mistral_tokenizer'] = AutoTokenizer.from_pretrained("BioMistral/BioMistral-7B")
|
| 137 |
-
models['mistral_model'] = AutoModelForCausalLM.from_pretrained(
|
| 138 |
-
"BioMistral/BioMistral-7B",
|
| 139 |
-
device_map="auto",
|
| 140 |
-
quantization_config=quant_config,
|
| 141 |
-
low_cpu_mem_usage=True
|
| 142 |
-
)
|
| 143 |
print("All models loaded successfully.")
|
| 144 |
|
| 145 |
class PatientMetrics(BaseModel):
|
|
@@ -215,8 +221,8 @@ async def predict(
|
|
| 215 |
tabfm_risk_probability = 68.2
|
| 216 |
tabfm_classification_label = "Positive for Heart Disease"
|
| 217 |
|
| 218 |
-
# 3. Reasoning Layer via
|
| 219 |
-
qwen_system_prompt = "You are a clinical reasoning engine. Analyze the provided patient metrics and ECG findings to provide a detailed, step-by-step diagnostic reasoning chain. Think through the correlations between demographics, vitals, and electrical cardiac activity."
|
| 220 |
qwen_user_content = f"""
|
| 221 |
PATIENT DATA:
|
| 222 |
- Age: {patient_metrics.age}, Sex: {patient_metrics.sex}, Ethnicity: {patient_metrics.ethnicity}
|
|
@@ -234,35 +240,26 @@ async def predict(
|
|
| 234 |
"""
|
| 235 |
|
| 236 |
qwen_messages = [{"role": "user", "content": f"{qwen_system_prompt}\n\n{qwen_user_content}"}]
|
| 237 |
-
|
| 238 |
qwen_messages,
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
qwen_outputs = models['qwen_model'].generate(
|
| 245 |
-
**qwen_inputs,
|
| 246 |
-
max_new_tokens=1024,
|
| 247 |
-
do_sample=True,
|
| 248 |
-
temperature=0.6,
|
| 249 |
-
top_p=0.95,
|
| 250 |
-
top_k=20,
|
| 251 |
-
min_p=0,
|
| 252 |
-
repetition_penalty=1.2
|
| 253 |
)
|
| 254 |
-
qwen_reasoning =
|
| 255 |
|
| 256 |
bmi_bp_interaction = 1.24 # Derived output
|
| 257 |
health_risk_score = 0.78 # Derived output
|
| 258 |
|
| 259 |
-
system_prompt = """You are
|
| 260 |
|
| 261 |
1. Google TabFM (google/tabfm-1.0.0-pytorch): Processes tabular clinical, demographic, metabolic, and engineered metrics.
|
| 262 |
2. GemmaECG-Vision (yasserrmd/GemmaECG-Vision via image-text-to-text pipeline): Processes 12-lead ECG image waveforms.
|
| 263 |
-
3.
|
| 264 |
|
| 265 |
-
Your job is to ingest all patient metrics along with the outputs of GemmaECG-Vision, Google TabFM, and the reasoning generated by
|
| 266 |
|
| 267 |
OPERATIONAL MANDATES:
|
| 268 |
1. Complete Parameter Coverage: You MUST account for every single parameter in the input data block (Demographics, Vitals, Labs, Cardiac Features, Lifestyle, and Engineered Metrics). Do not omit any parameter.
|
|
@@ -316,31 +313,24 @@ OUTPUT HEADINGS:
|
|
| 316 |
- TabFM Risk Probability: {tabfm_risk_probability}%
|
| 317 |
- TabFM Classification Label: {tabfm_classification_label}
|
| 318 |
|
| 319 |
-
### 4. UPSTREAM MODEL 3 OUTPUT:
|
| 320 |
- Clinical Reasoning Chain: {qwen_reasoning}
|
| 321 |
"""
|
| 322 |
|
| 323 |
-
|
| 324 |
-
{"role": "
|
|
|
|
| 325 |
]
|
| 326 |
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
return_tensors="pt",
|
| 333 |
-
).to(models['mistral_model'].device)
|
| 334 |
-
|
| 335 |
-
outputs = models['mistral_model'].generate(
|
| 336 |
-
**inputs,
|
| 337 |
-
max_new_tokens=1024,
|
| 338 |
-
do_sample=True,
|
| 339 |
-
temperature=0.7,
|
| 340 |
top_p=0.9,
|
| 341 |
-
repetition_penalty=1.
|
| 342 |
)
|
| 343 |
-
final_report =
|
| 344 |
|
| 345 |
return {
|
| 346 |
"clinical_report": final_report,
|
|
@@ -359,7 +349,7 @@ OUTPUT HEADINGS:
|
|
| 359 |
async def analyze_ecg(file: UploadFile = File(...)):
|
| 360 |
"""
|
| 361 |
Analyzes a 12-lead ECG image and generates a detailed clinical report using
|
| 362 |
-
GemmaECG-Vision for visual analysis and
|
| 363 |
"""
|
| 364 |
image_data = await file.read()
|
| 365 |
image = Image.open(io.BytesIO(image_data)).convert("RGB")
|
|
@@ -386,31 +376,22 @@ async def analyze_ecg(file: UploadFile = File(...)):
|
|
| 386 |
ecg_outputs = models['ecg_model'].generate(**ecg_inputs, max_new_tokens=100)
|
| 387 |
raw_findings = models['ecg_processor'].tokenizer.decode(ecg_outputs[0][ecg_inputs["input_ids"].shape[-1]:], skip_special_tokens=True)
|
| 388 |
|
| 389 |
-
# 2. Reasoning Layer via
|
| 390 |
-
qwen_system_prompt = "You are a clinical reasoning engine. Analyze the raw AI-extracted ECG findings and provide a detailed, step-by-step clinical interpretation."
|
| 391 |
qwen_user_content = f"RAW AI ECG FINDINGS: {raw_findings}"
|
| 392 |
|
| 393 |
qwen_messages = [{"role": "user", "content": f"{qwen_system_prompt}\n\n{qwen_user_content}"}]
|
| 394 |
-
|
| 395 |
qwen_messages,
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
qwen_outputs = models['qwen_model'].generate(
|
| 402 |
-
**qwen_inputs,
|
| 403 |
-
max_new_tokens=1024,
|
| 404 |
-
do_sample=True,
|
| 405 |
-
temperature=0.6,
|
| 406 |
-
top_p=0.95,
|
| 407 |
-
top_k=20,
|
| 408 |
-
min_p=0,
|
| 409 |
-
repetition_penalty=1.2
|
| 410 |
)
|
| 411 |
-
qwen_reasoning =
|
| 412 |
|
| 413 |
-
# 3. Clinical Synthesis via
|
| 414 |
ecg_report_system_prompt = """You are a Board-Certified Cardiologist. Your task is to take raw visual findings from an AI-based ECG analysis tool and a reasoning chain from a clinical reasoning engine, and synthesize them into a professional, structured clinical ECG report.
|
| 415 |
|
| 416 |
Your report MUST include:
|
|
@@ -428,27 +409,20 @@ async def analyze_ecg(file: UploadFile = File(...)):
|
|
| 428 |
{qwen_reasoning}
|
| 429 |
"""
|
| 430 |
|
| 431 |
-
|
| 432 |
-
{"role": "
|
|
|
|
| 433 |
]
|
| 434 |
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
return_tensors="pt",
|
| 441 |
-
).to(models['mistral_model'].device)
|
| 442 |
-
|
| 443 |
-
outputs = models['mistral_model'].generate(
|
| 444 |
-
**inputs,
|
| 445 |
-
max_new_tokens=1024,
|
| 446 |
-
do_sample=True,
|
| 447 |
-
temperature=0.7,
|
| 448 |
top_p=0.9,
|
| 449 |
-
repetition_penalty=1.
|
| 450 |
)
|
| 451 |
-
final_report =
|
| 452 |
|
| 453 |
return {
|
| 454 |
"ecg_report": final_report,
|
|
|
|
| 2 |
from fastapi import FastAPI, UploadFile, File, Form
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from typing import Optional
|
| 5 |
+
from transformers import AutoProcessor, AutoModelForMultimodalLM, AutoTokenizer, AutoModel, BitsAndBytesConfig, pipeline
|
| 6 |
from PIL import Image
|
| 7 |
import io
|
| 8 |
import uvicorn
|
|
|
|
| 80 |
|
| 81 |
models = {}
|
| 82 |
|
| 83 |
+
def extract_generated_text(response):
|
| 84 |
+
"""Normalize chat-pipeline output to a plain string."""
|
| 85 |
+
if not response:
|
| 86 |
+
return ""
|
| 87 |
+
|
| 88 |
+
generated = response[0].get("generated_text", "")
|
| 89 |
+
if isinstance(generated, list):
|
| 90 |
+
if generated and isinstance(generated[-1], dict):
|
| 91 |
+
return generated[-1].get("content", "")
|
| 92 |
+
return " ".join(part.get("content", "") for part in generated if isinstance(part, dict))
|
| 93 |
+
if isinstance(generated, str):
|
| 94 |
+
return generated
|
| 95 |
+
return str(generated)
|
| 96 |
+
|
| 97 |
+
|
| 98 |
def load_models():
|
| 99 |
if models:
|
| 100 |
return
|
|
|
|
| 138 |
print(f"Warning: Could not load TabFM model: {e}. Using mock for pipeline demonstration.")
|
| 139 |
models['tabfm_clf'] = None
|
| 140 |
|
| 141 |
+
print("Loading Qwen2.5-1.5B-Instruct via pipeline...")
|
| 142 |
+
models['qwen_pipeline'] = pipeline(
|
| 143 |
+
"text-generation",
|
| 144 |
+
model="Qwen/Qwen2.5-1.5B-Instruct",
|
| 145 |
+
torch_dtype=DTYPE,
|
| 146 |
device_map="auto",
|
|
|
|
|
|
|
| 147 |
)
|
| 148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
print("All models loaded successfully.")
|
| 150 |
|
| 151 |
class PatientMetrics(BaseModel):
|
|
|
|
| 221 |
tabfm_risk_probability = 68.2
|
| 222 |
tabfm_classification_label = "Positive for Heart Disease"
|
| 223 |
|
| 224 |
+
# 3. Reasoning Layer via Qwen2.5-1.5B-Instruct
|
| 225 |
+
qwen_system_prompt = "You are a clinical reasoning engine powered by Qwen2.5-1.5B-Instruct. Analyze the provided patient metrics and ECG findings to provide a detailed, step-by-step diagnostic reasoning chain. Think through the correlations between demographics, vitals, and electrical cardiac activity."
|
| 226 |
qwen_user_content = f"""
|
| 227 |
PATIENT DATA:
|
| 228 |
- Age: {patient_metrics.age}, Sex: {patient_metrics.sex}, Ethnicity: {patient_metrics.ethnicity}
|
|
|
|
| 240 |
"""
|
| 241 |
|
| 242 |
qwen_messages = [{"role": "user", "content": f"{qwen_system_prompt}\n\n{qwen_user_content}"}]
|
| 243 |
+
qwen_outputs = models['qwen_pipeline'](
|
| 244 |
qwen_messages,
|
| 245 |
+
max_new_tokens=300,
|
| 246 |
+
do_sample=False,
|
| 247 |
+
temperature=0.2,
|
| 248 |
+
top_p=0.9,
|
| 249 |
+
repetition_penalty=1.1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
)
|
| 251 |
+
qwen_reasoning = extract_generated_text(qwen_outputs)
|
| 252 |
|
| 253 |
bmi_bp_interaction = 1.24 # Derived output
|
| 254 |
health_risk_score = 0.78 # Derived output
|
| 255 |
|
| 256 |
+
system_prompt = """You are a specialized clinical decision-support model powered by Qwen2.5-1.5B-Instruct. You are part of an end-to-end multimodal diagnostic pipeline that integrates three upstream specialized models:
|
| 257 |
|
| 258 |
1. Google TabFM (google/tabfm-1.0.0-pytorch): Processes tabular clinical, demographic, metabolic, and engineered metrics.
|
| 259 |
2. GemmaECG-Vision (yasserrmd/GemmaECG-Vision via image-text-to-text pipeline): Processes 12-lead ECG image waveforms.
|
| 260 |
+
3. Qwen2.5-1.5B-Instruct: A reasoning engine that generates a diagnostic chain-of-thought.
|
| 261 |
|
| 262 |
+
Your job is to ingest all patient metrics along with the outputs of GemmaECG-Vision, Google TabFM, and the reasoning generated by Qwen2.5-1.5B-Instruct to generate a unified, explainable medical evaluation report.
|
| 263 |
|
| 264 |
OPERATIONAL MANDATES:
|
| 265 |
1. Complete Parameter Coverage: You MUST account for every single parameter in the input data block (Demographics, Vitals, Labs, Cardiac Features, Lifestyle, and Engineered Metrics). Do not omit any parameter.
|
|
|
|
| 313 |
- TabFM Risk Probability: {tabfm_risk_probability}%
|
| 314 |
- TabFM Classification Label: {tabfm_classification_label}
|
| 315 |
|
| 316 |
+
### 4. UPSTREAM MODEL 3 OUTPUT: Qwen2.5-1.5B-Instruct
|
| 317 |
- Clinical Reasoning Chain: {qwen_reasoning}
|
| 318 |
"""
|
| 319 |
|
| 320 |
+
final_messages = [
|
| 321 |
+
{"role": "system", "content": system_prompt},
|
| 322 |
+
{"role": "user", "content": user_content},
|
| 323 |
]
|
| 324 |
|
| 325 |
+
final_output = models['qwen_pipeline'](
|
| 326 |
+
final_messages,
|
| 327 |
+
max_new_tokens=350,
|
| 328 |
+
do_sample=False,
|
| 329 |
+
temperature=0.2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
top_p=0.9,
|
| 331 |
+
repetition_penalty=1.1,
|
| 332 |
)
|
| 333 |
+
final_report = extract_generated_text(final_output)
|
| 334 |
|
| 335 |
return {
|
| 336 |
"clinical_report": final_report,
|
|
|
|
| 349 |
async def analyze_ecg(file: UploadFile = File(...)):
|
| 350 |
"""
|
| 351 |
Analyzes a 12-lead ECG image and generates a detailed clinical report using
|
| 352 |
+
GemmaECG-Vision for visual analysis and Qwen2.5-1.5B-Instruct for clinical synthesis.
|
| 353 |
"""
|
| 354 |
image_data = await file.read()
|
| 355 |
image = Image.open(io.BytesIO(image_data)).convert("RGB")
|
|
|
|
| 376 |
ecg_outputs = models['ecg_model'].generate(**ecg_inputs, max_new_tokens=100)
|
| 377 |
raw_findings = models['ecg_processor'].tokenizer.decode(ecg_outputs[0][ecg_inputs["input_ids"].shape[-1]:], skip_special_tokens=True)
|
| 378 |
|
| 379 |
+
# 2. Reasoning Layer via Qwen2.5-1.5B-Instruct
|
| 380 |
+
qwen_system_prompt = "You are a clinical reasoning engine powered by Qwen2.5-1.5B-Instruct. Analyze the raw AI-extracted ECG findings and provide a detailed, step-by-step clinical interpretation."
|
| 381 |
qwen_user_content = f"RAW AI ECG FINDINGS: {raw_findings}"
|
| 382 |
|
| 383 |
qwen_messages = [{"role": "user", "content": f"{qwen_system_prompt}\n\n{qwen_user_content}"}]
|
| 384 |
+
qwen_outputs = models['qwen_pipeline'](
|
| 385 |
qwen_messages,
|
| 386 |
+
max_new_tokens=200,
|
| 387 |
+
do_sample=False,
|
| 388 |
+
temperature=0.2,
|
| 389 |
+
top_p=0.9,
|
| 390 |
+
repetition_penalty=1.1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 391 |
)
|
| 392 |
+
qwen_reasoning = extract_generated_text(qwen_outputs)
|
| 393 |
|
| 394 |
+
# 3. Clinical Synthesis via Qwen2.5-1.5B-Instruct
|
| 395 |
ecg_report_system_prompt = """You are a Board-Certified Cardiologist. Your task is to take raw visual findings from an AI-based ECG analysis tool and a reasoning chain from a clinical reasoning engine, and synthesize them into a professional, structured clinical ECG report.
|
| 396 |
|
| 397 |
Your report MUST include:
|
|
|
|
| 409 |
{qwen_reasoning}
|
| 410 |
"""
|
| 411 |
|
| 412 |
+
final_messages = [
|
| 413 |
+
{"role": "system", "content": ecg_report_system_prompt},
|
| 414 |
+
{"role": "user", "content": user_content},
|
| 415 |
]
|
| 416 |
|
| 417 |
+
final_output = models['qwen_pipeline'](
|
| 418 |
+
final_messages,
|
| 419 |
+
max_new_tokens=250,
|
| 420 |
+
do_sample=False,
|
| 421 |
+
temperature=0.2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
top_p=0.9,
|
| 423 |
+
repetition_penalty=1.1,
|
| 424 |
)
|
| 425 |
+
final_report = extract_generated_text(final_output)
|
| 426 |
|
| 427 |
return {
|
| 428 |
"ecg_report": final_report,
|
preload_models.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
import torch
|
| 2 |
-
from transformers import AutoProcessor, AutoModelForMultimodalLM, AutoTokenizer,
|
| 3 |
|
| 4 |
DTYPE = torch.float16 if torch.cuda.is_available() else torch.float32
|
| 5 |
|
|
|
|
| 6 |
def preload():
|
| 7 |
print("Preloading models to disk...")
|
| 8 |
|
|
@@ -17,9 +18,9 @@ def preload():
|
|
| 17 |
AutoProcessor.from_pretrained("yasserrmd/GemmaECG-Vision")
|
| 18 |
AutoModelForMultimodalLM.from_pretrained(
|
| 19 |
"yasserrmd/GemmaECG-Vision",
|
| 20 |
-
device_map="cpu",
|
| 21 |
quantization_config=quant_config,
|
| 22 |
-
low_cpu_mem_usage=True
|
| 23 |
)
|
| 24 |
|
| 25 |
print("Preloading Google TabFM...")
|
|
@@ -29,24 +30,17 @@ def preload():
|
|
| 29 |
except Exception as e:
|
| 30 |
print(f"Warning: Could not preload TabFM model: {e}")
|
| 31 |
|
| 32 |
-
print("Preloading
|
| 33 |
-
AutoTokenizer.from_pretrained("Qwen/
|
| 34 |
-
|
| 35 |
-
"
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
low_cpu_mem_usage=True
|
| 39 |
-
)
|
| 40 |
-
|
| 41 |
-
print("Preloading BioMistral-7B...")
|
| 42 |
-
AutoTokenizer.from_pretrained("BioMistral/BioMistral-7B")
|
| 43 |
-
AutoModelForCausalLM.from_pretrained(
|
| 44 |
-
"BioMistral/BioMistral-7B",
|
| 45 |
device_map="cpu",
|
| 46 |
-
quantization_config=quant_config,
|
| 47 |
-
low_cpu_mem_usage=True
|
| 48 |
)
|
|
|
|
| 49 |
print("All models preloaded successfully.")
|
| 50 |
|
|
|
|
| 51 |
if __name__ == "__main__":
|
| 52 |
preload()
|
|
|
|
| 1 |
import torch
|
| 2 |
+
from transformers import AutoProcessor, AutoModelForMultimodalLM, AutoTokenizer, BitsAndBytesConfig, pipeline
|
| 3 |
|
| 4 |
DTYPE = torch.float16 if torch.cuda.is_available() else torch.float32
|
| 5 |
|
| 6 |
+
|
| 7 |
def preload():
|
| 8 |
print("Preloading models to disk...")
|
| 9 |
|
|
|
|
| 18 |
AutoProcessor.from_pretrained("yasserrmd/GemmaECG-Vision")
|
| 19 |
AutoModelForMultimodalLM.from_pretrained(
|
| 20 |
"yasserrmd/GemmaECG-Vision",
|
| 21 |
+
device_map="cpu", # Use CPU for build time to avoid needing GPU in Docker build
|
| 22 |
quantization_config=quant_config,
|
| 23 |
+
low_cpu_mem_usage=True,
|
| 24 |
)
|
| 25 |
|
| 26 |
print("Preloading Google TabFM...")
|
|
|
|
| 30 |
except Exception as e:
|
| 31 |
print(f"Warning: Could not preload TabFM model: {e}")
|
| 32 |
|
| 33 |
+
print("Preloading Qwen2.5-1.5B-Instruct...")
|
| 34 |
+
AutoTokenizer.from_pretrained("Qwen/Qwen2.5-1.5B-Instruct")
|
| 35 |
+
pipeline(
|
| 36 |
+
"text-generation",
|
| 37 |
+
model="Qwen/Qwen2.5-1.5B-Instruct",
|
| 38 |
+
torch_dtype=DTYPE,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
device_map="cpu",
|
|
|
|
|
|
|
| 40 |
)
|
| 41 |
+
|
| 42 |
print("All models preloaded successfully.")
|
| 43 |
|
| 44 |
+
|
| 45 |
if __name__ == "__main__":
|
| 46 |
preload()
|