fsconvo / app /controllers /models.py
hari7775's picture
feat(llm): add Qwen 2.5 3B 1.6-bit IQ1_S and expose dynamic model catalog in GET /api/models
0c6ae44
Raw History Blame Contribute Delete
2.94 kB
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
import logging
from app.llm.manager import LLMManager, HAS_LLAMA_CPP, GGUF_MODEL_MAP, AVAILABLE_CLOUD_MODELS
logger = logging.getLogger(__name__)
router = APIRouter(
prefix="/api/models",
tags=["Models"]
)
class ModelRequest(BaseModel):
model_name: str
class EngineRequest(BaseModel):
engine: str
@router.get("")
def get_models():
manager = LLMManager.get_instance()
settings = manager.settings
models = []
for m in settings.get("recommended_models", []):
models.append({
"name": m,
"is_llm": True,
"capabilities": ["text-generation"],
"has_gguf": m in GGUF_MODEL_MAP
})
return {
"models": models,
"catalog": AVAILABLE_CLOUD_MODELS,
"hardware": settings,
"active_model": manager.active_model_name,
"active_engine": manager.get_active_engine(),
"preferred_engine": manager.preferred_engine,
"has_llama_cpp": HAS_LLAMA_CPP,
"available_engines": [
{
"id": "llama.cpp",
"label": "llama.cpp (C++ GGUF Q4)",
"description": "Ultra-fast 4-bit native C++ execution (~2-4s response)",
"available": HAS_LLAMA_CPP
},
{
"id": "transformers",
"label": "Transformers (PyTorch FP32)",
"description": "Standard unquantized PyTorch Hugging Face pipeline",
"available": True
}
]
}
@router.post("/set-engine")
def set_inference_engine(req: EngineRequest):
manager = LLMManager.get_instance()
try:
active_engine = manager.set_engine(req.engine)
return {
"status": "success",
"message": f"Inference engine switched to {active_engine}",
"active_engine": active_engine,
"preferred_engine": manager.preferred_engine
}
except Exception as e:
logger.error(f"Error setting inference engine: {e}")
raise HTTPException(status_code=400, detail=str(e))
@router.post("/set-default")
def set_default_model(req: ModelRequest):
manager = LLMManager.get_instance()
manager.active_model_name = req.model_name
try:
manager.load_model(req.model_name)
except Exception as e:
logger.warning(f"Error preloading model {req.model_name}: {e}")
return {
"message": f"Default model set to {req.model_name}",
"active_model": manager.active_model_name,
"active_engine": manager.get_active_engine()
}
@router.post("/pull")
def pull_model(req: ModelRequest):
manager = LLMManager.get_instance()
manager.load_model(req.model_name)
return {
"message": f"Model {req.model_name} pulled and loaded.",
"active_engine": manager.get_active_engine()
}