File size: 6,497 Bytes
59ac0fe 0485056 83d8c54 0485056 83d8c54 d5d4e8c 83d8c54 0485056 83d8c54 d5d4e8c 83d8c54 59ac0fe 83d8c54 d5d4e8c 83d8c54 d5d4e8c 83d8c54 d5d4e8c 83d8c54 d5d4e8c 83d8c54 d5d4e8c 83d8c54 59ac0fe |
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 |
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import gradio as gr
import numpy as np # Import numpy jika belum ada
# --- 1. Inisialisasi Model dan Tokenizer (Dilakukan Sekali Saat Aplikasi Dimulai) ---
# Pastikan 'model_name' ini adalah model yang sudah kamu unggah ke Hugging Face Hub
# atau model publik lain yang ingin kamu gunakan.
model_name = "atsnetwork/my-custom-tinyllama-chatbot"
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token # Pastikan token padding diatur
tokenizer.padding_side = "right" # Penting untuk efisiensi saat memproses sequence
# --- 2. Fungsi Pemroses Utama untuk Chatbot (Dipanggil Oleh Gradio) ---
# Fungsi ini mengintegrasikan logika inferensi dan analisis developer info
def generate_response_with_dev_info(prompt, max_new_tokens=100, temperature=0.6, top_k=30):
formatted_prompt = f"<s>[INST] {prompt} [/INST]"
inputs = tokenizer(formatted_prompt, return_tensors="pt").to(model.device)
# Generate dengan output_scores=True untuk analisis probabilitas
outputs = model.generate(
**inputs,
max_new_tokens=max_new_tokens,
do_sample=True,
temperature=temperature,
top_k=top_k,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.pad_token_id,
return_dict_in_generate=True,
output_scores=True
)
generated_ids = outputs.sequences[0]
generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
# Ekstrak jawaban bersih
answer = ""
start_answer = generated_text.find("[/INST]")
if start_answer != -1:
answer = generated_text[start_answer + len("[/INST]"):].strip()
if answer.endswith("</s>"):
answer = answer[:-len("</s>")].strip()
else:
answer = generated_text.strip() # Fallback jika format tidak ditemukan
# --- Analisis Konfidensi Berbasis ENTROPY (PENGGANTI avg_max_prob) ---
avg_entropy = 0
total_generated_tokens = 0
if outputs.scores:
for score_tensor in outputs.scores:
probabilities = torch.softmax(score_tensor, dim=-1)
# Menghitung entropy untuk setiap distribusi probabilitas
epsilon = 1e-9 # Tambahkan sedikit epsilon untuk menghindari log(0)
entropy = -torch.sum(probabilities * torch.log(probabilities + epsilon), dim=-1).item()
avg_entropy += entropy
total_generated_tokens += 1
if total_generated_tokens > 0:
avg_entropy /= total_generated_tokens
else:
# Jika tidak ada token yang dihasilkan setelah prompt (kasus jarang)
avg_entropy = float('inf')
# Batas ambang keyakinan (contoh) untuk ENTROPY
# Penting: Nilai ini HARUS ditentukan setelah analisis empiris pada modelmu.
# Nilai entropy yang lebih RENDAH berarti model lebih YAKIN.
# Nilai entropy yang lebih TINGGI berarti model lebih TIDAK YAKIN.
# Sebagai titik awal, kamu bisa coba sekitar 1.0 atau lebih,
# tetapi validasi empiris sangat dianjurkan.
entropy_threshold = 1.0 # <--- SESUAIKAN NILAI INI BERDASARKAN ANALISISMU!
if avg_entropy > entropy_threshold: # <--- Perhatikan operatornya berubah (lebih besar = LOW_CONFIDENCE)
confidence_status = "LOW_CONFIDENCE: Model mungkin tidak memiliki pola yang jelas (Entropy Tinggi)."
else:
confidence_status = "HIGH_CONFIDENCE"
# --- Analisis Frasa "Tidak Tahu" yang Dilatih ---
is_explicitly_unknown = False
explicit_unknown_reason = ""
unknown_phrases = [
"maaf, saya tidak memiliki informasi",
"saya tidak familiar dengan",
"di luar cakupan data pelatihan saya",
"saya tidak tahu",
"tidak dapat menemukan informasi"
]
answer_lower = answer.lower()
for phrase in unknown_phrases:
if phrase in answer_lower:
is_explicitly_unknown = True
explicit_unknown_reason = f"Model menggunakan frasa 'tidak tahu': '{phrase}'"
break # Hentikan setelah menemukan frasa pertama
# --- Gabungkan Informasi untuk Developer ---
developer_info = {
"confidence_score": f"{avg_entropy:.4f}", # Sekarang ini adalah entropy
"confidence_status": confidence_status,
"explicit_unknown_phrase_detected": is_explicitly_unknown,
"explicit_unknown_reason": explicit_unknown_reason if is_explicitly_unknown else "Tidak ada frasa 'tidak tahu' eksplisit.",
# "raw_generated_text": generated_text # Bisa diaktifkan untuk debug, tapi akan terlihat di UI
}
# Untuk tampilan user, hanya tampilkan jawabannya.
# Informasi developer bisa ditampilkan di antarmuka terpisah atau log.
return answer, developer_info
# --- 3. Fungsi Adaptor untuk Gradio Interface (Mengonversi Dictionary info menjadi String) ---
# Gradio Interface mengharapkan output string/angka, bukan dictionary.
# Fungsi ini akan mengubah dictionary developer_info menjadi string yang mudah dibaca.
def gradio_interface_fn(prompt):
answer, dev_info = generate_response_with_dev_info(prompt)
# Format developer info untuk ditampilkan di Gradio
dev_info_str = "--- Developer Info ---\n"
dev_info_str += f"Confidence Score (Entropy): {dev_info['confidence_score']} ({dev_info['confidence_status']})\n"
dev_info_str += f"Explicit Unknown Phrase Detected: {dev_info['explicit_unknown_phrase_detected']}\n"
dev_info_str += f"Reason: {dev_info['explicit_unknown_reason']}\n"
# dev_info_str += f"Raw Generated Text: {dev_info['raw_generated_text']}\n"
return answer, dev_info_str
# --- 4. Inisialisasi Antarmuka Gradio ---
# Ini yang akan membangun UI di Hugging Face Space.
iface = gr.Interface(
fn=gradio_interface_fn, # Fungsi yang akan dipanggil saat ada input
inputs=gr.Textbox(lines=2, label="Your Question"), # Input berupa kotak teks untuk pertanyaan
outputs=[
gr.Textbox(label="Chatbot Response", lines=5), # Output pertama untuk jawaban chatbot
gr.Textbox(label="Developer Information", lines=5) # Output kedua untuk informasi developer
],
title="TinyLlama Custom Chatbot with Developer Insights π",
description="Ask anything and get a response from the chatbot. Additional information for developers will be displayed below."
)
# --- 5. Jalankan Aplikasi Gradio ---
iface.launch() |