demoparity
Counterfactual demographic auditing for LLM prompts. Swap protected attributes (sex, race, residency, or anything you define) into an otherwise identical prompt, send every variant to the same model, and test statistically whether the response changes with the attribute.
This work is a generalised, reusable version of the paired-prompt audit design from my Bachelor Thesis "Breaking the Bias: Addressing the Social Biases in Artificial Natural Language Models for Neuroscientific and Medical Implementation" (Steward, 2023; presented at the 3rd Connected Learning Symposium (2024), and the Black Scholar and Expert Conference (2023)). My original thesis built a "NeuroAnalyser" tool around a ChatGPT-3.5 use case.
demoparity keeps the same statistical design (descriptive stats, an enter-method OLS regression, Pearson's correlations with Fisher's z) but detaches it from one use case, so it works for multiple uses.
Motivation
Common design for LLM bias checks look at some example outputs or run a static benchmark dataset once. This design also wants to assess why a model's behaviour may differ, or whether different responses show a pattern that is distinguishable from noise.
Install
```bash
pip install demoparity
pip install demoparity[litellm] # call a model
How it works
build_designcrosses every scenario with every attribute-level combination.run_designsends each prompt through a model, concurrently, via litellm (OpenAI, Anthropic, Gemini, Bedrock, Ollama, 100+ providers, one model-string convention). Each provider's key comes from its standard environment variable (OPENAI_API_KEY,ANTHROPIC_API_KEY, ...).annotateextracts response length and attribute-mention counts.run_auditruns descriptive stats, an enter-method OLS regression, and Pearson correlations, and returns a report you can save to Markdown/CSV.
import demoparity as dp
design = dp.build_design(
[dp.Scenario("c1", "A {sex} patient reports a headache. Advise.")],
[dp.Attribute("sex", ["neutral", "male", "female"])],
)
results = dp.run_design(design, dp.litellm_generator(model="gpt-4o-mini"))
results = dp.annotate(results)
report = dp.run_audit(results, outcomes=["word_count"], predictors=["sex"])
print(report.to_markdown())
See examples/ for full worked audits with mention-tracking, checkpointing, and saved output.
Examples
Require a real API key (see Install above)
examples/hiring_screen_audit.pyis a resume screener, sex/name-origin/locationexamples/clinical_triage_audit.pymirrors clinical triage, sex/race/residency (my thesis study)
export OPENAI_API_KEY=sk-..
python examples/hiring_screen_audit.py --model gpt-4o-mini
Concurrency and checkpointing
run_design sends requests concurrently (concurrency=, default 5) and, with checkpoint_path=, writes each completed trial to a JSONL file as it finishes. Re-running with the same checkpoint path resumes and skips already-completed trials.
Saving output
from demoparity.persistence import save_results, save_report
save_results(results, "results.csv")
save_report(report, "report_dir") # report.md + descriptives.csv + correlations.csv + one CSV per regression
Command line
demoparity design spec.json --out design.csv
demoparity run design.csv --model gpt-4o-mini --checkpoint run.jsonl --out results.csv
demoparity report results.csv --outcomes word_count --predictors sex --save-dir report_dir
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file demoparity-0.2.0.tar.gz.
File metadata
- Download URL: demoparity-0.2.0.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c16bd4b1460bf6ad2a4a6f45527cdb7c5555c2e224b91a085c38444e464dc0b6
|
|
| MD5 |
1982bae02453925010d6dd7c932c1eb4
|
|
| BLAKE2b-256 |
c1e5470c1f9c40aa29d44a67fce60b3b867832d3494b236d1bab16c74e59a5f3
|
File details
Details for the file demoparity-0.2.0-py3-none-any.whl.
File metadata
- Download URL: demoparity-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e7a91d5c8f83287f879de3ad60a670353986429e568cc34f6979b564038a661
|
|
| MD5 |
41b07590218553379e6fd0cf25e0dc2a
|
|
| BLAKE2b-256 |
0f15da9b91b24162bc96a1bf812a802e9096dbd152f2c7a6d60e6e1140c5a395
|