Rid3 commited on
Commit
3808e95
·
verified ·
1 Parent(s): 0e057d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -63
app.py CHANGED
@@ -6,9 +6,9 @@ from pydantic import BaseModel
6
  from llama_cpp import Llama
7
  from huggingface_hub import hf_hub_download
8
 
9
- app = FastAPI(title="Xtime GGUF Remote API")
10
 
11
- # Настройка CORS для удаленного подключения
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
@@ -17,87 +17,77 @@ app.add_middleware(
17
  allow_headers=["*"],
18
  )
19
 
20
- # Глобальные переменные для хранения текущей модели в памяти
21
- current_llm = None
22
- current_model_id = "" # format: repo_id/filename
23
 
24
  class ChatRequest(BaseModel):
25
- repo_id: str # Ссылка на репозиторий (напр. "bartowski/Llama-3.2-3B-Instruct-GGUF")
26
- filename: str # Имя файла (напр. "Llama-3.2-3B-Instruct-Q4_K_M.gguf")
27
- prompt: str # Текст пользователя
28
  system_prompt: str = "You are a helpful assistant."
29
  max_tokens: int = 512
30
  temperature: float = 0.7
31
 
32
- def load_model_if_new(repo_id: str, filename: str):
33
- """Загружает модель, если она еще не в памяти или если пришла новая ссылка"""
34
- global current_llm, current_model_id
35
-
36
- new_model_id = f"{repo_id}/{filename}"
37
-
38
- # Если модель уже загружена, просто выходим
39
- if current_llm is not None and current_model_id == new_model_id:
40
- return
41
-
42
- print(f"--- Загрузка новой модели: {new_model_id} ---")
43
-
44
- # Очистка памяти перед загрузкой новой модели
45
- if current_llm is not None:
46
- del current_llm
47
- gc.collect()
48
-
49
- try:
50
- # Скачивание файла с Hugging Face (использует кэш, если файл уже есть)
51
- model_path = hf_hub_download(repo_id=repo_id, filename=filename)
52
-
53
- # Инициализация Llama
54
- current_llm = Llama(
55
- model_path=model_path,
56
- n_ctx=2048,
57
- n_threads=os.cpu_count() or 4,
58
- n_gpu_layers=0, # Установите > 0, если у вас есть GPU
59
- verbose=False
60
- )
61
- current_model_id = new_model_id
62
- print(f"✅ Модель {filename} успешно загружена и готова")
63
- except Exception as e:
64
- print(f"❌ Ошибка при загрузке модели: {e}")
65
- raise HTTPException(status_code=500, detail=f"Failed to load model: {str(e)}")
66
 
67
  @app.post("/chat")
68
  async def chat(request: ChatRequest):
69
- """Эндпоинт для чата, который сам переключает модели"""
70
- # 1. Проверяем/загружаем модель
71
- load_model_if_new(request.repo_id, request.filename)
72
-
73
  try:
74
- # 2. Генерация ответа (базовый формат, подходящий для большинства моделей)
75
- formatted_prompt = f"System: {request.system_prompt}\nUser: {request.prompt}\nAssistant:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
- output = current_llm.create_completion(
78
- prompt=formatted_prompt,
79
  max_tokens=request.max_tokens,
80
  temperature=request.temperature,
81
- stop=["User:", "System:", "</s>", "<|endoftext|>"]
82
  )
83
 
84
  return {
85
  "response": output["choices"][0]["text"].strip(),
86
- "model_id": current_model_id
87
  }
 
88
  except Exception as e:
89
- print(f"Ошибка генерации: {e}")
90
- raise HTTPException(status_code=500, detail="Generation error")
91
-
92
- @app.get("/health")
93
- async def health():
94
- """Проверка состояния сервера"""
95
- return {
96
- "status": "online",
97
- "current_model": current_model_id if current_model_id else "None"
98
- }
99
 
100
  if __name__ == "__main__":
101
  import uvicorn
102
- # Запуск на порту 7860 (стандарт для HF Spaces)
 
 
 
 
 
 
 
 
 
103
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
6
  from llama_cpp import Llama
7
  from huggingface_hub import hf_hub_download
8
 
9
+ app = FastAPI()
10
 
11
+ # Разрешаем все подключения
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
 
17
  allow_headers=["*"],
18
  )
19
 
20
+ # Глобальная переменная для модели
21
+ model = None
22
+ current_id = ""
23
 
24
  class ChatRequest(BaseModel):
25
+ repo_id: str
26
+ filename: str
27
+ prompt: str
28
  system_prompt: str = "You are a helpful assistant."
29
  max_tokens: int = 512
30
  temperature: float = 0.7
31
 
32
+ @app.get("/")
33
+ async def health():
34
+ return {"status": "online", "info": "Server is running. Send POST to /chat"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  @app.post("/chat")
37
  async def chat(request: ChatRequest):
38
+ global model, current_id
39
+
40
+ new_id = f"{request.repo_id}/{request.filename}"
41
+
42
  try:
43
+ # 1. Загружаем модель, если она еще не в памяти
44
+ if model is None or current_id != new_id:
45
+ print(f"--- Loading model: {new_id} ---")
46
+ if model is not None:
47
+ del model
48
+ gc.collect()
49
+
50
+ # Скачивание файла (использует кэш HF)
51
+ path = hf_hub_download(repo_id=request.repo_id, filename=request.filename)
52
+
53
+ model = Llama(
54
+ model_path=path,
55
+ n_ctx=2048, # Оптимально для 16ГБ RAM
56
+ n_threads=os.cpu_count() or 4,
57
+ n_gpu_layers=0, # Только CPU
58
+ verbose=False
59
+ )
60
+ current_id = new_id
61
+
62
+ # 2. Форматируем промпт и генерируем ответ
63
+ full_prompt = f"System: {request.system_prompt}\nUser: {request.prompt}\nAssistant:"
64
 
65
+ output = model.create_completion(
66
+ prompt=full_prompt,
67
  max_tokens=request.max_tokens,
68
  temperature=request.temperature,
69
+ stop=["User:", "System:", "</s>"]
70
  )
71
 
72
  return {
73
  "response": output["choices"][0]["text"].strip(),
74
+ "model": current_id
75
  }
76
+
77
  except Exception as e:
78
+ print(f"Error: {e}")
79
+ raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
 
 
 
80
 
81
  if __name__ == "__main__":
82
  import uvicorn
83
+
84
+ # Автоматический вывод ссылки для подключения
85
+ space_id = os.getenv("SPACE_ID")
86
+ if space_id:
87
+ # Прямая ссылка на API для внешних программ
88
+ host_link = f"https://{space_id.replace('/', '-').lower()}.hf.space/chat"
89
+ print("\n" + "="*50)
90
+ print(f"URL ДЛЯ ПОДКЛЮЧЕНИЯ:\n{host_link}")
91
+ print("="*50 + "\n")
92
+
93
  uvicorn.run(app, host="0.0.0.0", port=7860)