Deterministic Inference Server is a manifest/lock based workflow for reproducible LLM inference runs. It provides:
- declarative manifests for inference intent,
- resolved lockfiles for pinned artifacts and runtime closure metadata,
- deterministic run execution with provenance bundles,
- pairwise bundle verification with determinism grading.
The reference behavior and schema live in spec.
deterministic_inference/: core package (schema,locking,execution,verification, CLI)configs/: model manifests (supports inheritance viax_base_manifest)manifests/: lockfiles and manifest-related artifactsartifacts/: generated run/bundle outputstests/: unit and workflow testsspec: normative project specification
- Python 3.10+
- Dependencies from
requirements.txt
Install dependencies:
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txtUse the CLI entrypoint:
python -m deterministic_inference.cli <command> ...Typical workflow:
# 1) Create a new manifest template
python -m deterministic_inference.cli init \
--output configs/my-model.json \
--model-id org/model-name \
--model-revision <revision>
# 2) (Optional) Bootstrap missing digests and write lock
python -m deterministic_inference.cli digest-bootstrap \
--config configs/my-model.json \
--in-place \
--write-lock
# 3) Resolve lockfile (requires real or bootstrapped sha256 digests in manifest)
python -m deterministic_inference.cli lock --config configs/my-model.json
# 4) Build runtime closure metadata and optionally refresh lock digest
python -m deterministic_inference.cli build --config configs/my-model.json --update-lock
# 5) Start serving stack (OpenAI-compatible endpoint)
python -m deterministic_inference.cli serve \
--config configs/my-model.json
# 5d) Start remote Modal serving stack (deploy + warm pool)
python -m deterministic_inference.cli serve-modal \
--config configs/my-model.json
# 5b) List active vLLM serve containers
python -m deterministic_inference.cli serve list
# 5c) Kill active vLLM serve containers
python -m deterministic_inference.cli serve kill
# 6) Execute run and emit bundle + tokens + run log
python -m deterministic_inference.cli run --config configs/my-model.json
# 6b) Execute run against Modal endpoint
python -m deterministic_inference.cli run --config configs/my-model.json --use-modal
# 7) Compare two runs
python -m deterministic_inference.cli verify \
--bundle-a runs/<run_a>/bundle.json \
--bundle-b runs/<run_b>/bundle.json
# 8) Archive a run directory
python -m deterministic_inference.cli bundle \
--run-dir runs/<run_id> \
--output artifacts/bundles/<run_id>.tar.gz
# 9) Inspect manifest/lock/bundle metadata
python -m deterministic_inference.cli inspect --input runs/<run_id>/bundle.jsoninit: create a new manifest templatelock: resolve and write lockfile with artifact digests/runtime digestbuild: emit runtime closure metadata (--update-lockoptionally rewrites lock)serve: manage vLLM docker-compose services (start,list,kill)serve-modal: manage Modal-backed vLLM services (start,list,stop)run: execute inference and emit run bundle artifactsverify: compare two bundles and emit report + summarybundle: tar/gzip a run directoryinspect: summarize manifest/lock/bundle metadatadigest-bootstrap: populate missing digests (sha256:unset) for manifest bootstrap
- Manifest (
kind=vllm.deterministic_inference_manifest):- declarative intent for hardware, runtime, model artifacts, inference requests, capture policy, and outputs.
- Lock (
kind=vllm.deterministic_inference_lock):- resolved artifacts with digests, plus runtime closure digest and stable
lock_id.
- resolved artifacts with digests, plus runtime closure digest and stable
Stable IDs:
manifest_id = sha256(canonical_manifest)lock_id = sha256(canonical_lock_without_lock_id)run_id = sha256(manifest_id + lock_id + requests_digest + hardware_fingerprint_digest)
- Pinned batching is enforced (
policy=fixed, pinned batch size, deterministic ordering). - Determinism grading:
conformantnon_conformant_hardwarenon_conformant_softwaremismatch_outputs
- Token output format is intentionally preserved:
sequences[].prompt_token_idssequences[].output_token_ids
run verifies artifact digests against the lockfile by default when local artifact paths are available.
- default: enabled
- disable flag:
--no-verify-artifact-digests
serve resolves the image in this order:
--imageCLI overrideruntime.execution.vllm_imagein manifestVLLM_IMAGEenvironment variable
Image references must be digest-pinned (...@sha256:<64-hex>).
Before starting the service, serve verifies the local image digest matches the pinned digest.
Use --pull to fetch the pinned image first.
serve currently maps and validates these vllm.engine_args keys:
modeldtypeasync_schedulingtensor_parallel_sizepipeline_parallel_sizemax_model_lenmax_num_batched_tokens(must matchinference.batching.max_num_batched_tokenswhen set)trust_remote_codegpu_memory_utilizationenable_auto_tool_choicetool_call_parserreasoning_parser
Example:
python -m deterministic_inference.cli run \
--config configs/my-model.json \
--no-verify-artifact-digestsThis repository includes a Modal-native serving path that moves vLLM from local Docker to remote Modal GPU instances.
- Install Modal SDK/CLI and authenticate:
pip install modal
modal token new- Create required Modal resources:
modal volume create deterministic-hf-cache --version=2
modal secret create huggingface-secret HUGGING_FACE_HUB_TOKEN=hf_xxx# deploy app + start (or reuse) config-specific pool
python -m deterministic_inference.cli serve-modal --config configs/qwen3-8b.json
# inspect locally tracked Modal pools
python -m deterministic_inference.cli serve-modal list
# scale a config pool down to zero
python -m deterministic_inference.cli serve-modal stop --name qwen3-8bpython -m deterministic_inference.cli run \
--config configs/qwen3-8b.json \
--use-modal--use-modal resolves a deployed Modal web endpoint for the config and uses it as a runtime base URL override for generation calls.
The Modal migration is intentionally one shared image + parametrized pools:
- one deployed Modal class (
VllmServer) backed by a pinned vLLM image, - one autoscaling container pool per manifest
metadata.name(class parameter), - per-config GPU shape inferred from manifest tensor parallel size and hardware hints.
This avoids maintaining one deployment artifact per config while still isolating runtime pools per model/config. If you need different vLLM base images per config, split into separate Modal app deployments.
A run directory contains:
bundle.json: provenance + run metadata + determinism grademanifest.used.json: exact manifest usedlock.used.json: exact lockfile usedtokens.json: token outputs (stable downstream format)run_log.json: detailed execution log, batch trace, determinism controls
verify outputs:
verify_report.json: machine-readable comparison reportverify_summary.txt: human-readable summary
The existing model manifests under configs/ are spec-shaped and loadable.
Some include placeholder digests (for example sha256:unset) intended for migration/bootstrap workflows; those must be replaced with real digests before lock/run in strict mode.
Repository configs now use a shared prompt source instead of hardcoded per-config prompts.
- source path (hardcoded):
/home/ubuntu/deterministic_inference_server/artifacts/reference_prompts/reference_prompts.json - prompt count control:
inference.n_prompts(valid range:1..100) - prompt request shape:
inference.request_template
The shared prompt dataset is pinned into lockfiles as inference.prompt_dataset so run digest verification enforces prompt immutability.
Run the test suite:
python3 -m unittest discover -s tests -p 'test_*.py'- Implement real logits capture + comparison
- Implement real activations capture + comparison
- Implement real vLLM trace capture + comparison
- Enforce
runtime.network_policy=offline_required(disable outbound network + fail retrieval attempts)
capture.logits,capture.activations, andcapture.engine_traceare currently configuration-only placeholders and no-op in run/verify.