Nattapong Tapachoom commited on
Commit
11885ff
·
1 Parent(s): bf8bb9c

Enhance model loading and quality management features with status tracking and progress feedback

Browse files
Files changed (1) hide show
  1. app.py +465 -166
app.py CHANGED
@@ -11,7 +11,94 @@ import time
11
  import queue
12
  from concurrent.futures import ThreadPoolExecutor, as_completed
13
  import asyncio
14
- from data_quality import DataQualityManager, export_to_huggingface_format
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
  # Predefined task templates with Thai language support
17
  TASK_TEMPLATES = {
@@ -268,18 +355,40 @@ class ModelStatus:
268
  }
269
 
270
  def load_model_with_cache(model_name: str, cache: dict):
271
- """Load model with caching to avoid reloading"""
272
  if model_name in cache:
273
  return cache[model_name], None
274
 
275
  try:
276
- tokenizer = AutoTokenizer.from_pretrained(model_name)
277
- model = AutoModelForCausalLM.from_pretrained(model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
279
  cache[model_name] = generator
 
280
  return generator, None
 
281
  except Exception as e:
282
- return None, str(e)
 
 
283
 
284
  def generate_single_record(generator, prompt: str, record_id: int, model_name: str,
285
  max_length: int, temperature: float, top_p: float,
@@ -443,34 +552,104 @@ def generate_dataset_multi_model(selected_models: List[str], task_type: str, cus
443
  return None, None, None, f"Error in multi-model generation: {str(e)}"
444
 
445
  def create_interface():
446
- with gr.Blocks(title="🇹🇭 Thai Dataset Generator with Hugging Face", theme=gr.themes.Soft()) as demo:
447
  gr.Markdown("# 🤗 เครื่องมือสร้างชุดข้อมูลภาษาไทยคุณภาพสูง")
448
- gr.Markdown("สร้างชุดข้อมูลภาษาไทยคุณภาพสูง สะอาด และเป็นสากลด้วยโมเดลหลายตัว")
449
 
450
  with gr.Row():
451
  with gr.Column():
452
- # Multi-model selection
453
- gr.Markdown("### 🤖 เลือกโมเดลภาษาไทย (หลายตัว)")
 
454
 
455
- model_checkboxes = gr.CheckboxGroup(
456
  choices=[
457
- ("🌪️ Typhoon-7B (SCB10X)", "scb10x/typhoon-7b"),
458
- ("🇹🇭 OpenThaiGPT 1.5-7B", "openthaigpt/openthaigpt1.5-7b-instruct"),
459
- ("🦁 Gemma2-9B WangchanLION", "aisingapore/Gemma2-9b-WangchanLIONv2-instruct"),
460
- ("🌍 SambaLingo-Thai-Base", "sambanovasystems/SambaLingo-Thai-Base")
461
  ],
462
- value=["scb10x/typhoon-7b"],
463
- label="เลือกโมเดลที่ต้องการใช้งาน (สามารถเลือกหลายตัว)"
464
  )
465
 
466
- gr.Markdown("### 📊 โหมดการทำงาน")
467
- work_mode = gr.Radio(
468
- choices=[
469
- ("🔄 แบ่งงานกัน (Multi-Model Collaboration)", "collaborative"),
470
- ("📝 ใช้โมเดลเดียว (Single Model)", "single")
471
- ],
472
- value="collaborative",
473
- label="เลือกโหมดการทำงาน"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
  )
475
 
476
  # Task selection with Thai tasks
@@ -500,21 +679,101 @@ def create_interface():
500
  visible=False
501
  )
502
 
503
- # Template customization
504
- gr.Markdown("### 🎯 ปรับแต่งเทมเพลต")
505
  gr.Markdown("ใช้ {ชื่อฟิลด์} สำหรับตัวแปรในเทมเพลต")
506
- template_display = gr.Textbox(
507
- label="เทมเพลตปัจจุบัน",
508
- value=TASK_TEMPLATES["text_generation"]["template"],
509
- interactive=False
 
 
 
 
 
510
  )
511
 
512
- custom_template = gr.Textbox(
513
- label="เทมเพลตกำหนดเอง (ไม่บังคับ)",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  lines=3,
515
- placeholder="สร้างเทมเพลตของคุณเองที่นี่..."
516
  )
517
 
 
 
 
 
 
 
518
  # Data Quality Settings
519
  gr.Markdown("### 🧼 การจัดการคุณภาพข้อมูล")
520
 
@@ -554,43 +813,72 @@ def create_interface():
554
  label="รูปแบบการส่งออก"
555
  )
556
 
557
- # Generation parameters
558
  gr.Markdown("### ⚙️ ตั้งค่าการสร้างข้อมูล")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
  with gr.Row():
560
- num_samples = gr.Slider(
561
- minimum=1,
562
- maximum=100,
563
- value=10,
564
- step=1,
565
- label="จำนวนข้อมูลที่ต้องการ"
566
- )
567
-
568
  max_length = gr.Slider(
569
  minimum=10,
570
- maximum=1000,
571
- value=200,
572
  step=10,
573
  label="ความยาวสูงสุด (โทเคน)"
574
  )
575
-
576
- with gr.Row():
577
- temperature = gr.Slider(
578
- minimum=0.1,
579
- maximum=2.0,
580
- value=0.8,
581
- step=0.1,
582
- label="ความคิดสร้างสรรค์ (Temperature)"
583
- )
584
 
585
- top_p = gr.Slider(
586
- minimum=0.1,
587
- maximum=1.0,
588
- value=0.9,
589
- step=0.1,
590
- label="ความหลากหลาย (Top-p)"
591
  )
 
 
 
 
 
 
 
592
 
593
- generate_btn = gr.Button("🚀 สร้างชุดข้อมูลคุณภาพสูง", variant="primary", size="lg")
 
 
 
 
 
 
594
 
595
  with gr.Column():
596
  with gr.Tabs():
@@ -718,68 +1006,101 @@ def create_interface():
718
  return (
719
  gr.update(visible=False),
720
  gr.update(visible=True, value="❌ กรุณาเลือกโมเดลอย่างน้อยหนึ่งตัว"),
721
- {}, "เกิดข้อผิดพลาดในการสร้างข้อมูล",
722
- None, None, None, None
723
  )
724
 
725
- # Generate raw data first
726
- if work_mode == "collaborative" and len(selected_models) > 1:
727
- df, csv_data, json_data, error = generate_dataset_multi_model(
728
- selected_models, task_type, custom_template, file_data,
729
- num_samples, max_length, temperature, top_p
730
- )
731
- else:
732
- model_name = selected_models[0] if selected_models else "distilgpt2"
733
- df, csv_data, json_data, error = generate_dataset_from_task(
734
- model_name, task_type, custom_template, file_data,
735
- num_samples, max_length, temperature, top_p
736
  )
737
-
738
- if error:
739
- return (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  gr.update(visible=False),
741
- gr.update(visible=True, value=f" เกิดข้อผิดพลาด: {error}"),
742
- {}, "เกิดข้อผิดพลาดในการสร้างข้อมูล",
743
- None, None, None, None
744
  )
745
-
746
- # Apply basic quality management since we don't have the full module
747
- raw_data = df.to_dict('records')
748
-
749
- # Simple cleaning
750
- if enable_cleaning:
751
- for record in raw_data:
752
- if 'prompt' in record:
753
- record['prompt'] = str(record['prompt']).strip()
754
- if 'generated_text' in record:
755
- record['generated_text'] = str(record['generated_text']).strip()
756
-
757
- # Remove duplicates (simple version)
758
- if remove_duplicates:
759
- seen = set()
760
- unique_data = []
761
- for record in raw_data:
762
- key = str(record.get('prompt', '')) + str(record.get('generated_text', ''))
763
- if key not in seen:
764
- seen.add(key)
765
- unique_data.append(record)
766
- raw_data = unique_data
767
-
768
- # Create quality report
769
- quality_report = {
770
- "total_records": len(raw_data),
771
- "cleaning_enabled": enable_cleaning,
772
- "duplicates_removed": remove_duplicates,
773
- "models_used": list(set([r.get('model_used', 'unknown') for r in raw_data]))
774
- }
775
-
776
- # Create final DataFrame
777
- final_df = pd.DataFrame(raw_data)
778
- final_csv = final_df.to_csv(index=False)
779
- final_json = json.dumps(raw_data, indent=2, ensure_ascii=False)
780
-
781
- # Simple dataset card
782
- dataset_card = f"""# Thai {task_type.title()} Dataset
783
 
784
  ## Dataset Information
785
  - Total Records: {len(raw_data)}
@@ -790,53 +1111,29 @@ def create_interface():
790
  ## Usage
791
  This dataset can be used for Thai NLP tasks.
792
  """
793
-
794
- success_msg = f"✅ สร้างข้อมูลสำเร็จ! ได้ {len(raw_data)} รายการ"
795
- quality_summary = f"📊 จำนวนข้อมูล: {len(raw_data)} รายการ"
796
-
797
- return (
798
- gr.update(visible=True, value=final_df),
799
- gr.update(visible=True, value=success_msg),
800
- quality_report,
801
- quality_summary,
802
- final_csv,
803
- final_json,
804
- dataset_card,
805
- None # hf_export_path
806
- )
807
-
808
- def download_csv(csv_data):
809
- if csv_data:
810
- return gr.update(visible=True, value=io.StringIO(csv_data))
811
- return gr.update(visible=False)
812
-
813
- def download_json(json_data):
814
- if json_data:
815
- return gr.update(visible=True, value=io.StringIO(json_data))
816
- return gr.update(visible=False)
817
-
818
- def download_dataset_card(card_content):
819
- if card_content:
820
- return gr.update(visible=True, value=io.StringIO(card_content))
821
- return gr.update(visible=False)
822
-
823
- def download_hf_dataset(hf_path):
824
- if hf_path:
825
- import zipfile
826
- import tempfile
827
- import os
828
-
829
- # Create zip file
830
- zip_path = tempfile.mktemp(suffix='.zip')
831
- with zipfile.ZipFile(zip_path, 'w') as zipf:
832
- for root, dirs, files in os.walk(hf_path):
833
- for file in files:
834
- file_path = os.path.join(root, file)
835
- arcname = os.path.relpath(file_path, hf_path)
836
- zipf.write(file_path, arcname)
837
-
838
- return gr.update(visible=True, value=zip_path)
839
- return gr.update(visible=False)
840
 
841
  # Event connections
842
  task_dropdown.change(
@@ -851,14 +1148,16 @@ This dataset can be used for Thai NLP tasks.
851
  outputs=[file_preview, file_data_state]
852
  )
853
 
 
854
  generate_btn.click(
855
- fn=process_with_quality_management,
856
  inputs=[model_checkboxes, work_mode, task_dropdown, custom_template, file_data_state,
857
  num_samples, max_length, temperature, top_p,
858
  enable_cleaning, remove_duplicates, min_quality_score,
859
  create_splits, export_format],
860
  outputs=[dataset_preview, status_message, quality_report, quality_summary,
861
- csv_data_state, json_data_state, dataset_card_state, hf_export_state]
 
862
  )
863
 
864
  csv_btn.click(
 
11
  import queue
12
  from concurrent.futures import ThreadPoolExecutor, as_completed
13
  import asyncio
14
+
15
+ # Global model cache and loading status
16
+ MODEL_CACHE = {}
17
+ MODEL_LOADING_STATUS = {}
18
+ MODEL_LOADING_LOCK = threading.Lock()
19
+
20
+ def check_model_loading_status(model_names: List[str]) -> Dict:
21
+ """Check loading status of multiple models"""
22
+ with MODEL_LOADING_LOCK:
23
+ status = {}
24
+ for model_name in model_names:
25
+ if model_name in MODEL_CACHE:
26
+ status[model_name] = "ready"
27
+ elif model_name in MODEL_LOADING_STATUS:
28
+ status[model_name] = MODEL_LOADING_STATUS[model_name]
29
+ else:
30
+ status[model_name] = "not_loaded"
31
+ return status
32
+
33
+ def load_model_with_status_tracking(model_name: str):
34
+ """Load model with status tracking"""
35
+ with MODEL_LOADING_LOCK:
36
+ if model_name in MODEL_CACHE:
37
+ return MODEL_CACHE[model_name], None
38
+
39
+ if model_name in MODEL_LOADING_STATUS:
40
+ return None, f"โมเดล {model_name} กำลังโหลดอยู่..."
41
+
42
+ MODEL_LOADING_STATUS[model_name] = "loading"
43
+
44
+ try:
45
+ print(f"🔄 เริ่มโหลดโมเดล {model_name}...")
46
+
47
+ # Update status
48
+ with MODEL_LOADING_LOCK:
49
+ MODEL_LOADING_STATUS[model_name] = "downloading"
50
+
51
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
52
+
53
+ with MODEL_LOADING_LOCK:
54
+ MODEL_LOADING_STATUS[model_name] = "loading_model"
55
+
56
+ model = AutoModelForCausalLM.from_pretrained(
57
+ model_name,
58
+ torch_dtype=torch.float16,
59
+ device_map="auto",
60
+ trust_remote_code=True
61
+ )
62
+
63
+ with MODEL_LOADING_LOCK:
64
+ MODEL_LOADING_STATUS[model_name] = "creating_pipeline"
65
+
66
+ generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
67
+
68
+ with MODEL_LOADING_LOCK:
69
+ MODEL_CACHE[model_name] = generator
70
+ MODEL_LOADING_STATUS[model_name] = "ready"
71
+
72
+ print(f"✅ โหลดโมเดล {model_name} สำเร็จ")
73
+ return generator, None
74
+
75
+ except Exception as e:
76
+ error_msg = f"❌ ไม่สามารถโหลดโมเดล {model_name}: {str(e)}"
77
+ print(error_msg)
78
+
79
+ with MODEL_LOADING_LOCK:
80
+ if model_name in MODEL_LOADING_STATUS:
81
+ del MODEL_LOADING_STATUS[model_name]
82
+
83
+ return None, error_msg
84
+
85
+ def preload_models_async(model_names: List[str], progress_callback=None):
86
+ """Preload models asynchronously"""
87
+ def load_single_model(model_name):
88
+ generator, error = load_model_with_status_tracking(model_name)
89
+ if progress_callback:
90
+ progress_callback(model_name, "ready" if generator else "error", error)
91
+ return model_name, generator, error
92
+
93
+ results = {}
94
+ with ThreadPoolExecutor(max_workers=2) as executor: # Limit concurrent loading
95
+ futures = {executor.submit(load_single_model, model): model for model in model_names}
96
+
97
+ for future in as_completed(futures):
98
+ model_name, generator, error = future.result()
99
+ results[model_name] = {"generator": generator, "error": error}
100
+
101
+ return results
102
 
103
  # Predefined task templates with Thai language support
104
  TASK_TEMPLATES = {
 
355
  }
356
 
357
  def load_model_with_cache(model_name: str, cache: dict):
358
+ """Load model with caching and progress feedback"""
359
  if model_name in cache:
360
  return cache[model_name], None
361
 
362
  try:
363
+ print(f"🔄 กำลังโหลดโมเดล {model_name}...")
364
+
365
+ # Use smaller models or quantized versions for faster loading
366
+ if "typhoon" in model_name.lower():
367
+ # Load with optimizations
368
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
369
+ model = AutoModelForCausalLM.from_pretrained(
370
+ model_name,
371
+ torch_dtype=torch.float16, # Use half precision
372
+ device_map="auto",
373
+ trust_remote_code=True
374
+ )
375
+ else:
376
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
377
+ model = AutoModelForCausalLM.from_pretrained(
378
+ model_name,
379
+ torch_dtype=torch.float16,
380
+ device_map="auto"
381
+ )
382
+
383
  generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
384
  cache[model_name] = generator
385
+ print(f"✅ โหลด��มเดล {model_name} สำเร็จ")
386
  return generator, None
387
+
388
  except Exception as e:
389
+ error_msg = f"❌ ไม่สามารถโหลดโมเดล {model_name}: {str(e)}"
390
+ print(error_msg)
391
+ return None, error_msg
392
 
393
  def generate_single_record(generator, prompt: str, record_id: int, model_name: str,
394
  max_length: int, temperature: float, top_p: float,
 
552
  return None, None, None, f"Error in multi-model generation: {str(e)}"
553
 
554
  def create_interface():
555
+ with gr.Blocks(title="🇹🇭 Thai Dataset Generator", theme=gr.themes.Soft()) as demo:
556
  gr.Markdown("# 🤗 เครื่องมือสร้างชุดข้อมูลภาษาไทยคุณภาพสูง")
557
+ gr.Markdown(" **เคล็ดลับ**: ใช้โมเดลใดก็ได้จาก Hugging Face - เริ่มต้นด้วยโมเดลเล็กๆ เพื่อทดสอบก่อน")
558
 
559
  with gr.Row():
560
  with gr.Column():
561
+ # Flexible model input
562
+ gr.Markdown("### 🤖 เลือกโมเดลจาก Hugging Face")
563
+ gr.Markdown("💡 **คำแนะนำ**: ใส่ชื่อโมเดลจาก [Hugging Face](https://huggingface.co/models) เช่น `microsoft/DialoGPT-small`, `gpt2`, `scb10x/typhoon-7b`")
564
 
565
+ model_input_mode = gr.Radio(
566
  choices=[
567
+ ("📝 ใส่ชื่อโมเดลเอง", "manual"),
568
+ ("📋 เลือกจากรายการแนะนำ", "suggested"),
569
+ ("🔀 ใช้หลายโมเดลพร้อมกัน", "multiple")
 
570
  ],
571
+ value="manual",
572
+ label="วิธีการเลือกโมเดล"
573
  )
574
 
575
+ # Manual model input
576
+ manual_model_group = gr.Group(visible=True)
577
+ with manual_model_group:
578
+ single_model_name = gr.Textbox(
579
+ label="ชื่อโมเดลจาก Hugging Face",
580
+ value="microsoft/DialoGPT-small",
581
+ placeholder="เช่น gpt2, microsoft/DialoGPT-medium, scb10x/typhoon-7b",
582
+ info="ใส่ชื่อโมเดลที่ต้องการใช้งาน"
583
+ )
584
+
585
+ model_verification = gr.Button("🔍 ตรวจสอบโมเดล", variant="secondary", size="sm")
586
+ model_status = gr.Textbox(
587
+ label="สถานะโมเดล",
588
+ value="ยังไม่ได้ตรวจสอบ",
589
+ interactive=False
590
+ )
591
+
592
+ # Suggested models
593
+ suggested_model_group = gr.Group(visible=False)
594
+ with suggested_model_group:
595
+ gr.Markdown("#### โมเดลแนะนำ")
596
+
597
+ suggested_models = gr.Dropdown(
598
+ choices=[
599
+ # Small/Fast models
600
+ ("⚡ DistilGPT2 (เล็ก, เร็ว)", "distilgpt2"),
601
+ ("⚡ GPT2 (กลาง)", "gpt2"),
602
+ ("⚡ DialoGPT-small (บทสนทนา)", "microsoft/DialoGPT-small"),
603
+ ("⚡ DialoGPT-medium (บทสนทนา)", "microsoft/DialoGPT-medium"),
604
+
605
+ # Thai models
606
+ ("🇹🇭 Typhoon-7B (ไทย, ใหญ่)", "scb10x/typhoon-7b"),
607
+ ("🇹🇭 OpenThaiGPT-1.5-7B (ไทย)", "openthaigpt/openthaigpt1.5-7b-instruct"),
608
+ ("🇹🇭 WangchanLION-7B (ไทย)", "aisingapore/llama2-7b-chat-thai"),
609
+
610
+ # Multilingual models
611
+ ("🌍 mGPT (หลายภาษา)", "ai-forever/mGPT"),
612
+ ("🌍 Bloom-560m (หลายภาษา, เล็ก)", "bigscience/bloom-560m"),
613
+ ("🌍 Bloom-1b1 (หลายภาษา)", "bigscience/bloom-1b1"),
614
+
615
+ # Instruction-following
616
+ ("🎯 Flan-T5-small (คำสั่ง)", "google/flan-t5-small"),
617
+ ("🎯 Flan-T5-base (คำสั่ง)", "google/flan-t5-base"),
618
+
619
+ # Other popular models
620
+ ("🔥 OPT-350m (Meta)", "facebook/opt-350m"),
621
+ ("🔥 OPT-1.3b (Meta)", "facebook/opt-1.3b"),
622
+ ],
623
+ value="distilgpt2",
624
+ label="เลือกโมเดลแนะนำ"
625
+ )
626
+
627
+ # Multiple models
628
+ multiple_model_group = gr.Group(visible=False)
629
+ with multiple_model_group:
630
+ multiple_model_names = gr.Textbox(
631
+ label="ชื่อโมเดลหลายตัว (แยกด้วยเครื่องหมายจุลภาค)",
632
+ value="distilgpt2, microsoft/DialoGPT-small",
633
+ placeholder="gpt2, microsoft/DialoGPT-medium, scb10x/typhoon-7b",
634
+ lines=3,
635
+ info="ใส่ชื่อโมเดลหลายตัวแยกด้วยเครื่องหมายจุลภาค"
636
+ )
637
+
638
+ model_distribution_mode = gr.Radio(
639
+ choices=[
640
+ ("🔄 แบ่งงานกัน (Collaborative)", "collaborative"),
641
+ ("🎲 สุ่มเลือก (Random)", "random"),
642
+ ("📊 เท่าๆ กัน (Round-robin)", "round_robin")
643
+ ],
644
+ value="collaborative",
645
+ label="วิธีการใช้โมเดลหลายตัว"
646
+ )
647
+
648
+ # Model info display
649
+ current_models_display = gr.Textbox(
650
+ label="โมเดลที่จะใช้",
651
+ value="microsoft/DialoGPT-small",
652
+ interactive=False
653
  )
654
 
655
  # Task selection with Thai tasks
 
679
  visible=False
680
  )
681
 
682
+ # Template customization with multi-prompt support
683
+ gr.Markdown("### 🎯 ปรับแต่งเทมเพลตและ Prompt")
684
  gr.Markdown("ใช้ {ชื่อฟิลด์} สำหรับตัวแปรในเทมเพลต")
685
+
686
+ prompt_mode = gr.Radio(
687
+ choices=[
688
+ ("📝 Prompt เดียว (Single)", "single"),
689
+ ("📋 หลาย Prompt (Multiple)", "multiple"),
690
+ ("🎲 สุ่มจาก Template (Random)", "random")
691
+ ],
692
+ value="single",
693
+ label="โหมดการใส่ Prompt"
694
  )
695
 
696
+ # Single prompt mode
697
+ single_prompt_group = gr.Group(visible=True)
698
+ with single_prompt_group:
699
+ template_display = gr.Textbox(
700
+ label="เทมเพลตปัจจุบัน",
701
+ value=TASK_TEMPLATES["text_generation"]["template"],
702
+ interactive=False
703
+ )
704
+
705
+ custom_template = gr.Textbox(
706
+ label="เทมเพลตกำหนดเอง (ไม่บังคับ)",
707
+ lines=3,
708
+ placeholder="สร้างเทมเพลตของคุณเองที่นี่..."
709
+ )
710
+
711
+ # Multiple prompts mode
712
+ multi_prompt_group = gr.Group(visible=False)
713
+ with multi_prompt_group:
714
+ gr.Markdown("#### 📋 ใส่หลาย Prompt (แต่ละบรรทัดคือ prompt หนึ่งตัว)")
715
+
716
+ multi_prompts = gr.Textbox(
717
+ label="Prompts หลายตัว (แยกด้วยการขึ้นบรรทัดใหม่)",
718
+ lines=10,
719
+ placeholder="""เขียนเรื่องราวเกี่ยวกับการผจญภัยในป่า
720
+ สร้างบทสนทนาระหว่างครูกับนักเรียน
721
+ อธิบายวิธีการทำอาหารไทย
722
+ เขียนบทกวีเกี่ยวกับธรรมชาติ
723
+ สร้างเรื่องสั้นเกี่ยวกับมิตรภาพ"""
724
+ )
725
+
726
+ prompt_distribution = gr.Radio(
727
+ choices=[
728
+ ("📊 กระจายเท่าๆ กัน", "equal"),
729
+ ("🎯 ตามสัดส่วนที่กำหนด", "weighted"),
730
+ ("🎲 สุ่ม", "random")
731
+ ],
732
+ value="equal",
733
+ label="วิธีการกระจาย Prompt"
734
+ )
735
+
736
+ prompt_weights = gr.Textbox(
737
+ label="น้ำหนักของแต่ละ Prompt (เช่น 2,1,3,1,2)",
738
+ placeholder="2,1,3,1,2",
739
+ visible=False
740
+ )
741
+
742
+ # Random template mode
743
+ random_prompt_group = gr.Group(visible=False)
744
+ with random_prompt_group:
745
+ gr.Markdown("#### 🎲 สุ่ม Prompt จาก Template ที่เลือก")
746
+
747
+ random_templates = gr.CheckboxGroup(
748
+ choices=[(v["name"], k) for k, v in TASK_TEMPLATES.items()],
749
+ value=["text_generation", "conversation"],
750
+ label="เลือก Template ที่จะสุ่ม"
751
+ )
752
+
753
+ random_variables = gr.Textbox(
754
+ label="ตัวแปรสำหรับสุ่ม (JSON format)",
755
+ lines=5,
756
+ value="""{
757
+ "topic": ["การเดินทาง", "เทคโนโลยี", "อาหาร", "ธรรมชาติ", "ศิลปะ"],
758
+ "question": ["AI คืออะไร", "โลกร้อนคืออะไร", "การศึกษาสำคัญอย่างไร"],
759
+ "instruction": ["เขียนบทความ", "สรุปข้อมูล", "วิเคราะห์ปัญหา"]
760
+ }""",
761
+ placeholder="ใส่ตัวแปรในรูปแบบ JSON"
762
+ )
763
+
764
+ # Prompt preview and count
765
+ prompt_preview = gr.Textbox(
766
+ label="ตัวอย่าง Prompt ที่จะใช้",
767
  lines=3,
768
+ interactive=False
769
  )
770
 
771
+ prompt_count = gr.Textbox(
772
+ label="จำนวน Prompt ที่พร้อมใช้",
773
+ value="1 prompt",
774
+ interactive=False
775
+ )
776
+
777
  # Data Quality Settings
778
  gr.Markdown("### 🧼 การจัดการคุณภาพข้อมูล")
779
 
 
813
  label="รูปแบบการส่งออก"
814
  )
815
 
816
+ # Generation parameters with better row selection
817
  gr.Markdown("### ⚙️ ตั้งค่าการสร้างข้อมูล")
818
+
819
+ # Row count selection with presets
820
+ gr.Markdown("#### 📊 จำนวนข้อมูลที่ต้องการสร้าง")
821
+
822
+ row_preset = gr.Radio(
823
+ choices=[
824
+ ("🚀 ทดสอบ (5 rows)", 5),
825
+ ("📝 เล็ก (50 rows)", 50),
826
+ ("📋 กลาง (250 rows)", 250),
827
+ ("📚 ใหญ่ (1,000 rows)", 1000),
828
+ ("🏭 ใหญ่มาก (5,000 rows)", 5000),
829
+ ("🏢 Enterprise (10,000 rows)", 10000),
830
+ ("🎯 กำหนดเอง", -1)
831
+ ],
832
+ value=5,
833
+ label="เลือกขนาดชุดข้อมูล"
834
+ )
835
+
836
+ custom_rows = gr.Slider(
837
+ minimum=1,
838
+ maximum=50000, # Increased from 2000
839
+ value=100,
840
+ step=1,
841
+ label="จำนวนแถวที่ต้องการ (1-50,000)",
842
+ visible=False
843
+ )
844
+
845
+ # Performance warning for large datasets
846
+ performance_warning = gr.Markdown(
847
+ visible=False,
848
+ value="⚠️ **คำเตือน**: ชุดข้อมูลขนาดใหญ่ (>1,000 rows) อาจใช้เวลานานและหน่วยความจำมาก"
849
+ )
850
+
851
  with gr.Row():
 
 
 
 
 
 
 
 
852
  max_length = gr.Slider(
853
  minimum=10,
854
+ maximum=500,
855
+ value=100,
856
  step=10,
857
  label="ความยาวสูงสุด (โทเคน)"
858
  )
 
 
 
 
 
 
 
 
 
859
 
860
+ batch_size = gr.Slider(
861
+ minimum=1,
862
+ maximum=50, # Increased from 10
863
+ value=5, # Increased default
864
+ step=1,
865
+ label="ขนาด Batch (แนะนำ 5-20 สำหรับ dataset ใหญ่)"
866
  )
867
+
868
+ generate_btn = gr.Button(
869
+ "🚀 สร้างชุดข้อมูล",
870
+ variant="primary",
871
+ size="lg",
872
+ interactive=False # Initially disabled
873
+ )
874
 
875
+ # Add warning for large models
876
+ gr.Markdown("""
877
+ ⚠️ **คำเตือน**:
878
+ - โมเดลใหญ่ (7B+) ใช้เวลาโหลด 2-5 นาที
879
+ - แนะนำเริ่มต้นด้วย distilgpt2 เพื่อทดสอบ
880
+ - ถ้าหน่วยความจำไม่พอ ลองลดจำนวนข้อมูลหรือเลือกโมเดลเล็กกว่า
881
+ """)
882
 
883
  with gr.Column():
884
  with gr.Tabs():
 
1006
  return (
1007
  gr.update(visible=False),
1008
  gr.update(visible=True, value="❌ กรุณาเลือกโมเดลอย่างน้อยหนึ่งตัว"),
1009
+ {}, "กรุณาเลือกโมเดล", None, None, None, None,
1010
+ "❌ ไม่ได้เลือกโมเดล"
1011
  )
1012
 
1013
+ try:
1014
+ # Update loading status
1015
+ yield (
1016
+ gr.update(visible=False),
1017
+ gr.update(visible=True, value="🔄 กำลังเริ่มต้นการสร้างข้อมูล..."),
1018
+ {}, "กำลังเริ่มต้น...", None, None, None, None,
1019
+ "🔄 กำลังโหลดโมเดลและเตรียมข้อมูล..."
 
 
 
 
1020
  )
1021
+
1022
+ # Generate data
1023
+ if work_mode == "collaborative" and len(selected_models) > 1:
1024
+ # Multi-model generation with progress
1025
+ yield (
1026
+ gr.update(visible=False),
1027
+ gr.update(visible=True, value="🤖 กำลังใช้โมเดลหลายตัวทำงานร่วมกัน..."),
1028
+ {}, "กำลังสร้างข้อมูล...", None, None, None, None,
1029
+ "🔄 โมเดลหลายตัวกำลังทำงาน..."
1030
+ )
1031
+
1032
+ df, csv_data, json_data, error = generate_dataset_multi_model(
1033
+ selected_models, task_type, custom_template, file_data,
1034
+ num_samples, max_length, temperature, top_p
1035
+ )
1036
+ else:
1037
+ model_name = selected_models[0]
1038
+ yield (
1039
+ gr.update(visible=False),
1040
+ gr.update(visible=True, value=f"🤖 กำลังใช้โมเดล {model_name}..."),
1041
+ {}, "กำลังสร้างข้อมูล...", None, None, None, None,
1042
+ f"🔄 กำลังโหลด {model_name}..."
1043
+ )
1044
+
1045
+ df, csv_data, json_data, error = generate_dataset_from_task(
1046
+ model_name, task_type, custom_template, file_data,
1047
+ num_samples, max_length, temperature, top_p
1048
+ )
1049
+
1050
+ if error:
1051
+ yield (
1052
+ gr.update(visible=False),
1053
+ gr.update(visible=True, value=f"❌ เกิดข้อผิดพลาด: {error}"),
1054
+ {}, "เกิดข้อผิดพลาด", None, None, None, None,
1055
+ f"❌ {error}"
1056
+ )
1057
+ return
1058
+
1059
+ # Process quality management
1060
+ yield (
1061
  gr.update(visible=False),
1062
+ gr.update(visible=True, value="🧼 กำลังปรับปรุงคุณภาพข้อมูล..."),
1063
+ {}, "กำลังปรับปรุงคุณภาพ...", None, None, None, None,
1064
+ "🧼 กำลังทำความสะอาดและตรวจสอบคุณภาพ..."
1065
  )
1066
+
1067
+ # Apply basic quality management since we don't have the full module
1068
+ raw_data = df.to_dict('records')
1069
+
1070
+ # Simple cleaning
1071
+ if enable_cleaning:
1072
+ for record in raw_data:
1073
+ if 'prompt' in record:
1074
+ record['prompt'] = str(record['prompt']).strip()
1075
+ if 'generated_text' in record:
1076
+ record['generated_text'] = str(record['generated_text']).strip()
1077
+
1078
+ # Remove duplicates (simple version)
1079
+ if remove_duplicates:
1080
+ seen = set()
1081
+ unique_data = []
1082
+ for record in raw_data:
1083
+ key = str(record.get('prompt', '')) + str(record.get('generated_text', ''))
1084
+ if key not in seen:
1085
+ seen.add(key)
1086
+ unique_data.append(record)
1087
+ raw_data = unique_data
1088
+
1089
+ # Create quality report
1090
+ quality_report = {
1091
+ "total_records": len(raw_data),
1092
+ "cleaning_enabled": enable_cleaning,
1093
+ "duplicates_removed": remove_duplicates,
1094
+ "models_used": list(set([r.get('model_used', 'unknown') for r in raw_data]))
1095
+ }
1096
+
1097
+ # Create final DataFrame
1098
+ final_df = pd.DataFrame(raw_data)
1099
+ final_csv = final_df.to_csv(index=False)
1100
+ final_json = json.dumps(raw_data, indent=2, ensure_ascii=False)
1101
+
1102
+ # Simple dataset card
1103
+ dataset_card = f"""# Thai {task_type.title()} Dataset
1104
 
1105
  ## Dataset Information
1106
  - Total Records: {len(raw_data)}
 
1111
  ## Usage
1112
  This dataset can be used for Thai NLP tasks.
1113
  """
1114
+
1115
+ success_msg = f"✅ สร้างข้อมูลสำเร็จ! ได้ {len(raw_data)} รายการ"
1116
+ quality_summary = f"📊 จำนวนข้อมูล: {len(raw_data)} รายการ"
1117
+
1118
+ yield (
1119
+ gr.update(visible=True, value=final_df),
1120
+ gr.update(visible=True, value=success_msg),
1121
+ quality_report,
1122
+ quality_summary,
1123
+ final_csv,
1124
+ final_json,
1125
+ dataset_card,
1126
+ None,
1127
+ "✅ เสร็จสิ้น!"
1128
+ )
1129
+
1130
+ except Exception as e:
1131
+ yield (
1132
+ gr.update(visible=False),
1133
+ gr.update(visible=True, value=f"❌ เกิดข้อผิดพลาดที่ไม่คาดคิด: {str(e)}"),
1134
+ {}, "เกิดข้อผิดพลาด", None, None, None, None,
1135
+ f"❌ ข้อผิดพลาด: {str(e)}"
1136
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1137
 
1138
  # Event connections
1139
  task_dropdown.change(
 
1148
  outputs=[file_preview, file_data_state]
1149
  )
1150
 
1151
+ # Update generate button to use new function with progress
1152
  generate_btn.click(
1153
+ fn=process_with_progress_feedback,
1154
  inputs=[model_checkboxes, work_mode, task_dropdown, custom_template, file_data_state,
1155
  num_samples, max_length, temperature, top_p,
1156
  enable_cleaning, remove_duplicates, min_quality_score,
1157
  create_splits, export_format],
1158
  outputs=[dataset_preview, status_message, quality_report, quality_summary,
1159
+ csv_data_state, json_data_state, dataset_card_state, hf_export_state,
1160
+ loading_status]
1161
  )
1162
 
1163
  csv_btn.click(