-
Notifications
You must be signed in to change notification settings - Fork 4
Running Workloads
Opal uses a stage-based workload orchestration system. A simulation can define one or more workload stages that execute sequentially, each with its own type, parameters, and termination conditions.
The workload system has three layers:
-
WorkloadOrchestrator (
opal/workload_orchestrator.py) — Manages the lifecycle of all stages. It dynamically loads workload classes from theopal/workloads/directory by matching thetypefield in the configuration to a class name (case-insensitive). Stages run sequentially; the orchestrator waits for each stage to complete before starting the next. -
AbstractWorkload (
opal/workloads/abstract_workload.py) — Base class that all workload types must extend. It handles:- Scheduling a per-stage timeout (via
time_duration_sec) - Running request generation and response processing as concurrent SimPy processes
- Tracking generated/received request counts
- Scheduling a per-stage timeout (via
-
Concrete workload classes — Implement
generate_requests()to produceLLMRequestobjects and feed them to the router.
| Type (config string) | Class | Description |
|---|---|---|
UniformReqRate |
UniformReqRate |
Generates requests at a fixed rate (requests/sec). Prompt and output sizes are drawn uniformly at random from configurable min/max ranges. |
ExponentialReqRate |
ExponentialReqRate |
Same as UniformReqRate but inter-arrival times follow an exponential distribution with configurable jitter. |
Trace |
Trace |
Replays a JSONL trace file. Each line contains timestamp, input_length, output_length, and hash_ids. Requests are dispatched at the recorded timestamps. |
SC25Workload |
SC25Workload |
A specialized benchmark workload that runs a cold pass (unique prompts) followed by a warm pass (repeated prompts for 100% cache hit), used for KV-cache performance characterization. |
Workloads are configured under the "workload" key in the simulation JSON. The "stages" array defines the ordered list of stages:
"workload": {
"stages": [
{
"type": "UniformReqRate",
"workload_params": {
"request_rate": 2.0,
"total_requests": 100,
"prompt_size_min": 32,
"prompt_size_max": 16384,
"default_prefix_length": 1024,
"jitter": 0.0,
"output_tokens_min": 32,
"output_tokens_max": 128
}
},
{
"type": "trace",
"workload_params": {
"total_requests": 10,
"chunk_size": 1,
"multiplier_to_sec": 0.001,
"trace_file": "traces/hello.jsonl"
}
}
]
}| Parameter | Description |
|---|---|
request_rate |
Target requests per second |
total_requests |
Stop after this many requests (set to -1 or 0 for unlimited) |
prompt_size_min / prompt_size_max
|
Range for randomly generated prompt token count |
default_prefix_length |
Number of prefix tokens (used for KV-cache matching) |
output_tokens_min / output_tokens_max
|
Range for generated output token count |
time_duration_sec |
(Optional) Stage timeout in seconds |
max_outstanding_requests |
(Optional) Max concurrent in-flight requests (default: 32) |
jitter |
(ExponentialReqRate only) Controls variance in inter-arrival times |
| Parameter | Description |
|---|---|
trace_file |
Path to the JSONL trace file |
total_requests |
Replay only this many entries (-1 for all) |
chunk_size |
Token chunk granularity for hash expansion (default: 512) |
multiplier_to_sec |
Multiply raw timestamps by this factor to convert to seconds (default: 1) |
A workload stage stops generating requests when any of the following becomes true:
-
Global timeout — The simulation-wide
simulation_timehas elapsed. -
Local timeout — The stage's
time_duration_sechas elapsed. -
Request count — The configured
total_requestshave been generated.
After request generation stops, the stage waits for all outstanding responses to return before the orchestrator advances to the next stage.
- Create a new Python file in
opal/workloads/. - Define a class that extends
AbstractWorkload. - Implement the
generate_requests()generator method — it shouldyieldrequests intoself.req_router.input_queuewith appropriate inter-arrival delays. - Set
self.is_finished = Truewhen generation completes. - Use the class name (case-insensitive) as the
"type"value in the configuration.
No registration step is needed — the orchestrator discovers classes automatically by scanning the opal/workloads/ directory.