import os import sys import time import re import json import multiprocessing from typing import List, Dict, Any, Optional, Union from contextlib import asynccontextmanager # FastAPI & Pydantic imports from fastapi import FastAPI, Request, HTTPException from fastapi.responses import StreamingResponse, JSONResponse from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel, Field # --------------------------------------------------------------------------- # ⚡ 1. CPU & THREADING OPTIMIZATIONS FOR MoE # --------------------------------------------------------------------------- try: import psutil PHYSICAL_CORES = psutil.cpu_count(logical=False) or max(1, multiprocessing.cpu_count() // 2) except Exception: PHYSICAL_CORES = max(1, multiprocessing.cpu_count() // 2) os.environ["OMP_NUM_THREADS"] = str(PHYSICAL_CORES) os.environ["MKL_NUM_THREADS"] = str(PHYSICAL_CORES) os.environ["OPENBLAS_NUM_THREADS"] = str(PHYSICAL_CORES) os.environ["OMP_PROC_BIND"] = "TRUE" try: p = psutil.Process() if sys.platform == "win32": p.nice(psutil.HIGH_PRIORITY_CLASS) else: p.nice(-15) except Exception: pass import gradio as gr import llama_cpp from llama_cpp import Llama from huggingface_hub import hf_hub_download MODEL_NAME = "arush/jarush" NUMA_STRATEGY = getattr(llama_cpp, "GGML_NUMA_STRATEGY_DISTRIBUTE", False) # Initialize the global LLM variable llm = None def cpu_detect(): import os, subprocess print(subprocess.check_output(["lscpu"], text=True)) print(subprocess.check_output(["free", "-h"], text=True)) # --------------------------------------------------------------------------- # ⚡ 2. FASTAPI LIFESPAN (MODEL DOWNLOAD & INITIALIZATION) # --------------------------------------------------------------------------- @asynccontextmanager async def lifespan(app: FastAPI): global llm print("Downloading MoE model GGUF...") model_path = hf_hub_download( repo_id='mradermacher/Qwen3.6-35B-A3B-Uncensored-HauhauCS-FP16-GGUF', filename="Qwen3.6-35B-A3B-Uncensored-HauhauCS-FP16.Q3_K_S.gguf", ) print("Model downloaded successfully!") print("Initializing llama-cpp MoE Model...") llm = Llama( model_path=model_path, n_gpu_layers=0, # 0 for CPU execution n_ctx=8192, # Threading optimizations n_threads=4, n_threads_batch=4, numa=NUMA_STRATEGY, # ⚡ TURBOQUANT EQUIVALENT SETTINGS: # Quantizing the KV cache to Q4_0 shrinks memory overhead and drastically # reduces RAM bandwidth usage, supercharging CPU generation speeds. type_k=getattr(llama_cpp, "GGML_TYPE_Q8_0", 2), type_v=getattr(llama_cpp, "GGML_TYPE_Q8_0", 2), n_batch=512, n_ubatch=512, #n_draft=3, # ⚡ A3B MoE OPTIMIZATION: # use_mmap=True ensures the OS only pages the active 3B parameters # from disk to RAM, keeping CPU cache thrashing to an absolute minimum. use_mlock=False, use_mmap=True, # FlashAttention removed as requested flash_attn=True, ) print("Server ready!") yield if llm is not None: print("Cleaning up Llama model memory...") del llm llm = None # --------------------------------------------------------------------------- # ⚡ 3. FASTAPI INITIALIZATION & OPENAI PYDANTIC SCHEMAS # --------------------------------------------------------------------------- app = FastAPI(title="OpenAI-Compatible CPU MoE Server", version="1.0.0", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class ChatMessage(BaseModel): role: str content: Union[str, List[Dict[str, Any]]] class ChatCompletionRequest(BaseModel): model: Optional[str] = MODEL_NAME messages: List[ChatMessage] temperature: Optional[float] = 0.7 top_p: Optional[float] = 0.95 max_tokens: Optional[int] = 512 stream: Optional[bool] = False # --------------------------------------------------------------------------- # ⚡ 4. OPENAI-COMPATIBLE REST ENDPOINTS # --------------------------------------------------------------------------- @app.get("/v1/models") async def list_models(): return { "object": "list", "data": [{"id": MODEL_NAME, "object": "model", "created": int(time.time()), "owned_by": "local"}], } async def openai_stream_generator(messages_dict: list, max_tokens: int, temperature: float, top_p: float): global llm if llm is None: yield f"data: {json.dumps({'error': 'Model loading in progress'})}\n\n" return for chunk in llm.create_chat_completion( messages=messages_dict, max_tokens=max_tokens, temperature=temperature, top_p=top_p, stream=True, ): yield f"data: {json.dumps(chunk)}\n\n" yield "data: [DONE]\n\n" @app.post("/v1/chat/completions") async def chat_completions(req: ChatCompletionRequest): global llm if llm is None: raise HTTPException(status_code=503, detail="Model is currently loading or unavailable.") try: messages_dict = [{"role": m.role, "content": m.content} for m in req.messages] if req.stream: return StreamingResponse( openai_stream_generator(messages_dict, req.max_tokens, req.temperature, req.top_p), media_type="text/event-stream", ) else: response = llm.create_chat_completion( messages=messages_dict, max_tokens=req.max_tokens, temperature=req.temperature, top_p=req.top_p, stream=False, ) return JSONResponse(content=response) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # --------------------------------------------------------------------------- # ⚡ 5. GRADIO UI & HISTORY CLEANER # --------------------------------------------------------------------------- def clean_assistant_reply(text): if not text: return "" if isinstance(text, list): extracted = [] for part in text: if isinstance(part, str): extracted.append(part) elif isinstance(part, dict): extracted.append(part.get("text", part.get("content", ""))) text = "".join(extracted) elif not isinstance(text, str): text = str(text) cleaned = re.sub(r'.*?\n*', '', text, flags=re.DOTALL) cleaned = cleaned.replace("", "") cleaned = re.sub(r'\n\n---\n\*⏱️.*?\*$', '', cleaned) return cleaned.strip() def respond(message, history, system_message, max_tokens, temperature, top_p): global llm if llm is None: yield "⚠️ *The model is currently loading. Please wait a few seconds and try again.*" return messages = [{"role": "system", "content": system_message}] for item in history: if isinstance(item, dict): role = item.get("role", "user") content = item.get("content", "") if role == "assistant": content = clean_assistant_reply(content) messages.append({"role": role, "content": content}) elif isinstance(item, (list, tuple)): if item[0]: messages.append({"role": "user", "content": item[0]}) if item[1]: messages.append({"role": "assistant", "content": clean_assistant_reply(item[1])}) messages.append({"role": "user", "content": message}) response = "" token_count = 0 start_time = time.time() for chunk in llm.create_chat_completion( messages=messages, max_tokens=max_tokens, temperature=temperature, top_p=top_p, stream=True, ): delta = chunk["choices"][0]["delta"] if "content" in delta and delta["content"]: response += delta["content"] token_count += 1 yield response end_time = time.time() elapsed_time = end_time - start_time if elapsed_time > 0 and token_count > 0: tps = token_count / elapsed_time response += f"\n\n---\n*⏱️ {tps:.2f} tok/s ({token_count} tokens in {elapsed_time:.2f}s)*" yield response chatbot = gr.ChatInterface( fn=respond, additional_inputs=[ gr.Textbox(value="You are a helpful coding assistant.", label="System message"), gr.Slider(minimum=1, maximum=8192, value=512, step=1, label="Max new tokens"), gr.Slider(minimum=0.1, maximum=2.0, value=0.7, step=0.1, label="Temperature"), gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"), ], title="FREEAPI RUNNING ON CPU Qwen 35B-A3B", ) app = gr.mount_gradio_app(app, chatbot, path="/") # --------------------------------------------------------------------------- # ⚡ 6. SERVER LAUNCH (WITH AUTOMATIC PORT CLEANUP) # --------------------------------------------------------------------------- def free_port(port: int = 7860): """Kills any lingering background process holding the specified port.""" current_pid = os.getpid() try: for conn in psutil.net_connections(kind='inet'): if conn.laddr and conn.laddr.port == port and conn.pid and conn.pid != current_pid: try: print(f"⚠️ Port {port} is held by PID {conn.pid}. Killing process...") p = psutil.Process(conn.pid) p.kill() time.sleep(1.5) # Wait for OS to release the socket print(f"✅ Port {port} freed successfully.") except Exception as e: print(f"Could not kill process {conn.pid}: {e}") except psutil.AccessDenied: pass # Ignore if run in restricted environment without root if __name__ == "__main__": import uvicorn cpu_detect() # Clean up port 7860 before trying to launch free_port(7860) # Port 7860 is required by Hugging Face Spaces for health checks uvicorn.run(app, host="0.0.0.0", port=7860)