dedlepexa commited on
Commit
7ad98df
·
verified ·
1 Parent(s): 03373ef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -96
app.py CHANGED
@@ -1,130 +1,78 @@
1
  from fastapi import FastAPI
2
- from fastapi.responses import PlainTextResponse
3
  from pydantic import BaseModel
4
- from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer
5
- from deep_translator import GoogleTranslator
6
  import torch
7
  import uvicorn
8
  import threading
9
  import time
10
  from collections import OrderedDict
 
11
 
12
  app = FastAPI()
13
 
14
- # 🔥 MODEL
15
- model_name = "Qwen/Qwen2.5-1.5B-Instruct"
16
 
17
- tokenizer = AutoTokenizer.from_pretrained(model_name)
18
- model = AutoModelForCausalLM.from_pretrained(
19
  model_name,
20
- torch_dtype=torch.float16,
21
- device_map="auto"
22
  )
23
 
24
- MAX_HISTORY = 40
25
- NUM_WORKERS = 3
26
 
27
- db = OrderedDict()
28
- queue = []
29
 
30
- class Message(BaseModel):
31
- message: str
 
 
 
32
 
33
 
34
- # 🔥 split text
35
- def split_text(text, max_len=100):
36
- return "\n".join([text[i:i+max_len] for i in range(0, len(text), max_len)])
37
 
 
 
38
 
39
- # 🔥 очистка мусора Qwen
40
- def clean_output(text: str):
41
- bad = [
42
- "system",
43
- "user",
44
- "assistant",
45
- "<|im_start|>",
46
- "<|im_end|>",
47
- "You are Qwen"
48
- ]
49
 
50
- for b in bad:
51
- text = text.replace(b, "")
52
 
53
- return text.strip()
 
54
 
55
 
56
- # 🔥 GENERATION
57
  def generate_ai_stream(message: str):
58
 
59
- messages = [
60
- {
61
- "role": "system",
62
- "content": (
63
- "Ты умный и точный ассистент. "
64
- "Отвечай логично,кратко и понятно. "
65
- "отвечай ВСЕГДА на русском."
66
- )
67
- },
68
- {
69
- "role": "user",
70
- "content": message
71
- }
72
- ]
73
-
74
- prompt = tokenizer.apply_chat_template(
75
- messages,
76
- tokenize=False,
77
- add_generation_prompt=True
78
- )
79
-
80
- inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
81
-
82
- streamer = TextIteratorStreamer(tokenizer, skip_special_tokens=True)
83
-
84
- gen_kwargs = dict(
85
- **inputs,
86
- max_new_tokens=400,
87
- do_sample=True,
88
- temperature=0.7,
89
- top_p=0.9,
90
- streamer=streamer,
91
- eos_token_id=tokenizer.eos_token_id
92
- )
93
-
94
- thread = threading.Thread(target=model.generate, kwargs=gen_kwargs)
95
- thread.start()
96
-
97
- partial = ""
98
-
99
- # 🔥 streaming
100
- for text in streamer:
101
- partial += text
102
-
103
- if message in db:
104
- db[message]["reply"] = split_text(partial)
105
 
106
- # 🔥 чистка
107
- raw = clean_output(partial)
108
 
109
- # 🔥 перевод (fallback)
110
- try:
111
- translated = GoogleTranslator(
112
- source='auto',
113
- target='ru'
114
- ).translate(raw)
115
- except:
116
- translated = raw
117
 
118
- final_text = split_text(translated) + " full generated"
 
119
 
120
  if message in db:
121
- db[message]["reply"] = final_text
122
  db[message]["status"] = "done"
123
 
124
- return final_text
125
 
126
 
127
- # 🔥 worker
128
  def worker():
129
  while True:
130
  if queue:
@@ -135,17 +83,17 @@ def worker():
135
 
136
  generate_ai_stream(message)
137
  else:
138
- time.sleep(0.01)
139
 
140
 
141
- # 🔥 workers
142
  for _ in range(NUM_WORKERS):
143
  threading.Thread(target=worker, daemon=True).start()
144
 
145
 
146
  @app.get("/")
147
  async def root():
148
- return PlainTextResponse("AI server running (Qwen2.5 1.5B Instruct)")
149
 
150
 
151
  @app.get("/ask")
@@ -176,10 +124,19 @@ async def get(message: str):
176
  data = db[message]
177
 
178
  if data["status"] == "pending":
179
- return PlainTextResponse(data["reply"] or "thinking...")
180
 
181
  return PlainTextResponse(data["reply"])
182
 
183
 
 
 
 
 
 
 
 
 
 
184
  if __name__ == "__main__":
185
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  from fastapi import FastAPI
2
+ from fastapi.responses import PlainTextResponse, FileResponse
3
  from pydantic import BaseModel
4
+ from diffusers import StableDiffusionPipeline
 
5
  import torch
6
  import uvicorn
7
  import threading
8
  import time
9
  from collections import OrderedDict
10
+ import os
11
 
12
  app = FastAPI()
13
 
14
+ # 🔥 MODEL (small Stable Diffusion)
15
+ model_name = "segmind/small-sd"
16
 
17
+ pipe = StableDiffusionPipeline.from_pretrained(
 
18
  model_name,
19
+ torch_dtype=torch.float16
 
20
  )
21
 
22
+ device = "cuda" if torch.cuda.is_available() else "cpu"
23
+ pipe = pipe.to(device)
24
 
25
+ # 🔥 оптимизации
26
+ pipe.enable_attention_slicing()
27
 
28
+ # если доступно
29
+ try:
30
+ pipe.enable_xformers_memory_efficient_attention()
31
+ except:
32
+ pass
33
 
34
 
35
+ MAX_HISTORY = 40
36
+ NUM_WORKERS = 2 # меньше воркеров для GPU
 
37
 
38
+ db = OrderedDict()
39
+ queue = []
40
 
41
+ # папка для изображений
42
+ IMG_DIR = "images"
43
+ os.makedirs(IMG_DIR, exist_ok=True)
 
 
 
 
 
 
 
44
 
 
 
45
 
46
+ class Message(BaseModel):
47
+ message: str
48
 
49
 
50
+ # 🔥 генерация изображения
51
  def generate_ai_stream(message: str):
52
 
53
+ try:
54
+ image = pipe(
55
+ message,
56
+ num_inference_steps=15,
57
+ guidance_scale=7.5
58
+ ).images[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ filename = f"{IMG_DIR}/img_{int(time.time()*1000)}.png"
61
+ image.save(filename)
62
 
63
+ result = filename
 
 
 
 
 
 
 
64
 
65
+ except Exception as e:
66
+ result = f"error: {str(e)}"
67
 
68
  if message in db:
69
+ db[message]["reply"] = result
70
  db[message]["status"] = "done"
71
 
72
+ return result
73
 
74
 
75
+ # 🔥 worker очередь
76
  def worker():
77
  while True:
78
  if queue:
 
83
 
84
  generate_ai_stream(message)
85
  else:
86
+ time.sleep(0.05)
87
 
88
 
89
+ # 🔥 запуск воркеров
90
  for _ in range(NUM_WORKERS):
91
  threading.Thread(target=worker, daemon=True).start()
92
 
93
 
94
  @app.get("/")
95
  async def root():
96
+ return PlainTextResponse("🎨 Image AI server running (small Stable Diffusion)")
97
 
98
 
99
  @app.get("/ask")
 
124
  data = db[message]
125
 
126
  if data["status"] == "pending":
127
+ return PlainTextResponse("generating...")
128
 
129
  return PlainTextResponse(data["reply"])
130
 
131
 
132
+ # 🔥 отдача изображения
133
+ @app.get("/image")
134
+ async def get_image(path: str):
135
+ if not os.path.exists(path):
136
+ return PlainTextResponse("file not found")
137
+
138
+ return FileResponse(path)
139
+
140
+
141
  if __name__ == "__main__":
142
  uvicorn.run(app, host="0.0.0.0", port=7860)