Wtiger commited on
Commit
9189851
·
verified ·
1 Parent(s): 63677b2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +516 -0
app.py ADDED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ !pip install fastapi transformers gradio bitsandbytes sounddevice PyAudio gtts --upgrade
2
+ !apt-get update && apt-get install -y portaudio19-dev libportaudio2 libportaudiocpp0
3
+
4
+ import torch
5
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, AutoConfig
6
+ from fastapi import FastAPI
7
+ from pydantic import BaseModel
8
+ import gradio as gr
9
+ import sounddevice as sd
10
+ import numpy as np
11
+ import wave
12
+ import tempfile
13
+ from gtts import gTTS
14
+ import os
15
+
16
+ # Клонирование репозитория Hugging Face
17
+ !git clone https://huggingface.co/spaces/Wtiger/Prosto_Ai
18
+ device = "cuda" if torch.cuda.is_available() else "cpu"
19
+
20
+ # Определяем стратегию загрузки модели
21
+ if torch.cuda.is_available():
22
+ vram_total = torch.cuda.get_device_properties(0).total_memory / (1024 ** 3)
23
+ if vram_total >= 16:
24
+ quantization_config = BitsAndBytesConfig(
25
+ load_in_4bit=True,
26
+ bnb_4bit_compute_dtype=torch.float16,
27
+ bnb_4bit_use_double_quant=True,
28
+ bnb_4bit_quant_type="nf4"
29
+ )
30
+ device_map = "auto"
31
+ elif vram_total >= 10:
32
+ quantization_config = BitsAndBytesConfig(load_in_8bit=True)
33
+ device_map = "auto"
34
+ else:
35
+ quantization_config = None
36
+ device_map = {"": "cpu"}
37
+ else:
38
+ quantization_config = None
39
+ device_map = {"": "cpu"}
40
+
41
+ # Загружаем модель FreedomIntelligence/RAG-Instruct-Llama3-3B
42
+ model_name = "FreedomIntelligence/RAG-Instruct-Llama3-3B"
43
+ config = AutoConfig.from_pretrained(model_name)
44
+
45
+ if quantization_config is not None:
46
+ quantization_config.llm_int8_enable_fp32_cpu_offload = True
47
+ quantization_config.offload_folder = "offload_weights"
48
+
49
+ model = AutoModelForCausalLM.from_pretrained(
50
+ model_name,
51
+ config=config,
52
+ quantization_config=quantization_config,
53
+ device_map=device_map,
54
+ )
55
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
56
+
57
+ # FastAPI
58
+ app = FastAPI()
59
+
60
+ class MathQuery(BaseModel):
61
+ topic: str
62
+ difficulty: str = "medium"
63
+
64
+ def generate_math_lesson(topic: str, difficulty: str):
65
+ prompt = f"Create a {difficulty} level math lesson on {topic} in English."
66
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
67
+ outputs = model.generate(**inputs, max_new_tokens=300, temperature=0.7, top_p=0.9)
68
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
69
+
70
+ def generate_english_task():
71
+ prompt = "Generate a random English learning exercise."
72
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
73
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
74
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
75
+ def generate_random_task(difficulty):
76
+ """
77
+ This function generates a random English learning exercise using the
78
+ language model. It's similar to generate_english_task but can be
79
+ modified to generate different types of random tasks.
80
+ """
81
+ prompt = f"Generate a random English learning exercise {difficulty}"
82
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
83
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
84
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
85
+
86
+
87
+ def answer_help_question(question: str):
88
+ prompt = f"Answer this question: {question}"
89
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
90
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
91
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
92
+
93
+
94
+ # Gradio Web UI - Киберпанк стиль
95
+ custom_css = """
96
+ body {
97
+ background-color: #000;
98
+ color: #0ff;
99
+ font-family: 'Orbitron', sans-serif;
100
+ background-image: url('https://wallpaperaccess.com/full/1503811.jpg');
101
+ background-size: cover;
102
+ }
103
+ .container {
104
+ max-width: 900px;
105
+ margin: auto;
106
+ padding: 20px;
107
+ background: rgba(10, 10, 10, 0.9);
108
+ border-radius: 10px;
109
+ box-shadow: 0px 0px 20px cyan;
110
+ }
111
+ button {
112
+ background: linear-gradient(45deg, #ff00ff, #00ffff);
113
+ color: black;
114
+ padding: 10px;
115
+ border: none;
116
+ border-radius: 5px;
117
+ cursor: pointer;
118
+ font-weight: bold;
119
+ }
120
+ button:hover {
121
+ background: linear-gradient(45deg, #ff0000, #00ff00);
122
+ }
123
+ """
124
+
125
+ # Проверяем доступность устройства
126
+ device = "cuda" if torch.cuda.is_available() else "cpu"
127
+
128
+ # Проверяем наличие необходимых библиотек и загружаем модель для распознавания речи
129
+ try:
130
+ model_name = "openai/whisper-small"
131
+ model = AutoModelForSpeechSeq2Seq.from_pretrained(model_name).to(device)
132
+ processor = AutoProcessor.from_pretrained(model_name)
133
+ stt_pipeline = pipeline(
134
+ "automatic-speech-recognition", model=model, tokenizer=processor.tokenizer,
135
+ feature_extractor=processor.feature_extractor, device=0 if torch.cuda.is_available() else -1
136
+ )
137
+ except ModuleNotFoundError as e:
138
+ print(f"Ошибка: {e}. Убедитесь, что все зависимости установлены.")
139
+ exit()
140
+
141
+ def record_audio(duration=5, samplerate=16000):
142
+ print("Recording...")
143
+ audio_data = sd.rec(int(duration * samplerate), samplerate=samplerate, channels=1, dtype='int16')
144
+ sd.wait()
145
+ print("Recording finished")
146
+ return np.squeeze(audio_data)
147
+
148
+ def save_audio(audio_data, samplerate=16000):
149
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_wav:
150
+ with wave.open(temp_wav.name, 'wb') as wf:
151
+ wf.setnchannels(1)
152
+ wf.setsampwidth(2)
153
+ wf.setframerate(samplerate)
154
+ wf.writeframes(audio_data.tobytes())
155
+ return temp_wav.name
156
+
157
+ def transcribe_audio():
158
+ try:
159
+ audio_data = record_audio()
160
+ audio_path = save_audio(audio_data)
161
+ result = stt_pipeline(audio_path)
162
+ return result.get("text", "Ошибка распознавания")
163
+ except Exception as e:
164
+ return f"Ошибка обработки аудио: {e}"
165
+
166
+ def generate_ai_response(user_text):
167
+ return f"Вы сказали: {user_text}. Это тестовый ответ AI."
168
+
169
+ def tts_response(text):
170
+ try:
171
+ tts = gTTS(text, lang='ru')
172
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
173
+ tts.save(temp_file.name)
174
+ return temp_file.name
175
+ except Exception as e:
176
+ print(f"Ошибка генерации речи: {e}")
177
+ return None
178
+
179
+ def voice_interaction():
180
+ greeting_text = "Привет! Я ваш голосовой ассистент. Как я могу помочь?"
181
+ greeting_audio = tts_response(greeting_text)
182
+ recognized_text = transcribe_audio()
183
+ print("User said:", recognized_text)
184
+ response_text = generate_ai_response(recognized_text)
185
+ response_audio = tts_response(response_text)
186
+ return greeting_text, greeting_audio, recognized_text, response_text, response_audio
187
+
188
+
189
+
190
+ with gr.Blocks(css=custom_css) as demo:
191
+ gr.Markdown("""
192
+ <div class='container'>
193
+ <h1>⚡ CyberAI Learning Platform ⚡</h1>
194
+ <h2>🚀 Powered by FreedomIntelligence/RAG-Instruct-Llama3-3B</h2>
195
+ </div>
196
+ """)
197
+
198
+ with gr.Tabs() as tabs:
199
+ with gr.TabItem("Math Lessons"):
200
+ topic_input = gr.Textbox(label="Enter Math Topic")
201
+ difficulty_level = gr.Radio(["Easy", "Medium", "Hard"], label="Select Difficulty", value="Medium")
202
+ generate_button = gr.Button("Generate Lesson")
203
+ lesson_output = gr.Textbox(label="Generated Lesson", interactive=False)
204
+ generate_button.click(generate_math_lesson, inputs=[topic_input, difficulty_level], outputs=lesson_output)
205
+
206
+ with gr.TabItem("English Tasks"):
207
+ task_list = gr.Textbox(label="Generated English Task", interactive=False)
208
+ refresh_button = gr.Button("Get New Task")
209
+ refresh_button.click(generate_english_task, outputs=task_list)
210
+
211
+ with gr.TabItem("English Study Plan"):
212
+ study_plan_text = """<h3>English Tenses Overview</h3>
213
+ <p>There are 12 tenses in English, divided into 4 groups...</p>"""
214
+ import torch
215
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, AutoConfig
216
+ from fastapi import FastAPI
217
+ from pydantic import BaseModel
218
+ import gradio as gr
219
+
220
+ # Определяем устройство
221
+ device = "cuda" if torch.cuda.is_available() else "cpu"
222
+
223
+ # Определяем стратегию загрузки модели
224
+ if torch.cuda.is_available():
225
+ vram_total = torch.cuda.get_device_properties(0).total_memory / (1024 ** 3)
226
+ if vram_total >= 16:
227
+ quantization_config = BitsAndBytesConfig(
228
+ load_in_4bit=True,
229
+ bnb_4bit_compute_dtype=torch.float16,
230
+ bnb_4bit_use_double_quant=True,
231
+ bnb_4bit_quant_type="nf4"
232
+ )
233
+ device_map = "auto"
234
+ elif vram_total >= 10:
235
+ quantization_config = BitsAndBytesConfig(load_in_8bit=True)
236
+ device_map = "auto"
237
+ else:
238
+ quantization_config = None
239
+ device_map = {"": "cpu"}
240
+ else:
241
+ quantization_config = None
242
+ device_map = {"": "cpu"}
243
+
244
+ # Загружаем модель FreedomIntelligence/RAG-Instruct-Llama3-3B
245
+ model_name = "FreedomIntelligence/RAG-Instruct-Llama3-3B"
246
+ config = AutoConfig.from_pretrained(model_name)
247
+
248
+ if quantization_config is not None:
249
+ quantization_config.llm_int8_enable_fp32_cpu_offload = True
250
+ quantization_config.offload_folder = "offload_weights"
251
+
252
+ model = AutoModelForCausalLM.from_pretrained(
253
+ model_name,
254
+ config=config,
255
+ quantization_config=quantization_config,
256
+ device_map=device_map,
257
+ )
258
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
259
+
260
+ # FastAPI
261
+ app = FastAPI()
262
+
263
+ class MathQuery(BaseModel):
264
+ topic: str
265
+ difficulty: str = "medium"
266
+
267
+ def generate_math_lesson(topic: str, difficulty: str):
268
+ prompt = f"Create a {difficulty} level math lesson on {topic} in English."
269
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
270
+ outputs = model.generate(**inputs, max_new_tokens=300, temperature=0.7, top_p=0.9)
271
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
272
+
273
+ def generate_english_task(difficulty):
274
+ prompt = f"Generate a random English learning exercise, {difficulty}"
275
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
276
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
277
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
278
+ def generate_task_by_topic(topic: str,difficulty):
279
+ prompt = f"Generate a random English learning {topic} exercise ,{difficulty} "
280
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
281
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
282
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
283
+
284
+ def answer_help_question(question: str):
285
+ prompt = f"Answer this question: {question}"
286
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
287
+ outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7, top_p=0.9)
288
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
289
+
290
+ # Gradio Web UI - Киберпанк стиль
291
+ custom_css = """
292
+ body {
293
+ background-color: #000;
294
+ color: #0ff;
295
+ font-family: 'Orbitron', sans-serif;
296
+ background-image: url('https://wallpaperaccess.com/full/1503811.jpg');
297
+ background-size: cover;
298
+ }
299
+ .container {
300
+ max-width: 900px;
301
+ margin: auto;
302
+ padding: 20px;
303
+ background: rgba(10, 10, 10, 0.9);
304
+ border-radius: 10px;
305
+ box-shadow: 0px 0px 20px cyan;
306
+ }
307
+ button {
308
+ background: linear-gradient(45deg, #ff00ff, #00ffff);
309
+ color: black;
310
+ padding: 10px;
311
+ border: none;
312
+ border-radius: 5px;
313
+ cursor: pointer;
314
+ font-weight: bold;
315
+ }
316
+ button:hover {
317
+ background: linear-gradient(45deg, #ff0000, #00ff00);
318
+ }
319
+ """
320
+
321
+ with gr.Blocks(css=custom_css) as demo:
322
+ gr.Markdown("""
323
+ <div class='container'>
324
+ <h1>⚡ Prosto AI⚡</h1>
325
+ <h2></h2>
326
+ </div>
327
+ """)
328
+
329
+ with gr.Tabs() as tabs:
330
+ with gr.TabItem("Math Lessons"):
331
+ topic_input = gr.Textbox(label="Enter Math Topic")
332
+ difficulty_level = gr.Radio(["Easy", "Medium", "Hard"], label="Select Difficulty", value="Medium")
333
+ generate_button = gr.Button("Generate Lesson")
334
+ lesson_output = gr.Textbox(label="Generated Lesson", interactive=False)
335
+ generate_button.click(generate_math_lesson, inputs=[topic_input, difficulty_level], outputs=lesson_output)
336
+
337
+ with gr.TabItem("English Tasks"):
338
+ difficulty_level = gr.Radio(["Easy", "Medium", "Hard"], label="Select Difficulty", value="Medium")
339
+
340
+
341
+
342
+ gr.Markdown("**Generate a task based on a specific topic or randomly:**")
343
+ task_topic_input = gr.Textbox(label="Enter a topic for the task")
344
+ generate_task_button = gr.Button("Generate Task by Topic")
345
+ generate_random_task_button = gr.Button("Generate Random Task")
346
+ generated_task_output = gr.Textbox(label="Generated Task", interactive=False)
347
+
348
+ generate_task_button.click(generate_task_by_topic, inputs=[task_topic_input, difficulty_level], outputs=generated_task_output)
349
+ generate_random_task_button.click(generate_random_task, inputs=[difficulty_level], outputs=generated_task_output)
350
+
351
+
352
+
353
+ with gr.TabItem("English Study Plan"):
354
+ study_plan_text = """<h3>English Tenses Overview</h3>
355
+ <p>План изучения английских времён
356
+ Изучение времён английского языка лучше всего разбивать на этапы, начиная с самых простых и постепенно переходя к более сложным. Этот план поможет вам постепенно освоить все времена и научиться их применять.
357
+
358
+ 🔹 Этап 1: Введение в систему времён
359
+ 📌 Цель: Ознакомиться с группами времён и их особенностями.
360
+
361
+ Понять, что в английском языке 12 времён, которые делятся на 4 группы:
362
+ Simple (Простые) – действие как факт.
363
+ Continuous (Длительные) – действие в процессе.
364
+ Perfect (Совершенные) – результат.
365
+ Perfect Continuous (Совершенные длительные) – процесс с акцентом на длительность.
366
+ 🔹 Этап 2: Освоение группы Simple (Простые времена)
367
+ 📌 Цель: Научиться выражать действия как факты, повторяющиеся события и события в будущем.
368
+
369
+ Present Simple (Настоящее простое)
370
+
371
+ Используется для регулярных действий, фактов и расписаний.
372
+ Формула: (I/You/We/They + V / He/She/It + V+s/es)
373
+ Пример: I go to school every day.
374
+ Past Simple (Прошедшее простое)
375
+
376
+ Действие, которое произошло в прошлом и закончилось.
377
+ Формула: (V2 или V+ed)
378
+ Пример: She visited Paris last year.
379
+ Future Simple (Будущее простое)
380
+
381
+ Действие, которое произойдёт в будущем.
382
+ Формула: (will + V)
383
+ Пример: They will travel to Japan next summer.
384
+ 📝 Практика: ✔️ Напишите 10 предложений в каждом времени.
385
+ ✔️ Используйте глаголы в разных формах.
386
+ ✔️ Расскажите о своём дне, вчерашнем дне и планах на завтра.
387
+
388
+ 🔹 Этап 3: Изучение группы Continuous (Длительные времена)
389
+ 📌 Цель: Научиться говорить о процессах, которые происходят в конкретный момент времени.
390
+
391
+ Present Continuous (Настоящее длительное)
392
+
393
+ Действие происходит прямо сейчас или в ближайшем будущем.
394
+ Формула: (am/is/are + V-ing)
395
+ Пример: She is reading a book now.
396
+ Past Continuous (Прошедшее длительное)
397
+
398
+ Действие длилось в определённый момент в прошлом.
399
+ Формула: (was/were + V-ing)
400
+ Пример: They were watching TV when I called.
401
+ Future Continuous (Будущее длительное)
402
+
403
+ Действие будет происходить в определённый момент в будущем.
404
+ Формула: (will be + V-ing)
405
+ Пример: This time tomorrow, I will be flying to New York.
406
+ 📝 Практика: ✔️ Опишите, что вы делаете прямо сейчас.
407
+ ✔️ Расскажите о том, что вы делали вчера в определённое время.
408
+ ✔️ Опишите, чем вы будете заниматься в завтрашний вечер.
409
+
410
+ 🔹 Этап 4: Освоение группы Perfect (Совершенные времена)
411
+ 📌 Цель: Научиться говорить о результатах действий.
412
+
413
+ Present Perfect (Настоящее совершенное)
414
+
415
+ Действие произошло в прошлом, но его результат важен сейчас.
416
+ Формула: (have/has + V3)
417
+ Пример: I have just finished my homework.
418
+ Past Perfect (Прошедшее совершенное)
419
+
420
+ Действие произошло до другого действия в прошлом.
421
+ Формула: (had + V3)
422
+ Пример: By the time I arrived, they had left.
423
+ Future Perfect (Будущее совершенное)
424
+
425
+ Действие завершится к определённому моменту в будущем.
426
+ Формула: (will have + V3)
427
+ Пример: I will have finished the report by tomorrow.
428
+ 📝 Практика: ✔️ Опишите, что вы уже сделали сегодня.
429
+ ✔️ Расскажите о событии, которое произошло до другого события в прошлом.
430
+ ✔️ Напишите, что вы завершите к концу следующей недели.
431
+
432
+ 🔹 Этап 5: Совершенные длительные времена (Perfect Continuous)
433
+ 📌 Цель: Использовать времена для описания длительных процессов с акцентом на продолжительность.
434
+
435
+ Present Perfect Continuous (Настоящее совершенное длительное)
436
+
437
+ Действие началось в прошлом и продолжается до сих пор.
438
+ Формула: (have/has been + V-ing)
439
+ Пример: I have been studying English for 5 years.
440
+ Past Perfect Continuous (Прошедшее совершенное длительное)
441
+
442
+ Действие длилось до определённого момента в прошлом.
443
+ Формула: (had been + V-ing)
444
+ Пример: She had been working at that company for 3 years before she quit.
445
+ Future Perfect Continuous (Будущее совершенное длительное)
446
+
447
+ Действие будет продолжаться до определённого момента в будущем.
448
+ Формула: (will have been + V-ing)
449
+ Пример: By next year, I will have been living here for 10 years.
450
+ 📝 Практика: ✔️ Опишите, как долго вы занимаетесь каким-либо хобби.
451
+ ✔️ Напишите, как долго длилось какое-то действие до определённого момента в прошлом.
452
+ ✔️ Составьте предложение о том, как долго вы будете чем-то заниматься в будущем.
453
+
454
+ 🔹 Этап 6: Итоговое повторение и практика
455
+ 📌 Цель: Закрепить знания и научиться использовать времена в речи.
456
+
457
+ ✅ Повторите основные отличия времён.
458
+ ✅ Составьте сравнительные таблицы, чтобы видеть разницу между временами.
459
+ ✅ Практикуйтесь в устной и письменной речи:
460
+
461
+ Опишите один день из жизни с разными временами.
462
+ Составьте рассказ о себе, используя все времена.
463
+ Потренируйтесь объяснять ситуации с разными временными формами.
464
+ 🔹 Совет: Лучше всего изучать времена постепенно, разбирая примеры и активно используя их в речи! 🚀
465
+
466
+ Такой подход поможет вам поэтапно освоить все времена и научиться использовать их правильно. Если нужна дополнительная практика или примеры — дайте знать! 😊
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+ </p>"""
475
+ gr.Markdown(study_plan_text)
476
+ help_button = gr.Button("❓ Need Help?")
477
+ help_button.click(lambda: tabs.select(tabs.value)) #Fixed this line
478
+
479
+ with gr.TabItem("Help"):
480
+ question_input = gr.Textbox(label="Ask a question")
481
+ answer_output = gr.Textbox(label="AI Response", interactive=False)
482
+ ask_button = gr.Button("Ask AI")
483
+ ask_button.click(answer_help_question, inputs=[question_input], outputs=answer_output)
484
+ with gr.TabItem("Talking"):
485
+ record_button = gr.Button("🎙️ Говорить")
486
+ upload_audio = gr.File(label="Upload Audio")
487
+ greeting_output = gr.Audio(label="AI Приветствие", autoplay=True)
488
+ transcription_output = gr.Textbox(label="Распознанный текст")
489
+ response_text_output = gr.Textbox(label="Ответ AI")
490
+ audio_output = gr.Audio(label="Голосовой ответ AI", autoplay=True)
491
+
492
+ record_button.click(voice_interaction, outputs=[greeting_output, transcription_output, response_text_output, audio_output])
493
+ upload_audio.change(transcribe_audio, inputs=[upload_audio], outputs=[transcription_output])
494
+
495
+
496
+ record_button.click(voice_interaction, outputs=[greeting_output, transcription_output, response_text_output, audio_output])
497
+ with gr.TabItem("Resources"): # Nested correctly under tabs
498
+ gr.Markdown("## 📚 Полезные ресурсы для изучения английского")
499
+
500
+ with gr.Row(): # Nested correctly under Resources TabItem
501
+ gr.Markdown("[🎬 Фильмы на английском](https://www.netflix.com/)", label="Фильмы")
502
+ gr.Markdown("[📖 Книги на английском](https://www.gutenberg.org/)", label="Книги")
503
+
504
+ with gr.Row(): # Nested correctly under Resources TabItem
505
+ gr.Markdown("[🎧 Аудиокниги](https://librivox.org/)", label="Аудиокниги")
506
+ gr.Markdown("[📚 Уроки английского](https://www.ef.com/wwen/english-resources/)", label="Уроки английского")
507
+
508
+ with gr.Row(): # Nested correctly under Resources TabItem
509
+ gr.Markdown("[📺 Видео-уроки](https://www.youtube.com/results?search_query=learn+english)", label="Видео-уроки")
510
+ gr.Markdown("[📝 Грамматические упражнения](https://www.englishclub.com/grammar/)", label="Грамматика")
511
+
512
+
513
+
514
+
515
+ demo.launch()
516
+