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.
Files changed (81) hide show
  1. auditkit/README.md +99 -0
  2. auditkit/__init__.py +177 -0
  3. auditkit/__main__.py +3 -0
  4. auditkit/_bootstrap.py +77 -0
  5. auditkit/_identity_guard.py +99 -0
  6. auditkit/adapter.py +264 -0
  7. auditkit/annotator.py +339 -0
  8. auditkit/api.py +502 -0
  9. auditkit/assets/auditkit_logo.png +0 -0
  10. auditkit/cache.py +47 -0
  11. auditkit/cli.py +417 -0
  12. auditkit/comparison.py +563 -0
  13. auditkit/diff.py +265 -0
  14. auditkit/errors.py +54 -0
  15. auditkit/evaluator.py +20 -0
  16. auditkit/experiment.py +145 -0
  17. auditkit/hf_publish.py +262 -0
  18. auditkit/lmeval_engine.py +550 -0
  19. auditkit/loaders.py +121 -0
  20. auditkit/logs.py +18 -0
  21. auditkit/metric.py +199 -0
  22. auditkit/metrics/README.md +15 -0
  23. auditkit/metrics/__init__.py +0 -0
  24. auditkit/metrics/code.py +222 -0
  25. auditkit/metrics/embedding.py +131 -0
  26. auditkit/metrics/encoder_judge.py +423 -0
  27. auditkit/metrics/generation.py +331 -0
  28. auditkit/metrics/guard.py +412 -0
  29. auditkit/metrics/hallucination.py +45 -0
  30. auditkit/metrics/judge.py +547 -0
  31. auditkit/metrics/pairwise.py +153 -0
  32. auditkit/metrics/perf.py +53 -0
  33. auditkit/metrics/rag.py +149 -0
  34. auditkit/metrics/security.py +64 -0
  35. auditkit/metrics/toxicity.py +238 -0
  36. auditkit/model/README.md +16 -0
  37. auditkit/model/__init__.py +485 -0
  38. auditkit/model/anthropic.py +94 -0
  39. auditkit/model/api_gen.py +133 -0
  40. auditkit/model/groq_gen.py +121 -0
  41. auditkit/model/hf_gen.py +385 -0
  42. auditkit/model/lexsi.py +155 -0
  43. auditkit/model/litellm_gen.py +65 -0
  44. auditkit/model/openai.py +90 -0
  45. auditkit/model/openrouter_gen.py +152 -0
  46. auditkit/model/vllm_gen.py +316 -0
  47. auditkit/model_compare.py +655 -0
  48. auditkit/redteam/README.md +9 -0
  49. auditkit/redteam/__init__.py +26 -0
  50. auditkit/redteam/detector.py +37 -0
  51. auditkit/redteam/detectors/README.md +5 -0
  52. auditkit/redteam/detectors/builtin.py +126 -0
  53. auditkit/redteam/probe.py +39 -0
  54. auditkit/redteam/probes/README.md +5 -0
  55. auditkit/redteam/probes/builtin.py +85 -0
  56. auditkit/redteam/runner.py +206 -0
  57. auditkit/registry.py +65 -0
  58. auditkit/report.py +278 -0
  59. auditkit/report_format.py +52 -0
  60. auditkit/router.py +54 -0
  61. auditkit/runner.py +575 -0
  62. auditkit/runspec.py +159 -0
  63. auditkit/sample.py +40 -0
  64. auditkit/scenario.py +88 -0
  65. auditkit/scenarios/README.md +10 -0
  66. auditkit/scenarios/__init__.py +4 -0
  67. auditkit/scenarios/arc.py +33 -0
  68. auditkit/scenarios/gsm8k.py +32 -0
  69. auditkit/scenarios/hellaswag.py +33 -0
  70. auditkit/scenarios/humaneval.py +32 -0
  71. auditkit/scenarios/mmlu.py +34 -0
  72. auditkit/scenarios/truthfulqa.py +33 -0
  73. auditkit/score.py +165 -0
  74. auditkit/scorers.py +117 -0
  75. auditkit/scoring.py +79 -0
  76. auditkit/types.py +69 -0
  77. auditkit-1.0.0.dist-info/METADATA +396 -0
  78. auditkit-1.0.0.dist-info/RECORD +81 -0
  79. auditkit-1.0.0.dist-info/WHEEL +4 -0
  80. auditkit-1.0.0.dist-info/entry_points.txt +2 -0
  81. 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.