Toilatop1sever commited on
Commit
0a73fa9
·
verified ·
1 Parent(s): 31decae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -25
app.py CHANGED
@@ -5,7 +5,9 @@ from pydantic import BaseModel
5
  from llama_cpp import Llama
6
  from huggingface_hub import hf_hub_download
7
  from typing import List, Optional
8
- import os, json, uvicorn
 
 
9
 
10
  app = FastAPI()
11
  app.add_middleware(
@@ -18,38 +20,42 @@ app.add_middleware(
18
  MODEL_REPO = "unsloth/Qwen3-4B-GGUF"
19
  MODEL_FILE = "Qwen3-4B-Q4_K_M.gguf"
20
 
21
- MAX_HISTORY = 4 # Giảm từ 6 xuống 4 để bớt prefill
22
- MAX_CTX = 4096
23
- MAX_TOKENS = 2048 # Giảm nếu không cần sinh dài
24
- THREADS = 2 # Giữ nguyên 2 vCPU
25
 
26
  llm: Optional[Llama] = None
27
 
28
  @app.on_event("startup")
29
  async def startup_event():
30
  global llm
 
31
  if os.path.exists(MODEL_FILE) and os.path.getsize(MODEL_FILE) < 1_000_000:
32
  os.remove(MODEL_FILE)
33
  if not os.path.exists(MODEL_FILE):
34
  print(f"Downloading {MODEL_FILE}...")
35
  hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE, local_dir=".")
36
  print("Download done!")
37
- print("Loading model...")
 
 
38
  llm = Llama(
39
- model_path = MODEL_FILE,
40
- n_ctx = MAX_CTX,
41
- n_threads = THREADS,
42
- n_threads_batch = THREADS, # Thêm nếu llama_cpp hỗ trợ
43
- n_batch = 256, # Giảm mạnh từ 8192 -> 256
44
- n_ubatch = 128, # Giảm từ 512 -> 128
45
- n_gpu_layers = 0,
46
- verbose = False,
47
- use_mmap = True,
48
- use_mlock = False,
49
- flash_attn = True, # Bật flash attention nếu phiên bản hỗ trợ
50
- logits_all = False, # Không cần logits, tiết kiệm
 
51
  )
52
- print("Model ready!")
53
 
54
  class Message(BaseModel):
55
  role: str
@@ -64,16 +70,18 @@ class ChatRequest(BaseModel):
64
  top_p: float = 0.9
65
 
66
  def build_messages(req: ChatRequest) -> list:
67
- # Prompt system ngắn gọn hơn một chút
68
- system = req.system_prompt or "Bạn là trợ lý AI, trả lời bằng tiếng Việt ."
69
  msgs = [{"role": "system", "content": system}]
70
- # Giữ lại tối đa 4 tin nhắn gần nhất (2 lượt)
 
71
  recent_history = req.history[-(MAX_HISTORY * 2):]
72
  for msg in recent_history:
73
  if msg.role in ("user", "assistant") and msg.content.strip():
74
  if msgs[-1]["role"] != msg.role:
75
  msgs.append({"role": msg.role, "content": msg.content.strip()})
76
- # Loại bỏ user cuối nếu trùng, rồi thêm prompt mới
 
77
  if msgs[-1]["role"] == "user":
78
  msgs.pop()
79
  msgs.append({"role": "user", "content": req.prompt.strip()})
@@ -82,7 +90,7 @@ def build_messages(req: ChatRequest) -> list:
82
  @app.post("/chat")
83
  async def chat(req: ChatRequest):
84
  if llm is None:
85
- raise HTTPException(503, "Model chưa sẵn sàng")
86
  if not req.prompt.strip():
87
  raise HTTPException(400, "Prompt trống")
88
  if len(req.prompt) > 4000:
@@ -118,7 +126,11 @@ async def chat(req: ChatRequest):
118
 
119
  @app.get("/")
120
  async def root():
121
- return {"status": "ok" if llm else "loading", "model": MODEL_FILE}
 
 
 
 
122
 
123
  @app.get("/health")
124
  async def health():
 
5
  from llama_cpp import Llama
6
  from huggingface_hub import hf_hub_download
7
  from typing import List, Optional
8
+ import os
9
+ import json
10
+ import uvicorn
11
 
12
  app = FastAPI()
13
  app.add_middleware(
 
20
  MODEL_REPO = "unsloth/Qwen3-4B-GGUF"
21
  MODEL_FILE = "Qwen3-4B-Q4_K_M.gguf"
22
 
23
+ MAX_HISTORY = 4 # Giảm để tiết kiệm token xử
24
+ MAX_CTX = 4096 # Khung ngữ cảnh tối đa
25
+ MAX_TOKENS = 2048 # Giới hạn token sinh ra để giải phóng tài nguyên sớm
26
+ THREADS = 2 # Số luồng CPU, khớp với vCPU bạn có
27
 
28
  llm: Optional[Llama] = None
29
 
30
  @app.on_event("startup")
31
  async def startup_event():
32
  global llm
33
+ # 1. Tải model (xóa file cũ nếu lỗi)
34
  if os.path.exists(MODEL_FILE) and os.path.getsize(MODEL_FILE) < 1_000_000:
35
  os.remove(MODEL_FILE)
36
  if not os.path.exists(MODEL_FILE):
37
  print(f"Downloading {MODEL_FILE}...")
38
  hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE, local_dir=".")
39
  print("Download done!")
40
+
41
+ # 2. Khởi tạo model với các tham số tối ưu cho CPU và RAM
42
+ print("Loading model with RAM-optimized settings...")
43
  llm = Llama(
44
+ model_path = MODEL_FILE,
45
+ n_ctx = MAX_CTX,
46
+ n_threads = THREADS,
47
+ n_threads_batch = THREADS,
48
+ n_batch = MAX_CTX, # Quan trọng: bằng với n_ctx để tối ưu cache
49
+ n_ubatch = 512, # Kích thước micro-batch, cân bằng với n_batch
50
+ n_gpu_layers = 0,
51
+ verbose = False,
52
+ use_mmap = False, # Tắt mmap, load toàn bộ model vào RAM
53
+ use_mlock = True, # Khóa model trong RAM, tránh swap ra ổ cứng
54
+ flash_attn = True, # Bật Flash Attention, giảm tải bộ nhớ
55
+ cache_type_k = "q8_0", # Lượng tử hóa KV cache (Key) xuống 8-bit
56
+ cache_type_v = "q8_0", # Lượng tử hóa KV cache (Value) xuống 8-bit
57
  )
58
+ print("Model ready! All weights and caches are locked in RAM.")
59
 
60
  class Message(BaseModel):
61
  role: str
 
70
  top_p: float = 0.9
71
 
72
  def build_messages(req: ChatRequest) -> list:
73
+ # System prompt ngắn gọn, tiết kiệm token
74
+ system = req.system_prompt or "Bạn là trợ lý AI, trả lời bằng tiếng Việt ngắn gọn."
75
  msgs = [{"role": "system", "content": system}]
76
+
77
+ # Chỉ giữ lại lịch sử tối đa MAX_HISTORY tin nhắn (mỗi lượt gồm user + assistant)
78
  recent_history = req.history[-(MAX_HISTORY * 2):]
79
  for msg in recent_history:
80
  if msg.role in ("user", "assistant") and msg.content.strip():
81
  if msgs[-1]["role"] != msg.role:
82
  msgs.append({"role": msg.role, "content": msg.content.strip()})
83
+
84
+ # Tránh trùng lặp role user cuối
85
  if msgs[-1]["role"] == "user":
86
  msgs.pop()
87
  msgs.append({"role": "user", "content": req.prompt.strip()})
 
90
  @app.post("/chat")
91
  async def chat(req: ChatRequest):
92
  if llm is None:
93
+ raise HTTPException(503, "Model chưa sẵn sàng, thử lại sau!")
94
  if not req.prompt.strip():
95
  raise HTTPException(400, "Prompt trống")
96
  if len(req.prompt) > 4000:
 
126
 
127
  @app.get("/")
128
  async def root():
129
+ return {
130
+ "status" : "ok" if llm else "loading",
131
+ "model" : MODEL_FILE,
132
+ "message" : "Model ready (RAM-optimized)!" if llm else "Model đang tải...",
133
+ }
134
 
135
  @app.get("/health")
136
  async def health():