File size: 7,025 Bytes
d36d50b
 
 
 
 
d7c4b94
d36d50b
 
f81acf7
d36d50b
 
bb42b73
d36d50b
 
 
 
bb42b73
d36d50b
d7c4b94
 
 
d36d50b
 
 
 
 
 
bb42b73
 
d7c4b94
 
 
 
 
 
 
 
 
 
bb42b73
 
d7c4b94
bb42b73
 
 
d7c4b94
 
 
 
 
 
 
bb42b73
d7c4b94
bb42b73
ebc546a
d36d50b
bb42b73
e5cfa50
d36d50b
 
3034f4c
e5cfa50
 
 
3034f4c
e5cfa50
 
 
 
d36d50b
ebc546a
d7c4b94
 
 
 
 
 
 
3034f4c
 
 
 
 
 
bb42b73
 
 
 
 
 
 
 
3034f4c
bb42b73
 
 
 
 
 
 
 
3034f4c
 
bb42b73
 
 
3034f4c
 
 
bb42b73
3034f4c
 
 
bb42b73
 
 
3034f4c
 
 
bb42b73
 
 
 
 
 
 
 
3034f4c
bb42b73
 
 
 
 
 
 
 
3034f4c
 
bb42b73
 
 
3034f4c
bb42b73
3034f4c
 
 
bb42b73
 
d36d50b
 
ebc546a
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import os
import yaml
import gdown 
import gradio as gr
from predict import PredictTri
from huggingface_hub import hf_hub_download

output_path = "tashkeela-d2.pt"
gdrive_templ = "https://drive.google.com/file/d/{}/view?usp=sharing"
if not os.path.exists(output_path):
    model_gdrive_id = "1FGelqImFkESbTyRsx_elkKIOZ9VbhRuo"
    gdown.download(gdrive_templ.format(model_gdrive_id), output=output_path, quiet=False, fuzzy=True)

output_path = "vocab.vec"
if not os.path.exists(output_path):
    vocab_gdrive_id = "1-0muGvcSYEf8RAVRcwXay4MRex6kmCii"
    gdown.download(gdrive_templ.format(vocab_gdrive_id), output=output_path, quiet=False, fuzzy=True)

if not os.path.exists("td2/tashkeela-ashaar-td2.pt"):
    hf_hub_download(repo_id="munael/Partial-Arabic-Diacritization-TD2", filename="tashkeela-ashaar-td2.pt", local_dir="td2")

with open("config.yaml", 'r', encoding="utf-8") as file:
    config = yaml.load(file, Loader=yaml.FullLoader)

config["train"]["max-sent-len"] = config["predictor"]["window"]
config["train"]["max-token-count"] = config["predictor"]["window"] * 3

predictor = PredictTri(config)

current_model_name = "TD2"
config["model-name"] = current_model_name

def diacritze_full(text, model_name):
    global current_model_name, predictor
    if model_name != current_model_name:
        config["model-name"] = model_name
        current_model_name = model_name
        predictor = PredictTri(config)

    do_hard_mask = None 
    threshold = None 
    predictor.create_dataloader(text, False, do_hard_mask, threshold, model_name)
    diacritized_lines = predictor.predict_partial(do_partial=False, lines=text.split('\n'))
    return diacritized_lines

def diacritze_partial(text, mask_mode, threshold, model_name):
    global current_model_name, predictor
    if model_name != current_model_name:
        config["model-name"] = model_name
        current_model_name = model_name
        predictor = PredictTri(config)

    do_partial = True 
    predictor.create_dataloader(text, do_partial, mask_mode=="Hard", threshold, model_name)
    diacritized_lines = predictor.predict_partial(do_partial=do_partial, lines=text.split('\n'))
    return diacritized_lines

with gr.Blocks(theme=gr.themes.Default(text_size="lg")) as demo:

    gr.Markdown(
    """
    <img src='https://huggingface.co/spaces/bkhmsi/Partial-Arabic-Diacritization/resolve/main/PartialDD.png' style='float:right; margin: 0 0 10px 10px; width: 20%'/>

    <h1> Partial Diacritization: A Context-Contrastive Inference Approach </h1>
    <h2> Authors: Muhammad ElNokrashy, Badr AlKhamissi </h2>
    <h3> Paper: <a href="https://arxiv.org/abs/2401.08919"> https://arxiv.org/abs/2401.08919 </a> </h3>
    <details>
    <summary>Abstract</summary>
    <p>Diacritization plays a pivotal role in improving readability and disambiguating the meaning of Arabic texts. Efforts have so far focused on marking every eligible character (Full Diacritization). Comparatively overlooked, Partial Diacritzation (PD) is the selection of a subset of characters to be marked to aid comprehension where needed.Research has indicated that excessive diacritic marks can hinder skilled readers---reducing reading speed and accuracy. We conduct a behavioral experiment and show that partially marked text is often easier to read than fully marked text, and sometimes easier than plain text. In this light, we introduce Context-Contrastive Partial Diacritization (CCPD)---a novel approach to PD which integrates seamlessly with existing Arabic diacritization systems. CCPD processes each word twice, once with context and once without, and diacritizes only the characters with disparities between the two inferences. Further, we introduce novel indicators for measuring partial diacritization quality {SR, PDER, HDER, ERE}, essential for establishing this as a machine learning task. Lastly, we introduce TD2, a Transformer-variant of an established model which offers a markedly different performance profile on our proposed indicators compared to all other known systems.</p>
    </details>
    """)


    model_choice = gr.Dropdown(
        choices=["D2", "TD2"], 
        label="Diacritization Model", 
        value=current_model_name
    )
    
    with gr.Tab(label="Partial Diacritization") as partial_settings:
        with gr.Row():
            masking_mode = gr.Radio(choices=["Hard", "Soft"], value="Hard", label="Masking Mode")
            threshold_slider = gr.Slider(label="Soft Masking Threshold", minimum=0, maximum=1, value=0.1)
        
        partial_input_txt = gr.Textbox(
            placeholder="ุงูƒุชุจ ู‡ู†ุง", 
            lines=5, 
            label="Input",
            type='text',
            rtl=True,
            text_align='right',
        )

        partial_output_txt = gr.Textbox(
            lines=5, 
            label="Output",
            type='text',
            rtl=True,  
            text_align='right',
            show_copy_button=True,
        )

        partial_btn = gr.Button(value="Shakkel")
        partial_btn.click(diacritze_partial, inputs=[partial_input_txt, masking_mode, threshold_slider, model_choice], outputs=[partial_output_txt], queue=True)

        gr.Examples(
            examples=[
                ["ูˆู„ูˆ ุญู…ู„ ู…ู† ู…ุฌู„ุณ ุงู„ุฎูŠุงุฑ ุŒ ูˆู„ู… ูŠู…ู†ุน ู…ู† ุงู„ูƒู„ุงู…", "Hard", 0, "TD2"],
                ["ูˆู„ูˆ ุญู…ู„ ู…ู† ู…ุฌู„ุณ ุงู„ุฎูŠุงุฑ ุŒ ูˆู„ู… ูŠู…ู†ุน ู…ู† ุงู„ูƒู„ุงู…", "Soft", 0.1, "TD2"],
                ["ูˆู„ูˆ ุญู…ู„ ู…ู† ู…ุฌู„ุณ ุงู„ุฎูŠุงุฑ ุŒ ูˆู„ู… ูŠู…ู†ุน ู…ู† ุงู„ูƒู„ุงู…", "Soft", 0.01, "TD2"],
            ],
            inputs=[partial_input_txt, masking_mode, threshold_slider, model_choice],
            outputs=partial_output_txt,
            fn=diacritze_partial,
            cache_examples=True,
        )

    with gr.Tab(label="Full Diacritization"):

        full_input_txt = gr.Textbox(
            placeholder="ุงูƒุชุจ ู‡ู†ุง", 
            lines=5, 
            label="Input",
            type='text',
            rtl=True,
            text_align='right',
        )

        full_output_txt = gr.Textbox(
            lines=5, 
            label="Output",
            type='text',
            rtl=True,  
            text_align='right',
            show_copy_button=True,
        )

        full_btn = gr.Button(value="Shakkel")
        full_btn.click(diacritze_full, inputs=[full_input_txt, model_choice], outputs=[full_output_txt], queue=True)

        gr.Examples(
            examples=[
                ["ูˆู„ูˆ ุญู…ู„ ู…ู† ู…ุฌู„ุณ ุงู„ุฎูŠุงุฑ ุŒ ูˆู„ู… ูŠู…ู†ุน ู…ู† ุงู„ูƒู„ุงู…", "TD2"],
            ],
            inputs=[full_input_txt, model_choice],
            outputs=full_output_txt,
            fn=diacritze_full,
            cache_examples=True,
        )

if __name__ == "__main__":
    demo.queue().launch(
        # share=False,
        # debug=False,
        # server_port=7860,
        # server_name="0.0.0.0",
        # ssl_verify=False,
        # ssl_certfile="cert.pem",
        # ssl_keyfile="key.pem"
    )