Hector Salvador [Fisharp] commited on
Commit
2bc3f5c
1 Parent(s): 32f7b3e

Structured dataclasses for requests and settings.

Browse files

Grouping client and utils source files into their own src directory

README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: StarCoder Completion
3
  emoji: 💫
4
  colorFrom: gray
5
  colorTo: blue
@@ -11,15 +11,17 @@ duplicated_from: bigcode/bigcode-playground
11
  ---
12
 
13
 
14
- # StarCoder Demo
15
 
16
- ## Star💫Coder Code Completion Playground 💻
17
 
18
- This is a demo playground to generate code with the power of [StarCoder](https://huggingface.co/bigcode/starcoder)💫 a **15B** parameter model for code generation in **80+** programming languages.
19
 
20
- This is not an instruction model but just a code completion tool.
21
 
22
- For instruction and chatting you can chat with a prompted version of the model directly at the [HuggingFace Chat 🤗 (hf.co/chat)](https://huggingface.co/chat/?model=starcoder)
 
 
23
 
24
  ---
25
 
 
1
  ---
2
+ title: StarCoder Demo
3
  emoji: 💫
4
  colorFrom: gray
5
  colorTo: blue
 
11
  ---
12
 
13
 
14
+ # StarCoder Demo💫
15
 
16
+ ## Code-Completion Playground 💻 with ⭐StarCoder Models
17
 
18
+ This is a demo playground to generate code with the power of [StarCoder](https://huggingface.co/bigcode/starcoder) a **15B** parameter model for code generation in **80+** programming languages.
19
 
20
+ ℹ️ This is not an instruction model but just a code completion tool.
21
 
22
+ 🗣️For instruction and chatting you can chat with a prompted version of the model directly at the [HuggingFace🤗Chat💬(hf.co/chat)](https://huggingface.co/chat/?model=starcoder)
23
+
24
+ ![StarCoder](https://huggingface.co/datasets/bigcode/admin/resolve/main/StarCoderBanner.png)
25
 
26
  ---
27
 
app.py CHANGED
@@ -1,27 +1,33 @@
1
  import sys
2
  import os
 
 
3
 
4
  import gradio as gr
5
  from gradio.themes.utils import sizes
6
  from text_generation import Client
 
7
 
8
  # todo: remove and replace by the actual js file instead
9
- from share_btn import (share_js)
10
- from utils import (
11
  get_file_as_string,
12
  get_sections,
13
  get_url_from_env_or_default_path,
14
  preview
15
  )
16
  from constants import (
17
- DEFAULT_STARCODER_API_PATH,
18
- DEFAULT_STARCODER_BASE_API_PATH,
19
  FIM_MIDDLE,
20
  FIM_PREFIX,
21
  FIM_SUFFIX,
22
  END_OF_TEXT,
23
  MIN_TEMPERATURE,
24
  )
 
 
 
 
 
25
 
26
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
27
  # Gracefully exit the app if the HF_TOKEN is not set,
@@ -37,17 +43,13 @@ if not HF_TOKEN:
37
  # gr.close_all(verbose=False)
38
  sys.exit(1)
39
 
40
- API_URL = get_url_from_env_or_default_path("STARCODER_API", DEFAULT_STARCODER_API_PATH)
41
  API_URL_BASE = get_url_from_env_or_default_path("STARCODER_BASE_API", DEFAULT_STARCODER_BASE_API_PATH)
42
 
43
- preview("StarCoder Model's URL", API_URL)
44
- preview("StarCoderBase Model's URL", API_URL_BASE)
45
  preview("HF Token", HF_TOKEN, ofuscate=True)
46
 
47
- DEFAULT_PORT = 7860
48
-
49
- FIM_INDICATOR = "<FILL_HERE>"
50
-
51
  # Loads the whole content of the formats.md file
52
  # and stores it into the FORMATS variable
53
  STATIC_PATH = "static"
@@ -81,55 +83,74 @@ theme = gr.themes.Monochrome(
81
  HEADERS = {
82
  "Authorization": f"Bearer {HF_TOKEN}",
83
  }
84
- client = Client(API_URL, headers = HEADERS)
85
- client_base = Client(API_URL_BASE, headers = HEADERS)
86
 
87
- def generate(prompt,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  temperature = 0.9,
89
  max_new_tokens = 256,
90
  top_p = 0.95,
91
  repetition_penalty = 1.0,
92
  version = "StarCoder",
93
- ):
94
-
95
- temperature = min(float(temperature), MIN_TEMPERATURE)
96
- top_p = float(top_p)
97
-
98
- generate_kwargs = dict(
99
- temperature = temperature,
100
- max_new_tokens = max_new_tokens,
101
- top_p = top_p,
102
- repetition_penalty = repetition_penalty,
103
- do_sample = True,
104
- seed = 42,
105
  )
 
106
 
107
- if fim_mode := FIM_INDICATOR in prompt:
108
- try:
109
- prefix, suffix = prompt.split(FIM_INDICATOR)
110
- except Exception as err:
111
- print(str(err))
112
- raise ValueError(f"Only one {FIM_INDICATOR} allowed in prompt!") from err
113
- prompt = f"{FIM_PREFIX}{prefix}{FIM_SUFFIX}{suffix}{FIM_MIDDLE}"
114
-
115
- model_client = client if version == "StarCoder" else client_base
116
-
117
- stream = model_client.generate_stream(prompt, **generate_kwargs)
118
-
119
- output = prefix if fim_mode else prompt
120
-
121
- for response in stream:
122
- if response.token.text == END_OF_TEXT:
123
- if fim_mode:
124
- output += suffix
125
- else:
126
- return output
127
- else:
128
- output += response.token.text
129
- # todo: log this value while in debug mode
130
- # previous_token = response.token.text
131
- yield output
132
- return output
133
 
134
  # todo: move it into the README too
135
  examples = [
@@ -138,12 +159,6 @@ examples = [
138
  "def alternating(list1, list2):\n results = []\n for i in range(min(len(list1), len(list2))):\n results.append(list1[i])\n results.append(list2[i])\n if len(list1) > len(list2):\n <FILL_HERE>\n else:\n results.extend(list2[i+1:])\n return results",
139
  ]
140
 
141
- def process_example(args):
142
- for x in generate(args):
143
- pass
144
- return x
145
-
146
-
147
  with gr.Blocks(theme=theme, analytics_enabled=False, css=CSS) as demo:
148
  with gr.Column():
149
  gr.Markdown(description)
@@ -226,6 +241,9 @@ with gr.Blocks(theme=theme, analytics_enabled=False, css=CSS) as demo:
226
  generate,
227
  inputs=[instruction, temperature, max_new_tokens, top_p, repetition_penalty, version],
228
  outputs=[output],
 
 
 
229
  )
230
  share_button.click(None, [], [], _js=share_js)
231
 
 
1
  import sys
2
  import os
3
+ import logging as log
4
+ from typing import Generator
5
 
6
  import gradio as gr
7
  from gradio.themes.utils import sizes
8
  from text_generation import Client
9
+ from src.request import StarCoderRequest, StarCoderRequestConfig
10
 
11
  # todo: remove and replace by the actual js file instead
12
+ from src.share_btn import (share_js)
13
+ from src.utils import (
14
  get_file_as_string,
15
  get_sections,
16
  get_url_from_env_or_default_path,
17
  preview
18
  )
19
  from constants import (
 
 
20
  FIM_MIDDLE,
21
  FIM_PREFIX,
22
  FIM_SUFFIX,
23
  END_OF_TEXT,
24
  MIN_TEMPERATURE,
25
  )
26
+ from settings import (
27
+ DEFAULT_PORT,
28
+ DEFAULT_STARCODER_API_PATH,
29
+ DEFAULT_STARCODER_BASE_API_PATH,
30
+ )
31
 
32
  HF_TOKEN = os.environ.get("HF_TOKEN", None)
33
  # Gracefully exit the app if the HF_TOKEN is not set,
 
43
  # gr.close_all(verbose=False)
44
  sys.exit(1)
45
 
46
+ API_URL_STAR = get_url_from_env_or_default_path("STARCODER_API", DEFAULT_STARCODER_API_PATH)
47
  API_URL_BASE = get_url_from_env_or_default_path("STARCODER_BASE_API", DEFAULT_STARCODER_BASE_API_PATH)
48
 
49
+ preview("StarCoder Model URL", API_URL_STAR)
50
+ preview("StarCoderBase Model URL", API_URL_BASE)
51
  preview("HF Token", HF_TOKEN, ofuscate=True)
52
 
 
 
 
 
53
  # Loads the whole content of the formats.md file
54
  # and stores it into the FORMATS variable
55
  STATIC_PATH = "static"
 
83
  HEADERS = {
84
  "Authorization": f"Bearer {HF_TOKEN}",
85
  }
86
+ client_star = Client(API_URL_STAR, headers=HEADERS)
87
+ client_base = Client(API_URL_BASE, headers=HEADERS)
88
 
89
+ def get_tokens_collector(request: StarCoderRequest) -> Generator[str, None, None]:
90
+
91
+ model_client = client_star if request.settings.version == "StarCoder" else client_base
92
+ stream = model_client.generate_stream(request.prompt, **request.settings.kwargs())
93
+ for response in stream:
94
+ # print(response.token.id, response.token.text)
95
+ # if token.text != END_OF_TEXT:
96
+ if response.token.id != 0:
97
+ yield response.token.text
98
+
99
+ def get_tokens_accumulator(request: StarCoderRequest) -> Generator[str, None, None]:
100
+ # start with the prefix (if in fim_mode)
101
+ output = request.prefix if request.fim_mode else request.prompt
102
+ for token in get_tokens_collector(request=request):
103
+ output += token
104
+ yield output
105
+ # after the last token, append the suffix (if in fim_mode)
106
+ if request.fim_mode:
107
+ output += request.suffix
108
+ yield output
109
+ # Append an extra line at the end
110
+ yield output + '\n'
111
+
112
+ def get_tokens_linker(request: StarCoderRequest) -> str:
113
+ return "".join(list(get_tokens_collector(request)))
114
+
115
+ def generate(
116
+ prompt: str,
117
  temperature = 0.9,
118
  max_new_tokens = 256,
119
  top_p = 0.95,
120
  repetition_penalty = 1.0,
121
  version = "StarCoder",
122
+ ) -> Generator[str, None, None]:
123
+ request = StarCoderRequest(
124
+ prompt=prompt,
125
+ settings=StarCoderRequestConfig(
126
+ version=version,
127
+ temperature=temperature,
128
+ max_new_tokens=max_new_tokens,
129
+ top_p=top_p,
130
+ repetition_penalty=repetition_penalty,
131
+ )
 
 
132
  )
133
+ yield from get_tokens_accumulator(request)
134
 
135
+ def process_example(
136
+ prompt: str,
137
+ temperature = 0.9,
138
+ max_new_tokens = 256,
139
+ top_p = 0.95,
140
+ repetition_penalty = 1.0,
141
+ version = "StarCoder",
142
+ ) -> Generator[str, None, None]:
143
+ request = StarCoderRequest(
144
+ prompt=prompt,
145
+ settings=StarCoderRequestConfig(
146
+ version=version,
147
+ temperature=temperature,
148
+ max_new_tokens=max_new_tokens,
149
+ top_p=top_p,
150
+ repetition_penalty=repetition_penalty,
151
+ )
152
+ )
153
+ yield from get_tokens_linker(request)
 
 
 
 
 
 
 
154
 
155
  # todo: move it into the README too
156
  examples = [
 
159
  "def alternating(list1, list2):\n results = []\n for i in range(min(len(list1), len(list2))):\n results.append(list1[i])\n results.append(list2[i])\n if len(list1) > len(list2):\n <FILL_HERE>\n else:\n results.extend(list2[i+1:])\n return results",
160
  ]
161
 
 
 
 
 
 
 
162
  with gr.Blocks(theme=theme, analytics_enabled=False, css=CSS) as demo:
163
  with gr.Column():
164
  gr.Markdown(description)
 
241
  generate,
242
  inputs=[instruction, temperature, max_new_tokens, top_p, repetition_penalty, version],
243
  outputs=[output],
244
+ # preprocess=False,
245
+ max_batch_size=8,
246
+ show_progress=True
247
  )
248
  share_button.click(None, [], [], _js=share_js)
249
 
constants.py CHANGED
@@ -1,10 +1,7 @@
1
- DEFAULT_HUGGINGFACE_MODELS_API_BASE_URL = "https://api-inference.huggingface.co/models/"
2
- DEFAULT_STARCODER_API_PATH = "bigcode/starcoder/"
3
- DEFAULT_STARCODER_BASE_API_PATH = "bigcode/starcoderbase/"
4
-
5
  FIM_PREFIX = "<fim_prefix>"
6
  FIM_MIDDLE = "<fim_middle>"
7
  FIM_SUFFIX = "<fim_suffix>"
8
  END_OF_TEXT = "<|endoftext|>"
9
 
10
- MIN_TEMPERATURE = 1e-3
 
 
 
 
 
 
1
  FIM_PREFIX = "<fim_prefix>"
2
  FIM_MIDDLE = "<fim_middle>"
3
  FIM_SUFFIX = "<fim_suffix>"
4
  END_OF_TEXT = "<|endoftext|>"
5
 
6
+ # Near zero temperature to avoid division by zero
7
+ MIN_TEMPERATURE = 1e-4
settings.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # URLs for the StarCoder Models/APIs
2
+ DEFAULT_HUGGINGFACE_MODELS_API_BASE_URL = "https://api-inference.huggingface.co/models/"
3
+ DEFAULT_STARCODER_API_PATH = "bigcode/starcoder/"
4
+ DEFAULT_STARCODER_BASE_API_PATH = "bigcode/starcoderbase/"
5
+ FIM_INDICATOR = "<FILL_HERE>"
6
+ DEFAULT_PORT = 7860
7
+
8
+ DEFAULT_SETTINGS = dict(
9
+ temperature = 0.9,
10
+ max_new_tokens = 256,
11
+ top_p = 0.95,
12
+ repetition_penalty = 1.0,
13
+ version = "StarCoder",
14
+ )
src/request.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from typing import Dict, Any, Union
3
+
4
+ from constants import (
5
+ FIM_MIDDLE,
6
+ FIM_PREFIX,
7
+ FIM_SUFFIX,
8
+ MIN_TEMPERATURE,
9
+ )
10
+ from settings import (
11
+ FIM_INDICATOR,
12
+ )
13
+
14
+ @dataclass
15
+ class StarCoderRequestConfig:
16
+ temperature: float
17
+ max_new_tokens: int
18
+ top_p: float
19
+ repetition_penalty: float
20
+ version: str
21
+
22
+ def __post_init__(self):
23
+ self.temperature = min(float(self.temperature), MIN_TEMPERATURE)
24
+ self.max_new_tokens = int(self.max_new_tokens)
25
+ self.top_p = float(self.top_p)
26
+ self.repetition_penalty = float(self.repetition_penalty)
27
+ self.do_sample = True
28
+ self.seed = 42
29
+
30
+ def __repr__(self) -> str:
31
+ """Returns a custom string representation of the Configurations."""
32
+ values = dict(
33
+ model = self.version,
34
+ temp = self.temperature,
35
+ tokens = self.max_new_tokens,
36
+ p = self.top_p,
37
+ penalty = self.repetition_penalty,
38
+ sample = self.do_sample,
39
+ seed = self.seed,
40
+ )
41
+ return f"StarCoderRequestConfig({values})"
42
+
43
+ def kwargs(self) -> Dict[str, Union[Any, float, int]]:
44
+ """
45
+ Returns a custom dictionary representation of the Configurations.
46
+ removing the model version.
47
+ """
48
+ values = vars(self).copy()
49
+ values.pop("version")
50
+ return values
51
+
52
+ @dataclass
53
+ class StarCoderRequest:
54
+ prompt: str
55
+ settings: StarCoderRequestConfig
56
+
57
+ def __post_init__(self):
58
+ self.fim_mode = FIM_INDICATOR in self.prompt
59
+ self.prefix, self.suffix = None, None
60
+ if self.fim_mode:
61
+ try:
62
+ self.prefix, self.suffix = self.prompt.split(FIM_INDICATOR)
63
+ except Exception as err:
64
+ print(str(err))
65
+ raise ValueError(f"Only one {FIM_INDICATOR} allowed in prompt!") from err
66
+ self.prompt = f"{FIM_PREFIX}{self.prefix}{FIM_SUFFIX}{self.suffix}{FIM_MIDDLE}"
67
+
68
+ def __repr__(self) -> str:
69
+ """Returns a custom string representation of the Request."""
70
+ values = dict(
71
+ prompt = self.prompt,
72
+ configuration = self.settings,
73
+ )
74
+ return f"StarCoderRequest({values})"
share_btn.py → src/share_btn.py RENAMED
@@ -67,7 +67,7 @@ ${outputTxt}`;
67
  .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
68
  .join('&');
69
 
70
- window.open(`https://huggingface.co/spaces/Fisharp/starcoder-playground/discussions/new?${paramsStr}`, '_blank');
71
 
72
  shareBtnEl.style.removeProperty('pointer-events');
73
  shareIconEl.style.removeProperty('display');
 
67
  .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
68
  .join('&');
69
 
70
+ window.open(`https://huggingface.co/spaces/fisharp/starcoder-playground/discussions/new?${paramsStr}`, '_blank');
71
 
72
  shareBtnEl.style.removeProperty('pointer-events');
73
  shareIconEl.style.removeProperty('display');
utils.py → src/utils.py RENAMED
@@ -2,7 +2,7 @@ import os
2
  from typing import List
3
  from urllib.parse import urljoin
4
 
5
- from constants import DEFAULT_HUGGINGFACE_MODELS_API_BASE_URL
6
 
7
 
8
  def masked(value: str, n_shown: int, length: int = None) -> str:
 
2
  from typing import List
3
  from urllib.parse import urljoin
4
 
5
+ from settings import DEFAULT_HUGGINGFACE_MODELS_API_BASE_URL
6
 
7
 
8
  def masked(value: str, n_shown: int, length: int = None) -> str:
static/share_btn.js CHANGED
@@ -67,7 +67,7 @@ ${outputTxt}`;
67
  .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
68
  .join('&');
69
 
70
- window.open(`https://huggingface.co/spaces/Fisharp/starcoder-playground/discussions/new?${paramsStr}`, '_blank');
71
 
72
  shareBtnEl.style.removeProperty('pointer-events');
73
  shareIconEl.style.removeProperty('display');
 
67
  .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
68
  .join('&');
69
 
70
+ window.open(`https://huggingface.co/spaces/fisharp/starcoder-playground/discussions/new?${paramsStr}`, '_blank');
71
 
72
  shareBtnEl.style.removeProperty('pointer-events');
73
  shareIconEl.style.removeProperty('display');