Download code/offload/gb10_budget/window_cells.py from ProprietaryLegal/dsv41-sampled-drafting: direct link, hf CLI and curl.
- Browser
- Download file 24.3 kB
-
https://huggingface.co/ProprietaryLegal/dsv41-sampled-drafting/resolve/main/code/offload/gb10_budget/window_cells.py
- Command line
-
hf download hf://ProprietaryLegal/dsv41-sampled-drafting/code/offload/gb10_budget/window_cells.py
-
curl -L -o window_cells.py https://huggingface.co/ProprietaryLegal/dsv41-sampled-drafting/resolve/main/code/offload/gb10_budget/window_cells.py
24.3 kB
| """SP1-WINDOW cell driver: build public prompts once, then run one control or profiled cell per invocation. | |
| Coordinator-only: offload/launch/windows/sp1_window.py calls it inside the HOLD through the owned tunnel 127.0.0.1:18001. | |
| Without --execute it prints the cell plan and touches nothing. It records numbers and hashes only: no prompt or generated | |
| text is written. Profiling uses vLLM's own /start_profile and /stop_profile (both TP ranks, collective RPC); a capture | |
| starts only if the latest 1 s telemetry of both Sparks shows MemAvailable >= the capture floor, otherwise it is recorded | |
| SKIPPED_MEMORY and the request still runs. See offload/gb10_budget/PROFILE-WINDOW-DESIGN.md. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| import os | |
| import threading | |
| import time | |
| import urllib.request | |
| from collections.abc import Callable, Iterable, Iterator | |
| from concurrent.futures import Future, ThreadPoolExecutor | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| from typing import Protocol, cast | |
| from offload.gb10_budget.capture import control, load_bench | |
| from offload.prefill_maxlen.evidence import Json, number, record | |
| from offload.prefill_trace.window_requests import HEADER, TEMPLATE, corpus, stream_summary | |
| URL = 'http://127.0.0.1:18001' | |
| CAP = 327680 | |
| TOLERANCE = .02 # built prompt: target*(1 - TOLERANCE) <= tokens <= target | |
| MAX_COUNT_CALLS = 4 # /tokenize calls per prompt (PF1's bisection used 20-23; its dips reached 4.17 GiB) | |
| FIRST_RATIO = 3.3 # characters per token, first guess (bench2 build_real) | |
| SETTLE_S = 2.0 # decode capture starts this long after every stream emitted | |
| DECODE_S = 3.0 # explicit stop after this; the profiler stops itself after 16 iterations first | |
| PREFILL_S = 5.0 # 2-3 chunks of 4,092 tokens at ~1.85 s each | |
| LATE_DELAY_S = 50.0 # 150K TTFT is 68.9-71.2 s (MEASURED PF1 W1/W3 off-327) | |
| TTFT_TIMEOUT_S = 600.0 | |
| TELEMETRY_AGE_S = 3.0 | |
| class Prompt: | |
| key: str | |
| target: int | |
| offset: int # characters into the corpus body (after HEADER) | |
| # Distinct, far-apart corpus offsets (11.8 M characters): no two cells send the same text. | |
| PROMPTS = {p.key: p for p in ( | |
| Prompt('warm-32k', 32000, 9_000_000), Prompt('short', 1024, 0), | |
| Prompt('32k-0', 32000, 1_000_000), Prompt('32k-1', 32000, 1_500_000), Prompt('32k-2', 32000, 2_000_000), | |
| Prompt('32k-3', 32000, 2_500_000), Prompt('150k', 150000, 4_000_000))} | |
| class Cell: | |
| name: str | |
| prompts: tuple[str, ...] | |
| captures: tuple[str, ...] = () | |
| max_tokens: int = 1500 | |
| warmup: bool = False | |
| estimate_s: float = 60 | |
| late: int = 0 # WIN2: the last `late` prompts arrive only after every earlier stream is decoding | |
| def __post_init__(self) -> None: | |
| if not 0 <= self.late < len(self.prompts) or (self.late and (self.captures or self.warmup)): | |
| raise ValueError(f'{self.name}: late arrivals need >= 1 early stream and no captures/warm-up') | |
| def batch(self) -> int: | |
| return len(self.prompts) | |
| B4 = ('32k-0', '32k-1', '32k-2', '32k-3') | |
| CELLS = {c.name: c for c in ( | |
| Cell('warmup', ('warm-32k',), max_tokens=64, warmup=True, estimate_s=60), | |
| Cell('ctl-short-b1', ('short',), estimate_s=60), | |
| Cell('ctl-32k-b1', ('32k-0',), estimate_s=90), | |
| Cell('ctl-32k-b4', B4, estimate_s=180), | |
| Cell('ctl-150k-b1', ('150k',), estimate_s=180), | |
| Cell('prof-short-b1', ('short',), ('decode',), estimate_s=120), | |
| Cell('prof-32k-b1', ('32k-0',), ('prefill-early', 'decode'), estimate_s=150), | |
| Cell('prof-32k-b4', B4, ('decode',), estimate_s=240), | |
| Cell('prof-150k-b1', ('150k',), ('prefill-late', 'decode'), estimate_s=240), | |
| # WIN2 (Fable review): multi-user and long-answer controls; not in ORDER, so existing windows are unchanged. | |
| # mixed: three 32K decoders start (MEASURED 32K B1 TTFT ~14.5-15.4 s each; B3 contends), the 150K document arrives | |
| # only after all three are decoding (MEASURED 150K TTFT 69 s alone, 117 s beside two decoders in PC1): ~300 s. | |
| Cell('ctl-mixed150k-4user', ('32k-1', '32k-2', '32k-3', '150k'), late=1, estimate_s=300), | |
| # long answer: 5,000 tokens at MEASURED 51-57 tok/s B1 decode ~ 90-100 s plus a short prefill: 180 s bound. | |
| Cell('ctl-long-5k', ('short',), max_tokens=5000, estimate_s=180))} | |
| WIN2_CELLS = ('ctl-mixed150k-4user', 'ctl-long-5k') # opt-in by name only | |
| ORDER = tuple(n for n in CELLS if n not in WIN2_CELLS) | |
| CAPTURE_KINDS = ('decode', 'prefill-early', 'prefill-late') | |
| def body(materials: str) -> str: | |
| if not materials.startswith(HEADER): | |
| raise ValueError('corpus no longer starts with the benchmark header') | |
| return materials[len(HEADER):] | |
| def render(materials: str, offset: int, chars: int) -> str: | |
| text = body(materials) | |
| if offset < 0 or chars < 1 or offset + chars > len(text): | |
| raise ValueError('prompt cut outside the public corpus; never repeat filler') | |
| return HEADER + text[offset:offset + chars] | |
| def cut(materials: str, prompt: Prompt, count: Callable[[str], int]) -> tuple[int, int]: | |
| """(characters, tokens) with target*(1-TOLERANCE) <= tokens <= target in at most MAX_COUNT_CALLS /tokenize calls.""" | |
| chars = int(prompt.target * FIRST_RATIO) | |
| low = prompt.target * (1 - TOLERANCE) | |
| for _ in range(MAX_COUNT_CALLS): | |
| n = count(render(materials, prompt.offset, chars)) | |
| if n < 1: | |
| raise ValueError('tokenizer returned no tokens') | |
| if low <= n <= prompt.target: | |
| return chars, n | |
| chars = max(1, int(chars * prompt.target / n * (1 - TOLERANCE / 2))) # aim at the middle of the band | |
| raise ValueError(f'{prompt.key}: no {prompt.target}-token cut within {MAX_COUNT_CALLS} /tokenize calls; window stops') | |
| class Counters(Protocol): | |
| """bench2's /metrics parser and speculative-counter delta (reused, not copied).""" | |
| def parse_metrics(self, text: str) -> dict[str, float]: ... | |
| def spec_delta(self, before: dict[str, float], after: dict[str, float]) -> dict[str, Json]: ... | |
| class Api(Protocol): | |
| def tokens(self, text: str) -> int: ... | |
| def metrics(self) -> str: ... | |
| def model(self) -> dict[str, Json]: ... | |
| def stream(self, body: dict[str, Json], first: threading.Event) -> dict[str, Json]: ... | |
| def profile(self, verb: str) -> None: ... | |
| def first_signal(lines: Iterable[bytes], first: threading.Event) -> Iterator[bytes]: | |
| """Pass SSE lines through unchanged; set `first` at the first reasoning/answer piece.""" | |
| for raw in lines: | |
| if not first.is_set() and raw.startswith(b'data:') and raw[5:].strip() != b'[DONE]': | |
| obj = record(cast(Json, json.loads(raw[5:].strip()))) | |
| choices = obj.get('choices') or [] | |
| for choice in choices if isinstance(choices, list) else []: | |
| delta = record(record(choice).get('delta') or {}) | |
| if delta.get('reasoning_content') or delta.get('reasoning') or delta.get('content'): | |
| first.set() | |
| yield raw | |
| class Http: | |
| def __init__(self, url: str) -> None: | |
| self.url = url | |
| self.served: dict[str, Json] | None = None | |
| def post(self, endpoint: str, body: dict[str, Json]) -> dict[str, Json]: | |
| req = urllib.request.Request(self.url + endpoint, json.dumps(body).encode(), {'Content-Type': 'application/json'}) | |
| with urllib.request.urlopen(req, timeout=900) as response: | |
| return record(cast(Json, json.load(response))) | |
| def model(self) -> dict[str, Json]: | |
| if self.served is None: | |
| with urllib.request.urlopen(self.url + '/v1/models', timeout=10) as response: | |
| models = record(cast(Json, json.load(response)))['data'] | |
| if not isinstance(models, list) or len(models) != 1: | |
| raise ValueError('expected one served target') | |
| self.served = record(models[0]) | |
| return self.served | |
| def tokens(self, text: str) -> int: | |
| result = self.post('/tokenize', {'model': self.model()['id'], 'messages': [{'role': 'user', 'content': text}], | |
| 'add_generation_prompt': True, 'chat_template_kwargs': TEMPLATE}) | |
| return int(number(result['count'])) | |
| def metrics(self) -> str: | |
| with urllib.request.urlopen(self.url + '/metrics', timeout=10) as response: | |
| return str(response.read().decode()) | |
| def stream(self, body: dict[str, Json], first: threading.Event) -> dict[str, Json]: | |
| req = urllib.request.Request(self.url + '/v1/chat/completions', json.dumps(body).encode(), | |
| {'Content-Type': 'application/json'}) | |
| started = time.monotonic() | |
| with urllib.request.urlopen(req, timeout=900) as response: | |
| return stream_summary(first_signal(response, first), started) | |
| def profile(self, verb: str) -> None: | |
| control(self.url, verb) | |
| def busy(text: str) -> float: | |
| total, seen = 0.0, set() | |
| for line in text.splitlines(): | |
| for name in ('vllm:num_requests_running', 'vllm:num_requests_waiting'): | |
| if line.startswith((name + '{', name + ' ')): | |
| total += float(line.split()[-1]) | |
| seen.add(name) | |
| if len(seen) != 2: | |
| raise ValueError('metrics lack the request gauges') | |
| return total | |
| def running(text: str) -> float: | |
| """vllm:num_requests_running only (admitted requests), for late-arrival overlap proof.""" | |
| values = [float(line.split()[-1]) for line in text.splitlines() | |
| if line.startswith(('vllm:num_requests_running{', 'vllm:num_requests_running '))] | |
| if not values: | |
| raise ValueError('metrics lack vllm:num_requests_running') | |
| return sum(values) | |
| def latest_memory(paths: list[Path], now: Callable[[], float] = time.time) -> dict[str, int]: | |
| """MemAvailable (kB) from the runner's 1 s telemetry files; refuses a stale or missing sample.""" | |
| found: dict[str, int] = {} | |
| for path in paths: | |
| if now() - path.stat().st_mtime > TELEMETRY_AGE_S: | |
| raise RuntimeError(f'{path.name}: telemetry older than {TELEMETRY_AGE_S:g} s; capture floor cannot be checked') | |
| rows = [record(cast(Json, json.loads(x))) for x in path.read_text().splitlines()[-8:] if x.startswith('{')] | |
| memory = [r for r in rows if r.get('kind') == 'memory'] | |
| if not memory: | |
| raise RuntimeError(f'{path.name}: no recent memory sample') | |
| found[path.name] = int(number(record(memory[-1]['kb'])['MemAvailable'])) | |
| return found | |
| class Plan: | |
| deadline: float | |
| floor_kb: int | |
| telemetry: list[Path] | |
| salt_prefix: str | |
| ledger: Path | None = None | |
| def salt(prefix: str, cell: str, stream: int) -> str: | |
| if not prefix or not cell: | |
| raise ValueError('invalid cache salt identity') | |
| return f'{prefix}:{cell}:{stream}' | |
| def run_cell(api: Api, cell: Cell, texts: dict[str, tuple[str, int]], plan: Plan, *, | |
| sleep: Callable[[float], None] = time.sleep, clock: Callable[[], float] = time.monotonic, | |
| wall: Callable[[], float] = time.time, cap: int = CAP, late_delay_s: float = LATE_DELAY_S) -> dict[str, Json]: | |
| """One cell. Captures always stop in `finally`; a stream failure propagates after the stop. `cap` and `late_delay_s` | |
| are PF2-LOWKV's (524,288; mid-prompt at 35 s); SP1 uses the defaults.""" | |
| if wall() + cell.estimate_s > plan.deadline: | |
| raise RuntimeError(f'window submission deadline reached: {cell.name} does not fit') | |
| model = api.model() | |
| if model.get('max_model_len') != cap: | |
| raise ValueError('served cap differs from the profiled arm') | |
| if busy(api.metrics()): | |
| raise RuntimeError('serve not verified idle before the cell') | |
| bench = cast(Counters, load_bench()) | |
| before = bench.parse_metrics(api.metrics()) | |
| origin = clock() | |
| captures: list[dict[str, Json]] = [] | |
| firsts = [threading.Event() for _ in cell.prompts] | |
| submitted: list[float] = [0.0] * cell.batch | |
| early = cell.batch - cell.late | |
| barrier = threading.Barrier(early) | |
| late: dict[str, Json] = {} | |
| def event(row: dict[str, Json]) -> None: | |
| if plan.ledger is not None: | |
| with plan.ledger.open('a') as handle: | |
| handle.write(json.dumps({**row, 'cell': cell.name, 'time': wall()}) + '\n') | |
| def request(i: int) -> dict[str, Json]: | |
| key = cell.prompts[i] | |
| text, tokens = texts[key] | |
| cache = salt(plan.salt_prefix, cell.name, i) | |
| body: dict[str, Json] = {'model': model['id'], 'messages': [{'role': 'user', 'content': text}], | |
| 'max_tokens': cell.max_tokens, 'temperature': 1.0, 'top_p': 1.0, 'seed': 42, | |
| 'priority': 10, 'cache_salt': cache, 'chat_template_kwargs': TEMPLATE, | |
| 'stream': True, 'stream_options': {'include_usage': True}} | |
| if cell.warmup: | |
| body['ignore_eos'] = True | |
| if i < early: | |
| barrier.wait(timeout=30) | |
| submitted[i] = clock() - origin | |
| event({'event': 'send', 'stream': i}) | |
| try: | |
| summary = api.stream(body, firsts[i]) | |
| except BaseException as exc: | |
| event({'event': 'failed', 'stream': i, 'error_class': type(exc).__name__}) | |
| raise | |
| event({'event': 'completed', 'stream': i}) | |
| usage = record(summary['usage']) | |
| cached = record(usage.get('prompt_tokens_details') or {}).get('cached_tokens') | |
| if usage.get('prompt_tokens') != tokens or cached is None or number(cached) != 0: | |
| raise ValueError('usage differs from the built prompt or a fresh salt hit the cache') | |
| if cell.warmup and (usage.get('completion_tokens') != cell.max_tokens or summary.get('finish') != 'length'): | |
| raise ValueError('warm-up did not generate its forced length') | |
| response = summary.pop('response_id') | |
| return {'stream': i, 'prompt': key, 'prompt_tokens': tokens, 'submitted_rel_s': submitted[i], | |
| 'prompt_sha256': hashlib.sha256(text.encode()).hexdigest(), | |
| 'cache_salt_sha256': hashlib.sha256(cache.encode()).hexdigest(), | |
| 'response_id_sha256': hashlib.sha256(str(response).encode()).hexdigest(), | |
| 'sampling': {'temperature': 1, 'top_p': 1, 'seed': 42, 'priority': 10, 'max_tokens': cell.max_tokens}, | |
| **summary} | |
| futures: list[Future[dict[str, Json]]] = [] | |
| def submit() -> None: | |
| futures.extend(pool.submit(request, i) for i in range(early)) | |
| if cell.late: | |
| arrive_late() | |
| def arrive_late() -> None: | |
| """Late streams start only after every early stream is decoding, and must be admitted beside them.""" | |
| end = clock() + TTFT_TIMEOUT_S | |
| while not all(firsts[i].is_set() for i in range(early)): | |
| check_failed() | |
| if ended(): | |
| raise RuntimeError('an early stream ended before every early stream reached decode') | |
| if clock() >= end: | |
| raise TimeoutError('early streams did not all reach decode before the TTFT bound') | |
| sleep(.02) | |
| settle = clock() + SETTLE_S | |
| while clock() < settle: | |
| check_failed() | |
| sleep(.05) | |
| if ended(): | |
| raise RuntimeError('an early stream finished before the late arrival') | |
| late['submitted_rel_s'] = clock() - origin | |
| futures.extend(pool.submit(request, i) for i in range(early, cell.batch)) | |
| end = clock() + TTFT_TIMEOUT_S | |
| while True: | |
| check_failed() | |
| if any(f.done() for f in futures[:early]): | |
| raise RuntimeError('a decoder finished before the late arrival was admitted beside it') | |
| if running(api.metrics()) >= cell.batch: | |
| late['admitted_rel_s'] = clock() - origin | |
| late['overlap'] = True | |
| return | |
| if clock() >= end: | |
| raise TimeoutError('late arrival was never admitted beside the live decoders') | |
| sleep(.05) | |
| def ended() -> bool: | |
| return any(f.done() for f in futures) | |
| def check_failed() -> None: | |
| for f in futures: | |
| if f.done(): | |
| f.result() # propagate a stream failure instead of waiting for a bound | |
| def capture(kind: str, then: Callable[[], None] | None = None) -> None: | |
| """Memory floor, start, optional action (submission), bounded wait, ALWAYS stop once started.""" | |
| row: dict[str, Json] = {'kind': kind} | |
| captures.append(row) | |
| memory = latest_memory(plan.telemetry) | |
| row['mem_available_kb'] = cast(Json, memory) | |
| if min(memory.values()) < plan.floor_kb: | |
| row['status'] = 'SKIPPED_MEMORY' | |
| if then is not None: | |
| then() | |
| return | |
| row['start_call_rel_s'] = clock() - origin | |
| api.profile('start_profile') | |
| row['start_return_rel_s'] = clock() - origin | |
| row['start_wall'] = wall() | |
| try: | |
| if then is not None: | |
| then() | |
| end = clock() + (DECODE_S if kind == 'decode' else PREFILL_S) | |
| while clock() < end and not ended(): | |
| sleep(.05) | |
| row['status'] = ('MIXED' if kind != 'decode' and any(f.is_set() for f in firsts) else # never "prefill" | |
| 'ENDED' if ended() else 'TAKEN') | |
| finally: | |
| row['stop_call_rel_s'] = clock() - origin | |
| api.profile('stop_profile') | |
| row['stop_return_rel_s'] = clock() - origin | |
| row['stop_wall'] = wall() | |
| with ThreadPoolExecutor(max_workers=cell.batch) as pool: | |
| try: | |
| if 'prefill-early' in cell.captures: | |
| capture('prefill-early', submit) # the first chunks are the first iterations recorded | |
| else: | |
| submit() | |
| if 'prefill-late' in cell.captures: | |
| end = clock() + late_delay_s | |
| while clock() < end: | |
| check_failed() | |
| if ended(): | |
| raise RuntimeError('stream ended before the late prefill capture') | |
| sleep(.05) | |
| if any(f.is_set() for f in firsts): | |
| raise RuntimeError('decode already started; a late prefill capture would be mislabelled') | |
| capture('prefill-late') | |
| if 'decode' in cell.captures: | |
| end = clock() + TTFT_TIMEOUT_S | |
| while not all(f.is_set() for f in firsts): | |
| check_failed() | |
| if ended(): | |
| raise RuntimeError('a stream ended before every stream reached decode') | |
| if clock() >= end: | |
| raise TimeoutError('not every stream reached decode before the TTFT bound') | |
| sleep(.02) | |
| settle = clock() + SETTLE_S | |
| while clock() < settle: | |
| check_failed() | |
| sleep(.05) | |
| capture('decode') | |
| finally: | |
| while not all(f.done() for f in futures): | |
| sleep(.05) # each stream keeps its own 900-second wall bound (stream_summary) | |
| streams = [f.result() for f in futures] | |
| after = bench.parse_metrics(api.metrics()) | |
| return {'type': 'cell', 'cell': cell.name, 'batch': cell.batch, 'profiled': bool(cell.captures), | |
| 'warmup': cell.warmup, 'origin_wall': wall() - (clock() - origin), 'late': cell.late, | |
| 'late_arrival': cast(Json, late or None), | |
| 'streams': cast(Json, streams), 'captures': cast(Json, captures), | |
| 'spec': cast(Json, bench.spec_delta(before, after)), | |
| 'status': 'MEASURED client observations; profiled cells are profile-affected, never promotion timings'} | |
| def build(api: Api, materials: str, hashes: dict[str, Json]) -> dict[str, Json]: | |
| if busy(api.metrics()): | |
| raise RuntimeError('serve not verified idle before prompt construction') | |
| prompts: dict[str, Json] = {} | |
| for prompt in PROMPTS.values(): | |
| chars, tokens = cut(materials, prompt, api.tokens) | |
| text = render(materials, prompt.offset, chars) | |
| prompts[prompt.key] = {'target': prompt.target, 'offset': prompt.offset, 'chars': chars, 'tokens': tokens, | |
| 'sha256': hashlib.sha256(text.encode()).hexdigest()} | |
| return {'type': 'cuts', 'corpus_sha256': hashes, 'header_sha256': hashlib.sha256(HEADER.encode()).hexdigest(), | |
| 'tolerance': TOLERANCE, 'prompts': prompts} | |
| def texts_from(cuts: dict[str, Json], materials: str, hashes: dict[str, Json]) -> dict[str, tuple[str, int]]: | |
| """Re-render every prompt from its numeric cut; refuses any drift (no /tokenize call).""" | |
| if cuts.get('corpus_sha256') != hashes: | |
| raise ValueError('public corpus changed since the prompts were built') | |
| out: dict[str, tuple[str, int]] = {} | |
| for key, value in record(cuts['prompts']).items(): | |
| row = record(value) | |
| prompt = PROMPTS[key] | |
| if row.get('offset') != prompt.offset or row.get('target') != prompt.target: | |
| raise ValueError('prompt plan changed since the prompts were built') | |
| text = render(materials, prompt.offset, int(number(row['chars']))) | |
| if hashlib.sha256(text.encode()).hexdigest() != row.get('sha256'): | |
| raise ValueError(f'{key}: rebuilt prompt differs from its recorded hash') | |
| out[key] = (text, int(number(row['tokens']))) | |
| if set(out) != set(PROMPTS): | |
| raise ValueError('incomplete prompt cuts') | |
| return out | |
| def main(argv: list[str] | None = None) -> int: | |
| ap = argparse.ArgumentParser(description=__doc__) | |
| ap.add_argument('--execute', action='store_true') | |
| ap.add_argument('--url', default=URL) | |
| ap.add_argument('--data-dir', type=Path, default=Path('/opt/dsv41/data/bench-data')) | |
| sub = ap.add_subparsers(dest='command', required=True) | |
| b = sub.add_parser('build', help='construct every prompt once; write numeric cuts and hashes only') | |
| b.add_argument('--output', type=Path, required=True) | |
| r = sub.add_parser('run', help='one cell') | |
| r.add_argument('--cell', choices=ORDER, required=True) | |
| r.add_argument('--cuts', type=Path, required=True) | |
| r.add_argument('--output', type=Path, required=True) | |
| r.add_argument('--deadline-utc', type=float, required=True) | |
| r.add_argument('--telemetry', type=Path, nargs=2, required=True) | |
| r.add_argument('--capture-floor-kb', type=int, required=True) | |
| r.add_argument('--cache-salt-prefix', required=True) | |
| r.add_argument('--ledger', type=Path) | |
| args = ap.parse_args(argv) | |
| if not args.execute: | |
| print(json.dumps({'executed': False, 'cells': {n: {'prompts': list(c.prompts), 'captures': list(c.captures), | |
| 'max_tokens': c.max_tokens} for n, c in CELLS.items()}, | |
| 'prompts': {k: {'target': p.target, 'offset': p.offset} for k, p in PROMPTS.items()}})) | |
| return 0 | |
| if args.url != URL: | |
| ap.error('coordinator must use the reserved experiment tunnel at 127.0.0.1:18001') | |
| if args.output.exists(): | |
| ap.error('refusing an existing output; use a fresh window directory') | |
| materials, hashes = corpus(args.data_dir) | |
| api = Http(args.url) | |
| if args.command == 'build': | |
| result = build(api, materials, hashes) | |
| else: | |
| if args.deadline_utc <= time.time(): | |
| ap.error('--deadline-utc is in the past') | |
| if not 4 * 1024**2 <= args.capture_floor_kb <= 8 * 1024**2: | |
| ap.error('capture floor must lie in 4..8 GiB') | |
| texts = texts_from(record(cast(Json, json.loads(args.cuts.read_text()))), materials, hashes) | |
| plan = Plan(args.deadline_utc, args.capture_floor_kb, list(args.telemetry), args.cache_salt_prefix, args.ledger) | |
| result = run_cell(api, CELLS[args.cell], texts, plan) | |
| with args.output.open('x') as handle: | |
| handle.write(json.dumps(result, allow_nan=False) + '\n') | |
| print(f'{args.command}: wrote {args.output.name} (numbers and hashes only)') | |
| return 0 | |
| if __name__ == '__main__': | |
| raise SystemExit(main()) | |