Spaces:
Paused
Paused
File size: 9,359 Bytes
68b01e5 9a21d12 1f65651 68b01e5 d97bb2a 1f65651 15fe2f0 68b01e5 99ffeb3 68b01e5 1f65651 68b01e5 01d2f88 2b6ba2c 01d2f88 68b01e5 6520c57 1f65651 174d037 5bf2829 174d037 5bf2829 174d037 68b01e5 d97bb2a 1f65651 68b01e5 d97bb2a 68b01e5 1f65651 68b01e5 ee4c323 1f65651 68b01e5 6520c57 68b01e5 6520c57 68b01e5 1f65651 68b01e5 1f65651 68b01e5 1f65651 d858119 68b01e5 174d037 6520c57 68b01e5 f59daa8 68b01e5 1f65651 68b01e5 1f65651 68b01e5 6907b75 1f65651 68b01e5 1f65651 68b01e5 1f65651 68b01e5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | from threading import Thread
import re
import gradio as gr
import spaces
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, StoppingCriteria, StoppingCriteriaList, BitsAndBytesConfig
import sys
print(sys.version)
# DESCRIPTION = """\
# # FinID
# Model ini berbasis dari Qwen2.5 dan dikembangkan lagi menjadi Sailor2, dan di finetunekan menjadi model FinID untuk domain Finansial Keuangan.
# Model ini di finetunekan menggunakan metode PEFT Lora.
# """
DESCRIPTION = """\
# FinID 💸
Chatbot ini dikembangkan menggunakan LLM model Sailor2 8B yang difinetunekan dengan dataset pertanyaan keuangan. \
⚠️ Aplikasi ini dilatih menggunakan dataset keuangan saja, sehingga pertanyaan non-keuangan akan menghasilkan informasi yang non faktual
"""
SYSTEM_PROMPT= \
'You are an AI financial assistant named FinID, Finetuned from base model Qwen2.5. \
As an AI assistant, you can answer questions in English and Indonesian \
Every of your responses should summarized at the end of the explanation \
Your responses should only be within the financial subject, any other prompt or input outside that subject should only be responded with Maaf, saya tidak dapat membantu dengan pertanyaan tersebut karena melanggar kebijakan atau hukum. Silakan ajukan pertanyaan terkait keuangan.'
# SYSTEM_PROMPT= \
# 'Anda adalah asisten keuangan AI bernama FinID. \
# Sebagai asisten AI, Anda dapat menjawab pertanyaan dalam bahasa Inggris dan Indonesia \
# Tanggapan Anda harus singkat jika bisa, ramah, tidak memihak, informatif, rinci, dan setia. \
# Tanggapan Anda hanya boleh dalam subjek keuangan, permintaan atau masukan lain di luar subjek tersebut hanya boleh ditanggapi dengan "Maaf, saya tidak dapat membantu dengan pertanyaan tersebut karena melalui kebijakan atau hukum. Silakan ajukan pertanyaan terkait keuangan."'
# MAX_MAX_NEW_TOKENS = 2048
# DEFAULT_MAX_NEW_TOKENS = 512
restricted_words = [
# Olahraga & aktivitas fisik
"olahraga", "sport", "sports", "sepak bola", "football", "basket", "basketball", "voli", "futsal", "renang",
"bersepeda", "yoga", "fitness", "workout", "gym", "lari", "jogging", "marathon", "bodybuilding",
# Hiburan & budaya populer
"anime", "manga", "komik", "comic", "kartun", "cartoon", "drama", "romance", "horror", "thriller", "action",
"comedy", "film", "movie", "tv series", "series", "Netflix", "Disney", "HBO", "Amazon Prime", "YouTube",
"streaming", "idol", "band", "musik", "lagu", "konser", "album", "artis", "aktor", "aktris", "selebritis",
"selebriti", "gosip", "viral", "trending", "meme", "influencer", "content creator", "tiktok", "vlogger",
# Kuliner & makanan
"makanan", "minuman", "resep", "memasak", "masakan", "masak", "kuliner", "menu", "ayam", "sapi", "ikan",
"rendang", "sate", "bakso", "mie", "lontong", "nasi goreng", "kue", "jajanan", "kopi", "teh", "es krim",
# Hubungan, percintaan, kehidupan pribadi
"pacaran", "cinta", "romantis", "romansa", "dating", "love", "jodoh", "nikah", "pernikahan", "mantan",
"crush", "friendzone", "friendship", "persahabatan", "PDA", "perasaan", "emosi",
# Fashion, kecantikan & gaya hidup
"fashion", "baju", "pakaian", "kaos", "celana", "jaket", "sepatu", "tas", "gaya", "OOTD", "skincare",
"makeup", "lipstik", "kecantikan", "beauty", "perawatan", "spa", "salon",
# Teknologi umum & AI
"AI", "artificial intelligence", "machine learning", "deep learning", "robot", "android", "teknologi",
"smartphone", "gadget", "gawai", "laptop", "hardware", "software", "game", "gaming", "console", "VR", "AR",
# Ilmu pengetahuan umum
"sains", "science", "astronomi", "planet", "galaksi", "bintang", "meteor", "luar angkasa", "kimia", "biologi",
"fisika", "matematika", "matematika diskrit", "aljabar", "statistika", "geografi", "sejarah",
# Filosofi & agama
"filsafat", "filosofi", "agama", "teologi", "psikologi", "mitologi", "mythology", "spiritual", "meditasi",
"karma", "reinkarnasi",
# Hukum & kriminalitas
"legal", "ilegal", "pengadilan", "hakim", "jaksa", "kriminal", "pencurian",
"korupsi", "penipuan", "pembunuhan", "kejahatan", "detektif", "penjara", "narkoba", "obat-obatan",
# Politik, militer, konflik
"politik", "partai", "kampanye", "pemilu", "kandidat", "presiden", "dpr", "militer", "tentara", "perang",
"konflik", "senjata", "roket", "bom", "rudal", "pemberontak", "terorisme",
# Alam, hewan, dan lingkungan
"binatang", "hewan", "anjing", "kucing", "pets", "flora", "fauna", "tumbuhan", "tanaman", "hutan", "alam",
"kebun", "cuaca", "iklim", "climate", "bencana", "gempa", "banjir", "angin", "sustainability", "green energy",
# Lain-lain di luar literasi keuangan
"astrologi", "zodiak", "ramalan", "santet", "sihir", "mistis", "dongeng", "cerita rakyat", "fantasi", "fiksi",
"hantu", "alien", "konspirasi", "misteri"
# Ekstra
"taylor swift", "beyoncé", "kim kardashian", "kylie jenner", "kendall jenner",
"selena gomez", "justin bieber", "ariana grande", "rihanna", "dua lipa",
"shawn mendes", "zendaya", "timothée chalamet", "miley cyrus", "lady gaga",
"harry styles", "olivia rodrigo", "billie eilish", "drake", "the weeknd",
"charli d'amelio", "addison rae", "mrbeast", "pewdiepie", "eminem", "snoop dogg",
"raffi ahmad", "nagita slavina", "ayu ting ting", "lucinta luna", "bts", "lesti",
"rizky billar", "bunga citra lestari", "maudy ayunda", "deddy corbuzier",
"kaesang", "anies", "ahok", "jokowi", "prabowo", "ganjar", "megawati",
"susilo bambang yudhoyono", "sby", "ridwan kamil", "ahmad dhani", "nissa sabyan",
"ferdy sambo", "nikita mirzani", "reza arap", "attahalilintar", "aurel hermansyah",
"joe biden", "donald trump", "barack obama", "hillary clinton", "vladimir putin",
"xi jinping", "kim jong un", "emmanuel macron", "justin trudeau", "narendra modi",
"selebriti", "selebritis", "artis", "aktor", "aktris", "influencer",
"presiden", "gubernur", "menteri", "dpr", "politik", "parpol", "pemilu", "kampanye"
]
model_id = "FOLZi/FinID_v2_8B_Chat"
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id,
trust_remote_code=True,
device_map="auto",
torch_dtype=torch.float16,
quantization_config=quantization_config
)
# model.config.sliding_window = 4096
# model.eval()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using {device.type.upper()}")
# model = model.to(device)
# Defining a custom stopping criteria class for the model's text generation.
class StopOnTokens(StoppingCriteria):
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> bool:
stop_ids = [151645] # consult the tokenizer.
for stop_id in stop_ids:
if input_ids[0][-1] == stop_id: # Checking if the last generated token is a stop token. (Llama and Qwen uses |im_end|)
return True
return False
system_role= 'system'
user_role = 'user'
assistant_role = 'assistant'
sft_start_token = "<|im_start|>"
sft_end_token = "<|im_end|>"
ct_end_token = "<|endoftext|>"
@spaces.GPU()
def generate(message, history):
# Pendeteksian via primitif TOO BAD!
matched_words = [word for word in restricted_words if re.search(rf"\b{word}\b", message, re.IGNORECASE)]
# Jika ditemukan, hentikan proses dan kembalikan pesan peringatan
if matched_words:
yield "Maaf, saya hanya dapat menjawab pertanyaan yang berkaitan dengan literasi keuangan."
return
history = [] # Disabled history.
history_transformer_format = history + [[message, ""]]
stop = StopOnTokens()
# Implementasi Prompt Engineering
messages = SYSTEM_PROMPT + sft_end_token.join([sft_end_token.join([f"\n{sft_start_token}{user_role}\n" + item[0], f"\n{sft_start_token}{assistant_role}\n" + item[1]])
for item in history_transformer_format])
model_inputs = tokenizer([messages], return_tensors="pt").to(device)
streamer = TextIteratorStreamer(tokenizer, timeout=20., skip_prompt=True, skip_special_tokens=True)
generate_kwargs = dict(
model_inputs,
streamer=streamer,
max_new_tokens=512,
do_sample=True,
top_p= 0.5,
top_k= 50,
temperature=0.2,
num_beams=1,
stopping_criteria=StoppingCriteriaList([stop]),
repetition_penalty=1.1,
)
t = Thread(target=model.generate, kwargs=generate_kwargs)
t.start()
partial_message = ""
for new_token in streamer:
partial_message += new_token
if sft_end_token in partial_message: # Stopper
break
yield partial_message
css = """
full-height {
height: 100%;
}
"""
chat_interface = gr.ChatInterface(
fn=generate,
examples=[
["Contoh pertanyaan: Apakah saya boleh menanyakan hal yang non finansial?"]
],
type="messages",
fill_height=True,
css=css
)
with gr.Blocks(theme=gr.themes.Soft(), css_paths="style.css", fill_height=True) as demo:
gr.Markdown(DESCRIPTION)
chat_interface.render()
if __name__ == "__main__":
demo.queue(max_size=20).launch() |