Denis202 commited on
Commit
12e3fda
·
1 Parent(s): 03b0147

Minimal requirements and proper gitignore for chat app

Browse files
Files changed (5) hide show
  1. .gitignore +68 -0
  2. README.md +46 -12
  3. app.py +229 -46
  4. chat.py +66 -0
  5. 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
- title: KiswahiliChetu Space
3
- emoji: 💬
4
- colorFrom: yellow
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.0.1
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ ![Multilingual Chat](https://img.shields.io/badge/Multilingual-English%20%26%20Swahili-blue)
6
+ ![Gradio](https://img.shields.io/badge/Interface-Gradio-orange)
7
+ ![HuggingFace](https://img.shields.io/badge/Deployed-HuggingFace%20Spaces-yellow)
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
+ [![Hugging Face Spaces](https://img.shields.io/badge/🤗%20Hugging%20Face-Spaces-blue)](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
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
 
26
  messages.append({"role": "user", "content": message})
27
 
28
  response = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
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
- huggingface_hub==0.25.2
 
 
1
+ gradio>=4.0.0
2
+ huggingface-hub>=0.20.0