harpreetsahota commited on
Commit
71d010d
1 Parent(s): 31ba814

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +195 -0
app.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fork of the SantaCoder demo (https://huggingface.co/spaces/bigcode/santacoder-demo)
2
+
3
+ import gradio as gr
4
+ from transformers import AutoTokenizer, AutoModelForCausalLM, set_seed
5
+ from transformers import pipeline
6
+ import os
7
+ import torch
8
+ from typing import Union, Tuple, List
9
+
10
+
11
+ description = """#<span style='color: #3264ff;'>🏎️ DeciCoder:</span> A Fast Code Generation Model💨 </p>
12
+ <span style='color: #292b47;'>Welcome to <a href="https://huggingface.co/deci/decicoder" style="color: #3264ff;">DeciCoder</a>!
13
+ DeciCoder is a 1B parameter code generation model trained on The Stack dataset and released under an Apache 2.0 license. It's capable of writing code in Python,
14
+ JavaScript, and Java. It's a code-completion model, not an instruction-tuned model; you should prompt the model with a function signature and docstring
15
+ and let it complete the rest. The model can also do infilling, specify where you would like the model to complete code with the <span style='color: #3264ff;'>&lt;FILL_HERE&gt;</span>
16
+ token.</span>"""
17
+
18
+ token = os.environ["HUGGINGFACEHUB_API_TOKEN"]
19
+ device="cuda" if torch.cuda.is_available() else "cpu"
20
+
21
+
22
+ FIM_PREFIX = "<fim_prefix>"
23
+ FIM_MIDDLE = "<fim_middle>"
24
+ FIM_SUFFIX = "<fim_suffix>"
25
+ FIM_PAD = "<fim_pad>"
26
+ EOD = "<|endoftext|>"
27
+
28
+ GENERATION_TITLE= "<p style='font-size: 24px; color: #292b47;'>💻 Your generated code:</p>"
29
+
30
+ tokenizer_fim = AutoTokenizer.from_pretrained("Deci/test_hf_converted_decicoder", use_auth_token=token, padding_side="left")
31
+
32
+ tokenizer_fim.add_special_tokens({
33
+ "additional_special_tokens": [EOD, FIM_PREFIX, FIM_MIDDLE, FIM_SUFFIX, FIM_PAD],
34
+ "pad_token": EOD,
35
+ })
36
+
37
+ tokenizer = AutoTokenizer.from_pretrained("Deci/test_hf_converted_decicoder", use_auth_token=token)
38
+ model = AutoModelForCausalLM.from_pretrained("Deci/DeciCoder-1b", trust_remote_code=True, use_auth_token=token).to(device)
39
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, device=device)
40
+
41
+ def post_processing(prompt: str, completion: str) -> str:
42
+ """
43
+ Post-processes the generated code completion with HTML styling.
44
+
45
+ Args:
46
+ prompt (str): The input code prompt.
47
+ completion (str): The generated code completion.
48
+
49
+ Returns:
50
+ str: The HTML-styled code with prompt and completion.
51
+ """
52
+ completion = "<span style='color: #ff5b86;'>" + completion + "</span>"
53
+ prompt = "<span style='color: #7484b7;'>" + prompt + "</span>"
54
+ code_html = f"<br><hr><br><pre style='font-size: 12px'><code>{prompt}{completion}</code></pre><br><hr>"
55
+ return GENERATION_TITLE + code_html
56
+
57
+
58
+ def post_processing_fim(prefix: str, middle: str, suffix: str) -> str:
59
+ """
60
+ Post-processes the FIM (fill in the middle) generated code with HTML styling.
61
+
62
+ Args:
63
+ prefix (str): The prefix part of the code.
64
+ middle (str): The generated middle part of the code.
65
+ suffix (str): The suffix part of the code.
66
+
67
+ Returns:
68
+ str: The HTML-styled code with prefix, middle, and suffix.
69
+ """
70
+ prefix = "<span style='color: #7484b7;'>" + prefix + "</span>"
71
+ middle = "<span style='color: #ff5b86;'>" + middle + "</span>"
72
+ suffix = "<span style='color: #7484b7;'>" + suffix + "</span>"
73
+ code_html = f"<br><hr><br><pre style='font-size: 12px'><code>{prefix}{middle}{suffix}</code></pre><br><hr>"
74
+ return GENERATION_TITLE + code_html
75
+
76
+ def fim_generation(prompt: str, max_new_tokens: int, temperature: float) -> str:
77
+ """
78
+ Generates code for FIM (fill in the middle) task.
79
+
80
+ Args:
81
+ prompt (str): The input code prompt with <FILL_HERE> token.
82
+ max_new_tokens (int): Maximum number of tokens to generate.
83
+ temperature (float): Sampling temperature for generation.
84
+
85
+ Returns:
86
+ str: The HTML-styled code with filled missing part.
87
+ """
88
+ prefix = prompt.split("<FILL_HERE>")[0]
89
+ suffix = prompt.split("<FILL_HERE>")[1]
90
+ [middle] = infill((prefix, suffix), max_new_tokens, temperature)
91
+ return post_processing_fim(prefix, middle, suffix)
92
+
93
+ def extract_fim_part(s: str) -> str:
94
+ """
95
+ Extracts the FIM (fill in the middle) part from the generated string.
96
+
97
+ Args:
98
+ s (str): The generated string with FIM tokens.
99
+
100
+ Returns:
101
+ str: The extracted FIM part.
102
+ """
103
+ # Find the index of
104
+ start = s.find(FIM_MIDDLE) + len(FIM_MIDDLE)
105
+ stop = s.find(EOD, start) or len(s)
106
+ return s[start:stop]
107
+
108
+ def infill(prefix_suffix_tuples: Union[Tuple[str, str], List[Tuple[str, str]]], max_new_tokens: int, temperature: float) -> List[str]:
109
+ """
110
+ Generates the infill for the given prefix and suffix tuples.
111
+
112
+ Args:
113
+ prefix_suffix_tuples (Union[Tuple[str, str], List[Tuple[str, str]]]): Prefix and suffix tuples.
114
+ max_new_tokens (int): Maximum number of tokens to generate.
115
+ temperature (float): Sampling temperature for generation.
116
+
117
+ Returns:
118
+ List[str]: The list of generated infill strings.
119
+ """
120
+ if type(prefix_suffix_tuples) == tuple:
121
+ prefix_suffix_tuples = [prefix_suffix_tuples]
122
+
123
+ prompts = [f"{FIM_PREFIX}{prefix}{FIM_SUFFIX}{suffix}{FIM_MIDDLE}" for prefix, suffix in prefix_suffix_tuples]
124
+ # `return_token_type_ids=False` is essential, or we get nonsense output.
125
+ inputs = tokenizer_fim(prompts, return_tensors="pt", padding=True, return_token_type_ids=False).to(device)
126
+ with torch.no_grad():
127
+ outputs = model.generate(
128
+ **inputs,
129
+ do_sample=True,
130
+ temperature=temperature,
131
+ max_new_tokens=max_new_tokens,
132
+ pad_token_id=tokenizer.pad_token_id
133
+ )
134
+ # WARNING: cannot use skip_special_tokens, because it blows away the FIM special tokens.
135
+ return [
136
+ extract_fim_part(tokenizer_fim.decode(tensor, skip_special_tokens=False)) for tensor in outputs
137
+ ]
138
+
139
+ def code_generation(prompt: str, max_new_tokens: int, temperature: float = 0.2, seed: int = 42) -> str:
140
+ """
141
+ Generates code based on the given prompt. Handles both regular and FIM (Fill-In-Missing) generation.
142
+
143
+ Args:
144
+ prompt (str): The input code prompt.
145
+ max_new_tokens (int): Maximum number of tokens to generate.
146
+ temperature (float, optional): Sampling temperature for generation. Defaults to 0.2.
147
+ seed (int, optional): Random seed for reproducibility. Defaults to 42.
148
+
149
+ Returns:
150
+ str: The HTML-styled generated code.
151
+ """
152
+ if "<FILL_HERE>" in prompt:
153
+ return fim_generation(prompt, max_new_tokens, temperature=temperature)
154
+ else:
155
+ completion = pipe(prompt, do_sample=True, top_p=0.95, temperature=temperature, max_new_tokens=max_new_tokens)[0]['generated_text']
156
+ completion = completion[len(prompt):]
157
+ return post_processing(prompt, completion)
158
+
159
+ demo = gr.Blocks(
160
+ css=".gradio-container {background-color: white; color: #292b47}"
161
+ )
162
+ with demo:
163
+ with gr.Row():
164
+ _, colum_2, _ = gr.Column(scale=1), gr.Column(scale=6), gr.Column(scale=1)
165
+ with colum_2:
166
+ gr.Markdown(value=description)
167
+ code = gr.Code(lines=5, language="python", label="Input code", value="def nth_element_in_fibonnaci(element):\n \"\"\"Returns the nth element of the Fibonnaci sequence.\"\"\"")
168
+
169
+ with gr.Accordion("Additional settings", open=True):
170
+ max_new_tokens= gr.Slider(
171
+ minimum=8,
172
+ maximum=2048,
173
+ step=1,
174
+ value=55,
175
+ label="Number of tokens to generate",
176
+ )
177
+ temperature = gr.Slider(
178
+ minimum=0.1,
179
+ maximum=2.5,
180
+ step=0.01,
181
+ value=0.02,
182
+ label="Temperature",
183
+ )
184
+ seed = gr.inputs.Number(
185
+ default=42,
186
+ label="Enter a seed value (integer)"
187
+ )
188
+ run = gr.Button(value="👨🏽‍💻 Generate code", size='lg')
189
+ output = gr.HTML(label="💻 Your generated code")
190
+
191
+
192
+ event = run.click(code_generation, [code, max_new_tokens, temperature, seed], output, api_name="predict")
193
+ gr.HTML(label="Keep in touch", value="<img src='https://huggingface.co/spaces/harpreetsahota/DeciCoder/blob/main/deci-coder-banner.png' alt='Keep in touch' style='display: block; color: #292b47; margin: auto; max-width: 800px;'>")
194
+
195
+ demo.launch()