GoshawkVortexAI commited on
Commit
0cc80cc
·
verified ·
1 Parent(s): bfcd3ed

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +223 -0
app.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import torch
4
+ import gradio as gr
5
+ from transformers import (
6
+ AutoConfig,
7
+ AutoTokenizer,
8
+ AutoModelForCausalLM
9
+ )
10
+
11
+ # ==================================================
12
+ # GOSHAWK AI — Hugging Face Space
13
+ # ==================================================
14
+
15
+ APP_NAME = "Goshawk AI"
16
+ MODEL_PATH = os.getenv("MODEL_PATH", "./")
17
+
18
+ MAX_NEW_TOKENS = 256
19
+ MAX_CONTEXT = 2048
20
+
21
+ device = "cuda" if torch.cuda.is_available() else "cpu"
22
+ dtype = torch.float16 if device == "cuda" else torch.float32
23
+
24
+ print(f"[{APP_NAME}] Device: {device}")
25
+ print(f"[{APP_NAME}] Model path: {MODEL_PATH}")
26
+
27
+ tokenizer = None
28
+ model = None
29
+ load_error = None
30
+
31
+ try:
32
+ config = AutoConfig.from_pretrained(
33
+ MODEL_PATH,
34
+ local_files_only=True,
35
+ trust_remote_code=False
36
+ )
37
+
38
+ print(f"Model architecture: {config.model_type}")
39
+
40
+ tokenizer = AutoTokenizer.from_pretrained(
41
+ MODEL_PATH,
42
+ local_files_only=True,
43
+ trust_remote_code=False
44
+ )
45
+
46
+ model = AutoModelForCausalLM.from_pretrained(
47
+ MODEL_PATH,
48
+ config=config,
49
+ torch_dtype=dtype,
50
+ low_cpu_mem_usage=True,
51
+ local_files_only=True,
52
+ trust_remote_code=False
53
+ )
54
+
55
+ model.to(device)
56
+ model.eval()
57
+
58
+ if tokenizer.pad_token_id is None:
59
+ tokenizer.pad_token = tokenizer.eos_token
60
+
61
+ print(f"[{APP_NAME}] Model loaded successfully.")
62
+
63
+ except Exception as exc:
64
+ load_error = f"{type(exc).__name__}: {exc}"
65
+ print(f"[{APP_NAME}] Loading failed: {load_error}")
66
+
67
+
68
+ SYSTEM_PROMPT = (
69
+ "You are Goshawk AI, a helpful and precise AI assistant. "
70
+ "Answer in the user's language. Be transparent about uncertainty. "
71
+ "Never invent facts, live market data, or sources."
72
+ )
73
+
74
+
75
+ def build_prompt(message, history):
76
+ messages = [
77
+ {"role": "system", "content": SYSTEM_PROMPT}
78
+ ]
79
+
80
+ for item in (history or [])[-8:]:
81
+ if isinstance(item, dict):
82
+ role = item.get("role")
83
+ content = item.get("content", "")
84
+
85
+ if role in ("user", "assistant") and isinstance(content, str):
86
+ messages.append({
87
+ "role": role,
88
+ "content": content
89
+ })
90
+
91
+ elif isinstance(item, (list, tuple)) and len(item) == 2:
92
+ if item[0]:
93
+ messages.append({
94
+ "role": "user",
95
+ "content": str(item[0])
96
+ })
97
+ if item[1]:
98
+ messages.append({
99
+ "role": "assistant",
100
+ "content": str(item[1])
101
+ })
102
+
103
+ messages.append({"role": "user", "content": message})
104
+
105
+ if hasattr(tokenizer, "apply_chat_template"):
106
+ try:
107
+ return tokenizer.apply_chat_template(
108
+ messages,
109
+ tokenize=False,
110
+ add_generation_prompt=True
111
+ )
112
+ except Exception:
113
+ pass
114
+
115
+ # Fallback for models without a chat template.
116
+ prompt = f"System: {SYSTEM_PROMPT}\n"
117
+ for msg in messages[1:]:
118
+ label = "User" if msg["role"] == "user" else "Assistant"
119
+ prompt += f"{label}: {msg['content']}\n"
120
+
121
+ return prompt + "Assistant:"
122
+
123
+
124
+ def respond(message, history, temperature, max_tokens):
125
+ if not message or not message.strip():
126
+ yield "Lütfen bir mesaj yaz."
127
+ return
128
+
129
+ if model is None or tokenizer is None:
130
+ yield (
131
+ "Model yüklenemedi.\n\n"
132
+ f"Hata: {load_error}\n\n"
133
+ "config.json, model.safetensors ve tokenizer "
134
+ "dosyalarını kontrol et. Model mimarisi metin "
135
+ "üretimini desteklemiyor olabilir."
136
+ )
137
+ return
138
+
139
+ try:
140
+ prompt = build_prompt(message.strip(), history)
141
+
142
+ inputs = tokenizer(
143
+ prompt,
144
+ return_tensors="pt",
145
+ truncation=True,
146
+ max_length=MAX_CONTEXT
147
+ )
148
+ inputs = {k: v.to(device) for k, v in inputs.items()}
149
+
150
+ input_length = inputs["input_ids"].shape[1]
151
+
152
+ if input_length >= MAX_CONTEXT:
153
+ yield "Girdi bağlam sınırına ulaştı. Daha kısa bir mesaj dene."
154
+ return
155
+
156
+ with torch.inference_mode():
157
+ output = model.generate(
158
+ **inputs,
159
+ max_new_tokens=int(max_tokens),
160
+ do_sample=float(temperature) > 0,
161
+ temperature=max(float(temperature), 0.01),
162
+ top_p=0.9,
163
+ repetition_penalty=1.08,
164
+ pad_token_id=tokenizer.pad_token_id,
165
+ eos_token_id=tokenizer.eos_token_id
166
+ )
167
+
168
+ new_tokens = output[0][input_length:]
169
+ answer = tokenizer.decode(
170
+ new_tokens,
171
+ skip_special_tokens=True
172
+ ).strip()
173
+
174
+ yield answer or "Model boş yanıt üretti."
175
+
176
+ except Exception as exc:
177
+ yield f"Üretim hatası: {type(exc).__name__}: {exc}"
178
+
179
+
180
+ with gr.Blocks(title=APP_NAME) as demo:
181
+ gr.Markdown(
182
+ "# 🦅 Goshawk AI\n"
183
+ "### Yerel model tabanlı yapay zekâ asistanı\n"
184
+ f"**Cihaz:** `{device}`"
185
+ )
186
+
187
+ if load_error:
188
+ gr.Markdown(
189
+ "⚠️ Model yüklenemedi. Ayrıntılar sohbet alanında görünür."
190
+ )
191
+
192
+ chatbot = gr.ChatInterface(
193
+ fn=respond,
194
+ chatbot=gr.Chatbot(height=480),
195
+ textbox=gr.Textbox(
196
+ placeholder="Goshawk AI'ye bir soru sor...",
197
+ lines=2
198
+ ),
199
+ additional_inputs=[
200
+ gr.Slider(
201
+ minimum=0.1,
202
+ maximum=1.2,
203
+ value=0.7,
204
+ step=0.1,
205
+ label="Yaratıcılık"
206
+ ),
207
+ gr.Slider(
208
+ minimum=32,
209
+ maximum=512,
210
+ value=MAX_NEW_TOKENS,
211
+ step=32,
212
+ label="Maksimum yeni token"
213
+ )
214
+ ]
215
+ )
216
+
217
+ gr.Markdown(
218
+ "Not: Yanıt kalitesi ve hızı kullanılan modelin "
219
+ "mimarisine ve donanıma bağlıdır."
220
+ )
221
+
222
+ if __name__ == "__main__":
223
+ demo.queue().launch()