File size: 5,221 Bytes
88bf4be
 
 
cf587bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88bf4be
 
 
cf587bc
88bf4be
 
 
 
cf587bc
88bf4be
 
cf587bc
 
 
 
 
 
 
88bf4be
cf587bc
 
88bf4be
cf587bc
 
 
 
 
 
88bf4be
cf587bc
88bf4be
 
cf587bc
88bf4be
cf587bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88bf4be
cf587bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88bf4be
cf587bc
 
 
 
 
 
 
 
 
 
 
 
 
88bf4be
cf587bc
03b8b7c
cf587bc
88bf4be
cf587bc
 
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
import gradio as gr
from huggingface_hub import InferenceClient

# ================================
# CẤU HÌNH NHẬN THỨC CỦA AI (TÙY CHỈNH TẠI ĐÂY)
# ================================
AI_NAME = "AI Assistant"
AI_CREATOR = "AI "
AI_DESCRIPTION = (
    "Tôi là một trợ lý trí tuệ nhân tạo được tạo ra bởi Trương Quốc Nam. "
    "Tôi được huấn luyện để hỗ trợ học tập, giải đáp thắc mắc bằng tiếng Việt một cách thân thiện, chính xác và giàu thông tin. "
    "Tôi luôn cố gắng trả lời ngắn gọn, dễ hiểu và có ví dụ minh họa khi cần."
)

DEFAULT_SYSTEM_MESSAGE = f"""
Bạn là {AI_NAME}, một trợ lý AI thông minh và thân thiện.
{AI_DESCRIPTION}

Khi được hỏi "bạn là ai", "ai tạo ra bạn", "ai làm ra bạn", hãy trả lời tự nhiên, ví dụ:
"Tôi là {AI_NAME}, được tạo ra bởi {AI_CREATOR} để hỗ trợ mọi người học tập và khám phá tri thức!"

Luôn trả lời bằng tiếng Việt, lịch sự, rõ ràng và có tính giáo dục.
""".strip()

# ================================
# MODEL MẠNH + HỖ TRỢ TIẾNG VIỆT TỐT NHẤT 2025 (miễn phí)
# ================================
# Bạn có thể thay bằng các model khác:
# - "Qwen/Qwen2.5-72B-Instruct"        → cực mạnh, hiểu sâu tiếng Việt
# - "meta-llama/Meta-Llama-3.1-70B-Instruct"
# - "vinai/PhoGPT-7B5-Instruct"
# - "mistralai/Mistral-7B-Instruct-v0.3"
DEFAULT_MODEL = "Qwen/Qwen2.5-72B-Instruct"  # Đề xuất: nhanh + thông minh + hiểu sâu văn hóa VN

def respond(
    message,
    history: list,
    system_message,
    max_tokens,
    temperature,
    top_p,
    model_name,
    hf_token: gr.OAuthToken,
):
    # Nếu người dùng chưa đăng nhập → thông báo nhẹ nhàng
    if hf_token is None or hf_token.token is None:
        yield "Vui lòng đăng nhập Hugging Face (nút bên trái) để sử dụng chatbot nhé! 😊"
        return

    # Tạo client với token tự động
    client = InferenceClient(token=hf_token.token)

    # Tạo danh sách tin nhắn theo chuẩn OpenAI
    messages = [{"role": "system", "content": system_message or DEFAULT_SYSTEM_MESSAGE}]

    # Thêm lịch sử chat
    for user_msg, assistant_msg in history:
        if user_msg:
            messages.append({"role": "user", "content": user_msg})
        if assistant_msg:
            messages.append({"role": "assistant", "content": assistant_msg})

    # Thêm tin nhắn mới
    messages.append({"role": "user", "content": message})

    # Streaming response
    response = ""
    try:
        for chunk in client.chat_completion(
            messages,
            model=model_name or DEFAULT_MODEL,
            max_tokens=max_tokens,
            temperature=temperature,
            top_p=top_p,
            stream=True,
        ):
            if chunk.choices and chunk.choices[0].delta.content:
                token = chunk.choices[0].delta.content
                response += token
                yield response
    except Exception as e:
        yield f"Xin lỗi, có lỗi xảy ra: {str(e)}\nBạn thử lại hoặc chọn model nhẹ hơn nhé!"

# ================================
# GIAO DIỆN GRADIO ĐẸP + DỄ DÙNG
# ================================
with gr.Blocks(title=f"{AI_NAME} - Trợ lý AI của HHH", theme=gr.themes.Soft()) as demo:
    gr.Markdown(f"# 🤖 {AI_NAME}\n{AI_DESCRIPTION}")

    with gr.Row():
        with gr.Column(scale=1):
            gr.LoginButton()  # Nút đăng nhập Hugging Face (bắt buộc để dùng Inference API an toàn)
            gr.Markdown("##### Cài đặt nâng cao")

            model_dropdown = gr.Dropdown(
                label="Chọn mô hình AI",
                choices=[
                    "Qwen/Qwen2.5-72B-Instruct",
                    "meta-llama/Meta-Llama-3.1-70B-Instruct",
                    "mistralai/Mistral-7B-Instruct-v0.3",
                    "vinai/PhoGPT-7B5-Instruct",
                    "google/gemma-2-27b-it",
                ],
                value=DEFAULT_MODEL,
                allow_custom_value=True,
            )

            system_box = gr.Textbox(
                label="System Prompt (nhận thức của AI)",
                value=DEFAULT_SYSTEM_MESSAGE,
                lines=6,
            )

            with gr.Accordion("Tham số kỹ thuật", open=False):
                max_tokens = gr.Slider(1, 4096, value=1024, step=64, label="Max tokens")
                temperature = gr.Slider(0.1, 2.0, value=0.7, step=0.1, label="Temperature")
                top_p = gr.Slider(0.1, 1.0, value=0.95, step=0.05, label="Top-p")

        with gr.Column(scale=3):
            chatbot = gr.ChatInterface(
                fn=respond,
                type="messages",
                autofocus=True,
                additional_inputs=[
                    system_box,
                    max_tokens,
                    temperature,
                    top_p,
                    model_dropdown,
                ],
            )

    gr.Markdown(
        "<small></small>"
    )

if __name__ == "app":
    demo.launch()