rahmanansah commited on
Commit
6bab504
·
verified ·
1 Parent(s): f5e9ff9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -89
app.py CHANGED
@@ -1,105 +1,90 @@
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
- from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
4
  import torch
5
- import requests
6
- import os
7
 
8
- # 🔹 Model Translator (lokal di Space)
9
- MODELS = {
10
- "in2bg": "rahmanansah/t5-id-bugis",
11
- "bg2id": "rahmanansah/t5-bugis-id"
12
- }
13
-
14
- loaded_models = {}
15
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
16
-
17
- def load_model(model_id):
18
- tokenizer = AutoTokenizer.from_pretrained(model_id)
19
- model = AutoModelForSeq2SeqLM.from_pretrained(model_id).to(device)
20
- return tokenizer, model
21
-
22
- for key, model_id in MODELS.items():
23
- print(f"🔄 Loading {key} -> {model_id}")
24
- loaded_models[key] = load_model(model_id)
25
- print("✅ Semua model sudah diload")
26
-
27
- # 🔹 Model Chat (panggil API Hugging Face)
28
- HF_TOKEN = os.getenv("HF_TOKEN")
29
- QWEN_MODEL = "Qwen/Qwen2.5-1.5B-Instruct"
30
- HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
31
-
32
- def query_hf(model_id, inputs, parameters=None):
33
- url = f"https://api-inference.huggingface.co/models/{model_id}"
34
- payload = {"inputs": inputs}
35
- if parameters:
36
- payload["parameters"] = parameters
37
- response = requests.post(url, headers=HEADERS, json=payload)
38
- if response.status_code == 200:
39
- return response.json()
40
- else:
41
- return {"error": f"{response.status_code}: {response.text}"}
42
-
43
- # 🔹 FastAPI
44
  app = FastAPI()
45
 
46
- class TranslateInput(BaseModel):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  text: str
48
  model: str # "in2bg" atau "bg2id"
49
 
50
- @app.post("/translate")
51
- def translate(input: TranslateInput):
52
- if input.model not in loaded_models:
53
- return {"error": f"Model '{input.model}' tidak tersedia. Pilihan: {list(loaded_models.keys())}"}
54
-
55
- tokenizer, model = loaded_models[input.model]
56
- text = input.text.strip()
57
-
58
- if not text:
59
- return {"result": ""}
60
-
61
- if input.model == "in2bg":
62
- prefixed_text = f"translate id2bg: {text}"
63
- else:
64
- prefixed_text = f"translate bg2id: {text}"
65
-
66
- inputs = tokenizer(prefixed_text, return_tensors="pt").to(device)
67
- outputs = model.generate(**inputs, max_length=64)
68
- decoded = tokenizer.decode(outputs[0], skip_special_tokens=True)
69
-
70
- return {"result": decoded}
71
-
72
- # 🔹 Chat endpoint
73
- class ChatInput(BaseModel):
74
- text: str
75
 
76
- @app.post("/chat")
77
- def chat(input: ChatInput):
78
- user_input = input.text.strip()
79
- if not user_input:
80
- return {"reply": "Teks kosong, silakan masukkan sesuatu."}
81
 
82
- # --- Jika prefiks "terjemahkan:", arahkan ke translator ---
83
- if user_input.lower().startswith("terjemahkan:"):
84
- clean_text = user_input[len("terjemahkan:"):].strip()
85
- if not clean_text:
86
- return {"reply": "Silakan masukkan teks setelah 'terjemahkan:'"}
87
-
88
- # Default Indo -> Bugis
89
- tokenizer, model = loaded_models["in2bg"]
90
- inputs = tokenizer(f"translate id2bg: {clean_text}", return_tensors="pt").to(device)
91
- outputs = model.generate(**inputs, max_length=64)
92
- decoded = tokenizer.decode(outputs[0], skip_special_tokens=True)
93
- return {"reply": decoded}
94
 
95
- # --- Jika bukan, pakai Qwen chatbot ---
96
- result = query_hf(QWEN_MODEL, user_input, parameters={"max_new_tokens": 200})
97
- if isinstance(result, list) and "generated_text" in result[0]:
98
- reply = result[0]["generated_text"]
 
 
 
 
 
99
  else:
100
- reply = result.get("error", "Terjadi kesalahan pada model interaktif.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  return {"reply": reply}
102
 
 
 
 
103
  if __name__ == "__main__":
104
- import uvicorn
105
- uvicorn.run("app:app", host="0.0.0.0", port=7860)
 
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, AutoModelForCausalLM
4
  import torch
5
+ import uvicorn
 
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  app = FastAPI()
8
 
9
+ # ----------------------------
10
+ # Load model Indonesia → Bugis
11
+ # ----------------------------
12
+ model_in2bg_name = "rahmanansah/in2bg" # ganti sesuai repo kamu
13
+ tokenizer_in2bg = AutoTokenizer.from_pretrained(model_in2bg_name)
14
+ model_in2bg = AutoModelForSeq2SeqLM.from_pretrained(model_in2bg_name)
15
+
16
+ # ----------------------------
17
+ # Load model Bugis → Indonesia
18
+ # ----------------------------
19
+ model_bg2id_name = "rahmanansah/bg2id" # ganti sesuai repo kamu
20
+ tokenizer_bg2id = AutoTokenizer.from_pretrained(model_bg2id_name)
21
+ model_bg2id = AutoModelForSeq2SeqLM.from_pretrained(model_bg2id_name)
22
+
23
+ # ----------------------------
24
+ # Load model Chat Qwen
25
+ # ----------------------------
26
+ model_qwen_name = "Qwen/Qwen2.5-1.5B-Instruct"
27
+ tokenizer_qwen = AutoTokenizer.from_pretrained(model_qwen_name)
28
+ model_qwen = AutoModelForCausalLM.from_pretrained(model_qwen_name, torch_dtype=torch.float16, device_map="auto")
29
+
30
+ # ----------------------------
31
+ # Request / Response Models
32
+ # ----------------------------
33
+ class TranslateRequest(BaseModel):
34
  text: str
35
  model: str # "in2bg" atau "bg2id"
36
 
37
+ class TranslateResponse(BaseModel):
38
+ result: str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ class ChatRequest(BaseModel):
41
+ message: str
 
 
 
42
 
43
+ class ChatResponse(BaseModel):
44
+ reply: str
 
 
 
 
 
 
 
 
 
 
45
 
46
+ # ----------------------------
47
+ # Translate Endpoint
48
+ # ----------------------------
49
+ @app.post("/translate", response_model=TranslateResponse)
50
+ def translate(req: TranslateRequest):
51
+ if req.model == "in2bg":
52
+ tokenizer, model = tokenizer_in2bg, model_in2bg
53
+ elif req.model == "bg2id":
54
+ tokenizer, model = tokenizer_bg2id, model_bg2id
55
  else:
56
+ return {"result": f"Model '{req.model}' tidak dikenali"}
57
+
58
+ inputs = tokenizer(req.text, return_tensors="pt", padding=True, truncation=True)
59
+ with torch.no_grad():
60
+ outputs = model.generate(**inputs, max_length=128)
61
+ result = tokenizer.decode(outputs[0], skip_special_tokens=True)
62
+ return {"result": result}
63
+
64
+ # ----------------------------
65
+ # Chat Endpoint
66
+ # ----------------------------
67
+ @app.post("/chat", response_model=ChatResponse)
68
+ def chat(req: ChatRequest):
69
+ prompt = f"User: {req.message}\nAssistant:"
70
+ inputs = tokenizer_qwen(prompt, return_tensors="pt").to(model_qwen.device)
71
+
72
+ with torch.no_grad():
73
+ outputs = model_qwen.generate(
74
+ **inputs,
75
+ max_new_tokens=200,
76
+ temperature=0.7,
77
+ top_p=0.9,
78
+ do_sample=True
79
+ )
80
+
81
+ reply = tokenizer_qwen.decode(outputs[0], skip_special_tokens=True)
82
+ # hapus prompt biar hasil lebih bersih
83
+ reply = reply.replace(prompt, "").strip()
84
  return {"reply": reply}
85
 
86
+ # ----------------------------
87
+ # Run Local (kalau di test manual)
88
+ # ----------------------------
89
  if __name__ == "__main__":
90
+ uvicorn.run(app, host="0.0.0.0", port=7860)