import os from fastapi import FastAPI from unsloth import FastLanguageModel from transformers import pipeline from pydantic import BaseModel from datetime import datetime app = FastAPI() model = None tokenizer = None pipe = None # === Log fonksiyonu def log(message): timestamp = datetime.now().strftime("%H:%M:%S") print(f"[{timestamp}] {message}", flush=True) # === System prompt (bizim intent yapımız) SYSTEM_PROMPT = """ Siz bir görev tabanlı asistan botsunuz. Kullanıcının doğal dildeki mesajlarını anlayabilir, niyetlerini (intent) tespit edebilir, eksik bilgileri sorabilir ve backend API'lerine tetikleme hazırlığı yapabilirsiniz. ❗ Cevaplarınızda mutlaka aşağıdaki formatlı blokları döndürmelisiniz ve bunların dışında hiçbir metin, açıklama veya selamlama eklememelisiniz. Eğer intent tespit ettiyseniz ANSWER kısmını NONE, tespit edemediyseniz INTENT kısmını NONE olarak dönmelisiniz. ✅ Format: #ANSWER: (veya NONE) #INTENT: (veya NONE) #PARAMS: {parametre_adı: değer, ...} #MISSING: [eksik_parametre_adı, ...] #ACTION_JSON: {api için gönderilecek json, eksikse boş bırak} ✅ Desteklenen intent'ler: - doviz-kuru-intent → parametre: (dolar, euro, TL) → json: { "currency": "" } - yol-durumu-intent → parametreler: , (Ankara, İstanbul, İzmir) → json: { "from_location": "", "to_location": "" } - hava-durumu-intent → parametre: (Ankara, İstanbul, İzmir) → json: { "city": "" } ❗ Kullanıcıya hitap ederken formal bir dil kullanınız, sadece bu formatlı blokları döndürünüz. """ class ChatRequest(BaseModel): prompt: str @app.on_event("startup") def load_model(): global model, tokenizer, pipe # Hugging Face ve Triton cache dizinleri os.environ["HF_HOME"] = "/app/.cache" os.environ["HF_DATASETS_CACHE"] = "/app/.cache" os.environ["HF_HUB_CACHE"] = "/app/.cache" os.environ["TRITON_CACHE_DIR"] = "/tmp/.triton" model_name = "atasoglu/Turkish-Llama-3-8B-function-calling" hf_token = os.getenv("HF_TOKEN") log("🚀 Model yüklemesi başlatılıyor...") model, tokenizer = FastLanguageModel.from_pretrained( model_name=model_name, load_in_4bit=True, token=hf_token, cache_dir="/app/.cache" ) FastLanguageModel.for_inference(model) pipe = pipeline( "text-generation", model=model, tokenizer=tokenizer, device_map="auto" ) log("✅ Model başarıyla yüklendi ve cache’e alındı.") @app.post("/chat") def chat(req: ChatRequest): try: log(f"💬 Yeni istek alındı: '{req.prompt}'") full_prompt = f"{SYSTEM_PROMPT}\n\nKullanıcı: {req.prompt}\nAsistan:" log("🧠 LLM çağrısı başlatılıyor...") outputs = pipe( full_prompt, max_new_tokens=256, temperature=0.2, top_p=0.95, repetition_penalty=1.1 ) answer = outputs[0]["generated_text"].replace(full_prompt, "").strip() log("✅ LLM cevabı başarıyla alındı.") return {"response": answer} except Exception as e: log(f"❌ /chat sırasında hata oluştu: {e}") return {"error": f"Hata: {str(e)}"} @app.get("/") def health(): return {"status": "ok"}