Spaces:
Running on Zero
Running on Zero
atakan commited on
Commit ·
306a458
1
Parent(s): 16e844c
perf: Preload model on container startup and optimize PyTorch CPU multi-threading
Browse files- app.py +10 -1
- controlai_agent/orchestrator.py +17 -3
app.py
CHANGED
|
@@ -7,6 +7,7 @@ import os
|
|
| 7 |
import shutil
|
| 8 |
import sys
|
| 9 |
import time
|
|
|
|
| 10 |
from pathlib import Path
|
| 11 |
from typing import Any
|
| 12 |
|
|
@@ -25,7 +26,15 @@ from controlai_rag.chunker import chunk_document
|
|
| 25 |
from controlai_rag.document_loader import load_single_file
|
| 26 |
from controlai_rag.index import ControlRAGIndex
|
| 27 |
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
app.add_middleware(
|
| 31 |
CORSMiddleware,
|
|
|
|
| 7 |
import shutil
|
| 8 |
import sys
|
| 9 |
import time
|
| 10 |
+
from contextlib import asynccontextmanager
|
| 11 |
from pathlib import Path
|
| 12 |
from typing import Any
|
| 13 |
|
|
|
|
| 26 |
from controlai_rag.document_loader import load_single_file
|
| 27 |
from controlai_rag.index import ControlRAGIndex
|
| 28 |
|
| 29 |
+
@asynccontextmanager
|
| 30 |
+
async def lifespan(app: FastAPI):
|
| 31 |
+
print("Pre-loading ControlAI Core Engine on startup...")
|
| 32 |
+
get_agent()
|
| 33 |
+
print("ControlAI Core Engine is online and ready for traffic.")
|
| 34 |
+
yield
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
app = FastAPI(title="ControlAI", version="1.0.0", lifespan=lifespan)
|
| 38 |
|
| 39 |
app.add_middleware(
|
| 40 |
CORSMiddleware,
|
controlai_agent/orchestrator.py
CHANGED
|
@@ -183,11 +183,23 @@ class ControlAIAgent:
|
|
| 183 |
self.hf_tokenizer = AutoTokenizer.from_pretrained(model_path)
|
| 184 |
else:
|
| 185 |
# Universal PyTorch / Transformers fallback on Linux, Colab, HuggingFace, CUDA
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
hf_id = "Qwen/Qwen2.5-3B-Instruct" if "mlx" in str(model_path) else model_path
|
|
|
|
| 187 |
self.hf_tokenizer = AutoTokenizer.from_pretrained(hf_id, trust_remote_code=True)
|
|
|
|
|
|
|
|
|
|
| 188 |
self.model = AutoModelForCausalLM.from_pretrained(
|
| 189 |
hf_id,
|
| 190 |
-
torch_dtype=
|
|
|
|
| 191 |
device_map="auto",
|
| 192 |
trust_remote_code=True,
|
| 193 |
)
|
|
@@ -195,8 +207,10 @@ class ControlAIAgent:
|
|
| 195 |
try:
|
| 196 |
from peft import PeftModel
|
| 197 |
self.model = PeftModel.from_pretrained(self.model, adapter_path)
|
| 198 |
-
|
| 199 |
-
|
|
|
|
|
|
|
| 200 |
|
| 201 |
# Initialize local offline RAG index
|
| 202 |
try:
|
|
|
|
| 183 |
self.hf_tokenizer = AutoTokenizer.from_pretrained(model_path)
|
| 184 |
else:
|
| 185 |
# Universal PyTorch / Transformers fallback on Linux, Colab, HuggingFace, CUDA
|
| 186 |
+
import torch
|
| 187 |
+
num_threads = min(os.cpu_count() or 2, 4)
|
| 188 |
+
try:
|
| 189 |
+
torch.set_num_threads(num_threads)
|
| 190 |
+
except Exception:
|
| 191 |
+
pass
|
| 192 |
+
|
| 193 |
hf_id = "Qwen/Qwen2.5-3B-Instruct" if "mlx" in str(model_path) else model_path
|
| 194 |
+
print(f"Loading PyTorch model: {hf_id} (CPU threads: {num_threads})...")
|
| 195 |
self.hf_tokenizer = AutoTokenizer.from_pretrained(hf_id, trust_remote_code=True)
|
| 196 |
+
|
| 197 |
+
# Use bfloat16 on CUDA, float32 on CPU for clean numerical stability
|
| 198 |
+
dtype = torch.bfloat16 if torch.cuda.is_available() else torch.float32
|
| 199 |
self.model = AutoModelForCausalLM.from_pretrained(
|
| 200 |
hf_id,
|
| 201 |
+
torch_dtype=dtype,
|
| 202 |
+
low_cpu_mem_usage=True,
|
| 203 |
device_map="auto",
|
| 204 |
trust_remote_code=True,
|
| 205 |
)
|
|
|
|
| 207 |
try:
|
| 208 |
from peft import PeftModel
|
| 209 |
self.model = PeftModel.from_pretrained(self.model, adapter_path)
|
| 210 |
+
print(f"Loaded PEFT LoRA adapter from: {adapter_path}")
|
| 211 |
+
except Exception as exc:
|
| 212 |
+
print(f"Warning: Could not load LoRA adapter in PyTorch: {exc}")
|
| 213 |
+
print("PyTorch model loaded successfully.")
|
| 214 |
|
| 215 |
# Initialize local offline RAG index
|
| 216 |
try:
|