divyanshx11 commited on
Commit
5d790ea
·
verified ·
1 Parent(s): 634f6d4

Add runnable 75K+ text-context example

Browse files
README.md CHANGED
@@ -96,6 +96,17 @@ Captured response for this exact image and request:
96
 
97
  The full response is saved as [`output.json`](examples/real-photo/output.json). This is one qualitative example, not an image benchmark or evidence of general image accuracy. The displayed latency came from a CPU smoke run and is not a performance claim.
98
 
 
 
 
 
 
 
 
 
 
 
 
99
  ## What is bundled
100
 
101
  | Component | Route | Notes |
 
96
 
97
  The full response is saved as [`output.json`](examples/real-photo/output.json). This is one qualitative example, not an image benchmark or evidence of general image accuracy. The displayed latency came from a CPU smoke run and is not a performance claim.
98
 
99
+ ## 75K+ text-context example
100
+
101
+ This request builds a long text state and asks JEVision to read a fact from its final record. The runner uses the pinned Qwen3.5 tokenizer and targets a 76,000-token state; the server's `usage.input_tokens` field reports the input-token count for the request it accepts.
102
+
103
+ ```bash
104
+ python run_jevvision.py --text-adapter jevbench-m3 --port 8009
105
+ python examples/long-context/run_demo.py --endpoint http://127.0.0.1:8009
106
+ ```
107
+
108
+ [`input.json`](examples/long-context/input.json) defines the target, generated log format, and typed question. Running [`run_demo.py`](examples/long-context/run_demo.py) creates `state-75k.txt`, submits the text-only request to `/v1/systemone`, and saves the server's returned JSON as `output.json`. This uses the selected text adapter; image-bearing requests use the separate visual route described above.
109
+
110
  ## What is bundled
111
 
112
  | Component | Route | Notes |
examples/long-context/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ /state-75k.txt
2
+ /output.json
examples/long-context/input.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "kev-latest",
3
+ "state_target_tokens": 76000,
4
+ "minimum_request_tokens": 75000,
5
+ "state_file": "state-75k.txt",
6
+ "tokenizer": {
7
+ "repo_id": "Qwen/Qwen3.5-0.8B-Base",
8
+ "revision": "dc7cdfe2ee4154fa7e30f5b51ca41bfa40174e68"
9
+ },
10
+ "state_prefix": "Archived operations log for the Northstar help desk. The following records summarize historical tickets. Use the final audit record to answer the question.\n",
11
+ "record_template": "Record {index:06d} | date=2025-{month:02d}-{day:02d} | team={team} | ticket=TK-{ticket:06d} | status={status} | priority={priority} | note=The customer confirmed the resolution and the support owner recorded the next review in the normal queue.\n",
12
+ "final_record": "FINAL AUDIT RECORD | date=2025-12-31 | verification_code=K7M4 | This is the final record in the archive.\n",
13
+ "questions": {
14
+ "verification_code": {
15
+ "type": "choice",
16
+ "instructions": "Which verification code is recorded in the FINAL AUDIT RECORD at the end of the state?",
17
+ "criteria": {
18
+ "K7M4": "The final audit record contains verification code K7M4.",
19
+ "N2R8": "The final audit record contains verification code N2R8.",
20
+ "not_present": "The final audit record contains no verification code."
21
+ }
22
+ }
23
+ }
24
+ }
examples/long-context/run_demo.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate and submit the bundled 75K+ text-context request to a running JEVision server."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+ from urllib.error import HTTPError, URLError
10
+ from urllib.request import Request, urlopen
11
+
12
+ EXAMPLE_DIR = Path(__file__).resolve().parent
13
+ CONFIG_PATH = EXAMPLE_DIR / "input.json"
14
+ MINIMUM_REQUEST_TOKENS = 75_000
15
+ BATCH_RECORDS = 32
16
+ TEAMS = ("billing", "accounts", "delivery", "returns", "technical")
17
+ STATUSES = ("closed", "resolved", "reviewed", "archived")
18
+ PRIORITIES = ("normal", "standard", "follow-up")
19
+
20
+
21
+ def token_length(tokenizer, text: str) -> int:
22
+ return len(tokenizer.encode(text, add_special_tokens=False))
23
+
24
+
25
+ def make_record(template: str, index: int) -> str:
26
+ return template.format(
27
+ index=index,
28
+ month=(index % 12) + 1,
29
+ day=(index % 28) + 1,
30
+ team=TEAMS[index % len(TEAMS)],
31
+ ticket=index,
32
+ status=STATUSES[index % len(STATUSES)],
33
+ priority=PRIORITIES[index % len(PRIORITIES)],
34
+ )
35
+
36
+
37
+ def make_state(tokenizer, config: dict) -> tuple[str, int]:
38
+ target = int(config["state_target_tokens"])
39
+ minimum = int(config["minimum_request_tokens"])
40
+ prefix = str(config["state_prefix"])
41
+ final_record = str(config["final_record"])
42
+ template = str(config["record_template"])
43
+ records: list[str] = []
44
+ next_index = 1
45
+
46
+ while True:
47
+ for _ in range(BATCH_RECORDS):
48
+ records.append(make_record(template, next_index))
49
+ next_index += 1
50
+
51
+ state = prefix + "".join(records) + final_record
52
+ count = token_length(tokenizer, state)
53
+ if count >= target:
54
+ while count > target and records:
55
+ records.pop()
56
+ state = prefix + "".join(records) + final_record
57
+ count = token_length(tokenizer, state)
58
+ if count < minimum:
59
+ raise RuntimeError(
60
+ f"Could not build the requested long state: {count} tokens; minimum is {minimum}."
61
+ )
62
+ return state, count
63
+
64
+
65
+ def main() -> int:
66
+ parser = argparse.ArgumentParser(description=__doc__)
67
+ parser.add_argument("--endpoint", default="http://127.0.0.1:8009")
68
+ parser.add_argument("--output", type=Path, default=EXAMPLE_DIR / "output.json")
69
+ args = parser.parse_args()
70
+
71
+ config = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
72
+ try:
73
+ from transformers import AutoTokenizer
74
+ except ImportError as exc:
75
+ raise SystemExit("Install the JEVision requirements first (including transformers).") from exc
76
+
77
+ tokenizer_config = config["tokenizer"]
78
+ tokenizer = AutoTokenizer.from_pretrained(
79
+ tokenizer_config["repo_id"],
80
+ revision=tokenizer_config["revision"],
81
+ )
82
+ state, state_tokens = make_state(tokenizer, config)
83
+
84
+ state_path = (EXAMPLE_DIR / config["state_file"]).resolve()
85
+ state_path.relative_to(EXAMPLE_DIR.resolve())
86
+ state_path.write_text(state, encoding="utf-8")
87
+
88
+ payload = {
89
+ "model": config["model"],
90
+ "state": state,
91
+ "questions": config["questions"],
92
+ }
93
+ request = Request(
94
+ args.endpoint.rstrip("/") + "/v1/systemone",
95
+ data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
96
+ headers={"content-type": "application/json"},
97
+ method="POST",
98
+ )
99
+ try:
100
+ with urlopen(request, timeout=1800) as response:
101
+ result = json.loads(response.read().decode("utf-8"))
102
+ except HTTPError as exc:
103
+ raise SystemExit(f"JEVision returned HTTP {exc.code}; no response file was written.") from None
104
+ except URLError as exc:
105
+ raise SystemExit(f"Could not reach the JEVision endpoint ({exc.reason}); no response file was written.") from None
106
+
107
+ usage = result.get("usage") or {}
108
+ accepted_tokens = usage.get("input_tokens")
109
+ if not isinstance(accepted_tokens, int) or accepted_tokens < int(config["minimum_request_tokens"]):
110
+ raise SystemExit(
111
+ "The server response did not report an accepted input of at least "
112
+ f"{config['minimum_request_tokens']} tokens; no response file was written."
113
+ )
114
+
115
+ args.output.parent.mkdir(parents=True, exist_ok=True)
116
+ args.output.write_text(json.dumps(result, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
117
+ print(
118
+ f"Generated state: {state_tokens:,} tokenizer tokens. "
119
+ f"Server-reported request: {accepted_tokens:,} input tokens."
120
+ )
121
+ print(f"Response saved to: {args.output}")
122
+ return 0
123
+
124
+
125
+ if __name__ == "__main__":
126
+ sys.exit(main())