You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2feebbb
Browse filesBrowse the repository at this point in the historyBrowse files
Keep the guard disabled by default; recommend a 300-second or longer deadline when enabled. Preserve standard artifacts after a liveness failure and cover session-wide progress semantics.
-**Online** (`poisson`): Fixed QPS with Poisson arrival distribution for latency profiling
91
91
-**Concurrency**: Fixed concurrent request count
92
92
93
+
### Endpoint liveness
94
+
95
+
Set an endpoint response idle timeout to fail the run when in-flight work stops responding. Use `>=300` seconds; raise it for long requests:
96
+
97
+
```yaml
98
+
settings:
99
+
timeouts:
100
+
endpoint_response_idle_timeout_s: 300
101
+
```
102
+
103
+
Or pass `--endpoint-response-idle-timeout 300`. The guard is client-side; see [the configuration guide](docs/config/DESIGN.md#endpoint-response-idle-timeout) for tuning.
Copy file name to clipboardExpand all lines: docs/CLI_DESIGN.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,6 +61,8 @@ Both paths produce the **same subclass with the same defaults**. A YAML file wit
61
61
62
62
3.**Datasets injected after construction.**`--dataset` strings are parsed by a `BeforeValidator` on the `datasets` field, then merged via `config.with_updates(datasets=...)`.
63
63
64
+
Fields get their dotted path automatically; those needing a shorter operational spelling also declare a `cyclopts.Parameter(alias=...)`. For example `settings.timeouts.endpoint_response_idle_timeout_s` accepts either `--timeouts.endpoint-response-idle-timeout-s` or the alias `--endpoint-response-idle-timeout`; it defaults to off and, when enabled, we recommend `>=300` seconds.
65
+
64
66
### YAML path
65
67
66
68
1.**`from_yaml_file(path)`** loads YAML, resolves `${VAR}` env vars on parsed values, then passes the dict to a Pydantic `TypeAdapter` with `Discriminator`.
|`RuntimeConfig`|Workload sizing, issue-duration cap, and RNG seeds |
52
52
|`ClientSettings`| Worker count and HTTP client settings |
53
53
|`EndpointConfig`| Endpoint URLs, API key |
54
54
|`Dataset`| Dataset path, type (performance / accuracy) |
@@ -71,6 +71,16 @@ Immutable snapshot of all parameters needed to execute a run.
71
71
72
72
Once constructed, `RuntimeSettings` cannot be modified. All consumers receive the same instance.
73
73
74
+
### Endpoint response idle timeout
75
+
76
+
`settings.timeouts.endpoint_response_idle_timeout_s` is a client-side liveness deadline, `None` by default. When enabled, use at least 300 seconds in normal deployments. Once a phase has an in-flight request, `BenchmarkSession` fails the run if no streamed chunk or final response arrives within the interval. The clock starts at local issuance — when the request is handed to the client transport. There is no server-acceptance acknowledgment in the client contract, so worker scheduling, connection acquisition, and local transport queueing all consume the deadline before the server even sees the request. It does not replace an engine's own KV-transfer deadline.
77
+
78
+
**What counts as progress.** Only messages that reach the main process reset the clock. Under the default `client.stream_all_chunks: false`, workers forward a request's first streamed chunk and its final result — intermediate chunks never cross the IPC boundary. The largest gap a healthy streaming request can therefore produce is its full first-chunk-to-completion span, not a per-token gap. With `stream_all_chunks: true` every chunk resets the clock, at the cost of per-chunk IPC traffic.
79
+
80
+
**Choosing a value.** Use `>=300` seconds and set it above the deployment's longest expected gap between main-process-visible events. Under the default `stream_all_chunks: false` — and for any non-streaming endpoint — that is the full latency of the longest single request, including pre-accept overhead; use `600` seconds or more for reasoning or long-output workloads. For TensorRT-LLM disaggregated serving, match the executor `hang_detection_timeout` (default 300 s), not `cache_transceiver_config.kv_transfer_timeout_ms`; raise the value if the normal p99 gap between visible events is longer.
81
+
82
+
**On failure**, the run still drains the metrics pipeline and writes the standard artifacts (`performance/result_summary.json`, `report.txt`) with the report marked `INTERRUPTED`, then exits non-zero.
83
+
74
84
### `BenchmarkSuiteRuleset` (abstract base)
75
85
76
86
Extension point for competition-specific constraints.
2. Start receiver coroutine (`_receive_responses`). When the endpoint response idle timeout is set, a single session-liveness timer is armed while work is in flight and fails the session if every in-flight request is silent for the interval. Configure `>=300` seconds; see `docs/config/DESIGN.md` for tuning.
177
178
3. For each phase:
178
179
a. Create `SampleOrder` and `LoadStrategy` from phase settings
Uses `recv()` exclusively — no `poll()` spin. The ZMQ fd is registered with
302
305
the event loop, so `recv()` wakes exactly when a response is available with
303
306
zero CPU overhead. Each `recv()` call yields to the event loop, ensuring
304
307
strategy coroutines (call_at callbacks, semaphore waiters) are never starved.
305
308
309
+
The endpoint response idle guard rides this same path to catch a client-visible worker or transport stall. It is not a per-request engine timeout: any chunk or final response counts as progress, and only a fully silent endpoint fails the run. A request may remain stuck while other in-flight requests respond; once those requests drain, the remaining stuck request causes the session to fail after the interval. The receiver only stamps a timestamp, and only when the deadline is set — streaming frame rate is QPS x output length, so per-chunk work is paid per token. The armed `call_later` timer re-derives its own deadline from that stamp when it fires, and re-arms for the remainder if progress raced it.
310
+
306
311
For `ConcurrencyStrategy`, `_handle_response` calls `strategy.on_query_complete()`
307
312
which releases the semaphore. Since `recv()` returns as soon as the fd is readable
308
313
and `eager_task_factory` executes the woken semaphore waiter synchronously, there
endpoint_response_idle_timeout_s: null # Endpoint liveness deadline: fail the run when work is in flight but no response chunk or completion arrives for this many seconds (None = off). When enabled, recommend >=300 seconds and size it above the longest single-request latency. See docs/config/DESIGN.md.
89
90
interrupted_teardown_grace_s: 30.0# Abort drain grace before remaining services are killed.
90
91
service_ready_timeout_s: 30.0# Service startup wait in seconds.
endpoint_response_idle_timeout_s: null # Endpoint liveness deadline: fail the run when work is in flight but no response chunk or completion arrives for this many seconds (None = off). When enabled, recommend >=300 seconds and size it above the longest single-request latency. See docs/config/DESIGN.md.
89
90
interrupted_teardown_grace_s: 30.0# Abort drain grace before remaining services are killed.
90
91
service_ready_timeout_s: 30.0# Service startup wait in seconds.
endpoint_response_idle_timeout_s: null # Endpoint liveness deadline: fail the run when work is in flight but no response chunk or completion arrives for this many seconds (None = off). When enabled, recommend >=300 seconds and size it above the longest single-request latency. See docs/config/DESIGN.md.
90
91
interrupted_teardown_grace_s: 30.0# Abort drain grace before remaining services are killed.
91
92
service_ready_timeout_s: 30.0# Service startup wait in seconds.
0 commit comments