alakxender commited on
Commit
cd9f86b
·
1 Parent(s): d5be7c6
Files changed (3) hide show
  1. app.py +48 -3
  2. instruct_dv.py +4 -3
  3. instruct_dv_tuned.py +68 -0
app.py CHANGED
@@ -3,7 +3,8 @@ import gradio as gr
3
  from typo_check import css, process_input,MODEL_OPTIONS_TYPO
4
  from title_gen import generate_title, MODEL_OPTIONS_TITLE
5
  from content_gen import generate_content, MODEL_OPTIONS_CONTENT, get_default_prompt
6
- from instruct_dv import generate_response, MODEL_OPTIONS_INSTRUCT
 
7
  from en_dv_latin import translate, MODEL_OPTIONS_TRANSLATE
8
 
9
  def update_textbox_direction(direction):
@@ -216,14 +217,15 @@ All outputs generated are synthetic, created using fine-tuned models for experim
216
  with gr.Row():
217
  model_choice = gr.Dropdown(choices=list(MODEL_OPTIONS_INSTRUCT.keys()), value=list(MODEL_OPTIONS_INSTRUCT.keys())[0], label="Model")
218
  with gr.Row():
 
219
  seed = gr.Slider(0, 10000, value=42, step=1, label="Random Seed")
220
- use_sampling = gr.Checkbox(label="Use Sampling (Creative/Random)", value=True)
221
  with gr.Row():
222
  generated_response = gr.Textbox(label="Model Response", rtl=True, elem_classes="textbox1")
223
  generate_btn = gr.Button("Generate Response")
224
  generate_btn.click(
225
  fn=generate_response,
226
- inputs=[instruction, input_text, seed, use_sampling, model_choice],
227
  outputs=generated_response
228
  )
229
  gr.Examples(
@@ -240,6 +242,49 @@ All outputs generated are synthetic, created using fine-tuned models for experim
240
  - This tab allows you to give instructions to the model, optionally with input text, for general-purpose generation or task following in Dhivehi.
241
  - Try different seeds or enable sampling for more creative outputs.
242
  - The model is experimental and may not always follow instructions perfectly.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  """)
244
 
245
  with gr.Tab("Translation Tasks"):
 
3
  from typo_check import css, process_input,MODEL_OPTIONS_TYPO
4
  from title_gen import generate_title, MODEL_OPTIONS_TITLE
5
  from content_gen import generate_content, MODEL_OPTIONS_CONTENT, get_default_prompt
6
+ from instruct_dv import generate_response, MODEL_OPTIONS_INSTRUCT
7
+ from instruct_dv_tuned import generate_response_tuned, MODEL_OPTIONS_INSTRUCT_TUNED
8
  from en_dv_latin import translate, MODEL_OPTIONS_TRANSLATE
9
 
10
  def update_textbox_direction(direction):
 
217
  with gr.Row():
218
  model_choice = gr.Dropdown(choices=list(MODEL_OPTIONS_INSTRUCT.keys()), value=list(MODEL_OPTIONS_INSTRUCT.keys())[0], label="Model")
219
  with gr.Row():
220
+ max_tokens_slider = gr.Slider(10, 512, value=256, label="Max New Tokens")
221
  seed = gr.Slider(0, 10000, value=42, step=1, label="Random Seed")
222
+ use_sampling = gr.Checkbox(label="Use Sampling (Creative/Random)", value=False)
223
  with gr.Row():
224
  generated_response = gr.Textbox(label="Model Response", rtl=True, elem_classes="textbox1")
225
  generate_btn = gr.Button("Generate Response")
226
  generate_btn.click(
227
  fn=generate_response,
228
+ inputs=[instruction, input_text, seed, use_sampling, model_choice,max_tokens_slider,num_beams_slider],
229
  outputs=generated_response
230
  )
231
  gr.Examples(
 
242
  - This tab allows you to give instructions to the model, optionally with input text, for general-purpose generation or task following in Dhivehi.
243
  - Try different seeds or enable sampling for more creative outputs.
244
  - The model is experimental and may not always follow instructions perfectly.
245
+ """)
246
+
247
+ with gr.Tab("Instruction Tuned"):
248
+ gr.Markdown("# <center>Dhivehi Instruction-Tuned Model</center>")
249
+ gr.Markdown("Generate answers by providing a custom instruction and optional input. This instruction-tuned model is designed for better format awareness, task generalization, and stronger alignment with user intent.")
250
+ with gr.Row():
251
+ instruction = gr.Textbox(lines=2, label="Instruction", rtl=True, elem_classes="textbox1")
252
+ with gr.Row():
253
+ input_text = gr.Textbox(lines=2, label="Input Text (optional)", rtl=True, elem_classes="textbox1")
254
+ with gr.Row():
255
+ model_choice = gr.Dropdown(choices=list(MODEL_OPTIONS_INSTRUCT_TUNED.keys()), value=list(MODEL_OPTIONS_INSTRUCT_TUNED.keys())[0], label="Model")
256
+ with gr.Row():
257
+ max_tokens = gr.Slider(64, 1024, value=768, step=16, label="Max New Tokens")
258
+ temperature = gr.Slider(0.0, 1.5, value=0.7, step=0.1, label="Temperature")
259
+ num_beams = gr.Slider(1, 8, value=4, step=1, label="Number of Beams")
260
+ with gr.Row():
261
+ generated_response = gr.Textbox(label="Model Response", rtl=True, elem_classes="textbox1")
262
+ generate_btn = gr.Button("Generate Response")
263
+ generate_btn.click(
264
+ fn=generate_response_tuned,
265
+ inputs=[instruction, input_text, seed, model_choice,max_tokens,temperature,num_beams],
266
+ outputs=generated_response
267
+ )
268
+ gr.Examples(
269
+ examples=[
270
+ ["ދީފައިވާ މައުޟޫޢާ ބެހޭގޮތުން ކުރު ޕެރެގްރާފެއް ލިޔެލާށެވެ.","އިއާދަކުރަނިވި ހަކަތަ ބޭނުންކުރުމުގެ މުހިންމުކަން"],
271
+ ["ދިގުމިނުގެ މިންވަރުތައް ބަދަލުކުރުން.","1 ކިލޯމީޓަރ"],
272
+ ["ދެ މޯބައިލް ފޯނެއްގެ ފީޗާސް އަޅާކިޔާށެވެ.","އައިފޯން 11 ޕްރޯ އަދި ސެމްސަންގް ގެލެކްސީ އެސް20 އަލްޓްރާ"],
273
+ ["މަސައްކަތްތައް ފައިދާހުރި ގޮތެއްގައި ހަވާލުކުރުމަށް އަޅަންޖެހޭ ފިޔަވަޅުތައް ބަޔާންކުރުން.",""],
274
+ ["އާ މޯބައިލް އެޕް ޕްރޮމޯޓް ކުރުމަށް މާކެޓިންގ ސްޓްރެޓެޖީތަކުގެ ލިސްޓެއް އުފެއްދުން.",""],
275
+ ["ދިގުމިނުގައި 10ސެންޓިމީޓަރު އަދި ފުޅާމިނަކީ 5ސެންޓިމީޓަރު ހުންނަ ރެކްޓަންގްލަރެއްގެ ސަރަހައްދު ހިސާބުކުރުން.",""],
276
+ ["ތިރީގައިވާ ބަސްފުޅު ތެދެއް ނުވަތަ ދޮގުގެ ގޮތުގައި ގިންތިކުރުން.","ސުޕްރީމް ކޯޓަކީ އެމެރިކާގެ އެންމެ މަތީ ކޯޓެވެ."],
277
+ ],
278
+ inputs=[instruction, input_text],
279
+ )
280
+ gr.Markdown("""
281
+ ### 📝 Notes:
282
+ - This model is **instruction-tuned** using Dhivehi data, designed to follow a wide variety of instructions.
283
+ - Provide both an instruction and input for best results, but input is optional for tasks like open-ended generation.
284
+ - Use **temperature** > 0 for more diverse outputs, or set to **0** for deterministic answers.
285
+ - **Number of beams** increases quality at the cost of speed.
286
+ - Assuming the model will have **better format awareness**, can handle **multiple task types**, and often **align more closely with your intent**. (Have to test)
287
+ - This model is experimental and may not always follow instructions perfectly.
288
  """)
289
 
290
  with gr.Tab("Translation Tasks"):
instruct_dv.py CHANGED
@@ -1,7 +1,7 @@
1
  import random
2
  import numpy as np
3
  import torch
4
- from transformers import T5Tokenizer, T5ForConditionalGeneration
5
  import spaces
6
 
7
 
@@ -17,7 +17,7 @@ MODEL_CACHE = {}
17
  def get_model_and_tokenizer(model_dir):
18
  if model_dir not in MODEL_CACHE:
19
  print(f"Loading model: {model_dir}")
20
- tokenizer = T5Tokenizer.from_pretrained(model_dir)
21
  model = T5ForConditionalGeneration.from_pretrained(model_dir)
22
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
  print(f"Moving model to device: {device}")
@@ -29,7 +29,7 @@ max_input_length = 256
29
  max_output_length = 256
30
 
31
  @spaces.GPU()
32
- def generate_response(instruction, input_text, seed, use_sampling, model_choice):
33
  random.seed(seed)
34
  np.random.seed(seed)
35
  torch.manual_seed(seed)
@@ -52,6 +52,7 @@ def generate_response(instruction, input_text, seed, use_sampling, model_choice)
52
  gen_kwargs = {
53
  "input_ids": inputs["input_ids"],
54
  "attention_mask": inputs["attention_mask"],
 
55
  "max_length": max_output_length,
56
  "no_repeat_ngram_size": 3,
57
  "repetition_penalty": 1.5,
 
1
  import random
2
  import numpy as np
3
  import torch
4
+ from transformers import AutoTokenizer, T5ForConditionalGeneration
5
  import spaces
6
 
7
 
 
17
  def get_model_and_tokenizer(model_dir):
18
  if model_dir not in MODEL_CACHE:
19
  print(f"Loading model: {model_dir}")
20
+ tokenizer = AutoTokenizer.from_pretrained(model_dir)
21
  model = T5ForConditionalGeneration.from_pretrained(model_dir)
22
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
  print(f"Moving model to device: {device}")
 
29
  max_output_length = 256
30
 
31
  @spaces.GPU()
32
+ def generate_response(instruction, input_text, seed, use_sampling, model_choice,max_tokens,num_beams):
33
  random.seed(seed)
34
  np.random.seed(seed)
35
  torch.manual_seed(seed)
 
52
  gen_kwargs = {
53
  "input_ids": inputs["input_ids"],
54
  "attention_mask": inputs["attention_mask"],
55
+ "max_new_tokens":max_tokens,
56
  "max_length": max_output_length,
57
  "no_repeat_ngram_size": 3,
58
  "repetition_penalty": 1.5,
instruct_dv_tuned.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import numpy as np
3
+ import torch
4
+ from transformers import AutoTokenizer, T5ForConditionalGeneration
5
+ import spaces
6
+
7
+
8
+ # Available models
9
+ MODEL_OPTIONS_INSTRUCT_TUNED = {
10
+ "EXT1 Model": "alakxender/flan-t5-base-alpaca-dv-ext"
11
+ }
12
+
13
+ # Cache for loaded models/tokenizers
14
+ MODEL_CACHE = {}
15
+
16
+ def get_model_and_tokenizer(model_dir):
17
+ if model_dir not in MODEL_CACHE:
18
+ print(f"Loading model: {model_dir}")
19
+ tokenizer = AutoTokenizer.from_pretrained(model_dir)
20
+ model = T5ForConditionalGeneration.from_pretrained(model_dir)
21
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
22
+ print(f"Moving model to device: {device}")
23
+ model.to(device)
24
+ MODEL_CACHE[model_dir] = (tokenizer, model)
25
+ return MODEL_CACHE[model_dir]
26
+
27
+ @spaces.GPU()
28
+ def generate_response_tuned(instruction, input_text, seed, model_choice,max_tokens, temperature, num_beams):
29
+ random.seed(seed)
30
+ np.random.seed(seed)
31
+ torch.manual_seed(seed)
32
+ if torch.cuda.is_available():
33
+ torch.cuda.manual_seed_all(seed)
34
+
35
+ model_dir = MODEL_OPTIONS_INSTRUCT_TUNED[model_choice]
36
+ tokenizer, model = get_model_and_tokenizer(model_dir)
37
+
38
+ combined_input = f"{instruction.strip()} {input_text.strip()}" if input_text else instruction.strip()
39
+ inputs = tokenizer(
40
+ combined_input,
41
+ return_tensors="pt",
42
+ truncation=True
43
+ )
44
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
45
+ inputs = {k: v.to(device) for k, v in inputs.items()}
46
+
47
+ gen_kwargs = {
48
+ **inputs,
49
+ "max_length":max_tokens,
50
+ "num_beams":num_beams,
51
+ "do_sample":(temperature > 0.0),
52
+ "temperature":temperature,
53
+ "repetition_penalty":1.2,
54
+ "top_p":0.95,
55
+ "top_k":50
56
+ }
57
+
58
+ with torch.no_grad():
59
+ outputs = model.generate(**gen_kwargs)
60
+ decoded_output = tokenizer.decode(outputs[0], skip_special_tokens=True)
61
+
62
+ # Trim to the last period
63
+ if '.' in decoded_output:
64
+ last_period = decoded_output.rfind('.')
65
+ decoded_output = decoded_output[:last_period+1]
66
+
67
+ decoded_output = ' '.join(decoded_output.split())
68
+ return decoded_output