Spaces:
Running
Running
Minimal requirements and proper gitignore for chat app
Browse files- .gitignore +68 -0
- README.md +46 -12
- app.py +229 -46
- chat.py +66 -0
- requirements.txt +2 -1
.gitignore
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Virtual environments
|
| 2 |
+
.venv/
|
| 3 |
+
venv/
|
| 4 |
+
env/
|
| 5 |
+
ENV/
|
| 6 |
+
|
| 7 |
+
# Python cache
|
| 8 |
+
__pycache__/
|
| 9 |
+
*.py[cod]
|
| 10 |
+
*$py.class
|
| 11 |
+
*.so
|
| 12 |
+
.Python
|
| 13 |
+
build/
|
| 14 |
+
develop-eggs/
|
| 15 |
+
dist/
|
| 16 |
+
downloads/
|
| 17 |
+
eggs/
|
| 18 |
+
.eggs/
|
| 19 |
+
lib/
|
| 20 |
+
lib64/
|
| 21 |
+
parts/
|
| 22 |
+
sdist/
|
| 23 |
+
var/
|
| 24 |
+
wheels/
|
| 25 |
+
pip-wheel-metadata/
|
| 26 |
+
share/python-wheels/
|
| 27 |
+
*.egg-info/
|
| 28 |
+
.installed.cfg
|
| 29 |
+
*.egg
|
| 30 |
+
MANIFEST
|
| 31 |
+
|
| 32 |
+
# IDE files
|
| 33 |
+
.vscode/
|
| 34 |
+
.idea/
|
| 35 |
+
*.swp
|
| 36 |
+
*.swo
|
| 37 |
+
|
| 38 |
+
# OS files
|
| 39 |
+
.DS_Store
|
| 40 |
+
Thumbs.db
|
| 41 |
+
|
| 42 |
+
# Logs
|
| 43 |
+
*.log
|
| 44 |
+
logs/
|
| 45 |
+
|
| 46 |
+
# Environment variables
|
| 47 |
+
.env
|
| 48 |
+
.env.local
|
| 49 |
+
.env.production
|
| 50 |
+
|
| 51 |
+
# Data files
|
| 52 |
+
*.pkl
|
| 53 |
+
*.pickle
|
| 54 |
+
*.h5
|
| 55 |
+
*.hdf5
|
| 56 |
+
*.pt
|
| 57 |
+
*.bin
|
| 58 |
+
|
| 59 |
+
# Hugging Face specific
|
| 60 |
+
.huggingface/
|
| 61 |
+
|
| 62 |
+
# Large directories
|
| 63 |
+
data/
|
| 64 |
+
models/
|
| 65 |
+
assets/
|
| 66 |
+
scripts/
|
| 67 |
+
swahili_data/
|
| 68 |
+
utils/
|
README.md
CHANGED
|
@@ -1,12 +1,46 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌍 Multilingual AI Chat Interface
|
| 2 |
+
|
| 3 |
+
A beautiful Gradio-based chatbot that supports both English and Swahili (Kiswahili) languages with seamless switching capability.
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+

|
| 7 |
+

|
| 8 |
+
|
| 9 |
+
## ✨ Features
|
| 10 |
+
|
| 11 |
+
- **🌐 Dual Language Support**: Switch effortlessly between English and Swahili
|
| 12 |
+
- **🤖 Smart AI Responses**: Context-aware responses in the selected language
|
| 13 |
+
- **🎨 Beautiful Interface**: Clean, modern UI with intuitive controls
|
| 14 |
+
- **⚙️ Customizable Parameters**: Adjust temperature, tokens, and sampling
|
| 15 |
+
- **📱 Responsive Design**: Works perfectly on desktop and mobile devices
|
| 16 |
+
- **📋 Example Prompts**: Pre-loaded conversation starters in both languages
|
| 17 |
+
|
| 18 |
+
## 🚀 Live Demo
|
| 19 |
+
|
| 20 |
+
[](https://huggingface.co/spaces/Denis202/KiswahiliChetu_space)
|
| 21 |
+
|
| 22 |
+
**Experience the chat here:**
|
| 23 |
+
👉 [https://huggingface.co/spaces/Denis202/KiswahiliChetu_space](https://huggingface.co/spaces/Denis202/KiswahiliChetu_space)
|
| 24 |
+
|
| 25 |
+
## 🛠️ Technical Stack
|
| 26 |
+
|
| 27 |
+
- **Framework**: Gradio 4.0+
|
| 28 |
+
- **AI Model**: HuggingFaceH4/zephyr-7b-beta
|
| 29 |
+
- **Backend**: Hugging Face Inference API
|
| 30 |
+
- **Deployment**: Hugging Face Spaces
|
| 31 |
+
- **Languages**: Python 3.8+
|
| 32 |
+
|
| 33 |
+
## 📦 Installation
|
| 34 |
+
|
| 35 |
+
### Local Development
|
| 36 |
+
|
| 37 |
+
```bash
|
| 38 |
+
# Clone the repository
|
| 39 |
+
git clone https://huggingface.co/spaces/Denis202/KiswahiliChetu_space
|
| 40 |
+
cd KiswahiliChetu_space
|
| 41 |
+
|
| 42 |
+
# Install dependencies
|
| 43 |
+
pip install -r requirements.txt
|
| 44 |
+
|
| 45 |
+
# Run locally
|
| 46 |
+
python app.py
|
app.py
CHANGED
|
@@ -1,64 +1,247 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from huggingface_hub import InferenceClient
|
|
|
|
| 3 |
|
| 4 |
-
|
| 5 |
-
For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
|
| 6 |
-
"""
|
| 7 |
client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
def respond(
|
| 11 |
-
message,
|
| 12 |
-
history: list[tuple[str, str]],
|
| 13 |
-
system_message,
|
| 14 |
-
max_tokens,
|
| 15 |
-
temperature,
|
| 16 |
-
top_p,
|
|
|
|
| 17 |
):
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
-
for
|
| 21 |
-
if
|
| 22 |
-
messages.append({"role": "user", "content":
|
| 23 |
-
if
|
| 24 |
-
messages.append({"role": "assistant", "content":
|
| 25 |
|
| 26 |
messages.append({"role": "user", "content": message})
|
| 27 |
|
| 28 |
response = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
""
|
| 44 |
-
|
| 45 |
-
"""
|
| 46 |
-
demo = gr.ChatInterface(
|
| 47 |
-
respond,
|
| 48 |
-
additional_inputs=[
|
| 49 |
-
gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
|
| 50 |
-
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
|
| 51 |
-
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
|
| 52 |
-
gr.Slider(
|
| 53 |
-
minimum=0.1,
|
| 54 |
-
maximum=1.0,
|
| 55 |
-
value=0.95,
|
| 56 |
-
step=0.05,
|
| 57 |
-
label="Top-p (nucleus sampling)",
|
| 58 |
),
|
| 59 |
-
|
| 60 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
if __name__ == "__main__":
|
| 64 |
-
demo.launch(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from huggingface_hub import InferenceClient
|
| 3 |
+
import time
|
| 4 |
|
| 5 |
+
# Initialize Hugging Face Inference Client
|
|
|
|
|
|
|
| 6 |
client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
|
| 7 |
|
| 8 |
+
# Language texts
|
| 9 |
+
LANGUAGE_TEXTS = {
|
| 10 |
+
"English": {
|
| 11 |
+
"title": "AI Chat - Conversation Service",
|
| 12 |
+
"description": "Chat with your AI assistant",
|
| 13 |
+
"system_default": "You are a friendly assistant who speaks both English and Swahili. Respond in the user's preferred language.",
|
| 14 |
+
"placeholder": "Type your message here...",
|
| 15 |
+
"thinking": "Thinking...",
|
| 16 |
+
"clear": "Clear Chat",
|
| 17 |
+
"submit": "Submit",
|
| 18 |
+
"retry": "Retry",
|
| 19 |
+
"undo": "Undo",
|
| 20 |
+
"system_label": "System Message",
|
| 21 |
+
"max_tokens_label": "Max Tokens per Response",
|
| 22 |
+
"temperature_label": "Creativity (Temperature)",
|
| 23 |
+
"top_p_label": "Top-p Sampling",
|
| 24 |
+
"language_label": "Conversation Language",
|
| 25 |
+
"loading": "Loading...",
|
| 26 |
+
"error": "An error occurred. Please try again later.",
|
| 27 |
+
"examples": [
|
| 28 |
+
["How are you? Can you tell me about Tanzania?"],
|
| 29 |
+
["Please suggest some good Swahili books"],
|
| 30 |
+
["Can you help me translate this to English?"],
|
| 31 |
+
["Tell me about Swahili culture"]
|
| 32 |
+
]
|
| 33 |
+
},
|
| 34 |
+
"Kiswahili": {
|
| 35 |
+
"title": "Mazungumzo ya AI - Huduma ya Mazungumzo",
|
| 36 |
+
"description": "Wasiliana na msaidizi wako wa AI",
|
| 37 |
+
"system_default": "Wewe ni msaidizi mwenye urafiki unaozungumza Kiingereza na Kiswahili. Jibu kwa lugha inayopendekezwa na mtumiaji.",
|
| 38 |
+
"placeholder": "Andika ujumbe wako hapa...",
|
| 39 |
+
"thinking": "Inakokotoa...",
|
| 40 |
+
"clear": "Futa Mazungumzo",
|
| 41 |
+
"submit": "Tuma",
|
| 42 |
+
"retry": "Jaribu Tenai",
|
| 43 |
+
"undo": "Rudisha",
|
| 44 |
+
"system_label": "Ujumbe wa Mfumo",
|
| 45 |
+
"max_tokens_label": "Upeo wa Vitokezi kwa Majibu",
|
| 46 |
+
"temperature_label": "Ubunifu (Joto)",
|
| 47 |
+
"top_p_label": "Uchaguzi wa Top-p",
|
| 48 |
+
"language_label": "Lugha ya Mazungumzo",
|
| 49 |
+
"loading": "Inapakia...",
|
| 50 |
+
"error": "Hitilafu imetokea. Tafadhali jaribu tena baadaye.",
|
| 51 |
+
"examples": [
|
| 52 |
+
["Habari yako? Unaweza kuniambia kuhusu Tanzania?"],
|
| 53 |
+
["Tafadhali nipe mapendekezo ya vitabu bora vya Kiswahili"],
|
| 54 |
+
["Unaweza kunisaidia kutafsiri hii kwa Kiingereza?"],
|
| 55 |
+
["Eleza kuhusu utamaduni wa Waswahili"]
|
| 56 |
+
]
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
def get_localized_text(language, key):
|
| 61 |
+
"""Get localized text based on selected language"""
|
| 62 |
+
return LANGUAGE_TEXTS.get(language, LANGUAGE_TEXTS["English"]).get(key, key)
|
| 63 |
|
| 64 |
def respond(
|
| 65 |
+
message: str,
|
| 66 |
+
history: list[tuple[str, str]] = None,
|
| 67 |
+
system_message: str = "",
|
| 68 |
+
max_tokens: int = 512,
|
| 69 |
+
temperature: float = 0.7,
|
| 70 |
+
top_p: float = 0.95,
|
| 71 |
+
language: str = "English"
|
| 72 |
):
|
| 73 |
+
"""
|
| 74 |
+
Handles streaming responses from Hugging Face API and yields output.
|
| 75 |
+
"""
|
| 76 |
+
history = history or []
|
| 77 |
+
|
| 78 |
+
# Use provided system message or default based on language
|
| 79 |
+
if not system_message:
|
| 80 |
+
system_message = get_localized_text(language, "system_default")
|
| 81 |
+
|
| 82 |
+
# Add language instruction to system message
|
| 83 |
+
if language == "Kiswahili":
|
| 84 |
+
enhanced_system_message = f"{system_message} Jibu kwa Kiswahili kila wakati."
|
| 85 |
+
else:
|
| 86 |
+
enhanced_system_message = f"{system_message} Respond in English always."
|
| 87 |
+
|
| 88 |
+
messages = [{"role": "system", "content": enhanced_system_message}]
|
| 89 |
|
| 90 |
+
for user_msg, assistant_msg in history:
|
| 91 |
+
if user_msg:
|
| 92 |
+
messages.append({"role": "user", "content": user_msg})
|
| 93 |
+
if assistant_msg:
|
| 94 |
+
messages.append({"role": "assistant", "content": assistant_msg})
|
| 95 |
|
| 96 |
messages.append({"role": "user", "content": message})
|
| 97 |
|
| 98 |
response = ""
|
| 99 |
+
try:
|
| 100 |
+
for chunk in client.chat_completion(
|
| 101 |
+
messages,
|
| 102 |
+
max_tokens=max_tokens,
|
| 103 |
+
stream=True,
|
| 104 |
+
temperature=temperature,
|
| 105 |
+
top_p=top_p,
|
| 106 |
+
):
|
| 107 |
+
if chunk.choices and chunk.choices[0].delta.content:
|
| 108 |
+
token = chunk.choices[0].delta.content
|
| 109 |
+
response += token
|
| 110 |
+
yield response
|
| 111 |
+
|
| 112 |
+
except Exception as e:
|
| 113 |
+
error_message = get_localized_text(language, "error")
|
| 114 |
+
yield f"❌ {error_message}\n\nError: {str(e)}"
|
| 115 |
|
| 116 |
+
def update_ui_language(language):
|
| 117 |
+
"""Update UI elements based on selected language"""
|
| 118 |
+
return [
|
| 119 |
+
gr.Markdown.update(value=f"# {get_localized_text(language, 'title')}"),
|
| 120 |
+
gr.Markdown.update(value=get_localized_text(language, "description")),
|
| 121 |
+
gr.Chatbot.update(label=get_localized_text(language, "title")),
|
| 122 |
+
gr.Textbox.update(
|
| 123 |
+
placeholder=get_localized_text(language, "placeholder"),
|
| 124 |
+
label=get_localized_text(language, "placeholder")
|
| 125 |
+
),
|
| 126 |
+
gr.Button.update(value=get_localized_text(language, "submit")),
|
| 127 |
+
gr.Button.update(value=get_localized_text(language, "clear")),
|
| 128 |
+
gr.Textbox.update(
|
| 129 |
+
value=get_localized_text(language, "system_default"),
|
| 130 |
+
label=get_localized_text(language, "system_label")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
),
|
| 132 |
+
gr.Slider.update(label=get_localized_text(language, "max_tokens_label")),
|
| 133 |
+
gr.Slider.update(label=get_localized_text(language, "temperature_label")),
|
| 134 |
+
gr.Slider.update(label=get_localized_text(language, "top_p_label")),
|
| 135 |
+
gr.Dropdown.update(label=get_localized_text(language, "language_label")),
|
| 136 |
+
gr.Examples.update(
|
| 137 |
+
examples=get_localized_text(language, "examples"),
|
| 138 |
+
label=f"{get_localized_text(language, 'examples')} ({language})"
|
| 139 |
+
)
|
| 140 |
+
]
|
| 141 |
|
| 142 |
+
# Create the Gradio interface
|
| 143 |
+
with gr.Blocks(
|
| 144 |
+
title="AI Chat - Multilingual",
|
| 145 |
+
theme=gr.themes.Soft(),
|
| 146 |
+
css="""
|
| 147 |
+
.gradio-container {max-width: 900px !important; margin: auto;}
|
| 148 |
+
.chatbot {min-height: 400px; max-height: 500px;}
|
| 149 |
+
"""
|
| 150 |
+
) as demo:
|
| 151 |
+
|
| 152 |
+
# Language state
|
| 153 |
+
current_language = gr.State(value="English")
|
| 154 |
+
|
| 155 |
+
# Header
|
| 156 |
+
title_md = gr.Markdown(value=f"# {get_localized_text('English', 'title')}")
|
| 157 |
+
description_md = gr.Markdown(value=get_localized_text('English', 'description'))
|
| 158 |
+
|
| 159 |
+
with gr.Row():
|
| 160 |
+
with gr.Column(scale=3):
|
| 161 |
+
chatbot = gr.Chatbot(
|
| 162 |
+
label=get_localized_text('English', 'title'),
|
| 163 |
+
show_copy_button=True,
|
| 164 |
+
bubble_full_width=False
|
| 165 |
+
)
|
| 166 |
+
|
| 167 |
+
msg = gr.Textbox(
|
| 168 |
+
placeholder=get_localized_text('English', 'placeholder'),
|
| 169 |
+
label=get_localized_text('English', 'placeholder'),
|
| 170 |
+
lines=2
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
with gr.Row():
|
| 174 |
+
submit_btn = gr.Button(get_localized_text('English', 'submit'), variant="primary")
|
| 175 |
+
clear_btn = gr.Button(get_localized_text('English', 'clear'))
|
| 176 |
+
|
| 177 |
+
with gr.Column(scale=1):
|
| 178 |
+
system_msg = gr.Textbox(
|
| 179 |
+
value=get_localized_text('English', 'system_default'),
|
| 180 |
+
label=get_localized_text('English', 'system_label'),
|
| 181 |
+
lines=3
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
max_tokens = gr.Slider(
|
| 185 |
+
minimum=64, maximum=2048, value=512, step=64,
|
| 186 |
+
label=get_localized_text('English', 'max_tokens_label')
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
temperature = gr.Slider(
|
| 190 |
+
minimum=0.1, maximum=2.0, value=0.7, step=0.1,
|
| 191 |
+
label=get_localized_text('English', 'temperature_label')
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
top_p = gr.Slider(
|
| 195 |
+
minimum=0.1, maximum=1.0, value=0.95, step=0.05,
|
| 196 |
+
label=get_localized_text('English', 'top_p_label')
|
| 197 |
+
)
|
| 198 |
+
|
| 199 |
+
language_dropdown = gr.Dropdown(
|
| 200 |
+
choices=["English", "Kiswahili"],
|
| 201 |
+
value="English",
|
| 202 |
+
label=get_localized_text('English', 'language_label')
|
| 203 |
+
)
|
| 204 |
+
|
| 205 |
+
# Examples section
|
| 206 |
+
examples = gr.Examples(
|
| 207 |
+
examples=get_localized_text('English', 'examples'),
|
| 208 |
+
inputs=msg,
|
| 209 |
+
label=f"{get_localized_text('English', 'examples')} (English)"
|
| 210 |
+
)
|
| 211 |
+
|
| 212 |
+
# Event handlers
|
| 213 |
+
submit_event = msg.submit(
|
| 214 |
+
respond,
|
| 215 |
+
inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p, current_language],
|
| 216 |
+
outputs=chatbot
|
| 217 |
+
).then(lambda: "", None, msg)
|
| 218 |
+
|
| 219 |
+
submit_btn.click(
|
| 220 |
+
respond,
|
| 221 |
+
inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p, current_language],
|
| 222 |
+
outputs=chatbot
|
| 223 |
+
).then(lambda: "", None, msg)
|
| 224 |
+
|
| 225 |
+
clear_btn.click(lambda: None, None, chatbot, queue=False)
|
| 226 |
+
|
| 227 |
+
# Language change handler
|
| 228 |
+
language_dropdown.change(
|
| 229 |
+
update_ui_language,
|
| 230 |
+
inputs=language_dropdown,
|
| 231 |
+
outputs=[
|
| 232 |
+
title_md, description_md, chatbot, msg, submit_btn, clear_btn,
|
| 233 |
+
system_msg, max_tokens, temperature, top_p, language_dropdown, examples
|
| 234 |
+
]
|
| 235 |
+
).then(
|
| 236 |
+
lambda x: x, # Update the current language state
|
| 237 |
+
inputs=language_dropdown,
|
| 238 |
+
outputs=current_language
|
| 239 |
+
)
|
| 240 |
|
| 241 |
if __name__ == "__main__":
|
| 242 |
+
demo.launch(
|
| 243 |
+
server_name="0.0.0.0",
|
| 244 |
+
share=False,
|
| 245 |
+
favicon_path=None,
|
| 246 |
+
show_error=True
|
| 247 |
+
)
|
chat.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# chat.py
|
| 2 |
+
import torch
|
| 3 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 4 |
+
|
| 5 |
+
class KiswahiliChatbot:
|
| 6 |
+
def __init__(self, model_name: str = "gpt2", device: str = None):
|
| 7 |
+
"""
|
| 8 |
+
Anzisha chatbot ya Kiswahili.
|
| 9 |
+
:param model_name: Jina la modeli ya Hugging Face au path
|
| 10 |
+
:param device: "cuda" au "cpu"; inagundua kiotomatiki ikiwa ni None
|
| 11 |
+
"""
|
| 12 |
+
self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
|
| 13 |
+
print(f"Inatumia kifaa: {self.device}")
|
| 14 |
+
|
| 15 |
+
print(f"Inapakia modeli '{model_name}'...")
|
| 16 |
+
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
| 17 |
+
self.model = AutoModelForCausalLM.from_pretrained(model_name)
|
| 18 |
+
self.model.to(self.device)
|
| 19 |
+
self.model.eval()
|
| 20 |
+
|
| 21 |
+
self.chat_history = []
|
| 22 |
+
|
| 23 |
+
def chat(self, user_input: str, max_new_tokens: int = 200):
|
| 24 |
+
"""
|
| 25 |
+
Tengeneza jibu kutoka kwa chatbot.
|
| 26 |
+
:param user_input: Maandishi ya mtumiaji
|
| 27 |
+
:param max_new_tokens: Idadi ya tokeni mpya za kuzalisha
|
| 28 |
+
:return: Jibu la chatbot kama string
|
| 29 |
+
"""
|
| 30 |
+
self.chat_history.append(f"Mtumiaji: {user_input}")
|
| 31 |
+
prompt = "\n".join(self.chat_history) + "\nBot:"
|
| 32 |
+
|
| 33 |
+
inputs = self.tokenizer(prompt, return_tensors="pt").to(self.device)
|
| 34 |
+
with torch.no_grad():
|
| 35 |
+
output = self.model.generate(
|
| 36 |
+
**inputs,
|
| 37 |
+
max_new_tokens=max_new_tokens,
|
| 38 |
+
pad_token_id=self.tokenizer.eos_token_id,
|
| 39 |
+
do_sample=True,
|
| 40 |
+
top_k=50,
|
| 41 |
+
top_p=0.95,
|
| 42 |
+
temperature=0.7
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
response = self.tokenizer.decode(output[0], skip_special_tokens=True)
|
| 46 |
+
response = response.split("Bot:")[-1].strip()
|
| 47 |
+
|
| 48 |
+
self.chat_history.append(f"Bot: {response}")
|
| 49 |
+
return response
|
| 50 |
+
|
| 51 |
+
def reset_history(self):
|
| 52 |
+
"""Futa historia ya mazungumzo."""
|
| 53 |
+
self.chat_history = []
|
| 54 |
+
|
| 55 |
+
if __name__ == "__main__":
|
| 56 |
+
bot = KiswahiliChatbot(model_name="gpt2") # Badilisha na modeli yako ya Kiswahili
|
| 57 |
+
print("Chatbot ya Kiswahili iko tayari! Andika 'toka' kuondoka.\n")
|
| 58 |
+
|
| 59 |
+
while True:
|
| 60 |
+
user_input = input("Wewe: ")
|
| 61 |
+
if user_input.lower() in ["toka", "ondoka"]:
|
| 62 |
+
print("Chatbot inafunga...")
|
| 63 |
+
break
|
| 64 |
+
response = bot.chat(user_input)
|
| 65 |
+
print(f"Bot: {response}\n")
|
| 66 |
+
|
requirements.txt
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
|
|
|
|
|
|
| 1 |
+
gradio>=4.0.0
|
| 2 |
+
huggingface-hub>=0.20.0
|