|
|
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: |
|
|
|
|
|
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: |
|
|
|
|
|
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: |
|
|
|
|
|
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: |
|
|
|
|
|
model_name = "google/gemma-2b-it" |
|
|
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"] |
|
|
|
|
|
|
|
|
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:" |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
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"] |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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)}" |
|
|
|
|
|
|
|
|
def chat_simple(message): |
|
|
"""Simple wrapper for quick testing""" |
|
|
return chat_indonesian(message, model_type="bahasa_gpt") |