Skip to content

Latest commit

 

History

History
172 lines (136 loc) · 7.83 KB

File metadata and controls

172 lines (136 loc) · 7.83 KB

SCIoT Configuration Guide

SCIoT now validates the primary server and static HTTP client YAML files before startup. Invalid values fail with field-level errors such as communication.http.port: must be between 1 and 65535.

Canonical files

  • Server runtime: src/server/settings.yaml
  • Static HTTP client runtime: src/client/python/http_config.yaml
  • Server examples: docs/config/server.minimal.yaml, docs/config/server.full.yaml
  • Static client examples: docs/config/client-http.minimal.yaml, docs/config/client-http.full.yaml

src/server/client_config.yaml is retained as legacy reference material. New runtime changes should use src/server/settings.yaml for server configuration and src/client/python/http_config.yaml for static-client configuration.

Override precedence

For current supported paths, settings are resolved in this order:

  1. Explicit CLI arguments, where available. For example, sciot-client --config src/client/python/http_config.yaml --device-id DEVICE_ID --max-cycles 1.
  2. Environment variables.
  3. YAML file values.

Supported environment overrides:

  • SCIOT_TRANSPORTS: comma-separated server transports, for example http,mqtt.
  • SCIOT_SERVER_HOST: server HTTP host for the server, or server host used by the static client.
  • SCIOT_SERVER_PORT: server HTTP port for the server, or server port used by the static client.
  • SCIOT_HTTP_MODEL: model key used by the server HTTP transport.
  • SCIOT_VERBOSE: true or false server verbosity.
  • SCIOT_CLIENT_DEVICE_ID: static-client device ID.
  • SCIOT_CLIENT_MAX_CYCLES: bounded client cycle count.
  • SCIOT_CLIENT_RUN_DURATION_SECONDS: bounded client run duration.

Validated fields

Server validation covers:

  • enabled transports in communication.mode;
  • HTTP/WebSocket/MQTT hostnames, ports, endpoints/topics, NTP server names, and model references;
  • model dimensions, split-layer limits, and model directories;
  • local-inference probability in the inclusive range 0.0..1.0;
  • offloading algorithm selection under offloading.algorithm (static or adaptive_risk) and adaptive tuning values;
  • delay sections and delay distributions;
  • boolean flags such as verbose, debug_cprofiler, compression, and input saving;
  • evaluation.split.max_rows and evaluation.split.interval_minutes (non-negative);
  • evaluation.outputs.inference_cycles and evaluation.outputs.offloading_decisions (booleans);
  • optional Firestore telemetry publishing under evaluation.firestore.

Offloading algorithm

The server chooses the next split point through the configured offloading algorithm. If the section is absent, the runtime keeps the legacy static behavior. To enable the adaptive risk-aware policy:

offloading:
  algorithm: adaptive_risk   # static | adaptive_risk
  adaptive_risk:
    network_window_size: 10
    uncertainty_weight: 0.50
    hysteresis_margin_ms: 5
    min_speed_bytes_per_second: 1
    probe_probability: 0.05
    device_load_weight: 0.50

adaptive_risk reuses the same candidate cost components as static, using the latest server-measured network speed directly for transfer cost. It then adds penalties for unstable device/edge measurements, noisy network speed, and small layer switches. network_window_size controls only the recent raw speed samples used to estimate network variability; it does not smooth the speed used for transfer cost. The policy also scales device-side compute estimates by the reported device CPU occupancy so a busy client moves toward earlier offloading points faster.

Evaluation outputs

The server writes inference-cycle CSV output under data/results/evaluations/inference_cycles_*.csv. Each offloading decision is mirrored to both CSV and JSONL:

  • data/results/offloading_decisions*.csv
  • data/results/offloading_decisions_<first_inference_timestamp>.jsonl

Each output stream can be enabled or disabled as needed (both default to true); a disabled stream skips its event construction entirely, so there is no runtime cost. Stable scalar metrics are emitted as normal CSV columns; variable-length values such as per-layer timing and offloading cost lists are preserved as JSON-encoded CSV cells. JSONL batches keep shared layer sizes once in file metadata and store scalar per-inference compute timing fields:

evaluation:
  outputs:
    inference_cycles: true       # inference_cycles_*.csv (structured evaluation)
    offloading_decisions: true   # decision CSV and compact JSONL batches

Splitting

Instead of a single CSV file with size-based rotation (which discards old data), CSV outputs are split into never-deleted segment files:

evaluation:
  split:
    max_rows: 5000        # open a new segment every N rows (0 = disabled)
    interval_minutes: 30  # open a new segment every T minutes (0 = disabled)

A new CSV segment is opened at the first criterion that trips. CSV segment filenames embed a zero-padded index and segment start time, e.g. offloading_decisions.seg0001_20260706_101500.csv. The JSONL mirror does not use CSV-style segments: it writes compact batches named from the first inference decision timestamp, for example offloading_decisions_20260706_101500.jsonl. Each JSONL batch starts with shared metadata such as layer sizes and then appends per-inference rows until adding another row would exceed 950 KiB. Fractional seconds and numeric suffixes are added only when a new batch would otherwise collide with an existing filename.

Firestore publishing

Local CSV output remains the primary runtime artifact. Optionally, the server can also queue each telemetry row for Cloud Firestore publishing in the background:

evaluation:
  firestore:
    enabled: false
    project_id: null          # Application Default Credentials project if null
    database: null            # default Firestore database if null
    credentials_path: null    # optional service-account JSON path
    collection: sciot_results
    run_document: null        # defaults to the compact server-start timestamp
    publish_inference_cycles: true
    publish_offloading_decisions: true
    flush_interval_seconds: 300

The Firestore client is part of the server runtime profile. Install the server with uv sync --extra server. Documents are written below:

  • sciot_results/{run_document}/inference_cycles/{document_id}
  • sciot_results/{run_document}/offloading_decisions/{document_id}

For offloading decisions, the Firestore document id and payload reference the local JSONL batch file containing the buffered inferences, such as offloading_decisions_20260630_105214.jsonl, via offloading_decisions_jsonl_file and offloading_decisions_jsonl_path. The latest pending offloading-decision JSONL file is parsed into structured batch_metadata and inferences fields on each flush and deleted locally after the Firestore write succeeds.

Publishing is buffered and best-effort: local CSV files are written immediately, then queued Firestore rows and the latest pending offloading-decision batch are flushed every flush_interval_seconds seconds (five minutes by default). Firestore errors are logged and do not stop local CSV writes or inference.

Static-client validation covers:

  • client identity and lifecycle limits;
  • server host/port and endpoint paths;
  • model image, input size, split layer, TFLite directory, and submodel prefix;
  • delay sections and distributions;
  • local-inference probability and boolean flags.

Migration notes

  • Do not keep edited runtime copies as committed .backup files. The checked-in .backup configuration files were removed; use Git history or files outside the repository for local snapshots.
  • Use the example files under docs/config/ when creating new deployments.
  • Prefer environment variables for temporary host, port, model, and bounded-run overrides.
  • Add new configuration keys to src/sciot/config.py and include valid/invalid tests before using them in runtime code.