Update app.py
Browse files
app.py
CHANGED
@@ -3,80 +3,16 @@ from huggingface_hub import InferenceClient
|
|
3 |
import os
|
4 |
import pandas as pd
|
5 |
from typing import List, Dict, Tuple
|
|
|
6 |
import io
|
7 |
import traceback
|
8 |
import csv
|
9 |
-
from functools import lru_cache
|
10 |
-
from concurrent.futures import ThreadPoolExecutor
|
11 |
-
import nltk
|
12 |
-
from nltk.tokenize import sent_tokenize
|
13 |
-
from transformers import AutoTokenizer
|
14 |
-
|
15 |
-
# NLTK 데이터 다운로드
|
16 |
-
nltk.download('punkt')
|
17 |
|
18 |
# 추론 API 클라이언트 설정
|
19 |
hf_client = InferenceClient(
|
20 |
"CohereForAI/c4ai-command-r-plus-08-2024", token=os.getenv("HF_TOKEN")
|
21 |
)
|
22 |
|
23 |
-
def chunk_text(text: str, chunk_size: int = 500) -> List[str]:
|
24 |
-
"""텍스트를 더 작은 청크로 분할"""
|
25 |
-
tokenizer = AutoTokenizer.from_pretrained("CohereForAI/c4ai-command-r-plus-08-2024")
|
26 |
-
sentences = sent_tokenize(text)
|
27 |
-
chunks = []
|
28 |
-
current_chunk = []
|
29 |
-
current_length = 0
|
30 |
-
|
31 |
-
for sentence in sentences:
|
32 |
-
sentence = sentence.strip()
|
33 |
-
tokenized_sentence = tokenizer.encode(sentence, add_special_tokens=False)
|
34 |
-
sentence_length = len(tokenized_sentence)
|
35 |
-
if current_length + sentence_length > chunk_size:
|
36 |
-
if current_chunk:
|
37 |
-
chunks.append(' '.join(current_chunk))
|
38 |
-
current_chunk = [sentence]
|
39 |
-
current_length = sentence_length
|
40 |
-
else:
|
41 |
-
current_chunk.append(sentence)
|
42 |
-
current_length += sentence_length
|
43 |
-
|
44 |
-
if current_chunk:
|
45 |
-
chunks.append(' '.join(current_chunk))
|
46 |
-
return chunks
|
47 |
-
|
48 |
-
# 나머지 코드는 이전과 동일하게 유지
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
@lru_cache(maxsize=100)
|
55 |
-
def cached_preprocess(text: str) -> str:
|
56 |
-
"""자주 사용되는 텍스트에 대한 전처리 결과를 캐싱"""
|
57 |
-
return preprocess_single_chunk(text)
|
58 |
-
|
59 |
-
def preprocess_single_chunk(chunk: str) -> str:
|
60 |
-
"""단일 청크에 대한 전처리 수행"""
|
61 |
-
system_prompt = """당신은 데이터 전처리 전문가입니다. 입력된 텍스트를 CSV 데이터셋 형식으로 빠르게 변환하세요.
|
62 |
-
[기존 규칙 동일]"""
|
63 |
-
|
64 |
-
full_prompt = f"{system_prompt}\n\n입력텍스트:\n{chunk}\n\n출력:"
|
65 |
-
|
66 |
-
try:
|
67 |
-
# 스트리밍 비활성화 및 파라미터 최적화
|
68 |
-
response = hf_client.text_generation(
|
69 |
-
prompt=full_prompt,
|
70 |
-
max_new_tokens=2000, # 토큰 수 제한
|
71 |
-
temperature=0.1, # 더 결정적인 출력
|
72 |
-
top_p=0.5, # 더 집중된 출력
|
73 |
-
stream=False # 스트리밍 비활성화
|
74 |
-
)
|
75 |
-
return response.strip()
|
76 |
-
except Exception as e:
|
77 |
-
print(f"청크 처리 중 오류 발생: {str(e)}\n{traceback.format_exc()}")
|
78 |
-
return "청크 처리 중 오류가 발생했습니다. 관리자에게 문의하세요."
|
79 |
-
|
80 |
def load_code(filename: str) -> str:
|
81 |
try:
|
82 |
with open(filename, 'r', encoding='utf-8') as file:
|
@@ -84,8 +20,7 @@ def load_code(filename: str) -> str:
|
|
84 |
except FileNotFoundError:
|
85 |
return f"{filename} 파일을 찾을 수 없습니다."
|
86 |
except Exception as e:
|
87 |
-
|
88 |
-
return "파일을 읽는 중 오류가 발생했습니다. 관리자에게 문의하세요."
|
89 |
|
90 |
def load_parquet(filename: str) -> str:
|
91 |
try:
|
@@ -94,8 +29,7 @@ def load_parquet(filename: str) -> str:
|
|
94 |
except FileNotFoundError:
|
95 |
return f"{filename} 파일을 찾을 수 없습니다."
|
96 |
except Exception as e:
|
97 |
-
|
98 |
-
return "파일을 읽는 중 오류가 발생했습니다. 관리자에게 문의하세요."
|
99 |
|
100 |
def respond(
|
101 |
message: str,
|
@@ -144,9 +78,9 @@ def respond(
|
|
144 |
response += msg
|
145 |
yield response
|
146 |
except Exception as e:
|
147 |
-
error_message = f"추론 중 오류가 발생했습니다: {str(e)}"
|
148 |
print(error_message)
|
149 |
-
yield
|
150 |
|
151 |
def upload_csv(file_path: str) -> Tuple[str, str]:
|
152 |
try:
|
@@ -168,8 +102,7 @@ def upload_csv(file_path: str) -> Tuple[str, str]:
|
|
168 |
df.to_parquet(parquet_filename, engine='pyarrow', compression='snappy')
|
169 |
return f"{parquet_filename} 파일이 성공적으로 업로드되고 변환되었습니다.", parquet_filename
|
170 |
except Exception as e:
|
171 |
-
|
172 |
-
return "CSV 파일 업로드 및 변환 중 오류가 발생했습니다. 관리자에게 문의하세요.", ""
|
173 |
|
174 |
def upload_parquet(file_path: str) -> Tuple[str, str, str]:
|
175 |
try:
|
@@ -181,26 +114,25 @@ def upload_parquet(file_path: str) -> Tuple[str, str, str]:
|
|
181 |
parquet_json = df.to_json(orient='records', force_ascii=False)
|
182 |
return "Parquet 파일이 성공적으로 업로드되었습니다.", parquet_content, parquet_json
|
183 |
except Exception as e:
|
184 |
-
|
185 |
-
return "Parquet 파일 업로드 중 오류가 발생했습니다. 관리자에게 문의하세요.", "", ""
|
186 |
|
187 |
def text_to_parquet(text: str) -> Tuple[str, str, str]:
|
188 |
try:
|
189 |
from io import StringIO
|
190 |
import csv
|
191 |
-
|
192 |
# 입력 텍스트 정제
|
193 |
lines = text.strip().split('\n')
|
194 |
cleaned_lines = []
|
195 |
-
|
196 |
for line in lines:
|
197 |
# 빈 줄 건너뛰기
|
198 |
if not line.strip():
|
199 |
continue
|
200 |
-
|
201 |
# 쌍따옴표 정규화
|
202 |
line = line.replace('""', '"') # 중복 쌍따옴표 처리
|
203 |
-
|
204 |
# CSV 파싱을 위한 임시 StringIO 객체 생성
|
205 |
temp_buffer = StringIO(line)
|
206 |
try:
|
@@ -211,14 +143,14 @@ def text_to_parquet(text: str) -> Tuple[str, str, str]:
|
|
211 |
# 각 필드를 적절히 포맷팅
|
212 |
formatted_line = f'{parsed_line[0]},"{parsed_line[1]}","{parsed_line[2]}","{parsed_line[3]}"'
|
213 |
cleaned_lines.append(formatted_line)
|
214 |
-
except
|
215 |
continue
|
216 |
finally:
|
217 |
temp_buffer.close()
|
218 |
-
|
219 |
# 정제된 CSV 데이터 생성
|
220 |
cleaned_csv = '\n'.join(cleaned_lines)
|
221 |
-
|
222 |
# DataFrame 생성
|
223 |
df = pd.read_csv(
|
224 |
StringIO(cleaned_csv),
|
@@ -227,28 +159,28 @@ def text_to_parquet(text: str) -> Tuple[str, str, str]:
|
|
227 |
escapechar='\\',
|
228 |
names=['id', 'text', 'label', 'metadata']
|
229 |
)
|
230 |
-
|
231 |
# 데이터 유형 최적화
|
232 |
df = df.astype({'id': 'int32', 'text': 'string', 'label': 'string', 'metadata': 'string'})
|
233 |
-
|
234 |
# Parquet 파일로 변환
|
235 |
parquet_filename = 'text_to_parquet.parquet'
|
236 |
df.to_parquet(parquet_filename, engine='pyarrow', compression='snappy')
|
237 |
-
|
238 |
# Parquet 파일 내용 미리보기
|
239 |
parquet_content = load_parquet(parquet_filename)
|
240 |
-
|
241 |
return f"{parquet_filename} 파일이 성공적으로 변환되었습니다.", parquet_content, parquet_filename
|
242 |
-
|
243 |
except Exception as e:
|
244 |
error_message = f"텍스트 변환 중 오류가 발생했습니다: {str(e)}"
|
245 |
print(f"{error_message}\n{traceback.format_exc()}")
|
246 |
-
return
|
247 |
|
248 |
def preprocess_text_with_llm(input_text: str) -> str:
|
249 |
if not input_text.strip():
|
250 |
-
return "입력 텍스트가
|
251 |
-
|
252 |
system_prompt = """당신은 데이터 전처리 전문가입니다. 입력된 텍스트를 CSV 데이터셋 형식으로 변환하세요.
|
253 |
|
254 |
규칙:
|
@@ -277,53 +209,41 @@ def preprocess_text_with_llm(input_text: str) -> str:
|
|
277 |
- 각 행은 새로운 줄로 구분
|
278 |
- 불필요한 반복 출력 금지"""
|
279 |
|
280 |
-
|
281 |
-
# 텍스트를 청크로 분할
|
282 |
-
chunks = chunk_text(input_text)
|
283 |
-
|
284 |
-
# 병렬 처리로 청크들을 처리
|
285 |
-
with ThreadPoolExecutor(max_workers=3) as executor:
|
286 |
-
futures = []
|
287 |
-
for chunk in chunks:
|
288 |
-
# 각 청크에 대한 프롬프트 생성
|
289 |
-
chunk_prompt = f"{system_prompt}\n\n입력텍스트:\n{chunk}\n\n출력:"
|
290 |
-
future = executor.submit(
|
291 |
-
hf_client.text_generation,
|
292 |
-
prompt=chunk_prompt,
|
293 |
-
max_new_tokens=2000,
|
294 |
-
temperature=0.1,
|
295 |
-
top_p=0.5,
|
296 |
-
stream=False
|
297 |
-
)
|
298 |
-
futures.append(future)
|
299 |
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
seen_texts = set()
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
line = line.strip()
|
315 |
-
if line and '출력:' not in line and line not in seen_texts:
|
316 |
-
# ID 재할당
|
317 |
-
parts = line.split(',', 1)
|
318 |
-
if len(parts) > 1:
|
319 |
-
new_line = f"{current_id},{parts[1]}"
|
320 |
-
if new_line not in seen_texts: # 추가적인 중복 검사
|
321 |
-
all_lines.append(new_line)
|
322 |
-
seen_texts.add(new_line)
|
323 |
-
current_id += 1
|
324 |
-
|
325 |
-
processed_text = '\n'.join(all_lines)
|
326 |
-
|
327 |
# CSV 형식 검증
|
328 |
try:
|
329 |
from io import StringIO
|
@@ -332,11 +252,11 @@ def preprocess_text_with_llm(input_text: str) -> str:
|
|
332 |
return processed_text
|
333 |
except csv.Error:
|
334 |
return "LLM이 올바른 CSV 형식을 생성하지 못했습니다. 다시 시도해주세요."
|
335 |
-
|
336 |
except Exception as e:
|
337 |
error_message = f"전처리 중 오류가 발생했습니다: {str(e)}"
|
338 |
print(error_message)
|
339 |
-
return
|
340 |
|
341 |
# CSS 설정
|
342 |
css = """
|
@@ -375,6 +295,8 @@ with gr.Blocks(css=css) as demo:
|
|
375 |
elem_id="initial-description"
|
376 |
)
|
377 |
|
|
|
|
|
378 |
# 첫 번째 탭: 챗봇 데이터 업로드 (탭 이름 변경: "My 데이터셋+LLM")
|
379 |
with gr.Tab("My 데이터셋+LLM"):
|
380 |
gr.Markdown("### LLM과 대화하기")
|
@@ -418,8 +340,7 @@ with gr.Blocks(css=css) as demo:
|
|
418 |
# 어시스턴트의 응답을 히스토리에 추가
|
419 |
history.append({"role": "assistant", "content": partial_response})
|
420 |
except Exception as e:
|
421 |
-
|
422 |
-
response = "메시지 처리 중 오류가 발생했습니다. 관리자에게 문의하세요."
|
423 |
history.append({"role": "assistant", "content": response})
|
424 |
yield history, ""
|
425 |
|
@@ -540,48 +461,49 @@ with gr.Blocks(css=css) as demo:
|
|
540 |
lines=15,
|
541 |
placeholder="여기에 전처리할 텍스트를 입력하세요..."
|
542 |
)
|
543 |
-
|
544 |
with gr.Row():
|
545 |
preprocess_button = gr.Button("전처리 실행", variant="primary")
|
546 |
clear_button = gr.Button("초기화")
|
547 |
-
|
548 |
preprocess_status = gr.Textbox(
|
549 |
label="전처리 상태",
|
550 |
interactive=False,
|
551 |
value="대기 중..."
|
552 |
)
|
553 |
-
|
554 |
processed_text_output = gr.Textbox(
|
555 |
label="전처리된 데이터셋 출력",
|
556 |
lines=15,
|
557 |
interactive=False
|
558 |
)
|
559 |
-
|
560 |
# Parquet 변환 및 다운로드 섹션
|
561 |
convert_to_parquet_button = gr.Button("Parquet으로 변환")
|
562 |
download_parquet = gr.File(label="변환된 Parquet 파일 다운로드")
|
563 |
|
|
|
|
|
|
|
564 |
def handle_text_preprocessing(input_text: str):
|
565 |
if not input_text.strip():
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
try:
|
570 |
preprocess_status_msg = "전처리를 시작합니다..."
|
571 |
yield preprocess_status_msg, ""
|
572 |
-
|
573 |
processed_text = preprocess_text_with_llm(input_text)
|
574 |
-
|
575 |
if processed_text:
|
576 |
preprocess_status_msg = "전처리가 완료되었습니다."
|
577 |
yield preprocess_status_msg, processed_text
|
578 |
else:
|
579 |
preprocess_status_msg = "전처리 결과가 없습니다."
|
580 |
yield preprocess_status_msg, ""
|
581 |
-
|
582 |
except Exception as e:
|
583 |
-
error_msg = "
|
584 |
-
print(f"전처리 중 오류 발생: {str(e)}\n{traceback.format_exc()}")
|
585 |
yield error_msg, ""
|
586 |
|
587 |
def clear_inputs():
|
@@ -590,15 +512,14 @@ with gr.Blocks(css=css) as demo:
|
|
590 |
def convert_to_parquet_file(processed_text: str):
|
591 |
if not processed_text.strip():
|
592 |
return "변환할 텍스트가 없습니다.", None
|
593 |
-
|
594 |
try:
|
595 |
message, parquet_content, parquet_filename = text_to_parquet(processed_text)
|
596 |
if parquet_filename:
|
597 |
return message, parquet_filename
|
598 |
return message, None
|
599 |
except Exception as e:
|
600 |
-
|
601 |
-
return "Parquet 변환 중 오류가 발생했습니다. 관리자에게 문의하세요.", None
|
602 |
|
603 |
# 이벤트 핸들러 연결
|
604 |
preprocess_button.click(
|
@@ -633,5 +554,5 @@ with gr.Blocks(css=css) as demo:
|
|
633 |
gr.Markdown("### [email protected]", elem_id="initial-description")
|
634 |
|
635 |
if __name__ == "__main__":
|
636 |
-
demo.launch(share=True)
|
637 |
|
|
|
3 |
import os
|
4 |
import pandas as pd
|
5 |
from typing import List, Dict, Tuple
|
6 |
+
import json
|
7 |
import io
|
8 |
import traceback
|
9 |
import csv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
# 추론 API 클라이언트 설정
|
12 |
hf_client = InferenceClient(
|
13 |
"CohereForAI/c4ai-command-r-plus-08-2024", token=os.getenv("HF_TOKEN")
|
14 |
)
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
def load_code(filename: str) -> str:
|
17 |
try:
|
18 |
with open(filename, 'r', encoding='utf-8') as file:
|
|
|
20 |
except FileNotFoundError:
|
21 |
return f"{filename} 파일을 찾을 수 없습니다."
|
22 |
except Exception as e:
|
23 |
+
return f"파일을 읽는 중 오류가 발생했습니다: {str(e)}"
|
|
|
24 |
|
25 |
def load_parquet(filename: str) -> str:
|
26 |
try:
|
|
|
29 |
except FileNotFoundError:
|
30 |
return f"{filename} 파일을 찾을 수 없습니다."
|
31 |
except Exception as e:
|
32 |
+
return f"파일을 읽는 중 오류가 발생했습니다: {str(e)}"
|
|
|
33 |
|
34 |
def respond(
|
35 |
message: str,
|
|
|
78 |
response += msg
|
79 |
yield response
|
80 |
except Exception as e:
|
81 |
+
error_message = f"추론 중 오류가 발생했습니다: {str(e)}\n{traceback.format_exc()}"
|
82 |
print(error_message)
|
83 |
+
yield error_message
|
84 |
|
85 |
def upload_csv(file_path: str) -> Tuple[str, str]:
|
86 |
try:
|
|
|
102 |
df.to_parquet(parquet_filename, engine='pyarrow', compression='snappy')
|
103 |
return f"{parquet_filename} 파일이 성공적으로 업로드되고 변환되었습니다.", parquet_filename
|
104 |
except Exception as e:
|
105 |
+
return f"CSV 파일 업로드 및 변환 중 오류가 발생했습니다: {str(e)}", ""
|
|
|
106 |
|
107 |
def upload_parquet(file_path: str) -> Tuple[str, str, str]:
|
108 |
try:
|
|
|
114 |
parquet_json = df.to_json(orient='records', force_ascii=False)
|
115 |
return "Parquet 파일이 성공적으로 업로드되었습니다.", parquet_content, parquet_json
|
116 |
except Exception as e:
|
117 |
+
return f"Parquet 파일 업로드 중 오류가 발생했습니다: {str(e)}", "", ""
|
|
|
118 |
|
119 |
def text_to_parquet(text: str) -> Tuple[str, str, str]:
|
120 |
try:
|
121 |
from io import StringIO
|
122 |
import csv
|
123 |
+
|
124 |
# 입력 텍스트 정제
|
125 |
lines = text.strip().split('\n')
|
126 |
cleaned_lines = []
|
127 |
+
|
128 |
for line in lines:
|
129 |
# 빈 줄 건너뛰기
|
130 |
if not line.strip():
|
131 |
continue
|
132 |
+
|
133 |
# 쌍따옴표 정규화
|
134 |
line = line.replace('""', '"') # 중복 쌍따옴표 처리
|
135 |
+
|
136 |
# CSV 파싱을 위한 임시 StringIO 객체 생성
|
137 |
temp_buffer = StringIO(line)
|
138 |
try:
|
|
|
143 |
# 각 필드를 적절히 포맷팅
|
144 |
formatted_line = f'{parsed_line[0]},"{parsed_line[1]}","{parsed_line[2]}","{parsed_line[3]}"'
|
145 |
cleaned_lines.append(formatted_line)
|
146 |
+
except:
|
147 |
continue
|
148 |
finally:
|
149 |
temp_buffer.close()
|
150 |
+
|
151 |
# 정제된 CSV 데이터 생성
|
152 |
cleaned_csv = '\n'.join(cleaned_lines)
|
153 |
+
|
154 |
# DataFrame 생성
|
155 |
df = pd.read_csv(
|
156 |
StringIO(cleaned_csv),
|
|
|
159 |
escapechar='\\',
|
160 |
names=['id', 'text', 'label', 'metadata']
|
161 |
)
|
162 |
+
|
163 |
# 데이터 유형 최적화
|
164 |
df = df.astype({'id': 'int32', 'text': 'string', 'label': 'string', 'metadata': 'string'})
|
165 |
+
|
166 |
# Parquet 파일로 변환
|
167 |
parquet_filename = 'text_to_parquet.parquet'
|
168 |
df.to_parquet(parquet_filename, engine='pyarrow', compression='snappy')
|
169 |
+
|
170 |
# Parquet 파일 내용 미리보기
|
171 |
parquet_content = load_parquet(parquet_filename)
|
172 |
+
|
173 |
return f"{parquet_filename} 파일이 성공적으로 변환되었습니다.", parquet_content, parquet_filename
|
174 |
+
|
175 |
except Exception as e:
|
176 |
error_message = f"텍스트 변환 중 오류가 발생했습니다: {str(e)}"
|
177 |
print(f"{error_message}\n{traceback.format_exc()}")
|
178 |
+
return error_message, "", ""
|
179 |
|
180 |
def preprocess_text_with_llm(input_text: str) -> str:
|
181 |
if not input_text.strip():
|
182 |
+
return "입력 텍스트가 비어있습니다."
|
183 |
+
|
184 |
system_prompt = """당신은 데이터 전처리 전문가입니다. 입력된 텍스트를 CSV 데이터셋 형식으로 변환하세요.
|
185 |
|
186 |
규칙:
|
|
|
209 |
- 각 행은 새로운 줄로 구분
|
210 |
- 불필요한 반복 출력 금지"""
|
211 |
|
212 |
+
full_prompt = f"{system_prompt}\n\n입력텍스트:\n{input_text}\n\n출력:"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
+
try:
|
215 |
+
response = ""
|
216 |
+
stream = hf_client.text_generation(
|
217 |
+
prompt=full_prompt,
|
218 |
+
max_new_tokens=4000,
|
219 |
+
temperature=0.1, # 더 결정적인 출력을 위해 낮춤
|
220 |
+
top_p=0.9,
|
221 |
+
stream=True,
|
222 |
+
)
|
223 |
+
|
224 |
+
for msg in stream:
|
225 |
+
if msg:
|
226 |
+
response += msg
|
227 |
+
|
228 |
+
# <EOS_TOKEN> 이전까지만 추출하고 정제
|
229 |
+
if "<EOS_TOKEN>" in response:
|
230 |
+
processed_text = response.split("<EOS_TOKEN>")[0].strip()
|
231 |
+
else:
|
232 |
+
processed_text = response.strip()
|
233 |
+
|
234 |
+
# 중복 출력 제거
|
235 |
+
lines = processed_text.split('\n')
|
236 |
+
unique_lines = []
|
237 |
seen_texts = set()
|
238 |
+
|
239 |
+
for line in lines:
|
240 |
+
line = line.strip()
|
241 |
+
if line and '출력:' not in line and line not in seen_texts:
|
242 |
+
unique_lines.append(line)
|
243 |
+
seen_texts.add(line)
|
244 |
+
|
245 |
+
processed_text = '\n'.join(unique_lines)
|
246 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
# CSV 형식 검증
|
248 |
try:
|
249 |
from io import StringIO
|
|
|
252 |
return processed_text
|
253 |
except csv.Error:
|
254 |
return "LLM이 올바른 CSV 형식을 생성하지 못했습니다. 다시 시도해주세요."
|
255 |
+
|
256 |
except Exception as e:
|
257 |
error_message = f"전처리 중 오류가 발생했습니다: {str(e)}"
|
258 |
print(error_message)
|
259 |
+
return error_message
|
260 |
|
261 |
# CSS 설정
|
262 |
css = """
|
|
|
295 |
elem_id="initial-description"
|
296 |
)
|
297 |
|
298 |
+
|
299 |
+
|
300 |
# 첫 번째 탭: 챗봇 데이터 업로드 (탭 이름 변경: "My 데이터셋+LLM")
|
301 |
with gr.Tab("My 데이터셋+LLM"):
|
302 |
gr.Markdown("### LLM과 대화하기")
|
|
|
340 |
# 어시스턴트의 응답을 히스토리에 추가
|
341 |
history.append({"role": "assistant", "content": partial_response})
|
342 |
except Exception as e:
|
343 |
+
response = f"추론 중 오류가 발생했습니다: {str(e)}"
|
|
|
344 |
history.append({"role": "assistant", "content": response})
|
345 |
yield history, ""
|
346 |
|
|
|
461 |
lines=15,
|
462 |
placeholder="여기에 전처리할 텍스트를 입력하세요..."
|
463 |
)
|
464 |
+
|
465 |
with gr.Row():
|
466 |
preprocess_button = gr.Button("전처리 실행", variant="primary")
|
467 |
clear_button = gr.Button("초기화")
|
468 |
+
|
469 |
preprocess_status = gr.Textbox(
|
470 |
label="전처리 상태",
|
471 |
interactive=False,
|
472 |
value="대기 중..."
|
473 |
)
|
474 |
+
|
475 |
processed_text_output = gr.Textbox(
|
476 |
label="전처리된 데이터셋 출력",
|
477 |
lines=15,
|
478 |
interactive=False
|
479 |
)
|
480 |
+
|
481 |
# Parquet 변환 및 다운로드 섹션
|
482 |
convert_to_parquet_button = gr.Button("Parquet으로 변환")
|
483 |
download_parquet = gr.File(label="변환된 Parquet 파일 다운로드")
|
484 |
|
485 |
+
|
486 |
+
|
487 |
+
|
488 |
def handle_text_preprocessing(input_text: str):
|
489 |
if not input_text.strip():
|
490 |
+
return "입력 텍스트가 없습니다.", ""
|
491 |
+
|
|
|
492 |
try:
|
493 |
preprocess_status_msg = "전처리를 시작합니다..."
|
494 |
yield preprocess_status_msg, ""
|
495 |
+
|
496 |
processed_text = preprocess_text_with_llm(input_text)
|
497 |
+
|
498 |
if processed_text:
|
499 |
preprocess_status_msg = "전처리가 완료되었습니다."
|
500 |
yield preprocess_status_msg, processed_text
|
501 |
else:
|
502 |
preprocess_status_msg = "전처리 결과가 없습니다."
|
503 |
yield preprocess_status_msg, ""
|
504 |
+
|
505 |
except Exception as e:
|
506 |
+
error_msg = f"처리 중 오류가 발생했습니다: {str(e)}"
|
|
|
507 |
yield error_msg, ""
|
508 |
|
509 |
def clear_inputs():
|
|
|
512 |
def convert_to_parquet_file(processed_text: str):
|
513 |
if not processed_text.strip():
|
514 |
return "변환할 텍스트가 없습니다.", None
|
515 |
+
|
516 |
try:
|
517 |
message, parquet_content, parquet_filename = text_to_parquet(processed_text)
|
518 |
if parquet_filename:
|
519 |
return message, parquet_filename
|
520 |
return message, None
|
521 |
except Exception as e:
|
522 |
+
return f"Parquet 변환 중 오류 발생: {str(e)}", None
|
|
|
523 |
|
524 |
# 이벤트 핸들러 연결
|
525 |
preprocess_button.click(
|
|
|
554 |
gr.Markdown("### [email protected]", elem_id="initial-description")
|
555 |
|
556 |
if __name__ == "__main__":
|
557 |
+
demo.launch(share=True)
|
558 |
|