tymbos commited on
Commit
4a4435c
·
verified ·
1 Parent(s): 29cc980

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +147 -105
app.py CHANGED
@@ -1,138 +1,180 @@
1
  import gradio as gr
2
- import numpy as np
3
- import matplotlib.pyplot as plt
 
4
  from io import BytesIO
5
- import tempfile
6
- import os
7
-
8
  from train_tokenizer import train_tokenizer
9
- from tokenizers import Tokenizer
10
  from datasets import load_dataset
 
 
 
11
 
12
- def create_iterator(files=None, dataset_name=None, dataset_config=None, split="train", streaming=True):
13
- if dataset_name:
14
- try:
15
- # Επεξεργασία ονόματος dataset με έλεγχο εγκυρότητας
16
- if not re.match(r'^[\w\-\.]+(/[\w\-\.]+)*$', dataset_name):
17
- raise ValueError(f"Μη έγκυρο όνομα dataset: {dataset_name}")
18
-
19
- # Φόρτωση dataset με config αν υπάρχει
20
- dataset = load_dataset(
21
- dataset_name,
22
- name=dataset_config if dataset_config else None,
23
- split=split,
24
- streaming=streaming
25
- )
26
- for example in dataset:
27
- yield example['text']
28
- except Exception as e:
29
- raise gr.Error(f"Σφάλμα φόρτωσης dataset: {str(e)}")
30
- elif files:
31
- for file in files:
32
- with open(file.name, 'r', encoding='utf-8') as f:
33
- for line in f:
34
- yield line.strip()
35
 
36
- def enhanced_validation(tokenizer, test_text):
37
- """
38
- Εκτελεί επικύρωση του tokenizer με ένα roundtrip test και παρέχει στατιστικά.
39
- """
40
- encoded = tokenizer.encode(test_text)
41
- decoded = tokenizer.decode(encoded.ids)
42
-
43
- # Μέτρηση των Unknown tokens
44
- unknown_tokens = sum(1 for t in encoded.tokens if t == "<unk>")
45
- unknown_percent = (unknown_tokens / len(encoded.tokens) * 100) if encoded.tokens else 0
46
-
47
- # Υπολογισμός μήκους των tokens
48
- token_lengths = [len(t) for t in encoded.tokens]
49
- avg_length = np.mean(token_lengths) if token_lengths else 0
50
-
51
- # Έλεγχος κάλυψης κώδικα: παραδείγματα συμβόλων
52
- code_symbols = ['{', '}', '(', ')', ';', '//', 'printf']
53
- code_coverage = {sym: (sym in test_text and sym in encoded.tokens) for sym in code_symbols}
54
 
55
- # Δημιουργία histogram για την κατανομή του μήκους των tokens
56
- fig = plt.figure()
57
- plt.hist(token_lengths, bins=20, color='skyblue', edgecolor='black')
58
- plt.xlabel('Μήκος Token')
59
- plt.ylabel('Συχνότητα')
60
- plt.title('Κατανομή Μήκους Tokens')
61
- img_buffer = BytesIO()
62
- plt.savefig(img_buffer, format='png')
63
- plt.close()
64
- img_buffer.seek(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- return {
67
- "roundtrip_success": test_text == decoded,
68
- "unknown_tokens": f"{unknown_tokens} ({unknown_percent:.2f}%)",
69
- "average_token_length": f"{avg_length:.2f}",
70
- "code_coverage": code_coverage,
71
- "token_length_distribution": img_buffer.getvalue()
72
- }
73
 
74
- # ... (προηγούμενο imports και functions παραμένουν ίδια)
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- def train_and_test(files, dataset_name, split, vocab_size, min_freq, test_text):
77
- if not files and not dataset_name:
78
- raise gr.Error("Πρέπει να παρέχετε αρχεία ή όνομα dataset!")
79
-
80
  try:
81
- # Δημιουργία iterator με fallback
82
- iterator = create_iterator(files, dataset_name, split)
83
 
84
- # Προσθήκη progress bar
85
  with gr.Progress() as progress:
86
- progress(0.1, desc="Προεπεξεργασία δεδομένων...")
87
  tokenizer = train_tokenizer(iterator, vocab_size, min_freq)
88
-
89
- # ... (υπόλοιπη λειτουργία παραμένει ίδια)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  except Exception as e:
92
  raise gr.Error(f"Σφάλμα εκπαίδευσης: {str(e)}")
93
-
94
- # Αποθήκευση και φόρτωση του tokenizer για επικύρωση
95
- with tempfile.NamedTemporaryFile(delete=False, suffix=".json") as tmp:
96
- tokenizer.save(tmp.name)
97
- trained_tokenizer = Tokenizer.from_file(tmp.name)
98
- os.unlink(tmp.name)
99
-
100
- # Εκτενής επικύρωση με το δοκιμαστικό κείμενο
101
- validation = enhanced_validation(trained_tokenizer, test_text)
102
-
103
- return {
104
- "validation_metrics": {k: v for k, v in validation.items() if k != "token_length_distribution"},
105
- "histogram": validation["token_length_distribution"]
106
- }
107
 
108
- # Ενημερωμένο Gradio Interface
109
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
110
- gr.Markdown("## Προχωρημένος BPE Tokenizer Trainer")
111
 
112
  with gr.Row():
113
  with gr.Column():
114
- with gr.Tab("Local Files"):
115
- file_input = gr.File(file_count="multiple", label="Ανέβασμα αρχείων")
116
- with gr.Tab("Hugging Face Dataset"):
117
- dataset_name = gr.Textbox(label="Όνομα Dataset (π.χ. 'wikitext', 'codeparrot/github-code')")
118
- split = gr.Textbox(value="train", label="Split")
119
-
120
- vocab_size = gr.Slider(1000, 100000, value=32000, label="Μέγεθος Λεξιλογίου")
121
- min_freq = gr.Slider(1, 100, value=2, label="Ελάχιστη Συχνότητα")
 
 
 
 
 
 
 
 
 
122
  test_text = gr.Textbox(
123
- value='function helloWorld() { console.log("Γειά σου Κόσμε!"); } // Ελληνικά + κώδικας',
124
  label="Test Text"
125
  )
126
- train_btn = gr.Button("Εκπαίδευση Tokenizer", variant="primary")
127
-
128
  with gr.Column():
129
- results_json = gr.JSON(label="Μετρικές")
130
- results_plot = gr.Image(label="Κατανομή Μήκους Tokens")
 
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  train_btn.click(
133
  fn=train_and_test,
134
- inputs=[file_input, dataset_name, split, vocab_size, min_freq, test_text],
135
  outputs=[results_json, results_plot]
136
  )
 
137
  if __name__ == "__main__":
138
  demo.launch()
 
1
  import gradio as gr
2
+ import requests
3
+ import json
4
+ import re
5
  from io import BytesIO
6
+ import matplotlib.pyplot as plt
 
 
7
  from train_tokenizer import train_tokenizer
 
8
  from datasets import load_dataset
9
+ from tokenizers import Tokenizer
10
+ import tempfile
11
+ import os
12
 
13
+ def fetch_splits(dataset_name):
14
+ try:
15
+ response = requests.get(
16
+ f"https://datasets-server.huggingface.co/splits?dataset={dataset_name}",
17
+ timeout=10
18
+ )
19
+ response.raise_for_status()
20
+ data = response.json()
21
+
22
+ splits_info = {}
23
+ for split in data['splits']:
24
+ config = split['config']
25
+ split_name = split['split']
26
+ if config not in splits_info:
27
+ splits_info[config] = []
28
+ splits_info[config].append(split_name)
29
+
30
+ return {
31
+ "splits": splits_info,
32
+ "viewer_template": f"https://huggingface.co/datasets/{dataset_name}/embed/viewer/{{config}}/{{split}}"
33
+ }
34
+ except Exception as e:
35
+ raise gr.Error(f"Σφάλμα κατάττην ανάκτηση splits: {str(e)}")
36
 
37
+ def update_components(dataset_name):
38
+ if not dataset_name:
39
+ return [gr.Dropdown.update(choices=[], value=None), gr.Dropdown.update(choices=[]), gr.HTML.update(value="")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ try:
42
+ splits_data = fetch_splits(dataset_name)
43
+ config_choices = list(splits_data['splits'].keys())
44
+
45
+ # Δημιουργία iframe preview για το πρώτο config
46
+ first_config = config_choices[0] if config_choices else None
47
+ iframe_html = f"""
48
+ <iframe
49
+ src="{splits_data['viewer_template'].format(config=first_config, split='train')}"
50
+ frameborder="0"
51
+ width="100%"
52
+ height="560px"
53
+ ></iframe>
54
+ """ if first_config else "Δεν βρέθηκαν διαθέσιμα δεδομένα"
55
+
56
+ return [
57
+ gr.Dropdown.update(choices=config_choices, value=first_config),
58
+ gr.Dropdown.update(choices=splits_data['splits'].get(first_config, [])),
59
+ gr.HTML.update(value=iframe_html)
60
+ ]
61
+ except Exception as e:
62
+ raise gr.Error(f"Σφάλμα: {str(e)}")
63
+
64
+ def update_split_choices(dataset_name, config):
65
+ if not dataset_name or not config:
66
+ return gr.Dropdown.update(choices=[])
67
 
68
+ try:
69
+ splits_data = fetch_splits(dataset_name)
70
+ return gr.Dropdown.update(choices=splits_data['splits'].get(config, []))
71
+ except:
72
+ return gr.Dropdown.update(choices=[])
 
 
73
 
74
+ def create_iterator(dataset_name, config, split):
75
+ try:
76
+ dataset = load_dataset(
77
+ dataset_name,
78
+ name=config,
79
+ split=split,
80
+ streaming=True
81
+ )
82
+ for example in dataset:
83
+ yield example.get('text', '')
84
+ except Exception as e:
85
+ raise gr.Error(f"Σφάλμα φόρτωσης dataset: {str(e)}")
86
 
87
+ def train_and_test(dataset_name, config, split, vocab_size, min_freq, test_text):
88
+ # Εκπαίδευση και validation logic
 
 
89
  try:
90
+ iterator = create_iterator(dataset_name, config, split)
 
91
 
 
92
  with gr.Progress() as progress:
93
+ progress(0.2, desc="Δημιουργία tokenizer...")
94
  tokenizer = train_tokenizer(iterator, vocab_size, min_freq)
95
+
96
+ # Αποθήκευση και φόρτωση tokenizer
97
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".json") as f:
98
+ tokenizer.save(f.name)
99
+ trained_tokenizer = Tokenizer.from_file(f.name)
100
+ os.unlink(f.name)
101
+
102
+ # Validation
103
+ encoded = trained_tokenizer.encode(test_text)
104
+ decoded = trained_tokenizer.decode(encoded.ids)
105
+
106
+ # Δημιουργία γραφήματος
107
+ token_lengths = [len(t) for t in encoded.tokens]
108
+ fig = plt.figure()
109
+ plt.hist(token_lengths, bins=20)
110
+ plt.xlabel('Μήκος Token')
111
+ plt.ylabel('Συχνότητα')
112
+ img_buffer = BytesIO()
113
+ plt.savefig(img_buffer, format='png')
114
+ plt.close()
115
+
116
+ return {
117
+ "Πρωτότυπο Κείμενο": test_text,
118
+ "Αποκωδικοποιημένο": decoded,
119
+ "Αριθμός Tokens": len(encoded.tokens),
120
+ "Αγνώστων Tokens": sum(1 for t in encoded.tokens if t == "<unk>")
121
+ }, img_buffer.getvalue()
122
 
123
  except Exception as e:
124
  raise gr.Error(f"Σφάλμα εκπαίδευσης: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
+ # Gradio Interface
127
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
128
+ gr.Markdown("## Wikipedia Tokenizer Trainer")
129
 
130
  with gr.Row():
131
  with gr.Column():
132
+ dataset_name = gr.Textbox(
133
+ label="Dataset Name",
134
+ value="wikimedia/wikipedia",
135
+ placeholder="π.χ. 'wikimedia/wikipedia'"
136
+ )
137
+ config = gr.Dropdown(
138
+ label="Config",
139
+ choices=[],
140
+ interactive=True
141
+ )
142
+ split = gr.Dropdown(
143
+ label="Split",
144
+ choices=[],
145
+ value="train"
146
+ )
147
+ vocab_size = gr.Slider(20000, 100000, value=50000, label="Μέγεθος Λεξιλογίου")
148
+ min_freq = gr.Slider(1, 100, value=3, label="Ελάχιστη Συχνότητα")
149
  test_text = gr.Textbox(
150
+ value='Η Ακρόπολη είναι σύμβολο της αρχαίας ελληνικής πολιτισμικής κληρονομιάς.',
151
  label="Test Text"
152
  )
153
+ train_btn = gr.Button("Εκπαίδευση", variant="primary")
154
+
155
  with gr.Column():
156
+ preview = gr.HTML(label="Dataset Preview")
157
+ results_json = gr.JSON(label="Αποτελέσματα")
158
+ results_plot = gr.Image(label="Κατανομή Μηκών Tokens")
159
 
160
+ # Event handlers
161
+ dataset_name.change(
162
+ fn=update_components,
163
+ inputs=dataset_name,
164
+ outputs=[config, split, preview]
165
+ )
166
+
167
+ config.change(
168
+ fn=update_split_choices,
169
+ inputs=[dataset_name, config],
170
+ outputs=split
171
+ )
172
+
173
  train_btn.click(
174
  fn=train_and_test,
175
+ inputs=[dataset_name, config, split, vocab_size, min_freq, test_text],
176
  outputs=[results_json, results_plot]
177
  )
178
+
179
  if __name__ == "__main__":
180
  demo.launch()