Spaces:
Running
Running
File size: 3,647 Bytes
393654c 773e1cf b807bd8 393654c a5de004 fe2f396 df7017f 393654c 2906245 14a42df 2906245 14a42df 2906245 b807bd8 2906245 12a2254 2906245 b807bd8 01a7be6 2906245 01a7be6 2906245 6bb1696 14a42df 019823b e1bcd6b 773e1cf 14a42df fe2f396 393654c 773e1cf 393654c 773e1cf 393654c 773e1cf 393654c 773e1cf 393654c b807bd8 773e1cf 393654c e1bcd6b df7017f 773e1cf b807bd8 393654c b807bd8 773e1cf b807bd8 773e1cf b807bd8 773e1cf 393654c 773e1cf | 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 | import os
import gc
import glob
import time
import logging
from typing import List, Union, Optional, Literal
from fastapi import FastAPI, Depends, HTTPException, Header, status
from fastapi.responses import JSONResponse, FileResponse
from pydantic import BaseModel, Field
from llama_cpp import Llama
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 🔒 SEGURANÇA: Falha imediata se API_KEY não estiver configurada
API_KEY = os.getenv("API_KEY")
if not API_KEY:
raise RuntimeError(
"❌ SECURITY ERROR: API_KEY environment variable is not set!\n"
"Please configure the API_KEY secret in your Hugging Face Space:\n"
"Settings → Variables and Secrets → Add secret\n"
"Name: API_KEY | Value: [your-secure-key]"
)
MODEL_PATH = glob.glob("/app/model/*.gguf")[0]
logger.info(f"Carregando modelo: {MODEL_PATH}")
load_start = time.time()
llm = Llama(
model_path=MODEL_PATH,
n_ctx=512,
n_threads=2,
n_batch=512,
embedding=True,
verbose=False
)
load_time = time.time() - load_start
logger.info(f"🚀 Model loaded in {load_time:.2f}s")
app = FastAPI(title="Embedding Engine (GGUF Q8_0)")
@app.get("/", include_in_schema=False)
async def root():
return FileResponse("index.html")
class EmbeddingRequest(BaseModel):
input: Union[str, List[str]]
model: str = "LiquidAI/LFM2.5-Embedding-350M"
input_type: Optional[Literal["query", "document"]] = Field(
default="document",
alias="inputType"
)
model_config = {"populate_by_name": True}
class EmbeddingObject(BaseModel):
object: str = "embedding"
embedding: List[float]
index: int
class EmbeddingResponse(BaseModel):
object: str = "list"
data: List[EmbeddingObject]
model: str
usage: dict
def verify_api_key(authorization: str = Header(None)):
if not authorization or not authorization.startswith("Bearer "):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or missing Authorization header",
headers={"WWW-Authenticate": "Bearer"},
)
token = authorization.replace("Bearer ", "")
if token != API_KEY:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key",
headers={"WWW-Authenticate": "Bearer"},
)
@app.post("/v1/embeddings", response_model=EmbeddingResponse)
async def create_embeddings(
request: EmbeddingRequest,
_: str = Depends(verify_api_key)
):
req_start = time.time()
inputs = request.input if isinstance(request.input, list) else [request.input]
if request.input_type == "query":
inputs = [f"query: {text}" for text in inputs]
else:
inputs = [f"document: {text}" for text in inputs]
prep_time = time.time() - req_start
logger.info(f"📝 Prep time: {prep_time:.3f}s | Input count: {len(inputs)} | First input length: {len(inputs[0])} chars")
try:
infer_start = time.time()
response = llm.create_embedding(input=inputs)
infer_time = time.time() - infer_start
logger.info(f"🧠 Inference time: {infer_time:.3f}s")
response["model"] = request.model
total_time = time.time() - req_start
logger.info(f"✅ Total request time: {total_time:.3f}s")
return JSONResponse(content=response)
except Exception as e:
logger.error(f"Embedding error: {str(e)}")
raise HTTPException(status_code=500, detail="Embedding generation failed")
finally:
gc.collect() |