admin commited on
Commit
82d808c
·
verified ·
1 Parent(s): 5e0326f

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +135 -177
app.py CHANGED
@@ -1,7 +1,7 @@
1
  """
2
  Hunter Omega — Live NIAH Demo
3
  One-click needle in a haystack test from 8K to 12M tokens.
4
- Hosted on HuggingFace Spaces.
5
  """
6
  import gradio as gr
7
  import requests
@@ -13,7 +13,6 @@ import os
13
  API_URL = os.environ.get("HUNTER_API")
14
  MODEL = "hunter-omega-12m-fast"
15
 
16
- # Diverse filler paragraphs (no repetition)
17
  FILLERS = [
18
  "The evolution of distributed systems has fundamentally changed how we architect software. Microservices emerged as a response to monolithic limitations, enabling teams to deploy independently and scale specific components. Service meshes handle the complexity of inter-service communication, providing observability and traffic management.",
19
  "Machine learning pipelines require careful orchestration from data ingestion through model deployment. Feature stores centralize feature computation and serving, ensuring consistency between training and inference. MLOps practices bring version control and automated testing to model development workflows.",
@@ -32,9 +31,14 @@ FILLERS = [
32
  "Robotics integrates sensing planning and actuation for autonomous interaction. Simultaneous localization and mapping builds environment models while tracking position. Motion planning finds collision-free paths through configuration spaces.",
33
  ]
34
 
 
 
 
 
 
 
35
 
36
  def generate_needle():
37
- """Generate a random unique passphrase that can't be guessed."""
38
  code = ''.join(random.choices(string.ascii_uppercase, k=4))
39
  nums = ''.join(random.choices(string.digits, k=4))
40
  word = random.choice(["ALPHA", "BRAVO", "DELTA", "ECHO", "FOXTROT", "GOLF", "HOTEL",
@@ -44,7 +48,6 @@ def generate_needle():
44
 
45
 
46
  def generate_haystack(target_tokens):
47
- """Generate diverse filler text of target token count."""
48
  words = []
49
  target_words = target_tokens * 3 // 4
50
  i = 0
@@ -54,178 +57,138 @@ def generate_haystack(target_tokens):
54
  return words[:target_words]
55
 
56
 
57
- def run_niah_native(context_tokens):
58
- """Run NIAH test within native 1M window (direct prompt)."""
 
59
  needle_code = generate_needle()
60
  needle = f"The classified authorization code for Operation Starfall is {needle_code}."
61
  query = "What is the classified authorization code for Operation Starfall? State ONLY the code."
 
62
 
63
  # Generate haystack
64
- words = generate_haystack(context_tokens)
65
- depth = random.randint(10, 90)
66
  insert_pos = int(len(words) * depth / 100)
67
  words.insert(insert_pos, needle)
68
- haystack = " ".join(words)
69
-
70
- actual_words = len(haystack.split())
71
- actual_tokens_est = actual_words * 4 // 3
72
-
73
- # Query the model
74
- t0 = time.time()
75
- try:
76
- r = requests.post(API_URL, json={
77
- "model": MODEL,
78
- "messages": [{"role": "user", "content": haystack + "\n\n" + query}],
79
- "max_tokens": 50,
80
- "temperature": 0,
81
- }, timeout=300)
82
- elapsed = time.time() - t0
83
-
84
- if r.status_code != 200:
85
- return f"Server returned {r.status_code}. Server may be busy, please retry.", "", "", ""
86
-
87
- d = r.json()
88
- answer = d["choices"][0]["message"]["content"]
89
- found = needle_code.lower() in answer.lower()
90
 
91
- status = "FOUND" if found else "NOT FOUND"
92
- result_text = f"""## Result: {"✅ NEEDLE FOUND" if found else "❌ NEEDLE NOT FOUND"}
93
 
94
- **Context:** {actual_tokens_est:,} tokens (~{actual_words:,} words)
95
- **Needle depth:** {depth}%
96
- **Query time:** {elapsed:.1f}s
97
- **Model answer:** {answer[:200]}"""
 
98
 
99
- needle_info = f"""**Hidden needle:** "{needle}"
100
- **Inserted at:** {depth}% depth (position {insert_pos:,} of {actual_words:,} words)
101
- **Passphrase:** {needle_code}"""
102
-
103
- return result_text, needle_info, status, f"{elapsed:.1f}s"
104
-
105
- except requests.exceptions.Timeout:
106
- return "Request timed out. Server may be processing other requests. Please retry.", "", "TIMEOUT", ""
107
- except Exception as e:
108
- return f"Connection error. Server may be busy. Please retry in a moment.", "", "ERROR", ""
109
-
110
-
111
- def run_niah_extended(context_tokens):
112
- """Run NIAH test beyond 1M using the overflow pipeline."""
113
- needle_code = generate_needle()
114
- needle = f"The classified authorization code for Operation Starfall is {needle_code}."
115
- query = "What is the classified authorization code for Operation Starfall? State ONLY the code."
116
-
117
- # Generate document
118
- words = generate_haystack(context_tokens)
119
- depth = random.randint(55, 95) # Always in overflow portion
120
- insert_pos = int(len(words) * depth / 100)
121
- words.insert(insert_pos, needle)
122
- doc = " ".join(words)
123
-
124
- actual_words = len(doc.split())
125
- actual_tokens_est = actual_words * 4 // 3
126
-
127
- user_id = f"demo_{random.randint(100000, 999999)}"
128
- api_base = API_URL.replace("/v1/chat/completions", "")
129
-
130
- # Upload document
131
- t0 = time.time()
132
- try:
133
- r = requests.post(f"{api_base}/v1/documents", json={
134
- "user_id": user_id,
135
- "text": doc,
136
- }, timeout=1800)
137
- upload_time = time.time() - t0
138
-
139
- if r.status_code != 200:
140
- return f"Upload failed ({r.status_code}). Server may be busy.", "", "", ""
141
-
142
- info = r.json()
143
- chunks = info.get("overflow_chunks", 0)
144
-
145
- # Query
146
- t1 = time.time()
147
- r = requests.post(API_URL, json={
148
- "model": MODEL,
149
- "messages": [{"role": "user", "content": query}],
150
- "max_tokens": 50,
151
- "temperature": 0,
152
- "user": user_id,
153
- }, timeout=600)
154
- query_time = time.time() - t1
155
- total_time = time.time() - t0
156
-
157
- # Cleanup
158
- requests.delete(f"{api_base}/v1/documents/{user_id}", timeout=10)
159
-
160
- if r.status_code != 200:
161
- return f"Query failed ({r.status_code}). Server may be busy.", "", "", ""
162
-
163
- d = r.json()
164
- answer = d["choices"][0]["message"]["content"]
165
- found = needle_code.lower() in answer.lower()
166
-
167
- result_text = f"""## Result: {"✅ NEEDLE FOUND" if found else "❌ NEEDLE NOT FOUND"}
168
-
169
- **Context:** {actual_tokens_est:,} tokens (~{actual_words:,} words)
170
- **Overflow chunks:** {chunks}
171
- **Needle depth:** {depth}%
172
- **Index time:** {upload_time:.1f}s
173
- **Query time:** {query_time:.1f}s
174
- **Total time:** {total_time:.1f}s
175
- **Model answer:** {answer[:200]}"""
176
-
177
- needle_info = f"""**Hidden needle:** "{needle}"
178
- **Inserted at:** {depth}% depth (position {insert_pos:,} of {actual_words:,} words)
179
- **Passphrase:** {needle_code}"""
180
-
181
- return result_text, needle_info, "FOUND" if found else "NOT FOUND", f"{total_time:.1f}s"
182
-
183
- except requests.exceptions.Timeout:
184
- requests.delete(f"{api_base}/v1/documents/{user_id}", timeout=10)
185
- return "Request timed out. Large documents take time to index. Please retry.", "", "TIMEOUT", ""
186
- except Exception as e:
187
- return f"Connection error. Server may be busy.", "", "ERROR", ""
188
 
 
189
 
190
- def run_test(context_size):
191
- """Main test function called by Gradio."""
192
- size_map = {
193
- "8K": 8000,
194
- "32K": 32000,
195
- "64K": 64000,
196
- "128K": 128000,
197
- "256K": 256000,
198
- "512K": 512000,
199
- "1M": 1000000,
200
- "1.5M": 1500000,
201
- "3M": 3000000,
202
- "6M": 6000000,
203
- "12M": 12000000,
204
- }
205
-
206
- tokens = size_map.get(context_size, 128000)
207
 
208
  if tokens <= 1000000:
209
- return run_niah_native(tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  else:
211
- return run_niah_extended(tokens)
212
-
213
-
214
- # Build Gradio interface
215
- with gr.Blocks(title="Hunter Omega — Live NIAH Demo", theme=gr.themes.Soft()) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  gr.Markdown("""
217
- # Hunter Omega — Live Needle in a Haystack Demo
218
 
219
- **Test it yourself.** Pick a context length, click the button. The app generates a random document,
220
- hides a random passphrase at a random depth, and the model finds it.
 
 
 
 
221
 
222
- You control nothing about the needle. It's random every time. Run it as many times as you want.
223
 
224
- **8K to 1M:** Native full attention window. Instant results.
225
- **1.5M to 12M:** Extended context via overflow pipeline. Larger sizes take longer to index.
226
 
227
- *Running on a single GPU cluster. If the server is busy, responses may be delayed. This is a capacity
228
- limitation, not an accuracy issue.*
229
  """)
230
 
231
  with gr.Row():
@@ -236,33 +199,28 @@ limitation, not an accuracy issue.*
236
  )
237
  run_btn = gr.Button("Find the Needle", variant="primary", size="lg")
238
 
239
- with gr.Row():
240
- with gr.Column():
241
- result_output = gr.Markdown(label="Result")
242
- with gr.Column():
243
- needle_output = gr.Markdown(label="Hidden Needle (revealed after test)")
244
 
245
  with gr.Row():
246
- status_output = gr.Textbox(label="Status", interactive=False)
247
- time_output = gr.Textbox(label="Time", interactive=False)
 
 
248
 
249
  gr.Markdown("""
250
  ---
251
- **Estimated wait times:**
252
-
253
- | Size | Index Time | Query Time | Total |
254
- |:----:|:----------:|:----------:|:-----:|
255
- | 8K - 1M | None (native) | 1-90s | 1-90s |
256
- | 1.5M | ~1 min | ~16s | ~1.5 min |
257
- | 3M | ~3 min | ~16s | ~3.5 min |
258
- | 6M | ~5 min | ~16s | ~6 min |
259
- | 12M | ~13 min | ~90s | ~14 min |
260
 
261
- If multiple users are testing, requests queue. The model processes them in order. Your request will complete, it may just take longer.
 
 
 
 
 
 
 
262
 
263
- **How this works:** A random passphrase is generated and hidden at a random depth in diverse technical
264
- filler text. The model is asked to retrieve the exact passphrase. No keyword hints in the query.
265
- The passphrase and its location are revealed after the test so you can verify.
266
 
267
  [Full benchmarks and methodology](https://github.com/SovNodeAI/hunter-omega-benchmarks)
268
  """)
@@ -270,7 +228,7 @@ The passphrase and its location are revealed after the test so you can verify.
270
  run_btn.click(
271
  fn=run_test,
272
  inputs=[context_dropdown],
273
- outputs=[result_output, needle_output, status_output, time_output],
274
  )
275
 
276
 
 
1
  """
2
  Hunter Omega — Live NIAH Demo
3
  One-click needle in a haystack test from 8K to 12M tokens.
4
+ Shows the needle BEFORE querying so users can verify it's not rigged.
5
  """
6
  import gradio as gr
7
  import requests
 
13
  API_URL = os.environ.get("HUNTER_API")
14
  MODEL = "hunter-omega-12m-fast"
15
 
 
16
  FILLERS = [
17
  "The evolution of distributed systems has fundamentally changed how we architect software. Microservices emerged as a response to monolithic limitations, enabling teams to deploy independently and scale specific components. Service meshes handle the complexity of inter-service communication, providing observability and traffic management.",
18
  "Machine learning pipelines require careful orchestration from data ingestion through model deployment. Feature stores centralize feature computation and serving, ensuring consistency between training and inference. MLOps practices bring version control and automated testing to model development workflows.",
 
31
  "Robotics integrates sensing planning and actuation for autonomous interaction. Simultaneous localization and mapping builds environment models while tracking position. Motion planning finds collision-free paths through configuration spaces.",
32
  ]
33
 
34
+ SIZE_MAP = {
35
+ "8K": 8000, "32K": 32000, "64K": 64000, "128K": 128000,
36
+ "256K": 256000, "512K": 512000, "1M": 1000000,
37
+ "1.5M": 1500000, "3M": 3000000, "6M": 6000000, "12M": 12000000,
38
+ }
39
+
40
 
41
  def generate_needle():
 
42
  code = ''.join(random.choices(string.ascii_uppercase, k=4))
43
  nums = ''.join(random.choices(string.digits, k=4))
44
  word = random.choice(["ALPHA", "BRAVO", "DELTA", "ECHO", "FOXTROT", "GOLF", "HOTEL",
 
48
 
49
 
50
  def generate_haystack(target_tokens):
 
51
  words = []
52
  target_words = target_tokens * 3 // 4
53
  i = 0
 
57
  return words[:target_words]
58
 
59
 
60
+ def run_test(context_size):
61
+ """Streaming test: shows needle first, then queries, then shows result."""
62
+ tokens = SIZE_MAP.get(context_size, 128000)
63
  needle_code = generate_needle()
64
  needle = f"The classified authorization code for Operation Starfall is {needle_code}."
65
  query = "What is the classified authorization code for Operation Starfall? State ONLY the code."
66
+ depth = random.randint(10, 90) if tokens <= 1000000 else random.randint(55, 95)
67
 
68
  # Generate haystack
69
+ words = generate_haystack(tokens)
 
70
  insert_pos = int(len(words) * depth / 100)
71
  words.insert(insert_pos, needle)
72
+ actual_words = len(words)
73
+ actual_tokens = actual_words * 4 // 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ # STEP 1: Show what we're about to test
76
+ setup_text = f"""## Step 1: Test Setup
77
 
78
+ **Context size:** {actual_tokens:,} tokens (~{actual_words:,} words)
79
+ **Generated needle:** `{needle_code}`
80
+ **Full needle sentence:** "{needle}"
81
+ **Hidden at:** {depth}% depth (word position {insert_pos:,} of {actual_words:,})
82
+ **Query:** "{query}"
83
 
84
+ The needle is now embedded in {actual_tokens:,} tokens of diverse technical text.
85
+ The model has never seen this passphrase before. It was just generated randomly.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ ---
88
 
89
+ ## Step 2: Querying model..."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  if tokens <= 1000000:
92
+ # Native window: direct prompt
93
+ haystack = " ".join(words)
94
+ yield setup_text, "", "QUERYING...", ""
95
+
96
+ t0 = time.time()
97
+ try:
98
+ r = requests.post(API_URL, json={
99
+ "model": MODEL,
100
+ "messages": [{"role": "user", "content": haystack + "\n\n" + query}],
101
+ "max_tokens": 50,
102
+ "temperature": 0,
103
+ }, timeout=300)
104
+ elapsed = time.time() - t0
105
+
106
+ if r.status_code != 200:
107
+ yield setup_text, "", "ERROR", f"Server returned {r.status_code}"
108
+ return
109
+
110
+ answer = r.json()["choices"][0]["message"]["content"]
111
+ found = needle_code.lower() in answer.lower()
112
+
113
+ except requests.exceptions.Timeout:
114
+ yield setup_text, "", "TIMEOUT", "Server busy, please retry"
115
+ return
116
+ except Exception:
117
+ yield setup_text, "", "ERROR", "Connection error, please retry"
118
+ return
119
  else:
120
+ # Overflow pipeline
121
+ doc = " ".join(words)
122
+ user_id = f"demo_{random.randint(100000, 999999)}"
123
+ api_base = API_URL.replace("/v1/chat/completions", "")
124
+
125
+ yield setup_text + "\n\n*Indexing large document...*", "", "INDEXING...", ""
126
+
127
+ t0 = time.time()
128
+ try:
129
+ r = requests.post(f"{api_base}/v1/documents", json={
130
+ "user_id": user_id, "text": doc,
131
+ }, timeout=1800)
132
+ index_time = time.time() - t0
133
+ info = r.json()
134
+ chunks = info.get("overflow_chunks", 0)
135
+
136
+ yield setup_text + f"\n\n*Indexed {chunks} chunks in {index_time:.0f}s. Querying...*", "", "QUERYING...", ""
137
+
138
+ t1 = time.time()
139
+ r = requests.post(API_URL, json={
140
+ "model": MODEL,
141
+ "messages": [{"role": "user", "content": query}],
142
+ "max_tokens": 50,
143
+ "temperature": 0,
144
+ "user": user_id,
145
+ }, timeout=600)
146
+ elapsed = time.time() - t0
147
+ answer = r.json()["choices"][0]["message"]["content"]
148
+ found = needle_code.lower() in answer.lower()
149
+
150
+ requests.delete(f"{api_base}/v1/documents/{user_id}", timeout=10)
151
+
152
+ except requests.exceptions.Timeout:
153
+ requests.delete(f"{api_base}/v1/documents/{user_id}", timeout=10)
154
+ yield setup_text, "", "TIMEOUT", "Large doc timed out, please retry"
155
+ return
156
+ except Exception:
157
+ yield setup_text, "", "ERROR", "Connection error"
158
+ return
159
+
160
+ # STEP 3: Show result
161
+ result_text = f"""## Step 3: Result {"✅ NEEDLE FOUND" if found else "❌ NOT FOUND"}
162
+
163
+ **Expected:** `{needle_code}`
164
+ **Model returned:** `{answer.strip()}`
165
+ **Match:** {"YES" if found else "NO"}
166
+ **Time:** {elapsed:.1f}s
167
+
168
+ {"The model correctly retrieved the randomly generated passphrase from " + f"{actual_tokens:,} tokens of text." if found else "The model did not find the needle."}"""
169
+
170
+ full_output = setup_text + "\n\n---\n\n" + result_text
171
+
172
+ yield full_output, "", "FOUND" if found else "MISSED", f"{elapsed:.1f}s"
173
+
174
+
175
+ # Build interface
176
+ with gr.Blocks(title="Hunter Omega — Live NIAH Demo") as demo:
177
  gr.Markdown("""
178
+ # Hunter Omega — Live Needle in a Haystack
179
 
180
+ **How this works:**
181
+ 1. You pick a context length
182
+ 2. The app generates a random passphrase and hides it at a random depth
183
+ 3. You see the passphrase and its position BEFORE the model runs
184
+ 4. The model searches the document and returns what it found
185
+ 5. You verify it matches
186
 
187
+ Nothing is pre-arranged. The passphrase is generated fresh every time. Run it as many times as you want.
188
 
189
+ **8K to 1M:** Native full attention. **1.5M to 12M:** Extended context engine.
 
190
 
191
+ *Running on a single GPU cluster. If busy, responses may queue. This is capacity, not accuracy.*
 
192
  """)
193
 
194
  with gr.Row():
 
199
  )
200
  run_btn = gr.Button("Find the Needle", variant="primary", size="lg")
201
 
202
+ output = gr.Markdown(label="Test Progress")
 
 
 
 
203
 
204
  with gr.Row():
205
+ status_box = gr.Textbox(label="Status", interactive=False)
206
+ time_box = gr.Textbox(label="Time", interactive=False)
207
+
208
+ hidden = gr.Textbox(visible=False)
209
 
210
  gr.Markdown("""
211
  ---
212
+ **Estimated times:**
 
 
 
 
 
 
 
 
213
 
214
+ | Size | Time |
215
+ |:----:|:----:|
216
+ | 8K - 128K | 2-8s |
217
+ | 256K - 512K | 10-30s |
218
+ | 1M | 60-90s |
219
+ | 1.5M - 3M | 1-4 min |
220
+ | 6M | 5-6 min |
221
+ | 12M | 13-15 min |
222
 
223
+ If multiple users are testing, requests queue behind each other.
 
 
224
 
225
  [Full benchmarks and methodology](https://github.com/SovNodeAI/hunter-omega-benchmarks)
226
  """)
 
228
  run_btn.click(
229
  fn=run_test,
230
  inputs=[context_dropdown],
231
+ outputs=[output, hidden, status_box, time_box],
232
  )
233
 
234