Deano Calver commited on
Commit
ce99e06
·
1 Parent(s): 538c8fa

Restore custom live prompts on benchmark config

Browse files
engines/live_request.py CHANGED
@@ -115,6 +115,9 @@ class LiveRuntimeSettings:
115
  learned_page_selector_prompt_variant: str | None
116
  learned_page_selector_path: str | None
117
  compact_task_name: str | None
 
 
 
118
 
119
 
120
  def canonicalize_benchmark_payload(request: dict[str, Any]) -> dict[str, Any]:
@@ -159,7 +162,6 @@ def resolve_live_runtime_settings(
159
  decode_steps: int,
160
  max_live_context: int,
161
  ) -> LiveRuntimeSettings:
162
- del decode_steps
163
  request = canonicalize_benchmark_payload(request)
164
  model_key = str(request.get("model") or "")
165
  if model_key not in MODEL_BY_KEY:
@@ -191,16 +193,10 @@ def resolve_live_runtime_settings(
191
  raise ValueError("Only the Qwen benchmark-backed live lane is supported in this Space.")
192
 
193
  custom_prompt = str(request.get("custom_prompt") or "").strip()
194
- if custom_prompt:
195
- raise ValueError(
196
- "Live Qwen compare now replays the benchmark rows directly. Custom prompts are disabled until a "
197
- "benchmark-faithful custom lane exists."
198
- )
199
-
200
  preset_key = str(request.get("preset") or "")
201
  if preset_key not in PRESET_BY_KEY:
202
  raise ValueError("Live Qwen compare requires a benchmark-backed preset selection.")
203
- if preset_key == "longbench_mini":
204
  raise ValueError(
205
  "Live LongBench replay is not wired in this Space yet. Preset-backed compare remains the valid benchmark view."
206
  )
@@ -215,10 +211,15 @@ def resolve_live_runtime_settings(
215
  )
216
 
217
  compact_task_name = None
218
- benchmark_decode_steps = 8
219
- if preset_key == "compact_task":
 
 
220
  compact_task_name = _compact_task_name(model_key, context_length)
221
  benchmark_decode_steps = COMPACT_TASK_DECODE_STEPS[compact_task_name]
 
 
 
222
 
223
  return LiveRuntimeSettings(
224
  model_key=model.key,
@@ -241,6 +242,9 @@ def resolve_live_runtime_settings(
241
  learned_page_selector_prompt_variant=variant_config["learned_page_selector_prompt_variant"],
242
  learned_page_selector_path=selector_artifact_path,
243
  compact_task_name=compact_task_name,
 
 
 
244
  )
245
 
246
 
 
115
  learned_page_selector_prompt_variant: str | None
116
  learned_page_selector_path: str | None
117
  compact_task_name: str | None
118
+ prompt_text: str
119
+ use_exact_length_prompt: bool
120
+ is_custom_prompt: bool
121
 
122
 
123
  def canonicalize_benchmark_payload(request: dict[str, Any]) -> dict[str, Any]:
 
162
  decode_steps: int,
163
  max_live_context: int,
164
  ) -> LiveRuntimeSettings:
 
165
  request = canonicalize_benchmark_payload(request)
166
  model_key = str(request.get("model") or "")
167
  if model_key not in MODEL_BY_KEY:
 
193
  raise ValueError("Only the Qwen benchmark-backed live lane is supported in this Space.")
194
 
195
  custom_prompt = str(request.get("custom_prompt") or "").strip()
 
 
 
 
 
 
196
  preset_key = str(request.get("preset") or "")
197
  if preset_key not in PRESET_BY_KEY:
198
  raise ValueError("Live Qwen compare requires a benchmark-backed preset selection.")
199
+ if not custom_prompt and preset_key == "longbench_mini":
200
  raise ValueError(
201
  "Live LongBench replay is not wired in this Space yet. Preset-backed compare remains the valid benchmark view."
202
  )
 
211
  )
212
 
213
  compact_task_name = None
214
+ prompt_text = custom_prompt
215
+ use_exact_length_prompt = False
216
+ benchmark_decode_steps = int(decode_steps or DEFAULT_LIVE_DECODE_STEPS)
217
+ if not custom_prompt and preset_key == "compact_task":
218
  compact_task_name = _compact_task_name(model_key, context_length)
219
  benchmark_decode_steps = COMPACT_TASK_DECODE_STEPS[compact_task_name]
220
+ elif not custom_prompt and preset_key == "backend_truth":
221
+ prompt_text = "Cache locality matters for fast decoding."
222
+ use_exact_length_prompt = True
223
 
224
  return LiveRuntimeSettings(
225
  model_key=model.key,
 
242
  learned_page_selector_prompt_variant=variant_config["learned_page_selector_prompt_variant"],
243
  learned_page_selector_path=selector_artifact_path,
244
  compact_task_name=compact_task_name,
245
+ prompt_text=prompt_text,
246
+ use_exact_length_prompt=use_exact_length_prompt,
247
+ is_custom_prompt=bool(custom_prompt),
248
  )
249
 
250
 
scripts/space_dotcache_runner.py CHANGED
@@ -12,7 +12,7 @@ if str(REPO_ROOT) not in sys.path:
12
 
13
  from benchmarks.bench_qwen35_attention_subset_dotcache_serving import _build_dotcache_config # noqa: E402
14
  from dotcache.integrations.qwen35 import Qwen35AttentionSubsetDotCacheHarness # noqa: E402
15
- from engines.live_request import resolve_live_runtime_settings # noqa: E402
16
  from scripts.run_qwen35_task_selector_compare import _set_selector_prompt_tags, _task_specs # noqa: E402
17
  from scripts.space_runner_common import ( # noqa: E402
18
  configure_model_cache_env,
@@ -176,7 +176,7 @@ def main() -> int:
176
  request = load_request_from_stdin()
177
  settings = resolve_live_runtime_settings(
178
  request,
179
- decode_steps=0,
180
  max_live_context=int(os.getenv("DOTCACHE_SPACE_MAX_LIVE_CONTEXT", "4096")),
181
  )
182
 
@@ -197,7 +197,24 @@ def main() -> int:
197
  weight_quantization=os.getenv("DOTCACHE_SPACE_WEIGHT_QUANTIZATION", "none"),
198
  )
199
 
200
- if settings.benchmark_suite == "compact_task":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  task_spec = _task_prompt_inputs(harness, settings)
202
  input_ids = task_spec["input_ids"]
203
  attention_mask = task_spec["attention_mask"]
@@ -212,10 +229,10 @@ def main() -> int:
212
  decoded_text = decode_generated_text(harness.tokenizer, generated_ids, limit=decode_steps)
213
  scored = dict(task_spec["score_fn"](decoded_text))
214
  text = str(scored.get("task_generated_text_cleaned") or scored.get("task_generated_value") or decoded_text)
215
- elif settings.benchmark_suite == "backend_truth":
216
  input_ids, attention_mask = _build_exact_length_inputs(
217
  harness,
218
- prompt_unit=BACKEND_TRUTH_PROMPT_UNIT,
219
  prompt_length=settings.context_length,
220
  )
221
  decode_steps = int(settings.decode_steps)
 
12
 
13
  from benchmarks.bench_qwen35_attention_subset_dotcache_serving import _build_dotcache_config # noqa: E402
14
  from dotcache.integrations.qwen35 import Qwen35AttentionSubsetDotCacheHarness # noqa: E402
15
+ from engines.live_request import DEFAULT_LIVE_DECODE_STEPS, resolve_live_runtime_settings # noqa: E402
16
  from scripts.run_qwen35_task_selector_compare import _set_selector_prompt_tags, _task_specs # noqa: E402
17
  from scripts.space_runner_common import ( # noqa: E402
18
  configure_model_cache_env,
 
176
  request = load_request_from_stdin()
177
  settings = resolve_live_runtime_settings(
178
  request,
179
+ decode_steps=int(os.getenv("DOTCACHE_SPACE_LIVE_DECODE_STEPS", str(DEFAULT_LIVE_DECODE_STEPS))),
180
  max_live_context=int(os.getenv("DOTCACHE_SPACE_MAX_LIVE_CONTEXT", "4096")),
181
  )
182
 
 
197
  weight_quantization=os.getenv("DOTCACHE_SPACE_WEIGHT_QUANTIZATION", "none"),
198
  )
199
 
200
+ if settings.is_custom_prompt:
201
+ input_ids, attention_mask = harness.tokenize_prompt(settings.prompt_text)
202
+ prompt_length = int(input_ids.shape[1])
203
+ if prompt_length > settings.context_length:
204
+ raise ValueError(
205
+ f"Custom prompt tokenized to {prompt_length} tokens, which exceeds the selected context limit "
206
+ f"of {settings.context_length}. Increase Context length or shorten the prompt."
207
+ )
208
+ decode_steps = int(settings.decode_steps)
209
+ record = harness.run_attention_subset_dotcache_serving(
210
+ input_ids=input_ids,
211
+ attention_mask=attention_mask,
212
+ decode_steps=decode_steps,
213
+ profile_backend=True,
214
+ )
215
+ generated_ids = list(record.get("dotcache_generated_ids") or [])
216
+ text = decode_generated_text(harness.tokenizer, generated_ids, limit=decode_steps)
217
+ elif settings.benchmark_suite == "compact_task":
218
  task_spec = _task_prompt_inputs(harness, settings)
219
  input_ids = task_spec["input_ids"]
220
  attention_mask = task_spec["attention_mask"]
 
229
  decoded_text = decode_generated_text(harness.tokenizer, generated_ids, limit=decode_steps)
230
  scored = dict(task_spec["score_fn"](decoded_text))
231
  text = str(scored.get("task_generated_text_cleaned") or scored.get("task_generated_value") or decoded_text)
232
+ elif settings.use_exact_length_prompt:
233
  input_ids, attention_mask = _build_exact_length_inputs(
234
  harness,
235
+ prompt_unit=settings.prompt_text or BACKEND_TRUTH_PROMPT_UNIT,
236
  prompt_length=settings.context_length,
237
  )
238
  decode_steps = int(settings.decode_steps)
space_app.py CHANGED
@@ -51,7 +51,7 @@ MAX_UI_LOG_LINES = 80
51
  MAX_UI_LOG_CHARS = 12000
52
  MAX_UI_TRACE_ITEMS = 8
53
  MAX_ARENA_MATCHES = 64
54
- CUSTOM_LIVE_PROMPTS_ENABLED = False
55
  LIVE_EXAMPLE_PROMPTS = {
56
  "retrieval": (
57
  "Context:\n"
@@ -1000,10 +1000,9 @@ def _build_request(
1000
  shortlist_policy: str,
1001
  compare_against_dense: bool,
1002
  ) -> DemoRequest:
1003
- normalized_custom_prompt = custom_prompt.strip()
1004
  return DemoRequest(
1005
  model=model,
1006
- preset=None if normalized_custom_prompt else (preset or None),
1007
  custom_prompt=custom_prompt,
1008
  context_length=int(context_length),
1009
  mode=mode,
@@ -1096,7 +1095,7 @@ def _live_context_guard_copy(mode: str) -> str:
1096
  if mode == "custom":
1097
  return (
1098
  "<div class='live-context-note active'>"
1099
- "<strong>⚡ Live mode (ZeroGPU)</strong><span>Your prompt runs live on shared GPU. Context stays limited to <code>512</code> or <code>1024</code> for responsiveness. Expect a short queue delay, and try prompts that depend on earlier text to see differences.</span>"
1100
  "</div>"
1101
  )
1102
  if mode == "benchmark":
@@ -1112,23 +1111,22 @@ def _live_context_guard_copy(mode: str) -> str:
1112
  )
1113
 
1114
 
 
 
 
 
 
 
1115
  def _guard_live_context(prompt_mode: str, custom_prompt: str, current_context_length: int) -> tuple[Any, str]:
1116
  if _is_live_prompt_mode(prompt_mode):
1117
- if not CUSTOM_LIVE_PROMPTS_ENABLED:
1118
- guarded_value = int(current_context_length)
1119
- if guarded_value not in BENCHMARK_LIVE_CONTEXT_CHOICES:
1120
- guarded_value = 2048
1121
- return (
1122
- gr.update(choices=BENCHMARK_LIVE_CONTEXT_CHOICES, value=guarded_value),
1123
- _live_context_guard_copy("benchmark"),
1124
- )
1125
  has_custom_prompt = bool(custom_prompt.strip())
1126
  if has_custom_prompt:
 
1127
  guarded_value = int(current_context_length)
1128
- if guarded_value not in LIVE_SAFE_CONTEXT_CHOICES:
1129
- guarded_value = 1024
1130
  return (
1131
- gr.update(choices=LIVE_SAFE_CONTEXT_CHOICES, value=guarded_value),
1132
  _live_context_guard_copy("custom"),
1133
  )
1134
  guarded_value = int(current_context_length)
@@ -1153,8 +1151,6 @@ def _is_live_prompt_mode(prompt_mode: str) -> bool:
1153
 
1154
 
1155
  def _effective_custom_prompt(prompt_mode: str, custom_prompt: str) -> str:
1156
- if not CUSTOM_LIVE_PROMPTS_ENABLED:
1157
- return ""
1158
  if _is_live_prompt_mode(prompt_mode):
1159
  return custom_prompt
1160
  return ""
 
51
  MAX_UI_LOG_CHARS = 12000
52
  MAX_UI_TRACE_ITEMS = 8
53
  MAX_ARENA_MATCHES = 64
54
+ CUSTOM_LIVE_PROMPTS_ENABLED = True
55
  LIVE_EXAMPLE_PROMPTS = {
56
  "retrieval": (
57
  "Context:\n"
 
1000
  shortlist_policy: str,
1001
  compare_against_dense: bool,
1002
  ) -> DemoRequest:
 
1003
  return DemoRequest(
1004
  model=model,
1005
+ preset=preset or None,
1006
  custom_prompt=custom_prompt,
1007
  context_length=int(context_length),
1008
  mode=mode,
 
1095
  if mode == "custom":
1096
  return (
1097
  "<div class='live-context-note active'>"
1098
+ "<strong>⚡ Live mode (ZeroGPU)</strong><span>Your prompt runs on the real Space system using the selected preset's benchmark configuration. Use this to sanity-check that live behavior stays in the same ballpark as the cached paper row.</span>"
1099
  "</div>"
1100
  )
1101
  if mode == "benchmark":
 
1111
  )
1112
 
1113
 
1114
+ def _available_live_context_choices() -> list[int]:
1115
+ max_live_context = int(os.getenv("DOTCACHE_SPACE_MAX_LIVE_CONTEXT", "4096"))
1116
+ choices = [value for value in FULL_CONTEXT_CHOICES if int(value) <= max_live_context]
1117
+ return choices or [min(max_live_context, 1024)]
1118
+
1119
+
1120
  def _guard_live_context(prompt_mode: str, custom_prompt: str, current_context_length: int) -> tuple[Any, str]:
1121
  if _is_live_prompt_mode(prompt_mode):
 
 
 
 
 
 
 
 
1122
  has_custom_prompt = bool(custom_prompt.strip())
1123
  if has_custom_prompt:
1124
+ available_choices = _available_live_context_choices()
1125
  guarded_value = int(current_context_length)
1126
+ if guarded_value not in available_choices:
1127
+ guarded_value = available_choices[min(len(available_choices) - 1, 1)]
1128
  return (
1129
+ gr.update(choices=available_choices, value=guarded_value),
1130
  _live_context_guard_copy("custom"),
1131
  )
1132
  guarded_value = int(current_context_length)
 
1151
 
1152
 
1153
  def _effective_custom_prompt(prompt_mode: str, custom_prompt: str) -> str:
 
 
1154
  if _is_live_prompt_mode(prompt_mode):
1155
  return custom_prompt
1156
  return ""