dev / chatbot_indonesian.py
syempuna's picture
Create chatbot_indonesian.py
3adc01b verified
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
import torch
class IndonesianChatbot:
def __init__(self):
"""Initialize Indonesian chatbot with multiple model options"""
self.device = 0 if torch.cuda.is_available() else -1
self.models = {}
self.tokenizers = {}
def load_model(self, model_type="bahasa_gpt"):
"""Load Indonesian chatbot model based on type"""
if model_type == "bahasa_gpt" and "bahasa_gpt" not in self.models:
# BahasaGPT - Best untuk Indonesian chat (7B parameters)
model_name = "Bahasalab/BahasaGpt-chat"
self.tokenizers["bahasa_gpt"] = AutoTokenizer.from_pretrained(model_name)
self.models["bahasa_gpt"] = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
device_map="auto" if torch.cuda.is_available() else None
)
elif model_type == "indo_gpt" and "indo_gpt" not in self.models:
# IndoGPT - Alternative bagus
model_name = "indolem/indobart-v2"
self.models["indo_gpt"] = pipeline(
"text-generation",
model=model_name,
device=self.device,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
)
elif model_type == "sea_llm" and "sea_llm" not in self.models:
# SeaLLM - Multi-language termasuk Indonesian
model_name = "SeaLLMs/SeaLLM-7B-v2-Chat"
self.tokenizers["sea_llm"] = AutoTokenizer.from_pretrained(model_name)
self.models["sea_llm"] = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
device_map="auto" if torch.cuda.is_available() else None
)
elif model_type == "gemma_id" and "gemma_id" not in self.models:
# Gemma fine-tuned untuk Indonesian
model_name = "google/gemma-2b-it" # Lightweight option
self.models["gemma_id"] = pipeline(
"text-generation",
model=model_name,
device=self.device,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
)
def chat_with_bahasa_gpt(self, message, history=None, max_tokens=512, temperature=0.7):
"""Chat using BahasaGPT model"""
if "bahasa_gpt" not in self.models:
self.load_model("bahasa_gpt")
tokenizer = self.tokenizers["bahasa_gpt"]
model = self.models["bahasa_gpt"]
# Format conversation history
conversation = ""
if history:
for turn in history:
role = turn.get("role", "user")
content = turn.get("content", "")
if role == "user":
conversation += f"Human: {content}\n"
elif role == "assistant":
conversation += f"Assistant: {content}\n"
conversation += f"Human: {message}\nAssistant:"
# Tokenize and generate
inputs = tokenizer.encode(conversation, return_tensors="pt")
if torch.cuda.is_available():
inputs = inputs.to("cuda")
with torch.no_grad():
outputs = model.generate(
inputs,
max_new_tokens=max_tokens,
temperature=temperature,
do_sample=True,
top_p=0.95,
pad_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# Extract only the new assistant response
response = response.replace(conversation, "").strip()
return response
def chat_with_sea_llm(self, message, history=None, max_tokens=512, temperature=0.7):
"""Chat using SeaLLM model"""
if "sea_llm" not in self.models:
self.load_model("sea_llm")
tokenizer = self.tokenizers["sea_llm"]
model = self.models["sea_llm"]
# Format prompt for SeaLLM
system_message = "Kamu adalah asisten AI yang membantu dalam bahasa Indonesia."
conversation = f"<|system|>\n{system_message}\n"
if history:
for turn in history:
role = turn.get("role", "user")
content = turn.get("content", "")
if role == "user":
conversation += f"<|user|>\n{content}\n"
elif role == "assistant":
conversation += f"<|assistant|>\n{content}\n"
conversation += f"<|user|>\n{message}\n<|assistant|>\n"
inputs = tokenizer.encode(conversation, return_tensors="pt")
if torch.cuda.is_available():
inputs = inputs.to("cuda")
with torch.no_grad():
outputs = model.generate(
inputs,
max_new_tokens=max_tokens,
temperature=temperature,
do_sample=True,
top_p=0.95,
eos_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
response = response.replace(conversation, "").strip()
return response
def chat_with_pipeline(self, message, model_type="gemma_id", max_tokens=512, temperature=0.7):
"""Chat using pipeline models"""
if model_type not in self.models:
self.load_model(model_type)
pipeline_model = self.models[model_type]
prompt = f"Pertanyaan: {message}\nJawaban:"
result = pipeline_model(
prompt,
max_new_tokens=max_tokens,
temperature=temperature,
do_sample=True,
top_p=0.95,
truncation=True
)
response = result[0]['generated_text'].replace(prompt, "").strip()
return response
# Global chatbot instance
chatbot = IndonesianChatbot()
def chat_indonesian(message, history=None, system_message="", max_tokens=512, temperature=0.7, model_type="bahasa_gpt"):
"""
Main chat function for Indonesian chatbot
Args:
message (str): User message
history (list): Conversation history
system_message (str): System prompt
max_tokens (int): Maximum tokens to generate
temperature (float): Temperature for generation
model_type (str): "bahasa_gpt", "sea_llm", "indo_gpt", "gemma_id"
"""
try:
if model_type == "bahasa_gpt":
return chatbot.chat_with_bahasa_gpt(message, history, max_tokens, temperature)
elif model_type == "sea_llm":
return chatbot.chat_with_sea_llm(message, history, max_tokens, temperature)
elif model_type in ["indo_gpt", "gemma_id"]:
return chatbot.chat_with_pipeline(message, model_type, max_tokens, temperature)
else:
return chatbot.chat_with_bahasa_gpt(message, history, max_tokens, temperature)
except Exception as e:
print(f"Chat error with {model_type}: {e}")
return f"Maaf, terjadi kesalahan: {str(e)}"
# Wrapper untuk kompatibilitas
def chat_simple(message):
"""Simple wrapper for quick testing"""
return chat_indonesian(message, model_type="bahasa_gpt")