Skip to main content

Same model. Same input. Find the first divergence.

Project description

Eleanity

Same model. Same input. Find the first causal divergence.

CI Local AI parity Python 3.11+ License Status

CLI-first tool for LLM runtime parity. It compares inference stacks on the same scenario and reports:

  • status (PASS, PASS_WITH_TOLERANCE, PASS_WITH_LIMITED_COVERAGE, INCONCLUSIVE, DIVERGENT, ERROR)
  • first divergent layer (when present)
  • coverage of required layers and diagnosis confidence
  • functional impact (separate from internal parity)
  • a reproduction command

It does not score model quality (no MMLU). It checks whether two runtimes still share the same causal path: artifact → template → special tokens → token IDs → generation / API.

Product surfaces: CLI (text / json / quiet / sarif) and a Python API for embedding without subprocess — see docs/api.md.

Hosting note: the repository currently lives at
TheusHen/eleanity (alpha).
Transfer to eleanity/eleanity is planned when the org is available (ROADMAP.md).


Install (clean machine)

From Git (available now)

# one-shot CLI without a permanent install
uvx --from git+https://github.com/TheusHen/eleanity.git eleanity --help

# or install into an environment
pip install "git+https://github.com/TheusHen/eleanity.git"
# optional HF backend (PEP 508 direct reference + extras)
pip install "eleanity[transformers] @ git+https://github.com/TheusHen/eleanity.git"
uv add git+https://github.com/TheusHen/eleanity.git
# or with transformers extra:
uv add "eleanity[transformers] @ git+https://github.com/TheusHen/eleanity.git"

From a local checkout

git clone https://github.com/TheusHen/eleanity.git
cd eleanity
uv sync --group dev
uv run eleanity --help

PyPI

pip install eleanity
# pin a specific alpha release if needed:
pip install "eleanity==0.4.0"

Every non-release commit pushed to main is released automatically through release.yml. The workflow increments the patch version directly on main, runs the quality suite, publishes to PyPI, then creates an immutable vX.Y.Z tag and GitHub prerelease with the wheel, sdist, and SHA256 checksums.

# Required repository secret (once):
gh secret set PYPI_API_TOKEN -R TheusHen/eleanity

Configure a fine-grained RELEASE_PAT for an account allowed to bypass the protected-branch checks when Actions writes the generated version commit. The job verifies wheel/sdist metadata and writes SHA256SUMS.

Requires Python 3.11+.


60-second offline check

uv run eleanity compare --model demo --backends fake,fake \
  --format quiet --no-parallel --no-gates

Exact output from a live run:

status=PASS impact=NONE coverage=100.0 confidence=0.85 first_divergence=none gates=True run_id=16c3f05b-70f9-4c6a-9170-3e5942f91bd6

Real model self-parity (PASS)

Model: HuggingFaceTB/SmolLM2-135M-Instruct (CPU).

Commands

uv sync --group dev --extra transformers

uv run eleanity pull HuggingFaceTB/SmolLM2-135M-Instruct --tokenizer-only

uv run eleanity compare \
  --model HuggingFaceTB/SmolLM2-135M-Instruct \
  --backends transformers,transformers \
  --format quiet --no-parallel --no-gates \
  --observe artifact,template,special_tokens,tokens,generation

Exact quiet output (live run)

status=PASS impact=NONE coverage=100.0 confidence=0.85 first_divergence=none gates=True run_id=0aba046a-5846-45b2-94d9-4584bb4fe98a
Metric Value
Engine total ~10276 ms
First observation ~9259 ms
Second (warm) ~1017 ms
Token match 31 / 31
Required coverage 100% (min 75%)
uv run eleanity report 0aba046a-5846-45b2-94d9-4584bb4fe98a --format text

Layer table excerpt:

Layer            Baseline obs   Candidate obs   Compare
artifact         OBSERVED       OBSERVED        PASS
special_tokens   OBSERVED       OBSERVED        PASS
template         OBSERVED       OBSERVED        PASS
tokens           OBSERVED       OBSERVED        PASS
generation       OBSERVED       OBSERVED        PASS

Template diff: PASS
Token diff:    PASS (count: 31)

This validates the engine + Transformers path.


Cross-runtime DIVERGENT (Transformers × real HF OpenAI-compat HTTP)

Both sides run real Hugging Face weights (SmolLM2-135M-Instruct):

Side Runtime path
Baseline transformers adapter (in-process)
Candidate vllm adapter → local OpenAI-compat server that loads the same HF model via Transformers

The HTTP server does not expose template/tokenize endpoints (same honesty profile as many LM Studio / gateway setups). By default it applies the chat template without the assistant generation prompt — a common production bug — so generation diverges for a causal reason, not a hard-coded string.

Commands (exact)

uv sync --group dev --extra transformers

# starts real HF server, runs doctor + compare, stops server
uv run python scripts/examples/run_cross_runtime_demo.py

Under the hood:

# terminal A
uv run python scripts/examples/hf_openai_server.py \
  --port 8765 --preload --omit-generation-prompt \
  --model HuggingFaceTB/SmolLM2-135M-Instruct

# terminal B
export ELEANITY_VLLM_URL=http://127.0.0.1:8765
uv run eleanity doctor --check-backends --backends vllm --format json
uv run eleanity compare \
  --model HuggingFaceTB/SmolLM2-135M-Instruct \
  --backends transformers,vllm \
  --backend-url vllm=http://127.0.0.1:8765 \
  --policy quantized \
  --format quiet --no-parallel --no-gates \
  --observe artifact,template,tokens,generation,api

Parity attempt (server uses full AGP): ELEANITY_DEMO_MATCH=1 uv run python scripts/examples/run_cross_runtime_demo.py

Point the same commands at LM Studio / vLLM serve by changing --backend-url. Offline fixed-string stub (CI without GPU weights): scripts/examples/mock_openai_diverge.py.

Exact quiet output (live run)

status=DIVERGENT impact=HIGH coverage=50.0 confidence=0.762 first_divergence=generation gates=False run_id=90028893-8848-463f-9331-daf5268f60b5
Field Value
Baseline transformers · HuggingFaceTB/SmolLM2-135M-Instruct (HF weights, in-process)
Candidate vllm adapter → hf_openai_server.py (same HF weights over HTTP, --omit-generation-prompt)
Policy quantized
Status DIVERGENT
First divergence generation
Coverage 50% required layers (template/tokens not mutually observed on HTTP)
Verified artifact, generation
Not verified template (NOT_SUPPORTED on HTTP), tokens (NOT_EXPOSED on HTTP)
Generation texts transformers: Hello! How can I help you today? · HTTP: assistant\nHello! How can I help you today?
Engine total ~8287 ms

Reproduction command stored on the run:

eleanity compare --model HuggingFaceTB/SmolLM2-135M-Instruct --backends transformers,vllm \
  --baseline transformers --policy quantized \
  --observe artifact,template,tokens,generation,api --no-gates \
  --backend-url vllm=http://127.0.0.1:8765 --format text

This is the cross-stack claim: two real runtimes, same model weights, localized first divergence, honest missing layers.


Template first-divergence (character-level)

Classic chat-template bug (missing assistant generation prompt), fully localized:

uv run python scripts/examples/demo_template_divergence.py

Exact output (live run):

status:            DIVERGENT
first_divergence:  template
character:         11
byte:              11
baseline template: 'user: Hello\nassistant:'
candidate template:'user: Hello'
probable_cause:    [CHAT_TEMPLATE_DIFFERENT] conf=0.92

More write-ups: docs/examples/first-divergence.md.


Compared to common alternatives

Approach Result type Causal first layer CI exit contract Missing-data honesty
Manual print / eyeball vibes no no no
String golden tests brittle text diff rare sometimes often silent
lm-eval / quality benches capability scores no yes n/a
API latency dashboards ops metrics no maybe n/a
Eleanity parity + location yes 0/1/2 yes (coverage)

Adapter capability matrix (summary)

Full table: docs/adapter-capabilities.md.

Adapter template tokens logits generation streaming API
fake yes yes no yes yes partial
transformers yes yes partial yes no no
vllm HTTP partial partial no yes partial yes
llamacpp HTTP partial partial no yes partial yes
ollama no no no yes partial yes
sglang / tgi / openai partial/no partial/no no yes partial yes

Everyday CLI

eleanity doctor --check-backends
eleanity compare --backends transformers,vllm --format text
eleanity test fixtures/public/tokenizer-edge.yaml --backends fake,fake --format quiet
eleanity report <run-id> --format text
eleanity replay <run-id>
eleanity stabilize --backend fake --repetitions 3 --format quiet
eleanity policy-spec --policy quantized

Exit codes: 0 pass family · 1 divergent / gate fail · 2 config / dependency error.

Full reference: docs/cli.md


Python API (no subprocess)

from eleanity import Eleanity

client = Eleanity()  # or Eleanity.from_yaml("eleanity.yaml")
result = client.compare(model="demo", backends=["fake", "fake"], no_gates=True)
print(result.status, result.first_divergence, result.coverage)
raise SystemExit(result.exit_code)

Low-level observe/compare: from eleanity.api import observe_backend, compare_traces, make_scenario.
Full reference: docs/api.md.


CI

Workflow Role
ci.yml Required quality: ruff + unit/contract/integration + CLI smoke
ci.yml typecheck job Informational mypy (does not fail the workflow in 0.4.x)
parity-local-ai.yml Downloads SmolLM2-135M and runs real Transformers self-parity
parity-public-fixtures.yml Public fixture suites
release.yml Automatic patch version, PyPI prerelease, immutable tag, and GitHub Release for each main commit
eleanity.yml Reusable monorepo gate

Local:

uv run ruff check src tests
uv run ruff format --check src tests
uv run pytest -q

Project docs

Doc Purpose
docs/cli.md CLI reference
docs/api.md Python client + low-level API
docs/parity-specification.md Status + comparator tables
docs/adapter-capabilities.md Honesty matrix
docs/trace-specification.md Trace Spec v1
ROADMAP.md Alpha boundaries
SUPPORT.md Where to get help
SECURITY.md Vulnerability reporting

License

Apache License 2.0 — full text in LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eleanity-0.4.1.tar.gz (581.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eleanity-0.4.1-py3-none-any.whl (193.1 kB view details)

Uploaded Python 3

File details

Details for the file eleanity-0.4.1.tar.gz.

File metadata

  • Download URL: eleanity-0.4.1.tar.gz
  • Upload date:
  • Size: 581.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for eleanity-0.4.1.tar.gz
Algorithm Hash digest
SHA256 a9373d2be988dbb715d9fe4c8ebd5f08095fd2a5779f114a5da72024692d2991
MD5 06a25a00073c16deb37ca67d62d1d3cb
BLAKE2b-256 29aa1ce25681664ed8502f18e07624d5928fd710334482026ddd02d425915a4a

See more details on using hashes here.

File details

Details for the file eleanity-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: eleanity-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 193.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for eleanity-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4f1f0d8654136d8f3e001b2d1571a5c449c0fb026ab684d92d335745a6997ca8
MD5 719d4db06c7f244de23f9d154addba53
BLAKE2b-256 7d4685cbc9c54fdcb8b267ad0199c17cb0e32f335131dd09855fd71e2a7c8403

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page