from flask import Flask, request, render_template_string, Response, stream_with_context import os import time import json import subprocess import atexit import requests from huggingface_hub import hf_hub_download app = Flask(__name__) # --- ১. আসল ১-বিট Bonsai চালানোর জন্য PrismML-এর llama.cpp ফর্ক বিল্ড করা --- # stock llama-cpp-python-এ Q1_0-এর দ্রুত কার্নেল নেই, তাই আসল স্পিড পেতে # PrismML-এর নিজস্ব ফর্ক সোর্স থেকে বিল্ড করতে হয়। HF Spaces-এ pip install # দিয়ে এটা সম্ভব না, তাই অ্যাপ স্টার্টআপের সময় নিজে থেকে git clone + cmake # build করা হচ্ছে (একবারই হবে, বিল্ড হয়ে গেলে পরের রিস্টার্টে স্কিপ হবে)। LLAMA_CPP_DIR = os.path.join(os.getcwd(), "llama.cpp") LLAMA_SERVER_BIN = os.path.join(LLAMA_CPP_DIR, "build", "bin", "llama-server") LLAMA_SERVER_PORT = 8081 LLAMA_SERVER_URL = f"http://127.0.0.1:{LLAMA_SERVER_PORT}" MODEL_REPO = "prism-ml/Bonsai-1.7B-gguf" MODEL_FILE = "Bonsai-1.7B-Q1_0.gguf" server_process = None llm_ready = False def build_llama_cpp_fork(): """PrismML-এর llama.cpp ফর্ক ক্লোন ও বিল্ড করে (Q1_0 কার্নেলসহ)।""" if os.path.exists(LLAMA_SERVER_BIN): print("✅ llama-server আগে থেকেই বিল্ড করা আছে, বিল্ড স্কিপ করা হলো") return print("⏳ PrismML-এর llama.cpp ফর্ক ক্লোন করা হচ্ছে...") subprocess.run( ["git", "clone", "--depth", "1", "https://github.com/PrismML-Eng/llama.cpp", LLAMA_CPP_DIR], check=True ) print("⏳ CMake কনফিগার করা হচ্ছে...") subprocess.run(["cmake", "-B", "build"], cwd=LLAMA_CPP_DIR, check=True) cpu_count = os.cpu_count() or 2 print(f"⏳ বিল্ড হচ্ছে ({cpu_count} থ্রেড দিয়ে)... এতে কয়েক মিনিট লাগতে পারে") subprocess.run( ["cmake", "--build", "build", "-j", str(cpu_count), "--target", "llama-server"], cwd=LLAMA_CPP_DIR, check=True ) print("✅ বিল্ড সম্পূর্ণ!") def start_llama_server(model_path): """বিল্ড হওয়া llama-server বাইনারি ব্যাকগ্রাউন্ডে চালু করে।""" global server_process cpu_count = os.cpu_count() or 2 print("⏳ llama-server চালু করা হচ্ছে...") server_process = subprocess.Popen([ LLAMA_SERVER_BIN, "-m", model_path, "--host", "127.0.0.1", "--port", str(LLAMA_SERVER_PORT), "-t", str(cpu_count), "-c", "2048" ]) atexit.register(server_process.terminate) # সার্ভার রেডি হওয়া পর্যন্ত অপেক্ষা (হেলথ চেক) for _ in range(90): try: r = requests.get(f"{LLAMA_SERVER_URL}/health", timeout=2) if r.status_code == 200: print("✅ llama-server প্রস্তুত!") return True except Exception: pass time.sleep(2) print("⚠️ নির্ধারিত সময়ে llama-server রেডি হয়নি") return False try: print("⏳ মডেল ডাউনলোড হচ্ছে...") model_path = hf_hub_download( repo_id=MODEL_REPO, filename=MODEL_FILE, local_dir="./models", token=None ) print(f"✅ মডেল ডাউনলোড সম্পূর্ণ: {model_path}") build_llama_cpp_fork() llm_ready = start_llama_server(model_path) except Exception as e: print(f"⚠️ সেটআপে সমস্যা হয়েছে: {e}") llm_ready = False # --- ২. HTML টেমপ্লেট --- HTML_TEMPLATE = """