auditkit 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- auditkit/README.md +99 -0
- auditkit/__init__.py +177 -0
- auditkit/__main__.py +3 -0
- auditkit/_bootstrap.py +77 -0
- auditkit/_identity_guard.py +99 -0
- auditkit/adapter.py +264 -0
- auditkit/annotator.py +339 -0
- auditkit/api.py +502 -0
- auditkit/assets/auditkit_logo.png +0 -0
- auditkit/cache.py +47 -0
- auditkit/cli.py +417 -0
- auditkit/comparison.py +563 -0
- auditkit/diff.py +265 -0
- auditkit/errors.py +54 -0
- auditkit/evaluator.py +20 -0
- auditkit/experiment.py +145 -0
- auditkit/hf_publish.py +262 -0
- auditkit/lmeval_engine.py +550 -0
- auditkit/loaders.py +121 -0
- auditkit/logs.py +18 -0
- auditkit/metric.py +199 -0
- auditkit/metrics/README.md +15 -0
- auditkit/metrics/__init__.py +0 -0
- auditkit/metrics/code.py +222 -0
- auditkit/metrics/embedding.py +131 -0
- auditkit/metrics/encoder_judge.py +423 -0
- auditkit/metrics/generation.py +331 -0
- auditkit/metrics/guard.py +412 -0
- auditkit/metrics/hallucination.py +45 -0
- auditkit/metrics/judge.py +547 -0
- auditkit/metrics/pairwise.py +153 -0
- auditkit/metrics/perf.py +53 -0
- auditkit/metrics/rag.py +149 -0
- auditkit/metrics/security.py +64 -0
- auditkit/metrics/toxicity.py +238 -0
- auditkit/model/README.md +16 -0
- auditkit/model/__init__.py +485 -0
- auditkit/model/anthropic.py +94 -0
- auditkit/model/api_gen.py +133 -0
- auditkit/model/groq_gen.py +121 -0
- auditkit/model/hf_gen.py +385 -0
- auditkit/model/lexsi.py +155 -0
- auditkit/model/litellm_gen.py +65 -0
- auditkit/model/openai.py +90 -0
- auditkit/model/openrouter_gen.py +152 -0
- auditkit/model/vllm_gen.py +316 -0
- auditkit/model_compare.py +655 -0
- auditkit/redteam/README.md +9 -0
- auditkit/redteam/__init__.py +26 -0
- auditkit/redteam/detector.py +37 -0
- auditkit/redteam/detectors/README.md +5 -0
- auditkit/redteam/detectors/builtin.py +126 -0
- auditkit/redteam/probe.py +39 -0
- auditkit/redteam/probes/README.md +5 -0
- auditkit/redteam/probes/builtin.py +85 -0
- auditkit/redteam/runner.py +206 -0
- auditkit/registry.py +65 -0
- auditkit/report.py +278 -0
- auditkit/report_format.py +52 -0
- auditkit/router.py +54 -0
- auditkit/runner.py +575 -0
- auditkit/runspec.py +159 -0
- auditkit/sample.py +40 -0
- auditkit/scenario.py +88 -0
- auditkit/scenarios/README.md +10 -0
- auditkit/scenarios/__init__.py +4 -0
- auditkit/scenarios/arc.py +33 -0
- auditkit/scenarios/gsm8k.py +32 -0
- auditkit/scenarios/hellaswag.py +33 -0
- auditkit/scenarios/humaneval.py +32 -0
- auditkit/scenarios/mmlu.py +34 -0
- auditkit/scenarios/truthfulqa.py +33 -0
- auditkit/score.py +165 -0
- auditkit/scorers.py +117 -0
- auditkit/scoring.py +79 -0
- auditkit/types.py +69 -0
- auditkit-1.0.0.dist-info/METADATA +396 -0
- auditkit-1.0.0.dist-info/RECORD +81 -0
- auditkit-1.0.0.dist-info/WHEEL +4 -0
- auditkit-1.0.0.dist-info/entry_points.txt +2 -0
- auditkit-1.0.0.dist-info/licenses/LICENSE.md +92 -0
auditkit/scorers.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""The public scorer decorator and adapters.
|
|
2
|
+
|
|
3
|
+
A *scorer* is the user-facing way to define a custom metric: decorate a
|
|
4
|
+
``(sample, output) -> float | Score`` function with ``@scorer`` and pass it to
|
|
5
|
+
:func:`evaluate`. The decorator returns a :class:`FunctionScorer`; the
|
|
6
|
+
:class:`ScorerMetric` adapter wraps it as an internal :class:`Metric`.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Any, Callable, Optional, Union
|
|
12
|
+
|
|
13
|
+
from .metric import Metric
|
|
14
|
+
from .sample import Sample
|
|
15
|
+
from .score import Score
|
|
16
|
+
from .types import Direction, ScoreKind
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FunctionScorer:
|
|
20
|
+
"""A user-defined scorer returned by the ``@scorer`` decorator.
|
|
21
|
+
|
|
22
|
+
Attributes
|
|
23
|
+
----------
|
|
24
|
+
name : str
|
|
25
|
+
The scorer name (defaults to the function's ``__name__``).
|
|
26
|
+
fn : Callable[[Sample, str], Union[float, Score]]
|
|
27
|
+
The underlying callable.
|
|
28
|
+
direction : Direction
|
|
29
|
+
Whether a higher (``MAXIMIZE``) or lower (``MINIMIZE``) value is
|
|
30
|
+
better -- required, not guessed, so ``RunComparison``/
|
|
31
|
+
``compare_models()`` grade this scorer in the right sense.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
fn: Callable[[Sample, str], Union[float, Score]],
|
|
37
|
+
direction: Direction,
|
|
38
|
+
name: Optional[str] = None,
|
|
39
|
+
) -> None:
|
|
40
|
+
self.fn = fn
|
|
41
|
+
self.name = name or fn.__name__
|
|
42
|
+
self.direction = direction
|
|
43
|
+
|
|
44
|
+
def __call__(self, sample: Sample, output: str, context: Any = None) -> Score:
|
|
45
|
+
try:
|
|
46
|
+
result = self.fn(sample, output, context=context)
|
|
47
|
+
except TypeError:
|
|
48
|
+
result = self.fn(sample, output)
|
|
49
|
+
if isinstance(result, Score):
|
|
50
|
+
result.direction = self.direction
|
|
51
|
+
return result
|
|
52
|
+
return Score(name=self.name, value=float(result), direction=self.direction)
|
|
53
|
+
|
|
54
|
+
def __repr__(self) -> str:
|
|
55
|
+
return f"<FunctionScorer {self.name!r}>"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ScorerMetric(Metric):
|
|
59
|
+
"""Wraps a :class:`FunctionScorer` as a :class:`Metric`."""
|
|
60
|
+
|
|
61
|
+
def __init__(self, scorer: FunctionScorer) -> None:
|
|
62
|
+
self._scorer = scorer
|
|
63
|
+
self.name = scorer.name
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def kind(self) -> ScoreKind:
|
|
67
|
+
return ScoreKind.CODE
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def direction(self) -> Direction:
|
|
71
|
+
return self._scorer.direction
|
|
72
|
+
|
|
73
|
+
def score(self, sample: Sample, output: str, context: Any = None) -> Score:
|
|
74
|
+
return self._scorer(sample, output, context=context)
|
|
75
|
+
|
|
76
|
+
def applicable(self, sample: Sample) -> bool:
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
ScorerType = Union[FunctionScorer, Callable[[Sample, str], Union[float, Score]]]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def scorer(
|
|
84
|
+
fn: Optional[Callable[[Sample, str], Union[float, Score]]] = None,
|
|
85
|
+
*,
|
|
86
|
+
direction: Direction,
|
|
87
|
+
name: Optional[str] = None,
|
|
88
|
+
) -> Union[FunctionScorer, Callable[..., FunctionScorer]]:
|
|
89
|
+
"""Decorate a function as a scorer usable with :func:`evaluate`.
|
|
90
|
+
|
|
91
|
+
``direction`` is required -- there is no library default, because only
|
|
92
|
+
you know whether your scorer's return value means "higher is better"
|
|
93
|
+
(``Direction.MAXIMIZE``, e.g. a similarity/accuracy-style score) or
|
|
94
|
+
"lower is better" (``Direction.MINIMIZE``, e.g. a latency/error-count-
|
|
95
|
+
style score). Getting this wrong silently flips every ``RunComparison``/
|
|
96
|
+
``compare_models()`` verdict for the metric. See
|
|
97
|
+
``docs/best_practices/scorers.md#direction`` for a full example.
|
|
98
|
+
|
|
99
|
+
Always called with parens, ``direction=`` required (the old bare
|
|
100
|
+
``@scorer`` form with no arguments no longer works -- there is nowhere
|
|
101
|
+
to put ``direction`` in that form)::
|
|
102
|
+
|
|
103
|
+
@scorer(direction=ak.Direction.MAXIMIZE)
|
|
104
|
+
def my_scorer(sample, output): ...
|
|
105
|
+
|
|
106
|
+
@scorer(direction=ak.Direction.MAXIMIZE, name="custom")
|
|
107
|
+
def another(sample, output): ...
|
|
108
|
+
"""
|
|
109
|
+
if fn is not None:
|
|
110
|
+
return FunctionScorer(fn, direction=direction, name=name or fn.__name__)
|
|
111
|
+
|
|
112
|
+
def decorator(
|
|
113
|
+
f: Callable[[Sample, str], Union[float, Score]],
|
|
114
|
+
) -> FunctionScorer:
|
|
115
|
+
return FunctionScorer(f, direction=direction, name=name or f.__name__)
|
|
116
|
+
|
|
117
|
+
return decorator
|
auditkit/scoring.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from auditkit.metric import Metric
|
|
6
|
+
from auditkit.sample import Sample
|
|
7
|
+
from auditkit.score import Score
|
|
8
|
+
from auditkit.types import Direction
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ScoreGate(Metric):
|
|
12
|
+
"""Wraps a Metric with weight and threshold."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, metric: Metric, weight: float = 1.0, threshold: float | None = None) -> None:
|
|
15
|
+
self._metric = metric
|
|
16
|
+
self.weight = weight
|
|
17
|
+
self._threshold = threshold
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def name(self) -> str:
|
|
21
|
+
return f"gate({self._metric.name})"
|
|
22
|
+
|
|
23
|
+
def identity(self) -> dict:
|
|
24
|
+
"""Includes weight/threshold (previously unhashed -- changing either
|
|
25
|
+
and rerunning would silently reuse a stale result scored under the
|
|
26
|
+
old settings) and delegates to the wrapped metric's own identity()
|
|
27
|
+
if it has one, rather than just its .name -- otherwise a ScoreGate
|
|
28
|
+
wrapping e.g. an LLMJudge would lose that judge's prompt/choices
|
|
29
|
+
from the fingerprint too, the same gap this class had for itself."""
|
|
30
|
+
wrapped_identity = getattr(self._metric, "identity", None)
|
|
31
|
+
wrapped = wrapped_identity() if callable(wrapped_identity) else {"name": self._metric.name}
|
|
32
|
+
return {"name": self.name, "weight": self.weight, "threshold": self._threshold, "wrapped": wrapped}
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def kind(self):
|
|
36
|
+
return self._metric.kind
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def direction(self) -> Direction:
|
|
40
|
+
"""Delegates to the wrapped metric -- a gate doesn't change what
|
|
41
|
+
"better" means, only adds a weight/threshold on top. Previously this
|
|
42
|
+
unconditionally overwrote direction to MAXIMIZE whenever a threshold
|
|
43
|
+
was set, silently flipping the pass/fail sense of any MINIMIZE
|
|
44
|
+
metric (latency, error rate, ...) wrapped in a ScoreGate."""
|
|
45
|
+
return self._metric.direction
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def required_fields(self):
|
|
49
|
+
return self._metric.required_fields
|
|
50
|
+
|
|
51
|
+
def applicable(self, sample: Sample) -> bool:
|
|
52
|
+
return self._metric.applicable(sample)
|
|
53
|
+
|
|
54
|
+
def score(self, sample: Sample, output: str, context: Any = None) -> list[Score]:
|
|
55
|
+
result = self._metric.score(sample, output, context)
|
|
56
|
+
if isinstance(result, Score):
|
|
57
|
+
scores = [result]
|
|
58
|
+
else:
|
|
59
|
+
scores = list(result)
|
|
60
|
+
for s in scores:
|
|
61
|
+
s.weight = self.weight
|
|
62
|
+
s.direction = self.direction
|
|
63
|
+
if self._threshold is not None:
|
|
64
|
+
s.threshold = self._threshold
|
|
65
|
+
return scores
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class WeightedSum:
|
|
69
|
+
def __init__(self, name: str = "weighted_sum") -> None:
|
|
70
|
+
self.name = name
|
|
71
|
+
|
|
72
|
+
def compute(self, scores: list[Score]) -> Score:
|
|
73
|
+
if not scores:
|
|
74
|
+
return Score(name=self.name, value=0.0)
|
|
75
|
+
total_weight = sum(s.weight for s in scores)
|
|
76
|
+
if total_weight == 0.0:
|
|
77
|
+
return Score(name=self.name, value=0.0)
|
|
78
|
+
weighted_value = sum(s.value * s.weight for s in scores) / total_weight
|
|
79
|
+
return Score(name=self.name, value=weighted_value)
|
auditkit/types.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Core enumerations for AuditKIT.
|
|
2
|
+
|
|
3
|
+
These are the fixed vocabulary of the evaluation spine: what an evaluation asks
|
|
4
|
+
the model to do (:class:`TaskKind`), what a score means (:class:`ScoreKind`,
|
|
5
|
+
:class:`DataType`, :class:`Direction`), what a model can do (:class:`Capability`),
|
|
6
|
+
and where a run came from (:class:`Source`).
|
|
7
|
+
|
|
8
|
+
Every enum is ``str``-backed so members compare equal to their string value and
|
|
9
|
+
serialize to plain JSON without a custom encoder.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from enum import Enum
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TaskKind(str, Enum):
|
|
18
|
+
"""What an evaluation asks the model to do."""
|
|
19
|
+
|
|
20
|
+
MCQ = "mcq"
|
|
21
|
+
GENERATIVE = "generative"
|
|
22
|
+
RAG = "rag"
|
|
23
|
+
SECURITY = "security"
|
|
24
|
+
PERFORMANCE = "performance"
|
|
25
|
+
LANGUAGE_MODELING = "language_modeling"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ScoreKind(str, Enum):
|
|
29
|
+
"""How a score was produced."""
|
|
30
|
+
|
|
31
|
+
BENCHMARK = "benchmark"
|
|
32
|
+
JUDGE = "judge"
|
|
33
|
+
CODE = "code"
|
|
34
|
+
SECURITY = "security"
|
|
35
|
+
PERF = "perf"
|
|
36
|
+
HUMAN = "human"
|
|
37
|
+
RAG = "rag"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DataType(str, Enum):
|
|
41
|
+
"""The value domain of a score."""
|
|
42
|
+
|
|
43
|
+
NUMERIC = "numeric"
|
|
44
|
+
CATEGORICAL = "categorical"
|
|
45
|
+
BOOLEAN = "boolean"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class Direction(str, Enum):
|
|
49
|
+
"""Which way is better for a metric."""
|
|
50
|
+
|
|
51
|
+
MAXIMIZE = "maximize"
|
|
52
|
+
MINIMIZE = "minimize"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class Capability(str, Enum):
|
|
56
|
+
"""What a model backend can be asked for."""
|
|
57
|
+
|
|
58
|
+
GENERATE = "generate"
|
|
59
|
+
LOGLIKELIHOOD = "loglikelihood"
|
|
60
|
+
CHAT = "chat"
|
|
61
|
+
EMBED = "embed"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Source(str, Enum):
|
|
65
|
+
"""Where a run or score originated."""
|
|
66
|
+
|
|
67
|
+
SDK = "sdk"
|
|
68
|
+
UI = "ui"
|
|
69
|
+
ONLINE = "online"
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: auditkit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Evaluate any model on any dataset and any task — standalone, no platform required
|
|
5
|
+
Project-URL: Homepage, https://github.com/Lexsi-Labs/AuditKIT
|
|
6
|
+
Project-URL: Repository, https://github.com/Lexsi-Labs/AuditKIT
|
|
7
|
+
Author: Lexsi Labs
|
|
8
|
+
License: # Lexsi Labs Source Available License (LSAL), Version 1.2 (AuditKit)
|
|
9
|
+
|
|
10
|
+
## Preamble
|
|
11
|
+
|
|
12
|
+
This Source Available License governs use of the software known as **AuditKit**, together with its documentation, CLI, and example pipelines (collectively, the "Licensed Work"), developed and owned by **Lexsi Labs (Lithasa Technologies Pvt. Ltd.)** ("Licensor").
|
|
13
|
+
|
|
14
|
+
This is **not** an open-source license as defined by the [Open Source Initiative (OSI)](https://opensource.org/). It grants **academic research and teaching** MIT-like permissions: free use, modification, and redistribution with the notice intact. Organizations must acknowledge their use or obtain permission (Section 1A). It also bars commercial exploitation.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. Grant of Rights
|
|
19
|
+
|
|
20
|
+
Subject to the terms of this License, permission is hereby granted, free of charge, to any person obtaining a copy of the Licensed Work, to use, copy, modify, merge, publish, and redistribute the Licensed Work and derivative works thereof, **for Noncommercial Purposes only**, provided that the above copyright notice and this License are included in full in all copies or substantial portions of the Licensed Work.
|
|
21
|
+
|
|
22
|
+
For academic research and teaching, this grant is MIT-like: you may use, modify, and redistribute the Licensed Work, provided the copyright notice and this License travel with every copy.
|
|
23
|
+
|
|
24
|
+
**Noncommercial Purposes** means:
|
|
25
|
+
|
|
26
|
+
* personal use for research, experimentation, private study, or hobby projects;
|
|
27
|
+
* academic and scholarly research, teaching, and publication (including use in papers, theses, benchmarks, and reproducibility artifacts).
|
|
28
|
+
|
|
29
|
+
Research and teaching by academics and their groups, including work done at a university or public research body, falls under this Section. Section 1A governs use by an organization as such, including a charitable organization, educational institution, public research organization, or government body acting for its own operations.
|
|
30
|
+
|
|
31
|
+
## 1A. Use by Organizations
|
|
32
|
+
|
|
33
|
+
Before any organization, including a charitable organization, educational institution, public research organization, or government body, uses the Licensed Work for **internal evaluation, red-teaming, benchmarking, auditing, or any use in connection with developing, evaluating, or safeguarding its own models, products, or services**, whether or not it charges a fee or provides the Licensed Work to third parties, it must either:
|
|
34
|
+
|
|
35
|
+
* obtain Licensor's **prior written permission**; or
|
|
36
|
+
* provide Licensor a written **acknowledgement of use**, identifying the organization, the intended use, and an undertaking to attribute the Licensed Work, which Licensor may accept in place of negotiated permission.
|
|
37
|
+
|
|
38
|
+
Both go to **support@lexsi.ai**.
|
|
39
|
+
|
|
40
|
+
Licensor grants permission at its discretion. The written permission sets out the terms, which may include sharing with Licensor the evaluation results the Licensed Work produces, in AuditKit's standard report format, excluding model weights, training data, prompt text, and model generations. Licensor uses shared results for research and for improving the Licensed Work, and handles them under the terms stated in the written permission.
|
|
41
|
+
|
|
42
|
+
Permission under this Section does not authorize any use described in Section 2.
|
|
43
|
+
|
|
44
|
+
## 2. Commercial Restriction
|
|
45
|
+
|
|
46
|
+
Without a separate **commercial license** from Lexsi Labs, you may **not** Sell the Licensed Work. "**Sell**" means practicing any right granted to you under this License to provide to third parties, for a fee or other consideration, a product or service whose value derives, entirely or substantially, from the functionality of the Licensed Work, including:
|
|
47
|
+
|
|
48
|
+
* offering the Licensed Work, or a derivative of it, as a commercial product, paid service, SaaS, hosted, or API offering;
|
|
49
|
+
* embedding the Licensed Work in proprietary or revenue-generating software;
|
|
50
|
+
* paid consulting or support whose substance is the Licensed Work.
|
|
51
|
+
|
|
52
|
+
If you redistribute a modified version, you must mark it as modified and must not present it as the original. You may also not **re-license, rebrand, or redistribute** the Licensed Work under different terms, nor use **Lexsi Labs**, **AuditKit**, or related trademarks, logos, or branding except to identify unmodified, licensed copies.
|
|
53
|
+
|
|
54
|
+
## 3. Patents
|
|
55
|
+
|
|
56
|
+
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. Any patent rights of Licensor relating to the Licensed Work are reserved and may be licensed only under a separate written agreement with Licensor.
|
|
57
|
+
|
|
58
|
+
## 3A. Third-Party Components
|
|
59
|
+
|
|
60
|
+
The Licensed Work evaluates and audits third-party base models and draws on third-party benchmarks and datasets. Each carries its own license, and this License grants no rights under any of them. You must comply with those terms in addition to this License, including any restrictions a base-model or dataset license places on your use of it.
|
|
61
|
+
|
|
62
|
+
## 4. Ownership
|
|
63
|
+
|
|
64
|
+
All rights, title, and interest in and to the Licensed Work remain with **Lithasa Technologies Pvt. Ltd.** Except as expressly stated in Sections 1 and 1A, nothing in this License transfers ownership or any other rights to the Licensee.
|
|
65
|
+
|
|
66
|
+
## 5. Contributions
|
|
67
|
+
|
|
68
|
+
If you submit modifications, pull requests, or patches ("Contributions") to Lexsi Labs, you grant Lexsi Labs a perpetual, worldwide, royalty-free right to use, modify, distribute, and license your Contributions under any terms, including commercial ones, and you represent that you have the right to make such Contributions.
|
|
69
|
+
|
|
70
|
+
## 6. Warranty Disclaimer and Responsibility for Use
|
|
71
|
+
|
|
72
|
+
THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE LICENSOR OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.
|
|
73
|
+
|
|
74
|
+
**You alone are responsible for your use of the Licensed Work.** This includes every evaluation, audit, output, or system you produce with it, and your compliance with applicable law. This responsibility applies to academic, personal, organizational, and commercial use alike. Licensor has no duty to monitor your use and bears no liability for misuse of the Licensed Work by you or by any third party who obtained it through you.
|
|
75
|
+
|
|
76
|
+
The Licensed Work is a research and auditing tool. Any measurements or findings it reports hold only under the conditions you configure. They do not certify that any model is safe to deploy; that decision rests with you.
|
|
77
|
+
|
|
78
|
+
If you use the Licensed Work under Section 1A or under a commercial license, you will, to the extent permitted by applicable law, indemnify and hold harmless Licensor and its contributors against any claim, loss, or expense, including legal fees, arising from your use or misuse of the Licensed Work or from any breach of this License by you. This indemnity does not apply to personal or academic use under Section 1; the two preceding paragraphs govern that use.
|
|
79
|
+
|
|
80
|
+
## 7. Termination
|
|
81
|
+
|
|
82
|
+
This License terminates without notice if you breach any of its terms. On termination, you must stop using the Licensed Work and destroy every copy in your possession. Licenses of parties who received the Licensed Work from you remain in force provided they remain in compliance.
|
|
83
|
+
|
|
84
|
+
Sections 3, 3A, 4, 5, 6, and 8 survive termination.
|
|
85
|
+
|
|
86
|
+
## 8. Governing Law and General Terms
|
|
87
|
+
|
|
88
|
+
This License shall be governed by and construed in accordance with the **laws of India**, without regard to its conflict of law principles. If a court holds any provision of this License unenforceable, the remaining provisions stay in effect. Licensor may publish revised versions of this License; a copy of the Licensed Work remains under the version it was received under unless you accept a later version.
|
|
89
|
+
|
|
90
|
+
## 9. Contact
|
|
91
|
+
|
|
92
|
+
For acknowledgements and permission requests under Section 1A, and for commercial use, partnership, or redistribution rights under Section 2, contact:
|
|
93
|
+
**support@lexsi.ai** · **https://lexsi.ai**
|
|
94
|
+
|
|
95
|
+
## 10. Notice
|
|
96
|
+
|
|
97
|
+
**AuditKit** © 2026 **Lithasa Technologies Pvt. Ltd.**
|
|
98
|
+
Licensed under the **Lexsi Labs Source Available License (LSAL) v1.2**.
|
|
99
|
+
**Academic research and teaching are free on MIT-like terms. Use by any organization requires written acknowledgement or permission (Section 1A). Commercial use requires a commercial license (Section 2).**
|
|
100
|
+
License-File: LICENSE.md
|
|
101
|
+
Classifier: Development Status :: 4 - Beta
|
|
102
|
+
Classifier: Intended Audience :: Developers
|
|
103
|
+
Classifier: Intended Audience :: Science/Research
|
|
104
|
+
Classifier: Programming Language :: Python :: 3
|
|
105
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
106
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
107
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
108
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
109
|
+
Classifier: Topic :: Software Development :: Testing
|
|
110
|
+
Requires-Python: >=3.10
|
|
111
|
+
Provides-Extra: all
|
|
112
|
+
Requires-Dist: accelerate; extra == 'all'
|
|
113
|
+
Requires-Dist: anthropic; extra == 'all'
|
|
114
|
+
Requires-Dist: bert-score; extra == 'all'
|
|
115
|
+
Requires-Dist: datasets; extra == 'all'
|
|
116
|
+
Requires-Dist: gitpython; extra == 'all'
|
|
117
|
+
Requires-Dist: litellm; extra == 'all'
|
|
118
|
+
Requires-Dist: lm-eval; extra == 'all'
|
|
119
|
+
Requires-Dist: mlcroissant; extra == 'all'
|
|
120
|
+
Requires-Dist: mlflow; extra == 'all'
|
|
121
|
+
Requires-Dist: openai; extra == 'all'
|
|
122
|
+
Requires-Dist: pillow; extra == 'all'
|
|
123
|
+
Requires-Dist: pytest; extra == 'all'
|
|
124
|
+
Requires-Dist: pytest-asyncio; extra == 'all'
|
|
125
|
+
Requires-Dist: pytest-mock; extra == 'all'
|
|
126
|
+
Requires-Dist: requests; extra == 'all'
|
|
127
|
+
Requires-Dist: torch>=2.4; extra == 'all'
|
|
128
|
+
Requires-Dist: torchmetrics; extra == 'all'
|
|
129
|
+
Requires-Dist: transformers<5,>=4.44; extra == 'all'
|
|
130
|
+
Requires-Dist: vllm<0.20,>=0.15; extra == 'all'
|
|
131
|
+
Provides-Extra: anthropic
|
|
132
|
+
Requires-Dist: anthropic; extra == 'anthropic'
|
|
133
|
+
Provides-Extra: bert-score
|
|
134
|
+
Requires-Dist: bert-score; extra == 'bert-score'
|
|
135
|
+
Requires-Dist: torch>=2.4; extra == 'bert-score'
|
|
136
|
+
Provides-Extra: dev
|
|
137
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
138
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
139
|
+
Requires-Dist: pytest-mock; extra == 'dev'
|
|
140
|
+
Provides-Extra: interop
|
|
141
|
+
Requires-Dist: datasets; extra == 'interop'
|
|
142
|
+
Requires-Dist: gitpython; extra == 'interop'
|
|
143
|
+
Requires-Dist: mlcroissant; extra == 'interop'
|
|
144
|
+
Provides-Extra: litellm
|
|
145
|
+
Requires-Dist: litellm; extra == 'litellm'
|
|
146
|
+
Provides-Extra: lmeval
|
|
147
|
+
Requires-Dist: accelerate; extra == 'lmeval'
|
|
148
|
+
Requires-Dist: lm-eval; extra == 'lmeval'
|
|
149
|
+
Provides-Extra: mlflow
|
|
150
|
+
Requires-Dist: mlflow; extra == 'mlflow'
|
|
151
|
+
Provides-Extra: openai
|
|
152
|
+
Requires-Dist: openai; extra == 'openai'
|
|
153
|
+
Provides-Extra: requests
|
|
154
|
+
Requires-Dist: requests; extra == 'requests'
|
|
155
|
+
Provides-Extra: transformers
|
|
156
|
+
Requires-Dist: torch>=2.4; extra == 'transformers'
|
|
157
|
+
Requires-Dist: transformers<5,>=4.44; extra == 'transformers'
|
|
158
|
+
Provides-Extra: vision
|
|
159
|
+
Requires-Dist: pillow; extra == 'vision'
|
|
160
|
+
Requires-Dist: torchmetrics; extra == 'vision'
|
|
161
|
+
Provides-Extra: vllm
|
|
162
|
+
Requires-Dist: vllm<0.20,>=0.15; extra == 'vllm'
|
|
163
|
+
Description-Content-Type: text/markdown
|
|
164
|
+
|
|
165
|
+
<p align="center">
|
|
166
|
+
<a href="https://github.com/Lexsi-Labs/AuditKIT">
|
|
167
|
+
<picture>
|
|
168
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/auditkit-logo-light.png">
|
|
169
|
+
<img src="docs/assets/auditkit-logo-dark.png" alt="AuditKit" width="480">
|
|
170
|
+
</picture>
|
|
171
|
+
</a>
|
|
172
|
+
</p>
|
|
173
|
+
|
|
174
|
+
<p align="center">
|
|
175
|
+
<b>Evaluate any model on any dataset and any task.</b><br>
|
|
176
|
+
One library for benchmark, judge, code, red-team, security, and performance<br>
|
|
177
|
+
evaluation — zero required deps.
|
|
178
|
+
</p>
|
|
179
|
+
|
|
180
|
+
<p align="center">
|
|
181
|
+
<a href="https://pypi.org/project/auditkit/"><img src="https://img.shields.io/badge/pypi-v1.0.0-0a8868" alt="PyPI v1.0.0"></a>
|
|
182
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+"></a>
|
|
183
|
+
<a href="https://github.com/Lexsi-Labs/AuditKIT/blob/main/LICENSE.md"><img src="https://img.shields.io/badge/license-LSAL--1.2-lightgrey" alt="License: LSAL-1.2 (source-available, noncommercial)"></a>
|
|
184
|
+
<a href="https://lexsi-labs.github.io/AuditKIT/"><img src="https://img.shields.io/badge/docs-internal%20·%20Lexsi%20SSO-4c6ef5" alt="Documentation (internal, requires Lexsi SSO)"></a>
|
|
185
|
+
<a href="https://github.com/Lexsi-Labs/AuditKIT/actions"><img src="https://img.shields.io/badge/tests-750%20passing-brightgreen" alt="Tests"></a>
|
|
186
|
+
</p>
|
|
187
|
+
|
|
188
|
+
<p align="center">
|
|
189
|
+
<a href="https://lexsi-labs.github.io/AuditKIT/">Documentation (internal)</a> ·
|
|
190
|
+
<a href="#quickstart">Quickstart</a> ·
|
|
191
|
+
<a href="#examples">Examples</a> ·
|
|
192
|
+
<a href="docs/community/contributing.md">Contributing</a>
|
|
193
|
+
</p>
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## TL;DR
|
|
198
|
+
|
|
199
|
+
| | |
|
|
200
|
+
|---|---|
|
|
201
|
+
| **What** | A unified Python library that evaluates any AI model on any dataset across any technique. |
|
|
202
|
+
| **Architecture** | 5-stage spine: Dataset → Adapter → Model → Metrics → RunResult. `ak.evaluate()` orchestrates it all. |
|
|
203
|
+
| **Techniques** | Benchmark, LLM-as-judge (GEval), code checks, RAG, hallucination, embedding similarity, toxicity/bias, pairwise/preference, red-teaming, security, performance |
|
|
204
|
+
| **Models** | 9 backends: OpenAI, Anthropic, HuggingFace, Lexsi, vLLM, LiteLLM, API, Groq, OpenRouter — all resolved via `AutoModel.resolve()`. Any `list[str] → list[str]` callable also works. |
|
|
205
|
+
| **Zero deps** | Core runs on stdlib. Backends and heavy metrics are optional extras (`pip install auditkit[openai]`). |
|
|
206
|
+
| **Fingerprints** | Every run gets a stable sha256 — results are cacheable, comparable, and reproducible by construction. |
|
|
207
|
+
| **Status** | 750+ tests, v1.0.0, LSAL-1.2 license (source-available, noncommercial). 10 metric families, 5 CLI subcommands, YAML config, MKDocs site. |
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Why AuditKIT
|
|
212
|
+
|
|
213
|
+
Evaluating AI models is fragmented. Academic benchmarks (MMLU, GSM8K) use one tool. LLM-as-judge evaluations use another. Red-teaming and performance profiling each have their own frameworks. There is no single library that does all of them with a consistent API, zero required dependencies, and a provenance-first data model.
|
|
214
|
+
|
|
215
|
+
AuditKIT is that library. It provides a unified evaluation spine that supports every technique, so you can compare results across benchmarks, judge evaluations, red-team probes, and performance profiles — all from a single `ak.evaluate()` call.
|
|
216
|
+
|
|
217
|
+
## Key features
|
|
218
|
+
|
|
219
|
+
- **Metric families.** Benchmark (exact match, F1, BLEU, ROUGE, ChrF), LLM-as-judge (GEval, rubric items), code/deterministic (contains, regex, JSON validation), RAG (lexical groundedness, context overlap/coverage), embedding similarity, hallucination detection, toxicity/bias, pairwise/preference (win rate, Elo, preference accuracy), security (DEFCON grade), performance (latency, throughput).
|
|
220
|
+
- **Zero required deps.** Core runs on the Python standard library alone. Heavy backends (BERTScore, vLLM, LiteLLM, OpenAI, Anthropic, HuggingFace) are optional extras.
|
|
221
|
+
- **Any model backend.** `echo` for testing, `openai:`, `anthropic:`, `hf:`, `lexsi:`, `vllm:`, `litellm:` (which also reaches Ollama, e.g. `litellm:ollama/llama3.1`), `api:`, `groq:`, `openrouter:`, or any callable. Auto-resolved via `AutoModel.resolve()`.
|
|
222
|
+
- **Many datasets, one model.** `evaluate_many()` runs one model across several datasets in a single call, returning one `RunResult` per dataset.
|
|
223
|
+
- **Red teaming.** Built-in adversarial probes (prompt injection, jailbreak, encoding, over-refusal) and detectors (keyword, refusal, injection success, system prompt leak) via `RedTeamRunner`.
|
|
224
|
+
- **Experiment tracking.** Named experiments with `ExperimentDB`, MLflow logging, cross-run comparison with bootstrap significance tests.
|
|
225
|
+
- **Model comparison.** `compare_models()` runs the same dataset against multiple models and produces side-by-side results with pairwise significance.
|
|
226
|
+
- **CLI with YAML config.** `auditkit eval`, `init`, `list`, `redteam`, `compare` subcommands. Define evaluations in YAML files with `prompts:`, model config, tags, and split strategies.
|
|
227
|
+
- **Provenance by default.** Every run writes a `RunResult` with a stable fingerprint (sha256 over model+seed+tasks+config). Results are cacheable and comparable by fingerprint.
|
|
228
|
+
|
|
229
|
+
## How it works
|
|
230
|
+
|
|
231
|
+
```mermaid
|
|
232
|
+
flowchart LR
|
|
233
|
+
A["Dataset<br/>Samples · Scenario · CSV"] --> B["Adapter<br/>generation · chat · instruction"]
|
|
234
|
+
B --> C["Model<br/>echo · openai · hf · vllm"]
|
|
235
|
+
C --> D{"Metrics"}
|
|
236
|
+
D -->|per sample| E["Score + Prediction"]
|
|
237
|
+
E --> F["Aggregate<br/>Stats · Headline"]
|
|
238
|
+
F --> G["RunResult<br/>fingerprint · cache"]
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Install
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
pip install auditkit # core (zero deps)
|
|
245
|
+
pip install "auditkit[openai]" # OpenAI backend
|
|
246
|
+
pip install "auditkit[all]" # all backends + heavy metrics
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Requires Python 3.10+ on Linux, macOS, or Windows.
|
|
250
|
+
|
|
251
|
+
<details>
|
|
252
|
+
<summary>More install options</summary>
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pip install "auditkit[anthropic]" # Anthropic backend
|
|
256
|
+
pip install "auditkit[litellm]" # LiteLLM (Ollama, etc.)
|
|
257
|
+
pip install "auditkit[vllm]" # vLLM backend
|
|
258
|
+
pip install "auditkit[transformers]" # HuggingFace + hallucination + embedding similarity
|
|
259
|
+
pip install "auditkit[bert-score]" # BERTScore
|
|
260
|
+
pip install "auditkit[mlflow]" # MLflow experiment tracking
|
|
261
|
+
|
|
262
|
+
# From source
|
|
263
|
+
pip install "auditkit @ git+https://github.com/Lexsi-Labs/AuditKIT.git"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
</details>
|
|
267
|
+
|
|
268
|
+
## Quickstart
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
import auditkit as ak
|
|
272
|
+
|
|
273
|
+
samples = [
|
|
274
|
+
ak.Sample(input="What is 2+2?", target="4"),
|
|
275
|
+
ak.Sample(input="What is 3+3?", target="6"),
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
result = ak.evaluate(samples, model=lambda prompts: prompts)
|
|
279
|
+
print(result.summary())
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**From the CLI:**
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
auditkit eval --model hf:gpt2 <<< "What is 2+2?"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**With a YAML config:**
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
model: openai:gpt-4o-mini
|
|
292
|
+
temperature: 0.0
|
|
293
|
+
prompts:
|
|
294
|
+
- "What is the capital of France?"
|
|
295
|
+
output: results.json
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
auditkit eval --config auditkit.yaml
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## What it evaluates
|
|
303
|
+
|
|
304
|
+
| Task | Technique | Example metrics |
|
|
305
|
+
|------|-----------|-----------------|
|
|
306
|
+
| Benchmark text | MCQ, generation | `ExactMatch`, `Bleu`, `F1Score` |
|
|
307
|
+
| LLM output quality | LLM-as-judge | `GEval`, `RubricItem` |
|
|
308
|
+
| RAG pipelines | RAG | `LexicalGroundedness`, `ContextOverlap` |
|
|
309
|
+
| Safety | Red-team | `KeywordDetector`, `DefconGrade`, probes |
|
|
310
|
+
| Performance | Latency/throughput | `LatencyStats`, `Throughput` |
|
|
311
|
+
|
|
312
|
+
## Output
|
|
313
|
+
|
|
314
|
+
Every `evaluate()` returns a `RunResult`:
|
|
315
|
+
|
|
316
|
+
| Field | Contents |
|
|
317
|
+
|-------|----------|
|
|
318
|
+
| `headline` | Per-metric averages |
|
|
319
|
+
| `predictions` | Per-sample scores with input, output, expected |
|
|
320
|
+
| `stats` | Full statistics (mean, std, min, max, count) |
|
|
321
|
+
| `fingerprint` | Stable sha256 for caching and comparison |
|
|
322
|
+
| `config` | The `RunConfig` used (seed, temperature, etc.) |
|
|
323
|
+
| `errors` | Any errors encountered during the run |
|
|
324
|
+
|
|
325
|
+
## Examples
|
|
326
|
+
|
|
327
|
+
Colab-ready notebooks with real models and real datasets — see
|
|
328
|
+
[`examples/README.md`](examples/README.md) for the full, current list.
|
|
329
|
+
|
|
330
|
+
| Example | File |
|
|
331
|
+
|---------|------|
|
|
332
|
+
| Full pipeline: adapter, 5 metrics, LLM judge, LLM annotator | [`01_full_evaluation_pipeline.ipynb`](examples/01_full_evaluation_pipeline.ipynb) |
|
|
333
|
+
| Generation across two real HF model families, compared | [`02_generation_across_hf_families.ipynb`](examples/02_generation_across_hf_families.ipynb) |
|
|
334
|
+
| Custom annotators (regex, LLM-backed, fully custom) | [`03_custom_annotators.ipynb`](examples/03_custom_annotators.ipynb) |
|
|
335
|
+
| Metrics deep dive: built-in, custom, LLM-as-judge, RAG | [`04_metrics_deep_dive.ipynb`](examples/04_metrics_deep_dive.ipynb) |
|
|
336
|
+
| Every data type/task kind: generative, MCQ, RAG, precomputed, chat | [`05_data_types.ipynb`](examples/05_data_types.ipynb) |
|
|
337
|
+
| Model comparison deep dive: `compare_models()` + `RunComparison` | [`06_model_comparison.ipynb`](examples/06_model_comparison.ipynb) |
|
|
338
|
+
| Annotators across 4 real model families, then compared together | [`07_annotators_across_models.ipynb`](examples/07_annotators_across_models.ipynb) |
|
|
339
|
+
| `CompareResult` deep dive: what `compare_models()`'s native per-model support still can't express (different scorers per model), full method surface | [`08_compare_result_deep_dive.ipynb`](examples/08_compare_result_deep_dive.ipynb) |
|
|
340
|
+
| `GuardJudge` implementation check: all 5 profiles, real and offline | [`09_guard_judge_implementation_check.ipynb`](examples/09_guard_judge_implementation_check.ipynb) |
|
|
341
|
+
| `GuardJudge` with real, flagship guard models | [`10_guard_judge_legit_models.ipynb`](examples/10_guard_judge_legit_models.ipynb) |
|
|
342
|
+
| `EncoderJudge`: the base mechanism plus its two prebuilt subclasses | [`11_encoder_judge_prebuilts.ipynb`](examples/11_encoder_judge_prebuilts.ipynb) |
|
|
343
|
+
| Performance metrics on a real, large-scale evaluation | [`12_performance_metrics_demo.ipynb`](examples/12_performance_metrics_demo.ipynb) |
|
|
344
|
+
|
|
345
|
+
## Applications
|
|
346
|
+
|
|
347
|
+
Real-world scenarios answered end to end, not feature tours — see
|
|
348
|
+
[`examples/applications/README.md`](examples/applications/README.md). Only `01` uses the
|
|
349
|
+
`lm-evaluation-harness` integration (`ak.run_lmeval()`, needs
|
|
350
|
+
`auditkit[lmeval]`), as an authoritative cross-check alongside the native
|
|
351
|
+
evaluation; none of the others do.
|
|
352
|
+
|
|
353
|
+
| Application | File |
|
|
354
|
+
|-------------|------|
|
|
355
|
+
| How much does pruning severity (20%/40%/60%) degrade a model? Real BoolQ, real annotator, ship/no-ship verdicts, cross-checked via `ak.run_lmeval()` | [`01_application_pruned_llama_boolq.ipynb`](examples/applications/01_application_pruned_llama_boolq.ipynb) |
|
|
356
|
+
| Healthcare: clinical QA correctness vs. grounding (PubMedQA) | [`02_application_healthcare_pubmedqa.ipynb`](examples/applications/02_application_healthcare_pubmedqa.ipynb) |
|
|
357
|
+
| Finance: QA grounded in real SEC 10-K filings | [`03_application_finance_10k_qa.ipynb`](examples/applications/03_application_finance_10k_qa.ipynb) |
|
|
358
|
+
| E-commerce: review-sentiment triage at scale | [`04_application_ecommerce_review_triage.ipynb`](examples/applications/04_application_ecommerce_review_triage.ipynb) |
|
|
359
|
+
| Education: auto-graded tutoring, correctness vs. explanation | [`05_application_education_arc_tutor.ipynb`](examples/applications/05_application_education_arc_tutor.ipynb) |
|
|
360
|
+
| Enterprise search: internal knowledge assistant (real retrieval + RAG grounding) | [`06_application_enterprise_search_rag.ipynb`](examples/applications/06_application_enterprise_search_rag.ipynb) |
|
|
361
|
+
| LLM-as-judge via a real BERT NLI classifier, not a generative model | [`07_application_bert_nli_judge.ipynb`](examples/applications/07_application_bert_nli_judge.ipynb) |
|
|
362
|
+
|
|
363
|
+
## Repository map
|
|
364
|
+
|
|
365
|
+
| Directory | Description | README |
|
|
366
|
+
|-----------|-------------|--------|
|
|
367
|
+
| [`src/auditkit/`](src/auditkit/) | Core library — spine, runner, metrics, models, CLI | [README](src/auditkit/README.md) |
|
|
368
|
+
| [`src/auditkit/metrics/`](src/auditkit/metrics/) | Metric families | [README](src/auditkit/metrics/README.md) |
|
|
369
|
+
| [`src/auditkit/model/`](src/auditkit/model/) | Model backends (echo, openai, hf, vllm, etc.) | [README](src/auditkit/model/README.md) |
|
|
370
|
+
| [`src/auditkit/redteam/`](src/auditkit/redteam/) | Red team probes and detectors | [README](src/auditkit/redteam/README.md) |
|
|
371
|
+
| [`src/auditkit/scenarios/`](src/auditkit/scenarios/) | Built-in benchmark datasets | [README](src/auditkit/scenarios/README.md) |
|
|
372
|
+
| [`tests/`](tests/) | Test suite (750+ tests) | [README](tests/README.md) |
|
|
373
|
+
| [`examples/`](examples/) | Colab-ready example notebooks | [README](examples/README.md) |
|
|
374
|
+
| [`examples/applications/`](examples/applications/) | Real-world application notebooks | [README](examples/applications/README.md) |
|
|
375
|
+
| [`docs/`](docs/) | MkDocs documentation site (internal, requires Lexsi SSO) | [index](docs/index.md) |
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Developed by Lexsi Labs
|
|
380
|
+
|
|
381
|
+
<p align="center">
|
|
382
|
+
Created by the team at <strong>Lexsi Labs</strong>, AuditKIT provides a unified evaluation spine for AI models across every technique and modality.
|
|
383
|
+
</p>
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## License
|
|
388
|
+
|
|
389
|
+
This project is released under the [Lexsi Labs Source Available License (LSAL) v1.2](LICENSE.md) — free for academic research and teaching on MIT-like terms; use by any organization requires written acknowledgement or permission (Section 1A); a separate commercial license is required to sell it or embed it in a paid product.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## Join Community / Contribute
|
|
394
|
+
|
|
395
|
+
- Issues and discussions are welcomed on the [GitHub issue tracker](https://github.com/Lexsi-Labs/AuditKIT/issues).
|
|
396
|
+
- See the **Contributing** section for contribution standards, code reviews, and documentation tips.
|