Spaces:
Runtime error
Runtime error
Add draw from test set, pull fp8 model
Browse files- .gitattributes +2 -0
- app.py +68 -10
- result.json +0 -0
- test.json +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
result.json filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
test.json filter=lfs diff=lfs merge=lfs -text
|
app.py
CHANGED
|
@@ -3,12 +3,15 @@ import torch
|
|
| 3 |
import gradio as gr
|
| 4 |
import spaces
|
| 5 |
import json
|
|
|
|
| 6 |
from threading import Thread
|
| 7 |
-
from transformers import AutoTokenizer, AutoModelForCausalLM,
|
| 8 |
|
| 9 |
# >>>> CHANGE THIS <<<<
|
| 10 |
-
MODEL_ID = os.getenv("MODEL_ID", "theostos/LLM4Docq-annotator")
|
| 11 |
RESULT_JSON_PATH = os.getenv("RESULT_JSON_PATH", "result.json")
|
|
|
|
|
|
|
| 12 |
# Matches your training style: messages=[{"role":"user","content": template.format(term=..., dependencies=...)}]
|
| 13 |
INSTRUCTION_TEMPLATE = "You are given a Coq source file along with an optional prefix.\n\n- The **prefix** contains lines that appear *before* the current chunk of code. It provides contextual information to help you understand the surrounding definitions, imports, and notation.\n- The **source** contains the chunk of code you must annotate and complete.\n\nSome parts of the code contain special placeholders:\n\n- [PREDICT_DOCSTRING]: This placeholder appears before an element. You must replace it with a descriptive comment (in Coq comment syntax (* ... *)) that explains what the element does.\n\n- [PREDICT_STATEMENT]: This placeholder appears after an explanatory comment. You must replace it with a valid Coq statement or definition that matches the meaning of the preceding comment.\n\nYour task is to rewrite the entire Coq source chunk, replacing all placeholders with appropriate content, while preserving all other parts of the source code exactly as they are.\n\n### Guidelines\n1. The **prefix** is only provided for context — do **not** modify it or include it in your output.\n2. Rewrite only the **source** content.\n3. Keep all existing Coq syntax, imports, and formatting intact.\n4. Replace [PREDICT_DOCSTRING] with a natural-language description of the next element.\n5. Replace [PREDICT_STATEMENT] with a complete and syntactically correct Coq statement (definition, lemma, theorem, etc.) that corresponds to the immediately preceding comment.\n6. Ensure the generated statements are consistent with the style and logic suggested by the prefix and surrounding code.\n7. Do not add or remove any lines except to substitute the placeholders.\n\n### Output format\nReturn **only** the full rewritten Coq source chunk (without the prefix), with all placeholders replaced.\n\nHere is the context and source:\n\n## Prefix:\n{prefix}\n\n## Source:\n{source}"
|
| 14 |
|
|
@@ -18,8 +21,6 @@ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, token=HF_TOKEN, use_fast=Tru
|
|
| 18 |
if tokenizer.pad_token_id is None and tokenizer.eos_token_id is not None:
|
| 19 |
tokenizer.pad_token_id = tokenizer.eos_token_id
|
| 20 |
|
| 21 |
-
quant_config = FineGrainedFP8Config()
|
| 22 |
-
|
| 23 |
_model = None
|
| 24 |
def load_model():
|
| 25 |
global _model
|
|
@@ -28,9 +29,8 @@ def load_model():
|
|
| 28 |
MODEL_ID,
|
| 29 |
token=HF_TOKEN,
|
| 30 |
device_map="auto",
|
| 31 |
-
dtype="auto",
|
| 32 |
-
|
| 33 |
-
trust_remote_code=True,
|
| 34 |
)
|
| 35 |
return _model
|
| 36 |
|
|
@@ -50,9 +50,39 @@ def load_prefixes(path=RESULT_JSON_PATH):
|
|
| 50 |
print(f"[warn] Could not load {path}: {e}")
|
| 51 |
return {}
|
| 52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
PREFIXES = load_prefixes()
|
| 54 |
PREFIX_KEYS = sorted(PREFIXES.keys())
|
| 55 |
|
|
|
|
|
|
|
| 56 |
# Estimate duration for ZeroGPU (default is 60s). Shorter = better queue priority.
|
| 57 |
def _duration(term, deps, temperature, top_p, max_new_tokens):
|
| 58 |
# crude: ~2.5 tok/s + 30s headroom
|
|
@@ -94,11 +124,27 @@ def generate(term, deps, temperature, top_p, max_new_tokens):
|
|
| 94 |
def set_prefix_from_key(key: str) -> str:
|
| 95 |
return PREFIXES.get(key, "") if key else ""
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
with gr.Blocks(title="Rocq Annotator (ZeroGPU, FP8)") as demo:
|
| 98 |
gr.Markdown(
|
| 99 |
"# Rocq annotator\n"
|
| 100 |
"Pick a **prefix** example from the dropdown to auto-fill the Prefix editor, "
|
| 101 |
-
"then write a **target snippet** (with [PREDICT_STATEMENT]/[PREDICT_DOCSTRING] tags) and click **Annotate
|
|
|
|
| 102 |
)
|
| 103 |
|
| 104 |
with gr.Row():
|
|
@@ -110,6 +156,8 @@ with gr.Blocks(title="Rocq Annotator (ZeroGPU, FP8)") as demo:
|
|
| 110 |
)
|
| 111 |
|
| 112 |
reload_btn = gr.Button("Reload result.json", variant="secondary")
|
|
|
|
|
|
|
| 113 |
|
| 114 |
with gr.Row():
|
| 115 |
prefix_box = gr.Code(
|
|
@@ -126,15 +174,20 @@ with gr.Blocks(title="Rocq Annotator (ZeroGPU, FP8)") as demo:
|
|
| 126 |
)
|
| 127 |
|
| 128 |
with gr.Row():
|
| 129 |
-
temperature = gr.Slider(0.0, 1.5, value=0.
|
| 130 |
top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="top_p")
|
| 131 |
max_new = gr.Slider(32, 512, value=128, step=32, label="max_new_tokens")
|
| 132 |
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
btn = gr.Button("Annotate", variant="primary")
|
| 135 |
|
| 136 |
# --- wiring ---
|
| 137 |
dropdown.change(set_prefix_from_key, inputs=dropdown, outputs=prefix_box)
|
|
|
|
| 138 |
# Optional: hot reload result.json without restarting Space
|
| 139 |
def _reload():
|
| 140 |
global PREFIXES, PREFIX_KEYS
|
|
@@ -145,6 +198,11 @@ with gr.Blocks(title="Rocq Annotator (ZeroGPU, FP8)") as demo:
|
|
| 145 |
notice = gr.Markdown("")
|
| 146 |
reload_btn.click(_reload, inputs=None, outputs=[dropdown, notice])
|
| 147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
btn.click(
|
| 149 |
generate,
|
| 150 |
inputs=[prefix_box, target_box, temperature, top_p, max_new],
|
|
|
|
| 3 |
import gradio as gr
|
| 4 |
import spaces
|
| 5 |
import json
|
| 6 |
+
import random # <<< NEW
|
| 7 |
from threading import Thread
|
| 8 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer
|
| 9 |
|
| 10 |
# >>>> CHANGE THIS <<<<
|
| 11 |
+
MODEL_ID = os.getenv("MODEL_ID", "theostos/LLM4Docq-annotator-fp8")
|
| 12 |
RESULT_JSON_PATH = os.getenv("RESULT_JSON_PATH", "result.json")
|
| 13 |
+
# NEW: path to your test set (list[dict])
|
| 14 |
+
TEST_JSON_PATH = os.getenv("TEST_JSON_PATH", "test.json")
|
| 15 |
# Matches your training style: messages=[{"role":"user","content": template.format(term=..., dependencies=...)}]
|
| 16 |
INSTRUCTION_TEMPLATE = "You are given a Coq source file along with an optional prefix.\n\n- The **prefix** contains lines that appear *before* the current chunk of code. It provides contextual information to help you understand the surrounding definitions, imports, and notation.\n- The **source** contains the chunk of code you must annotate and complete.\n\nSome parts of the code contain special placeholders:\n\n- [PREDICT_DOCSTRING]: This placeholder appears before an element. You must replace it with a descriptive comment (in Coq comment syntax (* ... *)) that explains what the element does.\n\n- [PREDICT_STATEMENT]: This placeholder appears after an explanatory comment. You must replace it with a valid Coq statement or definition that matches the meaning of the preceding comment.\n\nYour task is to rewrite the entire Coq source chunk, replacing all placeholders with appropriate content, while preserving all other parts of the source code exactly as they are.\n\n### Guidelines\n1. The **prefix** is only provided for context — do **not** modify it or include it in your output.\n2. Rewrite only the **source** content.\n3. Keep all existing Coq syntax, imports, and formatting intact.\n4. Replace [PREDICT_DOCSTRING] with a natural-language description of the next element.\n5. Replace [PREDICT_STATEMENT] with a complete and syntactically correct Coq statement (definition, lemma, theorem, etc.) that corresponds to the immediately preceding comment.\n6. Ensure the generated statements are consistent with the style and logic suggested by the prefix and surrounding code.\n7. Do not add or remove any lines except to substitute the placeholders.\n\n### Output format\nReturn **only** the full rewritten Coq source chunk (without the prefix), with all placeholders replaced.\n\nHere is the context and source:\n\n## Prefix:\n{prefix}\n\n## Source:\n{source}"
|
| 17 |
|
|
|
|
| 21 |
if tokenizer.pad_token_id is None and tokenizer.eos_token_id is not None:
|
| 22 |
tokenizer.pad_token_id = tokenizer.eos_token_id
|
| 23 |
|
|
|
|
|
|
|
| 24 |
_model = None
|
| 25 |
def load_model():
|
| 26 |
global _model
|
|
|
|
| 29 |
MODEL_ID,
|
| 30 |
token=HF_TOKEN,
|
| 31 |
device_map="auto",
|
| 32 |
+
dtype="auto",
|
| 33 |
+
trust_remote_code=True
|
|
|
|
| 34 |
)
|
| 35 |
return _model
|
| 36 |
|
|
|
|
| 50 |
print(f"[warn] Could not load {path}: {e}")
|
| 51 |
return {}
|
| 52 |
|
| 53 |
+
# --- NEW: test set loader + helpers ---
|
| 54 |
+
def load_test_examples(path=TEST_JSON_PATH):
|
| 55 |
+
"""
|
| 56 |
+
Expects a JSON list of dicts with keys:
|
| 57 |
+
- 'prefix'
|
| 58 |
+
- 'partially_annotated_last_target'
|
| 59 |
+
- 'fully_annotated_last_target'
|
| 60 |
+
Returns a cleaned list with {'prefix','target','truth'} strings.
|
| 61 |
+
"""
|
| 62 |
+
try:
|
| 63 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 64 |
+
data = json.load(f)
|
| 65 |
+
if not isinstance(data, list):
|
| 66 |
+
raise ValueError("Test set JSON must be a list of objects.")
|
| 67 |
+
cleaned = []
|
| 68 |
+
for i, ex in enumerate(data):
|
| 69 |
+
if not isinstance(ex, dict):
|
| 70 |
+
continue
|
| 71 |
+
prefix = str(ex.get("prefix", ""))
|
| 72 |
+
target = str(ex.get("partially_annotated_last_target", ""))
|
| 73 |
+
truth = str(ex.get("fully_annotated_last_target", ""))
|
| 74 |
+
cleaned.append({"prefix": prefix, "target": target, "truth": truth})
|
| 75 |
+
print(f"[info] Loaded {len(cleaned)} test examples from {path}")
|
| 76 |
+
return cleaned
|
| 77 |
+
except Exception as e:
|
| 78 |
+
print(f"[warn] Could not load test set {path}: {e}")
|
| 79 |
+
return []
|
| 80 |
+
|
| 81 |
PREFIXES = load_prefixes()
|
| 82 |
PREFIX_KEYS = sorted(PREFIXES.keys())
|
| 83 |
|
| 84 |
+
TEST_EXAMPLES = load_test_examples() # <<< NEW
|
| 85 |
+
|
| 86 |
# Estimate duration for ZeroGPU (default is 60s). Shorter = better queue priority.
|
| 87 |
def _duration(term, deps, temperature, top_p, max_new_tokens):
|
| 88 |
# crude: ~2.5 tok/s + 30s headroom
|
|
|
|
| 124 |
def set_prefix_from_key(key: str) -> str:
|
| 125 |
return PREFIXES.get(key, "") if key else ""
|
| 126 |
|
| 127 |
+
# NEW: sample a random test example
|
| 128 |
+
def _sample_test_example():
|
| 129 |
+
if not TEST_EXAMPLES:
|
| 130 |
+
# Return empty prefix/target and a notice in the truth box
|
| 131 |
+
return "", "", "No test examples loaded. Set TEST_JSON_PATH or add test.json at repo root."
|
| 132 |
+
ex = random.choice(TEST_EXAMPLES)
|
| 133 |
+
truth_md = f"```rocq\n{ex['truth']}\n```" if ex["truth"] else ""
|
| 134 |
+
return ex["prefix"], ex["target"], truth_md
|
| 135 |
+
|
| 136 |
+
# NEW: hot-reload the test set
|
| 137 |
+
def _reload_test_set():
|
| 138 |
+
global TEST_EXAMPLES
|
| 139 |
+
TEST_EXAMPLES = load_test_examples()
|
| 140 |
+
return gr.update(value=f"Reloaded {len(TEST_EXAMPLES)} test examples from {TEST_JSON_PATH}.")
|
| 141 |
+
|
| 142 |
with gr.Blocks(title="Rocq Annotator (ZeroGPU, FP8)") as demo:
|
| 143 |
gr.Markdown(
|
| 144 |
"# Rocq annotator\n"
|
| 145 |
"Pick a **prefix** example from the dropdown to auto-fill the Prefix editor, "
|
| 146 |
+
"then write a **target snippet** (with [PREDICT_STATEMENT]/[PREDICT_DOCSTRING] tags) and click **Annotate**.\n\n"
|
| 147 |
+
"You can also use **🎲 Draw test example** to pull a sample from the test set; the **Baseline (truth)** panel shows the expected annotated result."
|
| 148 |
)
|
| 149 |
|
| 150 |
with gr.Row():
|
|
|
|
| 156 |
)
|
| 157 |
|
| 158 |
reload_btn = gr.Button("Reload result.json", variant="secondary")
|
| 159 |
+
sample_btn = gr.Button("🎲 Draw test example", variant="secondary")
|
| 160 |
+
reload_test_btn = gr.Button("Reload test set", variant="secondary")
|
| 161 |
|
| 162 |
with gr.Row():
|
| 163 |
prefix_box = gr.Code(
|
|
|
|
| 174 |
)
|
| 175 |
|
| 176 |
with gr.Row():
|
| 177 |
+
temperature = gr.Slider(0.0, 1.5, value=0.7, step=0.05, label="Temperature")
|
| 178 |
top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="top_p")
|
| 179 |
max_new = gr.Slider(32, 512, value=128, step=32, label="max_new_tokens")
|
| 180 |
|
| 181 |
+
# Output panels: model vs baseline/truth
|
| 182 |
+
with gr.Row():
|
| 183 |
+
out = gr.Markdown(label="Annotated Rocq")
|
| 184 |
+
truth_md = gr.Markdown(label="Baseline (truth)") # <<< NEW
|
| 185 |
+
|
| 186 |
btn = gr.Button("Annotate", variant="primary")
|
| 187 |
|
| 188 |
# --- wiring ---
|
| 189 |
dropdown.change(set_prefix_from_key, inputs=dropdown, outputs=prefix_box)
|
| 190 |
+
|
| 191 |
# Optional: hot reload result.json without restarting Space
|
| 192 |
def _reload():
|
| 193 |
global PREFIXES, PREFIX_KEYS
|
|
|
|
| 198 |
notice = gr.Markdown("")
|
| 199 |
reload_btn.click(_reload, inputs=None, outputs=[dropdown, notice])
|
| 200 |
|
| 201 |
+
# NEW: wire test set actions
|
| 202 |
+
test_notice = gr.Markdown("")
|
| 203 |
+
sample_btn.click(_sample_test_example, inputs=None, outputs=[prefix_box, target_box, truth_md])
|
| 204 |
+
reload_test_btn.click(_reload_test_set, inputs=None, outputs=test_notice)
|
| 205 |
+
|
| 206 |
btn.click(
|
| 207 |
generate,
|
| 208 |
inputs=[prefix_box, target_box, temperature, top_p, max_new],
|
result.json
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:547fd7e37c43ef05a1681a60192234a31ebb95efad32e829937ebf77ae5140b3
|
| 3 |
+
size 16240662
|