FairStream is a research-oriented streaming fairness-aware AutoML system. It combines online model selection, streaming fairness measurement, a dynamic fairness envelope, drift monitoring, explainability, topology-based bias diagnostics, and an interactive dashboard for running experiments on tabular data streams.
The system is built for settings where:
- data arrives as a stream rather than a single static batch
- predictive quality and fairness both need to be monitored continuously
- fairness may drift over time even when raw accuracy looks stable
- the acceptable fairness boundary should adapt to evidence quality and recent drift
At a high level, the runtime loop is:
- ingest a stream window
- measure fairness on the window
- smooth fairness and estimate drift/uncertainty
- update a dynamic fairness envelope
- evaluate candidate models against performance and fairness constraints
- let the OSMAC-style optimizer propose better configurations
- expose live metrics, diagnostics, and benchmark views through the API and Streamlit UI
The current design centers on three pieces:
SFM(Streaming Fairness Measurement): producesfm_smooth,fm_drift, andfm_uncertaintyDFE(Dynamic Fairness Envelope): maintains a time-varying allowable fairness region, typically as an upper bound on a fairness gap- constrained online optimization: the optimizer ranks candidates using predictive utility, feasibility probability, fairness risk, and support/reliability penalties
- streaming fairness-aware AutoML over tabular datasets
- rolling-window fairness monitoring and drift detection
- dynamic fairness envelope updates from SFM telemetry
- online candidate evaluation and OSMAC-style constrained optimization
- fairness scope management for protected attributes and intersections
- topology-aware bias analysis
- explainability and LLM-backed narrative auditing
- optional CO2/emissions tracking through CodeCarbon
- Streamlit dashboard for uploads, live monitoring, benchmark views, and debugging
- built-in benchmark helpers for Adult, German Credit, and COMPAS-style datasets
FairStream/
|- backend/
| |- api.py
| |- candidate_evaluator.py
| |- dynamic_fairness_envelope.py
| |- fairness_engine.py
| |- fairness_scope_manager.py
| |- osmac_optimizer.py
| |- topological_bias_engine.py
|- Dataset
|- experiments/
| |- synthetic_streams.py
|- forntend/
| |- app.py
`- README.md
Notes:
- the UI folder is named
forntendin the repository; the README keeps that spelling when referencing paths or commands Dataset/contains local benchmark datasets and stream variantsexperiments/reports/contains generated HTML and JSON report artifacts from prior runs
- backend/api.py: Flask API, experiment registry, polling loop, and payload assembly
- backend/candidate_evaluator.py: window-level candidate scoring for accuracy, fairness, feasibility, and constrained utility
- backend/dynamic_fairness_envelope.py: adaptive upper/lower fairness bounds driven by SFM telemetry
- backend/osmac_optimizer.py: streaming constrained optimizer with feasibility-first and CEI-style acquisition
- backend/fairness_engine.py: fairness metric computation and fairness snapshots
- backend/fairness_scope_manager.py: attribute/intersection scope selection
- backend/topological_bias_engine.py: topology and cluster-based bias diagnostics
- backend/explainability_engine.py: model and state explanations
- backend/llm_auditor.py: narrative audit generation over Ollama-compatible LLM endpoints
- backend/offline_benchmarks: reference search baselines and dataset loaders
- forntend/app.py is a Streamlit application
- default backend target:
http://127.0.0.1:5000 - the UI exposes dataset upload, fairness scope controls, live metrics, optimizer views, fairness diagnostics, benchmark views, comparison views, LLM output, and raw payload debugging
The intended research path in the current code is:
- upload or stream a dataset
- choose the target and protected attribute(s)
- configure fairness scope, window size, and optimizer behavior
- run the streaming experiment
- monitor fairness gaps, drift, uncertainty, envelope pressure, and model accuracy
- compare live optimization with reference benchmark behavior
- inspect generated figures and reports
The backend expects tabular data represented as records. In the Streamlit UI this is uploaded as a CSV and then sent to the API as JSON rows.
Important assumptions:
- the target column must be binary or coercible to binary
- at least one sensitive attribute should be supplied for fairness tracking
- benchmark helpers assume binary sensitive grouping for the current streaming FairBO-style reference flow
- some built-in loaders normalize common benchmark conventions automatically
Examples handled in code:
- Adult:
incometarget withsexas a sensitive attribute - German Credit: one of
class,credit_risk,risk,target, orlabel, with gender/sex information - COMPAS:
two_year_recidor equivalent, with race/ethnicity information
The benchmark loader registry in backend/offline_benchmarks/datasets.py currently exposes:
adultgermancompas
The repository also contains other local CSVs and generated stream variants under Dataset/, which can be uploaded directly through the UI even when they are not formal registry entries.
Recommended:
- Python 3.10
pip- a virtual environment
Optional:
- Ollama for local LLM auditing
- CodeCarbon if you want emissions tracking
Use the included requirements.txt:
pip install -r requirements.txtThe file includes the main runtime, plotting, benchmark, and optional integration packages already used by the repository.
Optional extras beyond that:
pip install jupyterIf you plan to use the LLM auditor, run an Ollama server separately and make sure the configured model is available.
Open two terminals from the repository root.
python backend/api.pyThis starts the Flask server on http://127.0.0.1:5000.
streamlit run forntend/app.pyBy default, the Streamlit app points at http://127.0.0.1:5000.
The backend exposes these main routes:
GET /healthGET /experimentsGET /experiment_meta/<exp_id>POST /start_experimentGET /poll_experiment/<exp_id>?chunk_size=NGET /finalize_experiment/<exp_id>POST /reset_experiment/<exp_id>POST /explain_mapper_node/<exp_id>
- call
POST /start_experiment - store the returned
experiment_id - repeatedly call
GET /poll_experiment/<exp_id> - optionally inspect
GET /experiment_meta/<exp_id> - finalize with
GET /finalize_experiment/<exp_id>
The Streamlit app sends a payload like this:
{
"dataset": [
{"feature_1": 0.12, "feature_2": "A", "target": 1, "sex": "male"}
],
"dataset_name": "adult",
"target": "target",
"sensitive_attr": ["sex"],
"window_size": 500,
"sample_budget": 5000
}Optional payload sections in the current code include configuration for:
- fairness scope
- optimizer runtime
- candidate evaluator behavior
- static or streaming benchmark settings
- mapper behavior
The Streamlit app is the easiest way to work with the project.
Typical flow:
- upload a CSV
- pick the target column
- select one or more sensitive attributes
- choose the rolling window size and sample budget
- configure fairness scope and benchmark options if needed
- start the experiment
- monitor live plots and diagnostics while polling runs
The UI includes:
- dataset preview and schema inspection
- target mapping preview
- live progress tracking
- accuracy and fairness trend plots
- SFM and DFE views
- optimizer convergence and candidate history views
- benchmark and method comparison views
- LLM auditor output
- raw payload debugging
The current implementation and accompanying design doc align around these choices:
- primary fairness control is a one-sided upper bound on a fairness gap
- the dynamic fairness envelope tightens when drift, uncertainty, or violations increase
- relaxation is gated by support and confidence
- candidate ranking uses constrained utility rather than raw predictive score alone
- feasible recent candidates are preferred for incumbent selection
- streaming fairness telemetry is tracked explicitly through
fm_raw,fm_smooth,fm_drift, andfm_uncertainty
The streaming reference benchmarking integrated into the experiment flow
- OnlineFairBO (baseline)
The repository also includes a critical-difference benchmark figure generated with the autorank library:
Other files under forntend/generated_figures/ are kept local and ignored by Git.
Generated artifacts commonly produced by local runs include:
- HTML experiment reports under
experiments/reports/ - fairness metric figures under
forntend/fairness_metric_figures/ - generated comparison figures under
forntend/generated_figures/ - validation landscape figures under
forntend/validation accuracy/
The backend reads several FAIRSTREAM_* environment variables. The most important ones currently include:
FAIRSTREAM_DEFAULT_CHUNKFAIRSTREAM_EXPERIMENT_TTLFAIRSTREAM_MAX_HISTORYFAIRSTREAM_MAX_DATASET_ROWSFAIRSTREAM_MAX_DATASET_COLSFAIRSTREAM_OSMAC_MIN_WINDOWFAIRSTREAM_OSMAC_MAX_WINDOWFAIRSTREAM_OPTIMIZER_CANDIDATE_HISTORYFAIRSTREAM_STATIC_BENCHMARK_BUDGETFAIRSTREAM_STATIC_BENCHMARK_POOLFAIRSTREAM_OLLAMA_MODELFAIRSTREAM_OLLAMA_URLFAIRSTREAM_OLLAMA_TIMEOUTFAIRSTREAM_OLLAMA_MAX_RETRIES
These are defined in backend/api.py.
If Ollama is running, the backend can request narrative explanations and audit text through the LLM auditor layer.
Relevant defaults:
- model:
llama3:latest - endpoint:
http://localhost:11434/api/generate
If codecarbon is installed, the backend reports emissions-tracking availability through /health and experiment startup responses.
- there is no packaged project configuration such as
pyproject.toml, andrequirements.txtis still a hand-curated environment file rather than a fully reproducible lock - the repository contains a mix of research code, dashboard code, and generated artifacts rather than a packaged library structure
- some naming is historical or inconsistent, such as
forntend/ - several dataset and figure directories contain generated outputs alongside source scripts
- the codebase is optimized for experimentation and iteration, not yet for distribution as a polished package
Run the backend from the repository root:
python backend/api.py- make sure the Flask backend is running on port
5000 - verify
http://127.0.0.1:5000/health - check the backend URL in the Streamlit sidebar/session settings
- confirm Ollama is running
- confirm the configured model exists
- verify the backend can reach
FAIRSTREAM_OLLAMA_URL
Check that:
- the target is binary or coercible to binary
- the sensitive attribute contains at least two groups
- the expected benchmark columns are present for Adult, German Credit, or COMPAS normalization
- add a
pyproject.tomland/or a fully reproducible lock file - add reproducible experiment configs
- separate generated artifacts from source directories
- standardize naming, especially
forntend/ - add automated tests around API payload contracts and benchmark loaders
No license file is currently present in the repository. If this project is going to be shared beyond local research use, add an explicit license before distribution.

