Spaces:
Running
Running
Delete notebook
Browse files- notebook/image_gen.ipynb +0 -190
- notebook/text_preprocessing.ipynb +0 -247
- notebook/text_to_speech.ipynb +0 -224
- notebook/text_to_video.ipynb +0 -0
notebook/image_gen.ipynb
DELETED
@@ -1,190 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": null,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"from huggingface_hub import InferenceClient\n",
|
10 |
-
"import os\n",
|
11 |
-
"import glob\n",
|
12 |
-
"from collections import defaultdict\n",
|
13 |
-
"import google.generativeai as genai\n",
|
14 |
-
"from tqdm import tqdm\n",
|
15 |
-
"from huggingface_hub.utils import HfHubHTTPError\n",
|
16 |
-
"import random\n",
|
17 |
-
"from dotenv import load_dotenv\n",
|
18 |
-
"import time\n",
|
19 |
-
"\n",
|
20 |
-
"\n",
|
21 |
-
"load_dotenv()\n",
|
22 |
-
"HF_API_KEY = os.getenv(\"HUGGINGFACE_API_KEY\")\n",
|
23 |
-
"GOOGLE_API_KEY = os.getenv(\"GOOGLE_API_KEY\")\n",
|
24 |
-
"genai.configure(api_key=GOOGLE_API_KEY)\n",
|
25 |
-
"client = InferenceClient(provider=\"hf-inference\", api_key=HF_API_KEY)\n",
|
26 |
-
"import time"
|
27 |
-
]
|
28 |
-
},
|
29 |
-
{
|
30 |
-
"cell_type": "code",
|
31 |
-
"execution_count": null,
|
32 |
-
"metadata": {},
|
33 |
-
"outputs": [],
|
34 |
-
"source": [
|
35 |
-
"def split_text_by_semantics(number_of_images):\n",
|
36 |
-
" with open(\"../data/text/text.txt\", \"r\", encoding=\"utf-8\") as file:\n",
|
37 |
-
" text = file.read()\n",
|
38 |
-
" prompt = f\"\"\"\n",
|
39 |
-
" Bạn là một chuyên gia xử lý văn bản. Hãy chia văn bản sau thành {number_of_images} đoạn có ý nghĩa sao cho mỗi đoạn vừa đủ để giải thích trong khoảng 3 đến 5 câu.\n",
|
40 |
-
"\n",
|
41 |
-
" Văn bản:\n",
|
42 |
-
" {text}\n",
|
43 |
-
"\n",
|
44 |
-
" Định dạng đầu ra:\n",
|
45 |
-
" - Phần 1: [Nội dung]\n",
|
46 |
-
" - Phần 2: [Nội dung]\n",
|
47 |
-
" - Phần 3: [Nội dung]\n",
|
48 |
-
" \"\"\"\n",
|
49 |
-
"\n",
|
50 |
-
" try:\n",
|
51 |
-
" model = genai.GenerativeModel(\"gemini-pro\")\n",
|
52 |
-
" response = model.generate_content(prompt)\n",
|
53 |
-
" result_text = response.text.strip()\n",
|
54 |
-
"\n",
|
55 |
-
" chunks = result_text.split(\"- Phần \")\n",
|
56 |
-
" chunks = [chunk.strip() for chunk in chunks if chunk]\n",
|
57 |
-
" return chunks\n",
|
58 |
-
" except Exception as e:\n",
|
59 |
-
" print(f\"Lỗi khi gọi API Gemini: {e}\")\n",
|
60 |
-
" return []"
|
61 |
-
]
|
62 |
-
},
|
63 |
-
{
|
64 |
-
"cell_type": "code",
|
65 |
-
"execution_count": null,
|
66 |
-
"metadata": {},
|
67 |
-
"outputs": [],
|
68 |
-
"source": [
|
69 |
-
"def describe_image(description, detail_level=\"short\", perspective=\"neutral\", emotion=None, time_setting=None, art_style=None):\n",
|
70 |
-
" \"\"\"\n",
|
71 |
-
" Nhận một đoạn văn mô tả chi tiết và trả về một câu mô tả hình ảnh theo các tùy chỉnh.\n",
|
72 |
-
"\n",
|
73 |
-
" Args:\n",
|
74 |
-
" description (str): Đoạn văn mô tả chi tiết.\n",
|
75 |
-
" detail_level (str): Mức độ chi tiết (\"short\" hoặc \"detailed\").\n",
|
76 |
-
" perspective (str): Góc nhìn (\"subjective\" hoặc \"neutral\").\n",
|
77 |
-
" emotion (str, optional): Cảm xúc chủ đạo (nếu có, ví dụ: \"mysterious\", \"romantic\").\n",
|
78 |
-
" time_setting (str, optional): Bối cảnh thời gian (ví dụ: \"modern\", \"medieval\", \"futuristic\").\n",
|
79 |
-
" art_style (str, optional): Phong cách nghệ thuật (ví dụ: \"realistic\", \"abstract\", \"sketch\").\n",
|
80 |
-
"\n",
|
81 |
-
" Returns:\n",
|
82 |
-
" str: Một câu mô tả hình ảnh theo yêu cầu.\n",
|
83 |
-
" \"\"\"\n",
|
84 |
-
" \n",
|
85 |
-
" prompt = f\"\"\"\n",
|
86 |
-
" Bạn là chuyên gia mô tả hình ảnh. Hãy đọc đoạn mô tả dưới đây và tạo một mô tả hình ảnh theo các tiêu chí sau:\n",
|
87 |
-
" - Mức độ chi tiết: {\"Ngắn gọn\" if detail_level == \"short\" else \"Chi tiết\"}.\n",
|
88 |
-
" - Góc nhìn: {\"Chủ quan\" if perspective == \"subjective\" else \"Trung lập\"}.\n",
|
89 |
-
" {f\"- Cảm xúc chủ đạo: {emotion}.\" if emotion else \"\"}\n",
|
90 |
-
" {f\"- Bối cảnh thời gian: {time_setting}.\" if time_setting else \"\"}\n",
|
91 |
-
" {f\"- Phong cách nghệ thuật: {art_style}.\" if art_style else \"\"}\n",
|
92 |
-
"\n",
|
93 |
-
" Đoạn mô tả:\n",
|
94 |
-
" {description}\n",
|
95 |
-
"\n",
|
96 |
-
" Hãy tạo một mô tả hình ảnh phù hợp với yêu cầu trên bằng Tiếng Anh.\n",
|
97 |
-
" \"\"\"\n",
|
98 |
-
"\n",
|
99 |
-
" try:\n",
|
100 |
-
" model = genai.GenerativeModel(\"gemini-pro\")\n",
|
101 |
-
" response = model.generate_content(prompt)\n",
|
102 |
-
" return response.text.strip()\n",
|
103 |
-
" except Exception as e:\n",
|
104 |
-
" print(f\"Lỗi khi gọi API Gemini: {e}\")\n",
|
105 |
-
" return \"\"\n"
|
106 |
-
]
|
107 |
-
},
|
108 |
-
{
|
109 |
-
"cell_type": "code",
|
110 |
-
"execution_count": null,
|
111 |
-
"metadata": {},
|
112 |
-
"outputs": [],
|
113 |
-
"source": [
|
114 |
-
"def generate_image(prompt, output_path, model=\"stabilityai/stable-diffusion-3.5-large\", resolution=(512, 512), style=None, color_palette=None):\n",
|
115 |
-
" \"\"\"\n",
|
116 |
-
" Tạo hình ảnh từ mô tả văn bản với các tùy chỉnh linh hoạt.\n",
|
117 |
-
" \n",
|
118 |
-
" :param prompt: Mô tả hình ảnh đầu vào.\n",
|
119 |
-
" :param output_path: Đường dẫn lưu ảnh đầu ra.\n",
|
120 |
-
" :param model: Mô hình AI sử dụng để tạo ảnh.\n",
|
121 |
-
" :param style: Phong cách hình ảnh (nếu có, ví dụ: 'realistic', 'anime', 'cyberpunk').\n",
|
122 |
-
" :param color_palette: Bảng màu ưu tiên (nếu có, ví dụ: 'vibrant', 'monochrome').\n",
|
123 |
-
" \"\"\"\n",
|
124 |
-
" \n",
|
125 |
-
" custom_prompt = prompt\n",
|
126 |
-
" \n",
|
127 |
-
" if style:\n",
|
128 |
-
" custom_prompt += f\" in {style} style\"\n",
|
129 |
-
" if color_palette:\n",
|
130 |
-
" custom_prompt += f\" with {color_palette} color scheme\"\n",
|
131 |
-
" \n",
|
132 |
-
" image = client.text_to_image(custom_prompt, model=model, resolution=resolution)\n",
|
133 |
-
" image.save(output_path)\n"
|
134 |
-
]
|
135 |
-
},
|
136 |
-
{
|
137 |
-
"cell_type": "code",
|
138 |
-
"execution_count": null,
|
139 |
-
"metadata": {},
|
140 |
-
"outputs": [],
|
141 |
-
"source": [
|
142 |
-
"texts = split_text_by_semantics(number_of_images=3)\n",
|
143 |
-
"index = 0\n",
|
144 |
-
"for merged_text in tqdm(texts, desc=\"Processing\", unit=\"image\"):\n",
|
145 |
-
" output_path = f\"../data/image/{index}.png\"\n",
|
146 |
-
" prompt = describe_image(merged_text)\n",
|
147 |
-
" print(prompt)\n",
|
148 |
-
"\n",
|
149 |
-
" # Cơ chế retry với backoff\n",
|
150 |
-
" max_retries = 5\n",
|
151 |
-
" retry_count = 0\n",
|
152 |
-
"\n",
|
153 |
-
" while retry_count < max_retries:\n",
|
154 |
-
" try:\n",
|
155 |
-
" generate_image(prompt, output_path)\n",
|
156 |
-
" time.sleep(60) # Chờ sau khi tạo ảnh thành công\n",
|
157 |
-
" break # Nếu thành công thì thoát khỏi vòng lặp retry\n",
|
158 |
-
" except HfHubHTTPError as e:\n",
|
159 |
-
" print(f\"Lỗi khi gọi API: {e}\")\n",
|
160 |
-
" retry_count += 1\n",
|
161 |
-
" wait_time = 2 ** retry_count + random.uniform(0, 1) # Exponential backoff\n",
|
162 |
-
" print(f\"Thử lại sau {wait_time:.2f} giây...\")\n",
|
163 |
-
" time.sleep(wait_time)\n",
|
164 |
-
"\n",
|
165 |
-
" index += 1"
|
166 |
-
]
|
167 |
-
}
|
168 |
-
],
|
169 |
-
"metadata": {
|
170 |
-
"kernelspec": {
|
171 |
-
"display_name": "base",
|
172 |
-
"language": "python",
|
173 |
-
"name": "python3"
|
174 |
-
},
|
175 |
-
"language_info": {
|
176 |
-
"codemirror_mode": {
|
177 |
-
"name": "ipython",
|
178 |
-
"version": 3
|
179 |
-
},
|
180 |
-
"file_extension": ".py",
|
181 |
-
"mimetype": "text/x-python",
|
182 |
-
"name": "python",
|
183 |
-
"nbconvert_exporter": "python",
|
184 |
-
"pygments_lexer": "ipython3",
|
185 |
-
"version": "3.12.7"
|
186 |
-
}
|
187 |
-
},
|
188 |
-
"nbformat": 4,
|
189 |
-
"nbformat_minor": 2
|
190 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notebook/text_preprocessing.ipynb
DELETED
@@ -1,247 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "markdown",
|
5 |
-
"metadata": {},
|
6 |
-
"source": [
|
7 |
-
"# Cài đặt thư viện\n",
|
8 |
-
"API Free của Gemini nên không cần private"
|
9 |
-
]
|
10 |
-
},
|
11 |
-
{
|
12 |
-
"cell_type": "code",
|
13 |
-
"execution_count": 1,
|
14 |
-
"metadata": {},
|
15 |
-
"outputs": [],
|
16 |
-
"source": [
|
17 |
-
"import os\n",
|
18 |
-
"import fitz # PyMuPDF\n",
|
19 |
-
"from docx import Document\n",
|
20 |
-
"import google.generativeai as genai\n",
|
21 |
-
"from dotenv import load_dotenv\n",
|
22 |
-
"\n",
|
23 |
-
"# Load biến môi trường từ .env\n",
|
24 |
-
"load_dotenv()\n",
|
25 |
-
"GOOGLE_API_KEY = os.getenv(\"GOOGLE_API_KEY\")\n",
|
26 |
-
"genai.configure(api_key=GOOGLE_API_KEY)"
|
27 |
-
]
|
28 |
-
},
|
29 |
-
{
|
30 |
-
"cell_type": "markdown",
|
31 |
-
"metadata": {},
|
32 |
-
"source": [
|
33 |
-
"# Thiết lập hàm đọc file\n",
|
34 |
-
"Chấp nhận hai định dạng là .doc và .pdf. Đảm bảo file bài giảng nhiều chữ."
|
35 |
-
]
|
36 |
-
},
|
37 |
-
{
|
38 |
-
"cell_type": "code",
|
39 |
-
"execution_count": 2,
|
40 |
-
"metadata": {},
|
41 |
-
"outputs": [],
|
42 |
-
"source": [
|
43 |
-
"def extract_text_from_pdf(pdf_path):\n",
|
44 |
-
" # Mở file PDF\n",
|
45 |
-
" doc = fitz.open(pdf_path)\n",
|
46 |
-
" text = \"\"\n",
|
47 |
-
" for page_num in range(doc.page_count):\n",
|
48 |
-
" page = doc.load_page(page_num)\n",
|
49 |
-
" text += page.get_text()\n",
|
50 |
-
" return text\n",
|
51 |
-
"\n",
|
52 |
-
"def extract_text_from_docx(docx_path):\n",
|
53 |
-
" # Mở file DOCX\n",
|
54 |
-
" doc = Document(docx_path)\n",
|
55 |
-
" text = \"\"\n",
|
56 |
-
" for para in doc.paragraphs:\n",
|
57 |
-
" text += para.text + \"\\n\"\n",
|
58 |
-
" return text\n",
|
59 |
-
"\n",
|
60 |
-
"def extract_text_from_file(file_path):\n",
|
61 |
-
" # Kiểm tra loại file và gọi hàm tương ứng\n",
|
62 |
-
" file_extension = os.path.splitext(file_path)[1].lower()\n",
|
63 |
-
"\n",
|
64 |
-
" if file_extension == '.pdf':\n",
|
65 |
-
" return extract_text_from_pdf(file_path)\n",
|
66 |
-
" elif file_extension == '.docx':\n",
|
67 |
-
" return extract_text_from_docx(file_path)\n",
|
68 |
-
" else:\n",
|
69 |
-
" raise ValueError(\"Unsupported file format. Only PDF and DOCX are supported.\")"
|
70 |
-
]
|
71 |
-
},
|
72 |
-
{
|
73 |
-
"cell_type": "code",
|
74 |
-
"execution_count": 4,
|
75 |
-
"metadata": {},
|
76 |
-
"outputs": [],
|
77 |
-
"source": [
|
78 |
-
"text = extract_text_from_file(\"../data/input/sample.pdf\")\n",
|
79 |
-
"with open(\"../data/text/text.txt\", \"w\", encoding=\"utf-8\") as f:\n",
|
80 |
-
" f.write(text) "
|
81 |
-
]
|
82 |
-
},
|
83 |
-
{
|
84 |
-
"cell_type": "markdown",
|
85 |
-
"metadata": {},
|
86 |
-
"source": [
|
87 |
-
"# Gọi API tiến hành chia đoạn và phân tích tóm tắt\n",
|
88 |
-
"Đưa ra phân tích và lưu lại file"
|
89 |
-
]
|
90 |
-
},
|
91 |
-
{
|
92 |
-
"cell_type": "code",
|
93 |
-
"execution_count": null,
|
94 |
-
"metadata": {},
|
95 |
-
"outputs": [],
|
96 |
-
"source": [
|
97 |
-
"def split_text_by_semantics(text, number_of_chunks):\n",
|
98 |
-
" prompt = f\"\"\"\n",
|
99 |
-
" Bạn là một chuyên gia xử lý văn bản. Hãy chia văn bản sau thành {number_of_chunks} đoạn có ý nghĩa sao cho mỗi đoạn vừa đủ để giải thích trong khoảng 3 đến 5 câu.\n",
|
100 |
-
"\n",
|
101 |
-
" Văn bản:\n",
|
102 |
-
" {text}\n",
|
103 |
-
"\n",
|
104 |
-
" Định dạng đầu ra:\n",
|
105 |
-
" - Phần 1: [Nội dung]\n",
|
106 |
-
" - Phần 2: [Nội dung]\n",
|
107 |
-
" - Phần 3: [Nội dung]\n",
|
108 |
-
" \"\"\"\n",
|
109 |
-
"\n",
|
110 |
-
" try:\n",
|
111 |
-
" model = genai.GenerativeModel(\"gemini-pro\")\n",
|
112 |
-
" response = model.generate_content(prompt)\n",
|
113 |
-
" result_text = response.text.strip()\n",
|
114 |
-
"\n",
|
115 |
-
" chunks = result_text.split(\"- Phần \")\n",
|
116 |
-
" chunks = [chunk.strip() for chunk in chunks if chunk]\n",
|
117 |
-
" return chunks\n",
|
118 |
-
" except Exception as e:\n",
|
119 |
-
" print(f\"Lỗi khi gọi API Gemini: {e}\")\n",
|
120 |
-
" return []"
|
121 |
-
]
|
122 |
-
},
|
123 |
-
{
|
124 |
-
"cell_type": "code",
|
125 |
-
"execution_count": null,
|
126 |
-
"metadata": {},
|
127 |
-
"outputs": [],
|
128 |
-
"source": [
|
129 |
-
"def generate_explaination_for_chunks(chunks, analysis_level='basic', style='academic', word_limit=100):\n",
|
130 |
-
" \"\"\"\n",
|
131 |
-
" Phân tích nội dung của văn bản theo mức độ và phong cách mong muốn.\n",
|
132 |
-
" \n",
|
133 |
-
" :param chunks: Danh sách các đoạn văn bản cần phân tích.\n",
|
134 |
-
" :param text: Toàn bộ văn bản gốc.\n",
|
135 |
-
" :param analysis_level: Mức độ phân tích ('basic' hoặc 'detailed').\n",
|
136 |
-
" :param style: Phong cách phân tích ('academic', 'popular', 'creative', 'humorous').\n",
|
137 |
-
" :param word_limit: Số từ ước lượng cho mỗi phần tóm tắt.\n",
|
138 |
-
" :return: Danh sách các phân tích tương ứng với từng đoạn.\n",
|
139 |
-
" \"\"\"\n",
|
140 |
-
" \n",
|
141 |
-
" level_prompts = {\n",
|
142 |
-
" 'basic': \"Hãy đưa ra một bản tóm tắt ngắn gọn, tập trung vào nội dung chính.\",\n",
|
143 |
-
" 'detailed': \"Hãy phân tích chuyên sâu từng phần, làm rõ ý nghĩa, ngữ cảnh và các yếu tố quan trọng.\"\n",
|
144 |
-
" }\n",
|
145 |
-
" \n",
|
146 |
-
" style_prompts = {\n",
|
147 |
-
" 'academic': \"Phân tích theo phong cách học thuật, sử dụng ngôn ngữ chuyên sâu và lập luận chặt chẽ.\",\n",
|
148 |
-
" 'popular': \"Trình bày theo phong cách phổ thông, dễ hiểu và phù hợp với nhiều đối tượng.\",\n",
|
149 |
-
" 'creative': \"Giải thích một cách sáng tạo, sử dụng hình ảnh ẩn dụ và cách diễn đạt thú vị.\",\n",
|
150 |
-
" 'humorous': \"Phân tích theo phong cách hài hước, thêm vào yếu tố vui nhộn và bất ngờ.\"\n",
|
151 |
-
" }\n",
|
152 |
-
" \n",
|
153 |
-
" overview_prompt = f\"\"\"\n",
|
154 |
-
" Đây là một văn bản có nội dung quan trọng. Bạn sẽ phân tích từng phần theo mức độ '{analysis_level}' và phong cách '{style}'.\n",
|
155 |
-
" Văn bản gồm các phần sau: {', '.join([f'Phần {i+1}' for i in range(len(chunks))])}.\n",
|
156 |
-
" {level_prompts[analysis_level]}\n",
|
157 |
-
" {style_prompts[style]}\n",
|
158 |
-
" Mỗi phần không vượt quá {word_limit} từ.\n",
|
159 |
-
" \"\"\"\n",
|
160 |
-
" \n",
|
161 |
-
" try:\n",
|
162 |
-
" model = genai.GenerativeModel(\"gemini-pro\")\n",
|
163 |
-
" response = model.generate_content(overview_prompt)\n",
|
164 |
-
" overview_text = response.text.strip()\n",
|
165 |
-
" \n",
|
166 |
-
" explanations = []\n",
|
167 |
-
" for idx, chunk in enumerate(chunks, start=1):\n",
|
168 |
-
" part_prompt = f\"\"\"\n",
|
169 |
-
" Phân tích phần {idx} của văn bản.\n",
|
170 |
-
" {level_prompts[analysis_level]}\n",
|
171 |
-
" {style_prompts[style]}\n",
|
172 |
-
" Nội dung phần này:\n",
|
173 |
-
" {chunk}\n",
|
174 |
-
" Hãy đảm bảo phần tóm tắt không vượt quá {word_limit} từ.\n",
|
175 |
-
" \"\"\"\n",
|
176 |
-
" \n",
|
177 |
-
" part_response = model.generate_content(part_prompt)\n",
|
178 |
-
" explanations.append(part_response.text.strip())\n",
|
179 |
-
" \n",
|
180 |
-
" return explanations\n",
|
181 |
-
" \n",
|
182 |
-
" except Exception as e:\n",
|
183 |
-
" print(f\"Lỗi khi gọi API Gemini: {e}\")\n",
|
184 |
-
" return []"
|
185 |
-
]
|
186 |
-
},
|
187 |
-
{
|
188 |
-
"cell_type": "code",
|
189 |
-
"execution_count": null,
|
190 |
-
"metadata": {},
|
191 |
-
"outputs": [],
|
192 |
-
"source": [
|
193 |
-
"# Tách văn bản theo ngữ nghĩa sử dụng API Gemini\n",
|
194 |
-
"semantic_chunks = split_text_by_semantics(text, number_of_chunks=3)\n",
|
195 |
-
"\n",
|
196 |
-
"# Tạo thuyết minh cho từng phần semantic chunk\n",
|
197 |
-
"explainations = generate_explaination_for_chunks(semantic_chunks)\n",
|
198 |
-
"\n",
|
199 |
-
"# In kết quả\n",
|
200 |
-
"for idx, explaination in enumerate(explainations, start=1):\n",
|
201 |
-
" print(f\"Giải thích cho Phần {idx}:\\n{explaination}\\n\")"
|
202 |
-
]
|
203 |
-
},
|
204 |
-
{
|
205 |
-
"cell_type": "code",
|
206 |
-
"execution_count": null,
|
207 |
-
"metadata": {},
|
208 |
-
"outputs": [],
|
209 |
-
"source": [
|
210 |
-
"# Lưu từng câu vào tệp riêng biệt\n",
|
211 |
-
"for idx, explaination in enumerate(explainations, start=1):\n",
|
212 |
-
" # Tách đoạn văn bản thành các câu dựa trên dấu chấm\n",
|
213 |
-
" sentences = explaination.split('.')\n",
|
214 |
-
" \n",
|
215 |
-
" # Lưu từng câu vào tệp riêng biệt\n",
|
216 |
-
" for sentence_idx, sentence in enumerate(sentences, start=1):\n",
|
217 |
-
" sentence = sentence.strip() # Loại bỏ khoảng trắng thừa\n",
|
218 |
-
" if sentence: # Kiểm tra nếu câu không rỗng\n",
|
219 |
-
" output_file = f\"../data/text/{idx}_{sentence_idx}.txt\" # Tên tệp theo định dạng x_y.txt\n",
|
220 |
-
" with open(output_file, \"w\", encoding=\"utf-8\") as f:\n",
|
221 |
-
" f.write(f\"'{sentence}'\") # Ghi câu trong dấu nháy đơn\n",
|
222 |
-
" print(f\"Đã lưu: {output_file}\")"
|
223 |
-
]
|
224 |
-
}
|
225 |
-
],
|
226 |
-
"metadata": {
|
227 |
-
"kernelspec": {
|
228 |
-
"display_name": "base",
|
229 |
-
"language": "python",
|
230 |
-
"name": "python3"
|
231 |
-
},
|
232 |
-
"language_info": {
|
233 |
-
"codemirror_mode": {
|
234 |
-
"name": "ipython",
|
235 |
-
"version": 3
|
236 |
-
},
|
237 |
-
"file_extension": ".py",
|
238 |
-
"mimetype": "text/x-python",
|
239 |
-
"name": "python",
|
240 |
-
"nbconvert_exporter": "python",
|
241 |
-
"pygments_lexer": "ipython3",
|
242 |
-
"version": "3.12.7"
|
243 |
-
}
|
244 |
-
},
|
245 |
-
"nbformat": 4,
|
246 |
-
"nbformat_minor": 2
|
247 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notebook/text_to_speech.ipynb
DELETED
@@ -1,224 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 6,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import torch\n",
|
10 |
-
"from transformers import VitsModel, AutoTokenizer\n",
|
11 |
-
"import torchaudio\n",
|
12 |
-
"import numpy as np\n",
|
13 |
-
"import os\n",
|
14 |
-
"from gtts import gTTS"
|
15 |
-
]
|
16 |
-
},
|
17 |
-
{
|
18 |
-
"cell_type": "code",
|
19 |
-
"execution_count": 11,
|
20 |
-
"metadata": {},
|
21 |
-
"outputs": [],
|
22 |
-
"source": [
|
23 |
-
"# Đọc và load danh sách từ các file .txt trong thư mục ../data/text\n",
|
24 |
-
"text_folder = \"../data/text\"\n",
|
25 |
-
"text_files = sorted([f for f in os.listdir(text_folder) if f.endswith('.txt')]) # Lọc các file .txt trong thư mục"
|
26 |
-
]
|
27 |
-
},
|
28 |
-
{
|
29 |
-
"cell_type": "code",
|
30 |
-
"execution_count": 9,
|
31 |
-
"metadata": {},
|
32 |
-
"outputs": [
|
33 |
-
{
|
34 |
-
"name": "stdout",
|
35 |
-
"output_type": "stream",
|
36 |
-
"text": [
|
37 |
-
"✅ Audio saved as hello.mp3 (gTTS - Female)\n"
|
38 |
-
]
|
39 |
-
}
|
40 |
-
],
|
41 |
-
"source": [
|
42 |
-
"def text_to_speech(text, filename=\"output.mp3\", gender=\"female\", speed=\"normal\"):\n",
|
43 |
-
" \"\"\"\n",
|
44 |
-
" Convert text to speech and save it as an audio file.\n",
|
45 |
-
" \n",
|
46 |
-
" Parameters:\n",
|
47 |
-
" text (str): The text to convert.\n",
|
48 |
-
" filename (str): The output file name.\n",
|
49 |
-
" gender (str): \"male\" (use MMS-TTS) or \"female\" (use gTTS).\n",
|
50 |
-
" speed (str): \"slow\", \"normal\", or \"fast\" (only for gTTS).\n",
|
51 |
-
" \"\"\"\n",
|
52 |
-
" lang = \"vi\"\n",
|
53 |
-
" \n",
|
54 |
-
" if gender.lower() == \"female\":\n",
|
55 |
-
" # gTTS chỉ có giọng nữ\n",
|
56 |
-
" speed_mapping = {\"slow\": True, \"normal\": False, \"fast\": False}\n",
|
57 |
-
" slow = speed_mapping.get(speed.lower(), False)\n",
|
58 |
-
" \n",
|
59 |
-
" tts = gTTS(text=text, lang=lang, slow=slow)\n",
|
60 |
-
" tts.save(filename)\n",
|
61 |
-
" print(f\"✅ Audio saved as {filename}\")\n",
|
62 |
-
" \n",
|
63 |
-
" elif gender.lower() == \"male\":\n",
|
64 |
-
" # MMS-TTS cho giọng nam\n",
|
65 |
-
" model = VitsModel.from_pretrained(\"facebook/mms-tts-vie\")\n",
|
66 |
-
" tokenizer = AutoTokenizer.from_pretrained(\"facebook/mms-tts-vie\")\n",
|
67 |
-
" \n",
|
68 |
-
" inputs = tokenizer(text, return_tensors=\"pt\")\n",
|
69 |
-
" with torch.no_grad():\n",
|
70 |
-
" output = model(**inputs).waveform\n",
|
71 |
-
" \n",
|
72 |
-
" # Lưu file âm thanh\n",
|
73 |
-
" torchaudio.save(filename, output, 24000)\n",
|
74 |
-
" print(f\"✅ Audio saved as {filename}\")\n",
|
75 |
-
" \n",
|
76 |
-
" else:\n",
|
77 |
-
" print(\"⚠️ Giọng không hợp lệ! Chỉ hỗ trợ 'male' hoặc 'female'.\")"
|
78 |
-
]
|
79 |
-
},
|
80 |
-
{
|
81 |
-
"cell_type": "code",
|
82 |
-
"execution_count": 12,
|
83 |
-
"metadata": {},
|
84 |
-
"outputs": [
|
85 |
-
{
|
86 |
-
"name": "stdout",
|
87 |
-
"output_type": "stream",
|
88 |
-
"text": [
|
89 |
-
"✅ Audio saved as 1_1.wav (gTTS - Female)\n",
|
90 |
-
"Đã lưu 1_1.wav\n",
|
91 |
-
"✅ Audio saved as 1_10.wav (gTTS - Female)\n",
|
92 |
-
"Đã lưu 1_10.wav\n",
|
93 |
-
"✅ Audio saved as 1_11.wav (gTTS - Female)\n",
|
94 |
-
"Đã lưu 1_11.wav\n",
|
95 |
-
"✅ Audio saved as 1_12.wav (gTTS - Female)\n",
|
96 |
-
"Đã lưu 1_12.wav\n",
|
97 |
-
"✅ Audio saved as 1_13.wav (gTTS - Female)\n",
|
98 |
-
"Đã lưu 1_13.wav\n",
|
99 |
-
"✅ Audio saved as 1_14.wav (gTTS - Female)\n",
|
100 |
-
"Đã lưu 1_14.wav\n",
|
101 |
-
"✅ Audio saved as 1_15.wav (gTTS - Female)\n",
|
102 |
-
"Đã lưu 1_15.wav\n",
|
103 |
-
"✅ Audio saved as 1_16.wav (gTTS - Female)\n",
|
104 |
-
"Đã lưu 1_16.wav\n",
|
105 |
-
"✅ Audio saved as 1_17.wav (gTTS - Female)\n",
|
106 |
-
"Đã lưu 1_17.wav\n",
|
107 |
-
"✅ Audio saved as 1_2.wav (gTTS - Female)\n",
|
108 |
-
"Đã lưu 1_2.wav\n",
|
109 |
-
"✅ Audio saved as 1_3.wav (gTTS - Female)\n",
|
110 |
-
"Đã lưu 1_3.wav\n",
|
111 |
-
"✅ Audio saved as 1_4.wav (gTTS - Female)\n",
|
112 |
-
"Đã lưu 1_4.wav\n",
|
113 |
-
"✅ Audio saved as 1_5.wav (gTTS - Female)\n",
|
114 |
-
"Đã lưu 1_5.wav\n",
|
115 |
-
"✅ Audio saved as 1_6.wav (gTTS - Female)\n",
|
116 |
-
"Đã lưu 1_6.wav\n",
|
117 |
-
"✅ Audio saved as 1_7.wav (gTTS - Female)\n",
|
118 |
-
"Đã lưu 1_7.wav\n",
|
119 |
-
"✅ Audio saved as 1_8.wav (gTTS - Female)\n",
|
120 |
-
"Đã lưu 1_8.wav\n",
|
121 |
-
"✅ Audio saved as 1_9.wav (gTTS - Female)\n",
|
122 |
-
"Đã lưu 1_9.wav\n",
|
123 |
-
"✅ Audio saved as 2_1.wav (gTTS - Female)\n",
|
124 |
-
"Đã lưu 2_1.wav\n",
|
125 |
-
"✅ Audio saved as 2_10.wav (gTTS - Female)\n",
|
126 |
-
"Đã lưu 2_10.wav\n",
|
127 |
-
"✅ Audio saved as 2_11.wav (gTTS - Female)\n",
|
128 |
-
"Đã lưu 2_11.wav\n",
|
129 |
-
"✅ Audio saved as 2_12.wav (gTTS - Female)\n",
|
130 |
-
"Đã lưu 2_12.wav\n",
|
131 |
-
"✅ Audio saved as 2_13.wav (gTTS - Female)\n",
|
132 |
-
"Đã lưu 2_13.wav\n",
|
133 |
-
"✅ Audio saved as 2_14.wav (gTTS - Female)\n",
|
134 |
-
"Đã lưu 2_14.wav\n",
|
135 |
-
"✅ Audio saved as 2_15.wav (gTTS - Female)\n",
|
136 |
-
"Đã lưu 2_15.wav\n",
|
137 |
-
"✅ Audio saved as 2_16.wav (gTTS - Female)\n",
|
138 |
-
"Đã lưu 2_16.wav\n",
|
139 |
-
"✅ Audio saved as 2_17.wav (gTTS - Female)\n",
|
140 |
-
"Đã lưu 2_17.wav\n",
|
141 |
-
"✅ Audio saved as 2_18.wav (gTTS - Female)\n",
|
142 |
-
"Đã lưu 2_18.wav\n",
|
143 |
-
"✅ Audio saved as 2_2.wav (gTTS - Female)\n",
|
144 |
-
"Đã lưu 2_2.wav\n",
|
145 |
-
"✅ Audio saved as 2_3.wav (gTTS - Female)\n",
|
146 |
-
"Đã lưu 2_3.wav\n",
|
147 |
-
"✅ Audio saved as 2_4.wav (gTTS - Female)\n",
|
148 |
-
"Đã lưu 2_4.wav\n",
|
149 |
-
"✅ Audio saved as 2_5.wav (gTTS - Female)\n",
|
150 |
-
"Đã lưu 2_5.wav\n",
|
151 |
-
"✅ Audio saved as 2_6.wav (gTTS - Female)\n",
|
152 |
-
"Đã lưu 2_6.wav\n",
|
153 |
-
"✅ Audio saved as 2_7.wav (gTTS - Female)\n",
|
154 |
-
"Đã lưu 2_7.wav\n",
|
155 |
-
"✅ Audio saved as 2_8.wav (gTTS - Female)\n",
|
156 |
-
"Đã lưu 2_8.wav\n",
|
157 |
-
"✅ Audio saved as 2_9.wav (gTTS - Female)\n",
|
158 |
-
"Đã lưu 2_9.wav\n",
|
159 |
-
"✅ Audio saved as 3_1.wav (gTTS - Female)\n",
|
160 |
-
"Đã lưu 3_1.wav\n",
|
161 |
-
"✅ Audio saved as 3_10.wav (gTTS - Female)\n",
|
162 |
-
"Đã lưu 3_10.wav\n",
|
163 |
-
"✅ Audio saved as 3_11.wav (gTTS - Female)\n",
|
164 |
-
"Đã lưu 3_11.wav\n",
|
165 |
-
"✅ Audio saved as 3_12.wav (gTTS - Female)\n",
|
166 |
-
"Đã lưu 3_12.wav\n",
|
167 |
-
"✅ Audio saved as 3_14.wav (gTTS - Female)\n",
|
168 |
-
"Đã lưu 3_14.wav\n",
|
169 |
-
"✅ Audio saved as 3_17.wav (gTTS - Female)\n",
|
170 |
-
"Đã lưu 3_17.wav\n",
|
171 |
-
"✅ Audio saved as 3_18.wav (gTTS - Female)\n",
|
172 |
-
"Đã lưu 3_18.wav\n",
|
173 |
-
"✅ Audio saved as 3_19.wav (gTTS - Female)\n",
|
174 |
-
"Đã lưu 3_19.wav\n",
|
175 |
-
"✅ Audio saved as 3_2.wav (gTTS - Female)\n",
|
176 |
-
"Đã lưu 3_2.wav\n",
|
177 |
-
"✅ Audio saved as 3_3.wav (gTTS - Female)\n",
|
178 |
-
"Đã lưu 3_3.wav\n",
|
179 |
-
"✅ Audio saved as 3_4.wav (gTTS - Female)\n",
|
180 |
-
"Đã lưu 3_4.wav\n",
|
181 |
-
"✅ Audio saved as 3_5.wav (gTTS - Female)\n",
|
182 |
-
"Đã lưu 3_5.wav\n",
|
183 |
-
"✅ Audio saved as 3_6.wav (gTTS - Female)\n",
|
184 |
-
"Đã lưu 3_6.wav\n",
|
185 |
-
"✅ Audio saved as 3_7.wav (gTTS - Female)\n",
|
186 |
-
"Đã lưu 3_7.wav\n",
|
187 |
-
"✅ Audio saved as 3_8.wav (gTTS - Female)\n",
|
188 |
-
"Đã lưu 3_8.wav\n",
|
189 |
-
"✅ Audio saved as 3_9.wav (gTTS - Female)\n",
|
190 |
-
"Đã lưu 3_9.wav\n"
|
191 |
-
]
|
192 |
-
}
|
193 |
-
],
|
194 |
-
"source": [
|
195 |
-
"for text_file in text_files:\n",
|
196 |
-
" with open(f\"../data/text/{text_file}\", \"r\", encoding=\"utf-8\") as file:\n",
|
197 |
-
" content = file.read()\n",
|
198 |
-
" audio_file = text_file.replace(\"txt\",\"wav\")\n",
|
199 |
-
" text_to_speech(content, audio_file)"
|
200 |
-
]
|
201 |
-
}
|
202 |
-
],
|
203 |
-
"metadata": {
|
204 |
-
"kernelspec": {
|
205 |
-
"display_name": "base",
|
206 |
-
"language": "python",
|
207 |
-
"name": "python3"
|
208 |
-
},
|
209 |
-
"language_info": {
|
210 |
-
"codemirror_mode": {
|
211 |
-
"name": "ipython",
|
212 |
-
"version": 3
|
213 |
-
},
|
214 |
-
"file_extension": ".py",
|
215 |
-
"mimetype": "text/x-python",
|
216 |
-
"name": "python",
|
217 |
-
"nbconvert_exporter": "python",
|
218 |
-
"pygments_lexer": "ipython3",
|
219 |
-
"version": "3.12.7"
|
220 |
-
}
|
221 |
-
},
|
222 |
-
"nbformat": 4,
|
223 |
-
"nbformat_minor": 2
|
224 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notebook/text_to_video.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|