Update app.py
Browse files
app.py
CHANGED
|
@@ -34,17 +34,10 @@ def analyze_text(text, top_k):
|
|
| 34 |
.tt{display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);
|
| 35 |
background:#1a1a2e;color:#eee;padding:14px;border-radius:12px;font-size:13px;z-index:9999;
|
| 36 |
box-shadow:0 10px 30px rgba(0,0,0,.35);min-width:220px;max-height:350px;overflow-y:auto}
|
| 37 |
-
|
| 38 |
-
/* Bridge the gap between token and tooltip with a pseudo-element */
|
| 39 |
.tt::after{content:'';position:absolute;top:100%;left:0;width:100%;height:12px}
|
| 40 |
-
|
| 41 |
-
/* Show on hover */
|
| 42 |
.tw:hover .tt{display:block}
|
| 43 |
-
|
| 44 |
-
/* Show when pinned via click */
|
| 45 |
.tw.pinned .tt{display:block}
|
| 46 |
.tw.pinned .tk{transform:translateY(-2px);box-shadow:0 4px 14px rgba(0,0,0,.18);border-color:#999;outline:2px solid #7fdbca}
|
| 47 |
-
|
| 48 |
.th{font-weight:700;font-size:14px;color:#7fdbca;border-bottom:1px solid #333;padding-bottom:6px;margin-bottom:6px}
|
| 49 |
.tp{color:#ffd700;margin-bottom:8px}
|
| 50 |
.at{color:#ff79c6;font-size:10px;text-transform:uppercase;letter-spacing:1px;margin-bottom:4px}
|
|
@@ -56,15 +49,11 @@ box-shadow:0 10px 30px rgba(0,0,0,.35);min-width:220px;max-height:350px;overflow
|
|
| 56 |
document.addEventListener('click', function(e) {
|
| 57 |
const tk = e.target.closest('.tk');
|
| 58 |
const tw = tk ? tk.closest('.tw') : null;
|
| 59 |
-
// If clicked a token, toggle its pin
|
| 60 |
if (tw) {
|
| 61 |
const wasPinned = tw.classList.contains('pinned');
|
| 62 |
-
// Unpin all others
|
| 63 |
document.querySelectorAll('.tw.pinned').forEach(el => el.classList.remove('pinned'));
|
| 64 |
-
// Toggle this one
|
| 65 |
if (!wasPinned) tw.classList.add('pinned');
|
| 66 |
} else if (!e.target.closest('.tt')) {
|
| 67 |
-
// Clicked outside any token or tooltip — unpin all
|
| 68 |
document.querySelectorAll('.tw.pinned').forEach(el => el.classList.remove('pinned'));
|
| 69 |
}
|
| 70 |
});
|
|
@@ -105,13 +94,48 @@ document.addEventListener('click', function(e) {
|
|
| 105 |
return ''.join(parts)
|
| 106 |
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
with gr.Blocks(theme=gr.themes.Soft(), css="footer{display:none!important}.main{max-width:960px;margin:auto}") as demo:
|
| 109 |
-
gr.Markdown("# 🔍 Token Probability Explorer\nPaste text, **hover** to preview or **click** a token to pin its tooltip open. Click elsewhere to dismiss.")
|
|
|
|
|
|
|
|
|
|
| 110 |
with gr.Row():
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
demo.launch()
|
|
|
|
| 34 |
.tt{display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);
|
| 35 |
background:#1a1a2e;color:#eee;padding:14px;border-radius:12px;font-size:13px;z-index:9999;
|
| 36 |
box-shadow:0 10px 30px rgba(0,0,0,.35);min-width:220px;max-height:350px;overflow-y:auto}
|
|
|
|
|
|
|
| 37 |
.tt::after{content:'';position:absolute;top:100%;left:0;width:100%;height:12px}
|
|
|
|
|
|
|
| 38 |
.tw:hover .tt{display:block}
|
|
|
|
|
|
|
| 39 |
.tw.pinned .tt{display:block}
|
| 40 |
.tw.pinned .tk{transform:translateY(-2px);box-shadow:0 4px 14px rgba(0,0,0,.18);border-color:#999;outline:2px solid #7fdbca}
|
|
|
|
| 41 |
.th{font-weight:700;font-size:14px;color:#7fdbca;border-bottom:1px solid #333;padding-bottom:6px;margin-bottom:6px}
|
| 42 |
.tp{color:#ffd700;margin-bottom:8px}
|
| 43 |
.at{color:#ff79c6;font-size:10px;text-transform:uppercase;letter-spacing:1px;margin-bottom:4px}
|
|
|
|
| 49 |
document.addEventListener('click', function(e) {
|
| 50 |
const tk = e.target.closest('.tk');
|
| 51 |
const tw = tk ? tk.closest('.tw') : null;
|
|
|
|
| 52 |
if (tw) {
|
| 53 |
const wasPinned = tw.classList.contains('pinned');
|
|
|
|
| 54 |
document.querySelectorAll('.tw.pinned').forEach(el => el.classList.remove('pinned'));
|
|
|
|
| 55 |
if (!wasPinned) tw.classList.add('pinned');
|
| 56 |
} else if (!e.target.closest('.tt')) {
|
|
|
|
| 57 |
document.querySelectorAll('.tw.pinned').forEach(el => el.classList.remove('pinned'));
|
| 58 |
}
|
| 59 |
});
|
|
|
|
| 94 |
return ''.join(parts)
|
| 95 |
|
| 96 |
|
| 97 |
+
def predict_next(text, num_tokens, temperature):
|
| 98 |
+
if not text.strip():
|
| 99 |
+
return ""
|
| 100 |
+
inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=512).to(device)
|
| 101 |
+
input_len = inputs['input_ids'].shape[1]
|
| 102 |
+
max_tokens = min(int(num_tokens), 512 - input_len)
|
| 103 |
+
|
| 104 |
+
if max_tokens <= 0:
|
| 105 |
+
return "Input too long to generate more."
|
| 106 |
+
|
| 107 |
+
with torch.no_grad():
|
| 108 |
+
output_ids = model.generate(
|
| 109 |
+
**inputs,
|
| 110 |
+
max_new_tokens=max_tokens,
|
| 111 |
+
do_sample=True if temperature > 0 else False,
|
| 112 |
+
temperature=temperature if temperature > 0 else 1.0,
|
| 113 |
+
top_k=50,
|
| 114 |
+
pad_token_id=tokenizer.eos_token_id,
|
| 115 |
+
repetition_penalty=1.1
|
| 116 |
+
)
|
| 117 |
+
result = tokenizer.decode(output_ids[0], skip_special_tokens=True)
|
| 118 |
+
return result[len(text):].strip()
|
| 119 |
+
|
| 120 |
+
|
| 121 |
with gr.Blocks(theme=gr.themes.Soft(), css="footer{display:none!important}.main{max-width:960px;margin:auto}") as demo:
|
| 122 |
+
gr.Markdown("# 🔍 Token Probability Explorer & Predictor\nPaste text, **hover** to preview or **click** a token to pin its tooltip open. Click elsewhere to dismiss.")
|
| 123 |
+
|
| 124 |
+
text_input = gr.Textbox(label="Input Text", placeholder="Paste your text here…", lines=5)
|
| 125 |
+
|
| 126 |
with gr.Row():
|
| 127 |
+
top_k_input = gr.Number(label="# Alternatives (Analysis)", value=10, minimum=1, maximum=200, step=1)
|
| 128 |
+
num_tokens_input = gr.Number(label="# Tokens to Predict", value=10, minimum=1, maximum=100, step=1)
|
| 129 |
+
temperature_input = gr.Slider(label="Temperature (Prediction)", minimum=0.0, maximum=2.0, value=0.7, step=0.05)
|
| 130 |
+
|
| 131 |
+
with gr.Row():
|
| 132 |
+
btn_analyze = gr.Button("Analyze", variant="primary")
|
| 133 |
+
btn_predict = gr.Button("Predict Next", variant="secondary")
|
| 134 |
+
|
| 135 |
+
output_analysis = gr.HTML(label="Analysis Output")
|
| 136 |
+
output_prediction = gr.Textbox(label="Predicted Continuation", lines=3, interactive=False)
|
| 137 |
+
|
| 138 |
+
btn_analyze.click(fn=analyze_text, inputs=[text_input, top_k_input], outputs=output_analysis)
|
| 139 |
+
btn_predict.click(fn=predict_next, inputs=[text_input, num_tokens_input, temperature_input], outputs=output_prediction)
|
| 140 |
|
| 141 |
demo.launch()
|