Spaces:
Build error
Build error
jijivski
commited on
Commit
•
9882e38
1
Parent(s):
e2bf898
hover and question _ppl
Browse files- data/mata_df.csv +0 -0
- data/model_release_time.csv +36 -0
- gradio_samples/gradio_hover.py +93 -0
- gradio_samples/web_ui.py +309 -0
data/mata_df.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
data/model_release_time.csv
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Model,Release Date,model,MMLU,GSM8,Humanities,SocialSciences,STEM,Other,Longbench
|
2 |
+
Baichuan2-13B-Base,2023-08-24,Baichuan2-13B-Base,58.1,52.7,51.54,66.2,47.89,65.24,62.55
|
3 |
+
Baichuan2-13B-Chat,2023-06-24,Baichuan2-13B-Chat,52.1,55.0,50.71,65.19,47.13,65.01,
|
4 |
+
Baichuan2-7B-Base,2023-08-24,Baichuan2-7B-Base,54.0,24.4,46.87,58.73,42.63,58.9,16.32
|
5 |
+
Baichuan2-7B-Chat,2023-08-24,Baichuan2-7B-Chat,52.9,32.0,46.44,58.82,41.93,59.22,32.22
|
6 |
+
Colossal-LLaMA-2-7b-base,2023-09-24,Colossal-LLaMA-2-7b-base,53.06,9.0,73.1,75.0,34.8,44.0,23.83
|
7 |
+
HF_RWKV_v5-Eagle-7B,2023-11-15,HF_RWKV_v5-Eagle-7B,33.04,9.3,32.58,34.94,28.29,36.66,19.33
|
8 |
+
Llama-2-13b-hf,2023-07-18,Llama-2-13b-hf,55.77,22.8,76.0,82.0,28.6,46.4,7.39
|
9 |
+
Llama-2-7b-hf,2023-07-18,Llama-2-7b-hf,46.87,14.4,70.2,65.0,38.4,42.2,15.29
|
10 |
+
Qwen-14B-Chat,2023-09-24,Qwen-14B-Chat,66.5,59.0,58.24,74.78,56.87,70.78,38.72
|
11 |
+
Qwen-1_8B,2023-11-30,Qwen-1_8B,45.3,32.0,40.77,50.93,37.04,51.92,35.4
|
12 |
+
Qwen-1_8B-Chat,2023-11-30,Qwen-1_8B-Chat,43.99,4.0,39.91,50.08,38.47,49.73,14.39
|
13 |
+
Qwen-7B,2023-09-24,Qwen-7B,59.84,44.9,75.4,80.0,37.5,48.2,45.53
|
14 |
+
Qwen-7B-Chat,2023-09-24,Qwen-7B-Chat,57.0,54.0,47.86,64.32,46.91,61.64,33.89
|
15 |
+
Skywork-13B-base,2023-10-22,Skywork-13B-base,62.1,55.0,56.62,70.13,47.19,67.69,23.48
|
16 |
+
TinyLlama-1.1B-Chat-v0.6,2023-11-24,TinyLlama-1.1B-Chat-v0.6,25.98,2.1,22.2,28.0,32.1,23.5,5.05
|
17 |
+
Yi-6B,2024-01-17,Yi-6B,64.11,12.1,83.0,85.0,42.9,45.8,38.89
|
18 |
+
Yi-6B-Chat,2024-01-17,Yi-6B-Chat,58.24,38.4,55.75,72.41,51.57,69.91,39.54
|
19 |
+
baichuan-13b-chat,2023-06-24,baichuan-13b-chat,52.1,0.1,43.95,56.48,38.19,56.2,9.29
|
20 |
+
baichuan-7b-chat,2023-09-24,baichuan-7b-chat,42.8,9.1,40.83,46.96,35.17,47.28,23.3
|
21 |
+
chatglm3-6b,2023-10-24,chatglm3-6b,61.4,72.0,46.12,59.12,42.82,56.49,
|
22 |
+
falcon-rw-1b,2023-04-24,falcon-rw-1b,25.28,0.5,29.2,28.0,29.5,28.9,5.31
|
23 |
+
interlm-20b,2023-09-18,interlm-20b,61.85,23.0,,,,,
|
24 |
+
internlm-chat-7b,2023-06-06,internlm-chat-7b,50.8,34.0,46.08,58.56,40.28,56.68,9.73
|
25 |
+
llama2-7b-chat-hf,2023-07-18,llama2-7b-chat-hf,48.32,45.5,72.5,72.0,30.4,43.4,19.58
|
26 |
+
llama_hf_7b,2023-02-18,llama_hf_7b,46.87,10.0,31.99,31.75,28.35,36.63,4.7
|
27 |
+
mistral-7b-v0.1,2023-09-18,mistral-7b-v0.1,64.16,37.8,83.0,86.0,48.2,55.4,32.2
|
28 |
+
opt-13b,2022-05-11,opt-13b,24.9,1.7,31.0,27.0,36.6,25.9,
|
29 |
+
opt-2.7b,2022-05-11,opt-2.7b,25.43,0.2,26.67,24.63,26.86,24.01,66.67
|
30 |
+
phi-1_5,2023-08-18,phi-1_5,43.89,12.4,46.8,64.0,38.4,41.0,8.07
|
31 |
+
phi-2,2023-12-24,phi-2,58.11,54.8,69.0,77.0,49.1,47.6,5.49
|
32 |
+
pythia-12b,2023-02-24,pythia-12b,26.76,1.7,30.4,29.0,33.0,31.9,
|
33 |
+
vicuna-7b-v1.5,2023-07-24,vicuna-7b-v1.5,50.82,8.1,71.3,76.0,44.6,42.8,20.39
|
34 |
+
xverse-13b,2023-08-06,xverse-13b,55.1,18.0,,,,,
|
35 |
+
zephyr-7b-beta,2023-10-26,zephyr-7b-beta,60.7,11.3,80.7,78.0,34.8,51.2,35.74
|
36 |
+
zhongjing-base,2023-09-24,zhongjing-base,48.23,26.0,75.4,69.0,39.3,45.2,3.36
|
gradio_samples/gradio_hover.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# import gradio as gr
|
2 |
+
|
3 |
+
# def generate_hoverable_html(text):
|
4 |
+
# # 分割文本为单词
|
5 |
+
# words = text.split()
|
6 |
+
|
7 |
+
# # 为每个单词创建一个带有悬停信息的 HTML span 元素
|
8 |
+
# html_words = [
|
9 |
+
# f'<span class="hoverable-word" data-info="Information about {word}">{word}</span>'
|
10 |
+
# for word in words
|
11 |
+
# ]
|
12 |
+
|
13 |
+
# # 将单词合并回字符串
|
14 |
+
# hoverable_html = ' '.join(html_words)
|
15 |
+
|
16 |
+
# # 添加 CSS 和 JavaScript
|
17 |
+
# custom_html = f"""
|
18 |
+
# <style>
|
19 |
+
# .hoverable-word {{
|
20 |
+
# color: blue;
|
21 |
+
# cursor: pointer;
|
22 |
+
# }}
|
23 |
+
# .hoverable-word:hover::after {{
|
24 |
+
# content: attr(data-info);
|
25 |
+
# color: white;
|
26 |
+
# background-color: black;
|
27 |
+
# padding: 4px;
|
28 |
+
# margin-left: 8px;
|
29 |
+
# position: absolute;
|
30 |
+
# }}
|
31 |
+
# </style>
|
32 |
+
# <div>{hoverable_html}</div>
|
33 |
+
# """
|
34 |
+
|
35 |
+
# return custom_html
|
36 |
+
|
37 |
+
# # 创建 Gradio 界面
|
38 |
+
# with gr.Blocks() as demo:
|
39 |
+
# with gr.Row():
|
40 |
+
# text_input = gr.Textbox(label="Input Text", placeholder="Type here...")
|
41 |
+
# output_html = gr.HTML()
|
42 |
+
|
43 |
+
# # 连接输入、处理函数和输出
|
44 |
+
# text_input.change(generate_hoverable_html, text_input, output_html)
|
45 |
+
|
46 |
+
# demo.launch()
|
47 |
+
|
48 |
+
import gradio as gr
|
49 |
+
|
50 |
+
def generate_hoverable_html(text):
|
51 |
+
# 分割文本为单词
|
52 |
+
words = text.split()
|
53 |
+
prob_dic={'a':{'b':0.1,'c':0.2},'b':{'a':0.1,'c':0.2}}
|
54 |
+
# 为每个单词创建一个带有悬停信息的 HTML span 元素
|
55 |
+
html_words = [
|
56 |
+
f'<span class="hoverable-word" data-info="{prob_dic[word]}">{word}</span>'
|
57 |
+
for word in words
|
58 |
+
]
|
59 |
+
|
60 |
+
# 将单词合并回字符串
|
61 |
+
hoverable_html = ' '.join(html_words)
|
62 |
+
|
63 |
+
# 添加 CSS 和 JavaScript
|
64 |
+
custom_html = f"""
|
65 |
+
<style>
|
66 |
+
.hoverable-word {{
|
67 |
+
color: blue;
|
68 |
+
cursor: pointer;
|
69 |
+
}}
|
70 |
+
.hoverable-word:hover::after {{
|
71 |
+
content: attr(data-info);
|
72 |
+
color: white;
|
73 |
+
background-color: black;
|
74 |
+
padding: 4px;
|
75 |
+
margin-left: 8px;
|
76 |
+
position: absolute;
|
77 |
+
}}
|
78 |
+
</style>
|
79 |
+
<div>{hoverable_html}</div>
|
80 |
+
"""
|
81 |
+
|
82 |
+
return custom_html
|
83 |
+
|
84 |
+
# 创建 Gradio 界面
|
85 |
+
with gr.Blocks() as demo:
|
86 |
+
with gr.Row():
|
87 |
+
text_input = gr.Textbox(label="Input Text", placeholder="Type here...")
|
88 |
+
output_html = gr.HTML()
|
89 |
+
|
90 |
+
# 连接输入、处理函数和输出
|
91 |
+
text_input.change(generate_hoverable_html, text_input, output_html)
|
92 |
+
|
93 |
+
demo.launch(debug=True)
|
gradio_samples/web_ui.py
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
|
3 |
+
import gradio
|
4 |
+
import numpy as np
|
5 |
+
import torch
|
6 |
+
from transformers import LogitsProcessor
|
7 |
+
|
8 |
+
from modules import html_generator, shared
|
9 |
+
|
10 |
+
params = {
|
11 |
+
'active': True,
|
12 |
+
'color_by_perplexity': False,
|
13 |
+
'color_by_probability': False,
|
14 |
+
'ppl_scale': 15.0, # No slider for this right now, because I don't think it really needs to be changed. Very large perplexity scores don't show up often.
|
15 |
+
'probability_dropdown': False,
|
16 |
+
'verbose': False # For debugging mostly
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
class PerplexityLogits(LogitsProcessor):
|
21 |
+
def __init__(self, verbose=False):
|
22 |
+
self.generated_token_ids = []
|
23 |
+
self.selected_probs = []
|
24 |
+
self.top_token_ids_list = []
|
25 |
+
self.top_probs_list = []
|
26 |
+
self.perplexities_list = []
|
27 |
+
self.last_probs = None
|
28 |
+
self.verbose = verbose
|
29 |
+
|
30 |
+
def __call__(self, input_ids, scores):
|
31 |
+
# t0 = time.time()
|
32 |
+
probs = torch.softmax(scores, dim=-1, dtype=torch.float)
|
33 |
+
log_probs = torch.nan_to_num(torch.log(probs)) # Note: This is to convert log(0) nan to 0, but probs*log_probs makes this 0 not affect the perplexity.
|
34 |
+
entropy = -torch.sum(probs * log_probs)
|
35 |
+
entropy = entropy.cpu().numpy()
|
36 |
+
perplexity = round(float(np.exp(entropy)), 4)
|
37 |
+
self.perplexities_list.append(perplexity)
|
38 |
+
last_token_id = int(input_ids[0][-1].cpu().numpy().item())
|
39 |
+
# Store the generated tokens (not sure why this isn't accessible in the output endpoint!)
|
40 |
+
self.generated_token_ids.append(last_token_id)
|
41 |
+
# Get last probability, and add to the list if it wasn't there
|
42 |
+
if len(self.selected_probs) > 0:
|
43 |
+
# Is the selected token in the top tokens?
|
44 |
+
if self.verbose:
|
45 |
+
print('Probs: Token after', shared.tokenizer.decode(last_token_id))
|
46 |
+
print('Probs:', [shared.tokenizer.decode(token_id) for token_id in self.top_token_ids_list[-1][0]])
|
47 |
+
print('Probs:', [round(float(prob), 4) for prob in self.top_probs_list[-1][0]])
|
48 |
+
if last_token_id in self.top_token_ids_list[-1][0]:
|
49 |
+
idx = self.top_token_ids_list[-1][0].index(last_token_id)
|
50 |
+
self.selected_probs.append(self.top_probs_list[-1][0][idx])
|
51 |
+
else:
|
52 |
+
self.top_token_ids_list[-1][0].append(last_token_id)
|
53 |
+
last_prob = round(float(self.last_probs[last_token_id]), 4)
|
54 |
+
self.top_probs_list[-1][0].append(last_prob)
|
55 |
+
self.selected_probs.append(last_prob)
|
56 |
+
else:
|
57 |
+
self.selected_probs.append(1.0) # Placeholder for the last token of the prompt
|
58 |
+
|
59 |
+
if self.verbose:
|
60 |
+
pplbar = "-"
|
61 |
+
if not np.isnan(perplexity):
|
62 |
+
pplbar = "*" * round(perplexity)
|
63 |
+
print(f"PPL: Token after {shared.tokenizer.decode(last_token_id)}\t{perplexity:.2f}\t{pplbar}")
|
64 |
+
|
65 |
+
# Get top 5 probabilities
|
66 |
+
top_tokens_and_probs = torch.topk(probs, 5)
|
67 |
+
top_probs = top_tokens_and_probs.values.cpu().numpy().astype(float).tolist()
|
68 |
+
top_token_ids = top_tokens_and_probs.indices.cpu().numpy().astype(int).tolist()
|
69 |
+
|
70 |
+
self.top_token_ids_list.append(top_token_ids)
|
71 |
+
self.top_probs_list.append(top_probs)
|
72 |
+
|
73 |
+
probs = probs.cpu().numpy().flatten()
|
74 |
+
self.last_probs = probs # Need to keep this as a reference for top probs
|
75 |
+
|
76 |
+
# t1 = time.time()
|
77 |
+
# print(f"PPL Processor: {(t1-t0):.3f} s")
|
78 |
+
# About 1 ms, though occasionally up to around 100 ms, not sure why...
|
79 |
+
# Doesn't actually modify the logits!
|
80 |
+
return scores
|
81 |
+
|
82 |
+
|
83 |
+
# Stores the perplexity and top probabilities
|
84 |
+
ppl_logits_processor = None
|
85 |
+
|
86 |
+
|
87 |
+
def logits_processor_modifier(logits_processor_list, input_ids):
|
88 |
+
global ppl_logits_processor
|
89 |
+
if params['active']:
|
90 |
+
ppl_logits_processor = PerplexityLogits(verbose=params['verbose'])
|
91 |
+
logits_processor_list.append(ppl_logits_processor)
|
92 |
+
|
93 |
+
|
94 |
+
def output_modifier(text):
|
95 |
+
global ppl_logits_processor
|
96 |
+
# t0 = time.time()
|
97 |
+
|
98 |
+
if not params['active']:
|
99 |
+
return text
|
100 |
+
|
101 |
+
# TODO: It's probably more efficient to do this above rather than modifying all these lists
|
102 |
+
# Remove last element of perplexities_list, top_token_ids_list, top_tokens_list, top_probs_list since everything is off by one because this extension runs before generation
|
103 |
+
perplexities = ppl_logits_processor.perplexities_list[:-1]
|
104 |
+
top_token_ids_list = ppl_logits_processor.top_token_ids_list[:-1]
|
105 |
+
top_tokens_list = [[shared.tokenizer.decode(token_id) for token_id in top_token_ids[0]] for top_token_ids in top_token_ids_list]
|
106 |
+
top_probs_list = ppl_logits_processor.top_probs_list[:-1]
|
107 |
+
# Remove first element of generated_token_ids, generated_tokens, selected_probs because they are for the last token of the prompt
|
108 |
+
gen_token_ids = ppl_logits_processor.generated_token_ids[1:]
|
109 |
+
gen_tokens = [shared.tokenizer.decode(token_id) for token_id in gen_token_ids]
|
110 |
+
sel_probs = ppl_logits_processor.selected_probs[1:]
|
111 |
+
|
112 |
+
end_part = '</div></div>' if params['probability_dropdown'] else '</span>' # Helps with finding the index after replacing part of the text.
|
113 |
+
|
114 |
+
i = 0
|
115 |
+
for token, prob, ppl, top_tokens, top_probs in zip(gen_tokens, sel_probs, perplexities, top_tokens_list, top_probs_list):
|
116 |
+
color = 'ffffff'
|
117 |
+
if params['color_by_probability'] and params['color_by_perplexity']:
|
118 |
+
color = probability_perplexity_color_scale(prob, ppl)
|
119 |
+
elif params['color_by_perplexity']:
|
120 |
+
color = perplexity_color_scale(ppl)
|
121 |
+
elif params['color_by_probability']:
|
122 |
+
color = probability_color_scale(prob)
|
123 |
+
if token in text[i:]:
|
124 |
+
if params['probability_dropdown']:
|
125 |
+
text = text[:i] + text[i:].replace(token, add_dropdown_html(token, color, top_tokens, top_probs[0], ppl), 1)
|
126 |
+
else:
|
127 |
+
text = text[:i] + text[i:].replace(token, add_color_html(token, color), 1)
|
128 |
+
i += text[i:].find(end_part) + len(end_part)
|
129 |
+
|
130 |
+
# Use full perplexity list for calculating the average here.
|
131 |
+
print('Average perplexity:', round(np.mean(ppl_logits_processor.perplexities_list[:-1]), 4))
|
132 |
+
# t1 = time.time()
|
133 |
+
# print(f"Modifier: {(t1-t0):.3f} s")
|
134 |
+
# About 50 ms
|
135 |
+
return text
|
136 |
+
|
137 |
+
|
138 |
+
def probability_color_scale(prob):
|
139 |
+
'''
|
140 |
+
Green-yellow-red color scale
|
141 |
+
'''
|
142 |
+
|
143 |
+
rv = 0
|
144 |
+
gv = 0
|
145 |
+
if prob <= 0.5:
|
146 |
+
rv = 'ff'
|
147 |
+
gv = hex(int(255 * prob * 2))[2:]
|
148 |
+
if len(gv) < 2:
|
149 |
+
gv = '0' * (2 - len(gv)) + gv
|
150 |
+
else:
|
151 |
+
rv = hex(int(255 - 255 * (prob - 0.5) * 2))[2:]
|
152 |
+
gv = 'ff'
|
153 |
+
if len(rv) < 2:
|
154 |
+
rv = '0' * (2 - len(rv)) + rv
|
155 |
+
|
156 |
+
return rv + gv + '00'
|
157 |
+
|
158 |
+
|
159 |
+
def perplexity_color_scale(ppl):
|
160 |
+
'''
|
161 |
+
Red component only, white for 0 perplexity (sorry if you're not in dark mode)
|
162 |
+
'''
|
163 |
+
value = hex(max(int(255.0 - params['ppl_scale'] * (float(ppl) - 1.0)), 0))[2:]
|
164 |
+
if len(value) < 2:
|
165 |
+
value = '0' * (2 - len(value)) + value
|
166 |
+
|
167 |
+
return 'ff' + value + value
|
168 |
+
|
169 |
+
|
170 |
+
def probability_perplexity_color_scale(prob, ppl):
|
171 |
+
'''
|
172 |
+
Green-yellow-red for probability and blue component for perplexity
|
173 |
+
'''
|
174 |
+
|
175 |
+
rv = 0
|
176 |
+
gv = 0
|
177 |
+
bv = hex(min(max(int(params['ppl_scale'] * (float(ppl) - 1.0)), 0), 255))[2:]
|
178 |
+
if len(bv) < 2:
|
179 |
+
bv = '0' * (2 - len(bv)) + bv
|
180 |
+
|
181 |
+
if prob <= 0.5:
|
182 |
+
rv = 'ff'
|
183 |
+
gv = hex(int(255 * prob * 2))[2:]
|
184 |
+
if len(gv) < 2:
|
185 |
+
gv = '0' * (2 - len(gv)) + gv
|
186 |
+
else:
|
187 |
+
rv = hex(int(255 - 255 * (prob - 0.5) * 2))[2:]
|
188 |
+
gv = 'ff'
|
189 |
+
if len(rv) < 2:
|
190 |
+
rv = '0' * (2 - len(rv)) + rv
|
191 |
+
|
192 |
+
return rv + gv + bv
|
193 |
+
|
194 |
+
|
195 |
+
def add_color_html(token, color):
|
196 |
+
return f'<span style="color: #{color}">{token}</span>'
|
197 |
+
|
198 |
+
|
199 |
+
# TODO: Major issue: Applying this to too many tokens will cause a permanent slowdown in generation speed until the messages are removed from the history.
|
200 |
+
# I think the issue is from HTML elements taking up space in the visible history, and things like history deepcopy add latency proportional to the size of the history.
|
201 |
+
# Potential solution is maybe to modify the main generation code to send just the internal text and not the visible history, to avoid moving too much around.
|
202 |
+
# I wonder if we can also avoid using deepcopy here.
|
203 |
+
def add_dropdown_html(token, color, top_tokens, top_probs, perplexity=0):
|
204 |
+
html = f'<div class="hoverable"><span style="color: #{color}">{token}</span><div class="dropdown"><table class="dropdown-content"><tbody>'
|
205 |
+
for token_option, prob in zip(top_tokens, top_probs):
|
206 |
+
# TODO: Bold for selected token?
|
207 |
+
# Using divs prevented the problem of divs inside spans causing issues.
|
208 |
+
# Now the problem is that divs show the same whitespace of one space between every token.
|
209 |
+
# There is probably some way to fix this in CSS that I don't know about.
|
210 |
+
row_color = probability_color_scale(prob)
|
211 |
+
row_class = ' class="selected"' if token_option == token else ''
|
212 |
+
html += f'<tr{row_class}><td style="color: #{row_color}">{token_option}</td><td style="color: #{row_color}">{prob:.4f}</td></tr>'
|
213 |
+
if perplexity != 0:
|
214 |
+
ppl_color = perplexity_color_scale(perplexity)
|
215 |
+
html += f'<tr><td>Perplexity:</td><td style="color: #{ppl_color}">{perplexity:.4f}</td></tr>'
|
216 |
+
html += '</tbody></table></div></div>'
|
217 |
+
return html # About 750 characters per token...
|
218 |
+
|
219 |
+
|
220 |
+
def custom_css():
|
221 |
+
return """
|
222 |
+
.dropdown {
|
223 |
+
display: none;
|
224 |
+
position: absolute;
|
225 |
+
z-index: 50;
|
226 |
+
background-color: var(--block-background-fill);
|
227 |
+
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
228 |
+
width: max-content;
|
229 |
+
overflow: visible;
|
230 |
+
padding: 5px;
|
231 |
+
border-radius: 10px;
|
232 |
+
border: 1px solid var(--border-color-primary);
|
233 |
+
}
|
234 |
+
|
235 |
+
.dropdown-content {
|
236 |
+
border: none;
|
237 |
+
z-index: 50;
|
238 |
+
}
|
239 |
+
|
240 |
+
.dropdown-content tr.selected {
|
241 |
+
background-color: var(--block-label-background-fill);
|
242 |
+
}
|
243 |
+
|
244 |
+
.dropdown-content td {
|
245 |
+
color: var(--body-text-color);
|
246 |
+
}
|
247 |
+
|
248 |
+
.hoverable {
|
249 |
+
color: var(--body-text-color);
|
250 |
+
position: relative;
|
251 |
+
display: inline-block;
|
252 |
+
overflow: visible;
|
253 |
+
font-size: 15px;
|
254 |
+
line-height: 1.75;
|
255 |
+
margin: 0;
|
256 |
+
padding: 0;
|
257 |
+
}
|
258 |
+
|
259 |
+
.hoverable:hover .dropdown {
|
260 |
+
display: block;
|
261 |
+
}
|
262 |
+
|
263 |
+
pre {
|
264 |
+
white-space: pre-wrap;
|
265 |
+
}
|
266 |
+
|
267 |
+
# TODO: This makes the hover menus extend outside the bounds of the chat area, which is good.
|
268 |
+
# However, it also makes the scrollbar disappear, which is bad.
|
269 |
+
# The scroll bar needs to still be present. So for now, we can't see dropdowns that extend past the edge of the chat area.
|
270 |
+
#.chat {
|
271 |
+
# overflow-y: auto;
|
272 |
+
#}
|
273 |
+
"""
|
274 |
+
|
275 |
+
|
276 |
+
# Monkeypatch applied to html_generator.py
|
277 |
+
# We simply don't render markdown into HTML. We wrap everything in <pre> tags to preserve whitespace
|
278 |
+
# formatting. If you're coloring tokens by perplexity or probability, or especially if you're using
|
279 |
+
# the probability dropdown, you probably care more about seeing the tokens the model actually outputted
|
280 |
+
# rather than rendering ```code blocks``` or *italics*.
|
281 |
+
def convert_to_markdown(string):
|
282 |
+
return '<pre>' + string + '</pre>'
|
283 |
+
|
284 |
+
|
285 |
+
html_generator.convert_to_markdown = convert_to_markdown
|
286 |
+
|
287 |
+
|
288 |
+
def ui():
|
289 |
+
def update_active_check(x):
|
290 |
+
params.update({'active': x})
|
291 |
+
|
292 |
+
def update_color_by_ppl_check(x):
|
293 |
+
params.update({'color_by_perplexity': x})
|
294 |
+
|
295 |
+
def update_color_by_prob_check(x):
|
296 |
+
params.update({'color_by_probability': x})
|
297 |
+
|
298 |
+
def update_prob_dropdown_check(x):
|
299 |
+
params.update({'probability_dropdown': x})
|
300 |
+
|
301 |
+
active_check = gradio.Checkbox(value=True, label="Compute probabilities and perplexity scores", info="Activate this extension. Note that this extension currently does not work with exllama or llama.cpp.")
|
302 |
+
color_by_ppl_check = gradio.Checkbox(value=False, label="Color by perplexity", info="Higher perplexity is more red. If also showing probability, higher perplexity has more blue component.")
|
303 |
+
color_by_prob_check = gradio.Checkbox(value=False, label="Color by probability", info="Green-yellow-red linear scale, with 100% green, 50% yellow, 0% red.")
|
304 |
+
prob_dropdown_check = gradio.Checkbox(value=False, label="Probability dropdown", info="Hover over a token to show a dropdown of top token probabilities. Currently slightly buggy with whitespace between tokens.")
|
305 |
+
|
306 |
+
active_check.change(update_active_check, active_check, None)
|
307 |
+
color_by_ppl_check.change(update_color_by_ppl_check, color_by_ppl_check, None)
|
308 |
+
color_by_prob_check.change(update_color_by_prob_check, color_by_prob_check, None)
|
309 |
+
prob_dropdown_check.change(update_prob_dropdown_check, prob_dropdown_check, None)
|