Spaces:
Sleeping
Sleeping
| import torch | |
| import faiss | |
| import gradio as gr | |
| from transformers import AutoTokenizer, AutoModel, AutoModelForCausalLM, pipeline | |
| # 1. SETUP CPU/GPU (HF Space Free pakai CPU) | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| # 2. EMBEDDING MODEL | |
| embed_id = "sentence-transformers/all-MiniLM-L6-v2" | |
| tok_emb = AutoTokenizer.from_pretrained(embed_id) | |
| model_emb = AutoModel.from_pretrained(embed_id).to(device) | |
| def embed(texts): | |
| inputs = tok_emb(texts, padding=True, truncation=True, return_tensors="pt").to(device) | |
| with torch.no_grad(): | |
| out = model_emb(**inputs) | |
| return out.last_hidden_state.mean(dim=1).cpu().numpy() | |
| # 3. DATABASE KULINER (Masukkan data lengkapmu di sini nanti) | |
| data = [ | |
| "Tahu aci adalah makanan khas Tegal berbahan tahu yang diisi adonan tepung kanji dan digoreng.", | |
| "Olos adalah gorengan khas Tegal berbentuk bola dengan isi kol pedas dan cabai rawit.", | |
| "Kupat glabed adalah makanan tradisional Tegal yang disajikan dengan kuah kental kuning.", | |
| "Sate kambing Tegal terkenal dengan potongan besar dan bumbu minimalis.", | |
| "Teh poci adalah minuman khas Tegal yang disajikan dalam poci tanah liat dengan gula batu.", | |
| "Nasi lengko adalah makanan khas Cirebon berisi tahu, tempe, tauge, dan sambal kacang.", | |
| "Empal gentong adalah sup daging khas Cirebon yang dimasak dalam gentong tanah liat.", | |
| "Mendoan adalah tempe goreng setengah matang khas Banyumas.", | |
| "Gudeg adalah makanan khas Yogyakarta berbahan nangka muda dimasak santan.", | |
| "Rawon adalah sup daging hitam khas Jawa Timur dengan kluwek.", | |
| "Soto Kudus adalah soto ayam khas Kudus dengan kuah bening ringan.", | |
| "Pecel adalah makanan Jawa dengan sayuran rebus dan sambal kacang.", | |
| "Bakso adalah makanan populer Indonesia berbentuk bola daging dalam kuah kaldu.", | |
| "Rendang adalah masakan daging khas Minang dimasak lama dengan santan dan rempah.", | |
| "Pempek adalah makanan khas Palembang berbahan ikan dan sagu disajikan dengan cuko.", | |
| "Soto Betawi menggunakan santan dan daging sapi sebagai bahan utama.", | |
| "Kerak telor adalah makanan tradisional Betawi berbahan telur dan beras ketan.", | |
| "Lumpia Semarang berisi rebung, telur, dan ayam atau udang.", | |
| "Papeda adalah makanan khas Papua berbentuk bubur sagu.", | |
| "Coto Makassar adalah sup daging dengan bumbu kacang khas Sulawesi Selatan." | |
| ] | |
| vecs = embed(data) | |
| index = faiss.IndexFlatL2(vecs.shape[1]) | |
| index.add(vecs) | |
| def retrieve(q): | |
| v = embed([q]) | |
| _, I = index.search(v, 2) | |
| return [data[i] for i in I[0]] | |
| # 4. LOAD GEMMA (Ganti ke forti2026/gemma-3-1b-chatbot-skripsi) | |
| llm_id = "google/gemma-2b-it" | |
| tok_llm = AutoTokenizer.from_pretrained(llm_id) | |
| model_llm = AutoModelForCausalLM.from_pretrained( | |
| llm_id, | |
| device_map="cpu", # Paksa CPU biar aman di Space gratisan | |
| torch_dtype=torch.float32 # CPU lebih stabil pakai float32 | |
| ) | |
| pipe = pipeline("text-generation", model=model_llm, tokenizer=tok_llm) | |
| # 5. FUNGSI UTAMA API | |
| def chat_api(pertanyaan): | |
| konteks = "\n".join(retrieve(pertanyaan)) | |
| prompt = f"<start_of_turn>user\nJawab berdasarkan konteks berikut:\n\n{konteks}\n\nPertanyaan: {pertanyaan}<end_of_turn>\n<start_of_turn>model\n" | |
| hasil = pipe( | |
| prompt, | |
| max_new_tokens=150, | |
| temperature=0.1, | |
| do_sample=True, # Memperbaiki warning tadi | |
| return_full_text=False | |
| )[0]["generated_text"] | |
| return hasil.strip() | |
| # 6. GRADIO INTERFACE (Ini yang bikin jadi API otomatis) | |
| iface = gr.Interface( | |
| fn=chat_api, | |
| inputs=gr.Textbox(lines=2, placeholder="Tanya soal kuliner Tegal..."), | |
| outputs="text", | |
| title="API RAG Chatbot Tegal", | |
| description="Backend untuk aplikasi Next.js Skripsi" | |
| ) | |
| iface.launch() |