theostos commited on
Commit
6ada464
·
1 Parent(s): eff999f

Add draw from test set, pull fp8 model

Browse files
Files changed (4) hide show
  1. .gitattributes +2 -0
  2. app.py +68 -10
  3. result.json +0 -0
  4. 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, FineGrainedFP8Config, TextIteratorStreamer
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", # load base weights in their optimal dtype
32
- quantization_config=quant_config, # <-- FP8 quantization
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.2, step=0.05, label="Temperature")
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
- out = gr.Markdown(label="Annotated Rocq")
 
 
 
 
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