File size: 3,105 Bytes
3e66fd0
 
7460785
 
2f0b1a7
8ab22e1
3e66fd0
 
7460785
 
 
3e66fd0
47ff742
 
 
 
3e66fd0
ec0184d
2f0b1a7
 
 
 
ec0184d
2f0b1a7
 
 
 
 
ec0184d
 
 
2f0b1a7
 
 
 
 
 
3e66fd0
 
7460785
de0a38c
ec0184d
47ff742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3e66fd0
2f0b1a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2a0585f
 
 
 
 
 
 
 
ec0184d
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
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 (intent yapısı)
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.
✅ Format:
#ANSWER: <cevap metni veya NONE>
#INTENT: <intent_adı> (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: currency (dolar, euro, TL)
- yol-durumu-intent → parametreler: from_location, to_location (Ankara, İstanbul, İzmir)
- hava-durumu-intent → parametre: city (Ankara, İstanbul, İzmir)
❗ 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

    # Ortam değişkenleri
    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"}