maddingface commited on
Commit
8e4b2e1
Β·
verified Β·
1 Parent(s): fd04e7b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -0
app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ # Set these before importing llama_cpp.
4
+ # They affect BLAS/OpenMP-style CPU threading.
5
+ CPU_COUNT = os.cpu_count() or 2
6
+ CPU_THREADS = int(os.getenv("CPU_THREADS", str(CPU_COUNT)))
7
+
8
+ os.environ.setdefault("OMP_NUM_THREADS", str(CPU_THREADS))
9
+ os.environ.setdefault("OPENBLAS_NUM_THREADS", str(CPU_THREADS))
10
+ os.environ.setdefault("MKL_NUM_THREADS", str(CPU_THREADS))
11
+ os.environ.setdefault("NUMEXPR_NUM_THREADS", str(CPU_THREADS))
12
+
13
+ from pathlib import Path
14
+
15
+ import gradio as gr
16
+ from huggingface_hub import hf_hub_download
17
+ from llama_cpp import Llama
18
+
19
+
20
+ # Official LFM2.5 target model.
21
+ # Q4_0 is generally the fastest small CPU option.
22
+ MODEL_REPO = os.getenv(
23
+ "MODEL_REPO",
24
+ "LiquidAI/LFM2.5-2.6B-GGUF",
25
+ )
26
+
27
+ MODEL_FILE = os.getenv(
28
+ "MODEL_FILE",
29
+ "LFM2.5-2.6B-Q4_0.gguf",
30
+ )
31
+
32
+ # Keep this moderate on shared CPU Spaces.
33
+ # 2048 is faster than 4096 and is enough for many API requests.
34
+ N_CTX = int(os.getenv("N_CTX", "2048"))
35
+
36
+ # llama.cpp can use all visible CPUs, but shared Spaces may perform
37
+ # better with a slightly lower value. Override with CPU_THREADS.
38
+ N_THREADS = int(os.getenv("CPU_THREADS", str(CPU_COUNT)))
39
+
40
+ MODEL_PATH = hf_hub_download(
41
+ repo_id=MODEL_REPO,
42
+ filename=MODEL_FILE,
43
+ cache_dir="/tmp/huggingface-cache",
44
+ )
45
+
46
+ print(f"Loading model: {MODEL_PATH}")
47
+ print(f"CPU threads: {N_THREADS}")
48
+ print("GPU layers: 0")
49
+ print("Backend: CPU-only")
50
+
51
+
52
+ llm = Llama(
53
+ model_path=MODEL_PATH,
54
+
55
+ # Absolute CPU-only settings.
56
+ n_gpu_layers=0,
57
+ split_mode=0,
58
+ main_gpu=0,
59
+
60
+ # CPU parallelism.
61
+ n_threads=N_THREADS,
62
+ n_threads_batch=N_THREADS,
63
+
64
+ # Prompt-processing batch size.
65
+ # Lower this to 256 if memory is limited.
66
+ n_batch=512,
67
+
68
+ # Context size.
69
+ n_ctx=N_CTX,
70
+
71
+ # Memory/performance settings.
72
+ use_mmap=True,
73
+ use_mlock=False,
74
+
75
+ # Do not use GPU-oriented KV-cache settings.
76
+ offload_kqv=False,
77
+ flash_attn=False,
78
+
79
+ # Prevent noisy native logs after startup.
80
+ verbose=False,
81
+ )
82
+
83
+
84
+ SYSTEM_PROMPT = os.getenv(
85
+ "SYSTEM_PROMPT",
86
+ "You are a helpful, concise assistant.",
87
+ )
88
+
89
+
90
+ def make_prompt(user_prompt: str) -> str:
91
+ """
92
+ LFM2.5 understands the chat-style format stored in the GGUF metadata.
93
+ llama-cpp-python's create_chat_completion applies the model template.
94
+ """
95
+ return user_prompt.strip()
96
+
97
+
98
+ def generate(user_prompt: str) -> str:
99
+ if not user_prompt or not user_prompt.strip():
100
+ return "Please enter a message."
101
+
102
+ response = llm.create_chat_completion(
103
+ messages=[
104
+ {
105
+ "role": "system",
106
+ "content": SYSTEM_PROMPT,
107
+ },
108
+ {
109
+ "role": "user",
110
+ "content": make_prompt(user_prompt),
111
+ },
112
+ ],
113
+
114
+ # Generation settings.
115
+ max_tokens=int(os.getenv("MAX_TOKENS", "512")),
116
+ temperature=float(os.getenv("TEMPERATURE", "0.2")),
117
+ top_p=float(os.getenv("TOP_P", "0.9")),
118
+ top_k=int(os.getenv("TOP_K", "40")),
119
+ repeat_penalty=float(os.getenv("REPEAT_PENALTY", "1.05")),
120
+
121
+ # Avoid unnecessary response metadata.
122
+ stream=False,
123
+ )
124
+
125
+ return response["choices"][0]["message"]["content"].strip()
126
+
127
+
128
+ demo = gr.Interface(
129
+ fn=generate,
130
+ inputs=gr.Textbox(
131
+ label="Prompt",
132
+ placeholder="Ask something...",
133
+ lines=5,
134
+ ),
135
+ outputs=gr.Textbox(
136
+ label="Response",
137
+ lines=12,
138
+ ),
139
+ title="LFM2.5 2.6B CPU API",
140
+ description="LFM2.5 running through a prebuilt CPU llama.cpp wheel.",
141
+ api_name="chat",
142
+ )
143
+
144
+
145
+ if __name__ == "__main__":
146
+ demo.queue(
147
+ max_size=16,
148
+ default_concurrency_limit=1,
149
+ ).launch(
150
+ server_name="0.0.0.0",
151
+ server_port=7860,
152
+ show_api=True,
153
+ )