Skip to content

Scenario reference

A scenario is one JSON (or YAML) object that holds every parameter of an experiment. It is validated against schemas/scenario.schema.json; the defaults below are the schema's. NNPM stores each saved scenario as a new version under scenarios/<name>/v<N>.json with its content hash (identical content reuses the version), and every run records the version it used, so a run can be replayed with run_experiment.sh --name <name> --version <N>.

Only name and model are required. Example files are in ../examples/scenarios/.

Top level

Field Type, default Meaning
name string scenario name ([A-Za-z0-9][A-Za-z0-9_.-]*)
description string free text
pipeline experiment (default) or benchmarking the seven-stage pipeline, or the four-stage benchmarking pipeline of Appendix B (no load, no shaping)
runtime string, testbed a registered runtime: testbed (per-layer profiling and partitioned inference), headsplit (the external HeadSplit runtime, see headsplit_integration.md) or a plug-in (see adding_a_runtime.md); the runtime's settings go in the block of the same name
model string a registered model name: alexnet, vgg16, resnet50, gru_qoe, mobilenetv2, efficientnetb0, densenet121, keras_app, gpt2, tinyllama, llama32_1b, qwen25_05b, hf_decoder, fake, or a plug-in (see adding_a_model.md)
model_args object the model's parameters (for example num_classes, seq_len, application, checkpoint), validated against the adapter's parameter schema and passed to every device tool
devices list of node ids, or null (default) the end devices that take part; null means every End Device in nodes.json
repetitions integer, 1 measured profiling repetitions per device
warmup integer, 1 warm-up passes before the measured repetitions
seed integer, 0 the random seed set on every device (random, NumPy, TensorFlow, PyTorch)
settle_s number, 5 seconds between applying load and shaping and the start of profiling
start_lead_s number, 3 how far in the future the start instant T0 is placed
input object what the devices feed to the model: source (synthetic, default; numpy_file; image_file; image_folder; text_prompt), path (on the device, relative to its data directory), index (image_folder: which image of the sorted listing; class sub-directories give a label), text and tokenizer (text_prompt)
checks object partition_equivalence (false): after profiling, every device compares each partition point with the unpartitioned model (python -m src.models.inference verify) and a relative deviation above tolerance (0.0001) aborts the run; the reports are collected under verification/
sweep object path (dotted field, for example network.default.added_rtt_ms) and values; expands into one run per value, each carrying sweep_origin (name, path, value) so that NNPM groups them

edge_server

Field Default Meaning
policy SJF scheduling policy of the inference service: RR (one stage per request per round) or SJF (ascending offloaded work, ties by device index)
nominal_frequency true pin the edge server's cores to their base frequency with turbo off for the run, restored at teardown
profile_capacity true measure the edge server's FLOP/s on the model, used as C^R by the delay model
port 5300 port of the inference service

inference

Field Default Meaning
enabled false run partitioned inference against the edge-server service after profiling
partition_points list the values of s to run (0 sends the raw input, S runs everything locally)
repetitions 1 inferences per partition point

network

A mapping from node id to a shaping block; the key default applies to every selected device. Shaping is applied with tc-netem on the device's data-plane interface (network_interface) at launch and removed at teardown.

Field Meaning
delay_ms added egress delay in milliseconds
added_rtt_ms extra round-trip time to the edge server, applied as egress delay; the Chapter 6 sweep variable
from_map true derives delay_ms from the marker positions on the map (5 ms + 1 ms/km, clipped to [5, 50] ms)
variation mode (constant; uniform: a new delay drawn from [min_ms, max_ms] every period_s; square: alternation between the delay and none every period_s)
jitter_ms uniformly distributed random component of the delay
loss_percent packet drop probability
rate_mbps egress bandwidth cap (token-bucket filter)
destinations node ids to shape separately (one netem leaf per destination); empty means all traffic of the interface
background_traffic_mbps an iperf3 UDP stream from the device to the edge server at this rate for the whole run

load

A mapping from node id to a load block (default applies to every selected device). The load generator runs on the device for the whole run; leave the node out of load for no injected load.

Field Default Meaning
mode fixed fixed (one CPU and memory target); continuous (a new target drawn every cycle_s within cpu_range and memory_range); regime (the Chapter 3 regimes: light 10-20 % CPU and 10-20 % memory, moderate 30-50 % and 30-40 %, heavy 60-80 % and 50-60 %); processes (processes fully busy processes, the Chapter 4 background-process model)
cpu_percent, memory_percent targets, in percent of one core (per worker) and of the device's memory
cpu_range, memory_range [min, max] for the continuous mode
regime light, moderate or heavy
processes number of fully busy processes
cores 1 number of CPU workers
cycle_s 10 resampling cycle of the continuous modes
period_ms 100 duty-cycle period of a CPU worker

heterogeneity

A mapping from node id to a block (default applies to every selected device).

Field Meaning
max_freq_mhz cap the CPU frequency with cpufreq (for example 1200 or 600 on a Raspberry Pi 4 at 1800)
memory_limit_mb run the experiment processes in a cgroups v2 group with this memory limit
threads number of threads the inference runtime may use

Every setting records the previous state and is restored at teardown.

monitoring

Field Default Meaning
enabled true run the resource-monitoring agent on every device
interval_s 1.0 sampling interval (CPU, memory, temperature, per-core frequency, throttling flags)
power false run the INA260 power monitor
power_interval_s 0.5 its sampling interval
latency_pings 10 pings per target in the latency capture of the collect stage
throughput false measure iperf3 throughput to the edge server
throughput_duration_s 5 duration of that measurement

optimisation

Field Default Meaning
enabled true run the partition optimiser after aggregation
algorithm greedy a registered algorithm: greedy, exhaustive, trend_based, or a plug-in
objective total_delay total_delay (sum of the per-device delays) or variance (population variance of the per-device delays)
initial_scheme null starting vector: a JSON list, a {node: s} mapping or a percentage of the model depth ("50%")
max_total_delays_ms null per-device limit on the total delay, a list or a {node: ms} mapping
transmission_mode rtt_only rtt_only (the ping round-trip time) or size_over_rate (cut size over the measured rate plus the one-way latency)
num_solutions, max_time_s 5, 300 parameters of the trend-based search

headsplit

Used when runtime is headsplit; the Create scenario dialog renders it from the runtime's schema. controller and workers (required) name nodes of nodes.json; model (the Hugging Face model name, TinyLlama/TinyLlama-1.1B-Chat-v1.0 by default), tokens (50), prompt_length (256), mode (headsplit, head_only, layer_based, all), profile (path of the speculation-accuracy profile, relative to the HeadSplit directory), prompt, worker_memory_bytes, epsilon, alpha_min, memory_replace_threshold, rtt_margin, timeout_s, extra_args. See headsplit_integration.md. A plug-in runtime contributes its own block under its name.

Examples

examples/scenarios/baseline.yaml: per-layer profiling of AlexNet on every device with no injected load (the benchmarking pipeline).

name: baseline
pipeline: benchmarking
model: alexnet
devices: null
repetitions: 3
warmup: 1
seed: 42
edge_server: {policy: SJF, nominal_frequency: true, profile_capacity: true}
monitoring: {enabled: true, interval_s: 1.0, latency_pings: 10}
optimisation: {enabled: true, algorithm: greedy, objective: total_delay, initial_scheme: "50%"}

examples/scenarios/local_demo.yaml: the fake model on two simulated devices with shaping, load and heterogeneity, runnable on any machine:

python -m src.orchestration.experiment run --scenario examples/scenarios/local_demo.yaml --local

The other examples: heavy_load.yaml (the heavy regime on every device), ch4_validation.yaml (the Chapter 4 procedure: AlexNet, four devices, partitioned inference at the table's partition points, RR and SJF), ch6_rtt_sweep.yaml (HeadSplit under a sweep of added round-trip times) and ch6_heterogeneity.yaml (HeadSplit with frequency caps and memory limits on the workers).