Skip to main content

popfidelity

Python R Rust uv Ruff mypy tests License arXiv

A language model that answers survey questions can match the average answer of a population and still erase the differences between the people in it. popfidelity measures how well a model's answers represent a human population, group by group. One Rust core gives a Python package, an R package and a command line the same numbers.

What it measures

The Population Fidelity Score (PFS; da Silva et al., 2026) compares the survey and the model on cells, the subpopulations a survey reports, and checks three conditions:

Component Question Score
Accuracy Is each cell's answer distribution close to the survey's? one minus the mean normalised earth mover's distance
Adaptability Do the model's cells differ from one another as much as the survey's do? min(A, 1/A) of the ratio of median pairwise distances
Structure Do the cells that differ in the survey also differ in the model? Spearman correlation of the pairwise distances, clipped at zero

PFS is their geometric mean, so a model fails as soon as one condition fails. It is reported for the pooled population and every demographic subgroup, for paired comparisons of a tuned and a base model, and across replicate runs and questions, with the paper's nine sensitivity specifications.

Beside PFS sits a registry of 126 measures from the literature on synthetic survey samples, each with the work it comes from and the work that applied it to language models; 66 ship in this release:

Family In 0.1 Examples
Distances 23 nEMD, Wasserstein, total variation, Kullback-Leibler, Jensen-Shannon, Hellinger, Kolmogorov-Smirnov, energy distance, MMD
Alignment scores 11 OpinionQA representativeness, steerability and consistency; GlobalOpinionQA similarity; Meister; SimBench; SubPOP with its noise floor; WorldValuesBench curve
PFS and its parts 10 components, centre alignment, binding component, variants
Dispersion 8 SD ratio, normalised variance, gap inflation, entropy and collision ratios, support and modal collapse, stereotyping
Reliability 7 ICC, Krippendorff's alpha, Fleiss' kappa, Cronbach's alpha, Spearman-Brown, noise-to-signal
Structure, inference, artefacts 7 Mantel test, quality bands, cell bootstrap, permutation nulls, pooled t intervals, mismatch rate

The measure catalogue lists all 126, including those planned for later releases, and 17 benchmarks.

Install

pip install popfidelity
remotes::install_github("neemiasbsilva/popfidelity", subdir = "r")
cargo add popfidelity

PyPI has wheels for Linux, macOS and Windows on Python 3.11 and newer, so pip needs no Rust toolchain there. The R package compiles the Rust core, so it needs Cargo and rustc 1.85 or newer, as does a Python install from source. The Python extras api (OpenAI, Anthropic, Google clients), local (transformers) and parquet add optional backends and formats.

Quickstart

Python:

import popfidelity as pf
from popfidelity.examples import toy
from popfidelity.io import read_cells

cells = toy()
scores = pf.score(cells["survey"], cells["M2"], pf.Variant(round_pairs=10))
print(scores["pfs"], scores["binding_component"])

questions = pf.read_questions("examples/ces/questions.yaml")
survey = read_cells("examples/ces/data/survey_cells.csv", questions)["ideo5"]
results = "examples/ces/results/ollama-qwen3-vl-2b/model_cells.csv"
model = read_cells(results, questions, mode="ntp")["ideo5"]
facets = pf.read_facets("examples/ces/facets.yaml").from_labels(survey.labels)
groups = pf.score_groups(survey, model, facets)

R:

library(popfidelity)
toy <- example_toy()
pfs_score(toy$survey, toy$M2)$pfs

questions <- read_questions("examples/ces/questions.yaml")
survey <- read_cells("examples/ces/data/survey_cells.csv", questions)$ideo5
results <- "examples/ces/results/ollama-qwen3-vl-2b/model_cells.csv"
model <- read_cells(results, questions, mode = "ntp")$ideo5
groups <- pfs_score_groups(survey, model, read_facets("examples/ces/facets.yaml"))

Command line:

popfidelity elicit --config examples/ces/elicit/ollama.yaml --limit 8
popfidelity aggregate records --config examples/ces/elicit/ollama.yaml --out model_cells.csv
popfidelity score --survey examples/ces/data/survey_cells.csv --model model_cells.csv \
    --questions examples/ces/questions.yaml --facets examples/ces/facets.yaml --out scores
popfidelity report --groups scores/groups.csv

Asking models

popfidelity elicit interviews a model once per respondent and question, with the respondent's demographics as prior turns, and stores resumable JSON-lines records. It reads next-token probabilities over the answer options where the endpoint returns them and samples full answers otherwise.

Backend Endpoints
openai_compatible OpenAI, vLLM, llama.cpp, Hugging Face router and TGI, OpenRouter, Together, Fireworks, DeepSeek, Gemini's OpenAI endpoint, or any compatible URL
ollama Ollama's native API with raw prompts
anthropic, google Claude and Gemini, full answers
transformers a local Hugging Face model, exact next-token probabilities

Examples

Example Survey Model answers
toy the paper's toy cells models M1 to M3
ces Cooperative Election Study 2024, 96 cells qwen3-vl:2b on Ollama, and configurations for six other backends
twin2k Twin-2K-500 wave 4, 24 cells GPT-4.1-mini digital twins and a human retest ceiling
globalopinionqa GlobalOpinionQA, 90 countries, fetched at run time qwen3-vl:2b on Ollama, one country per interview
machine-bias World Values Survey cells the paper's archived and fine-tuned models

On the CES, the local model is close to every cell on average but does not order the cells as the survey does, so structure binds and PFS stays at 0.30 or below. On Twin-2K-500, people answering the same items again reach PFS 0.95 and the digital twins 0.58 to 0.66.

Reproducibility

  • Python and R give the same tables: ./run.sh parity runs both on shared inputs and compares 19 tables at 1e-12.
  • The library reproduces the paper: ./run.sh crosscheck recomputes its 9,548 subgroup rows and 5,952 paired rows with differences of at most 4.4e-16.
  • Bootstrap and permutation draws are seeded one by one, so results do not depend on the number of threads.
  • Every reference in docs/references.bib is checked against Crossref and arXiv by scripts/check_references.py.

Development

uv sync --locked --group dev --extra api --extra parquet
./run.sh test     # Rust and Python tests
./run.sh lint     # rustfmt, clippy, ruff, mypy strict, style check
./run.sh r        # R CMD check --as-cran
./run.sh parity   # Python against R

See CONTRIBUTING.md for the conventions.

Citation

TODO - Demo Paper

@misc{dasilva2026population,
  author = {da Silva, Neemias B. and Lukk, Martin and Sutani, Ali and Moturu, Abhishek and
            Yang, Harris and Silver, Daniel and Ratto, Matt and Silva, Thiago H.},
  title = {Population Fidelity: Evaluating Population Representativeness in {LLMs}},
  year = {2026},
  eprint = {2609.36253},
  archivePrefix = {arXiv},
  primaryClass = {cs.CL}
}

Please also cite the works behind the other measures you report; the registry names them. The software citation is in CITATION.cff.

Licence

Apache License 2.0; see LICENSE and NOTICE.

Metadata

Release files for popfidelity 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for popfidelity 0.1.0
File Size Uploaded
popfidelity-0.1.0.tar.gz 99.8 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for popfidelity 0.1.0
File
popfidelity-0.1.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
popfidelity-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
popfidelity-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details
popfidelity-0.1.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
popfidelity-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.7 MB

Release files / popfidelity-0.1.0.tar.gz

Download URL popfidelity-0.1.0.tar.gz
Size 99.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f2ecb55f0d205e63b36ee996c226d3adbb583e6f29ad7db773e7e58cef85da37
BLAKE2b-256 checksum
How to use checksums
b90f5a861cd444efb5f62b33e935ece7ba85ee24ed49760d0f1c7c27225c7a75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / popfidelity-0.1.0-cp311-abi3-win_amd64.whl

Download URL popfidelity-0.1.0-cp311-abi3-win_amd64.whl
Size 424.5 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4f86f932317c399629b268d2c961c86575dd60eb5bff395d2f7e71d37d105372
BLAKE2b-256 checksum
How to use checksums
ec280de8cc4e7a7602f47890b79b4b6212d0502349ffd7d0905575cf08b59aa1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / popfidelity-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL popfidelity-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 570.9 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
5b7e8f4b97d3e4205c89d5d9cf0a67bfe6cde2e4a79ca9254be79ab7ca71e18b
BLAKE2b-256 checksum
How to use checksums
70bdfa5e0ab47334db219a9b6742deb34bd7283ac0435e8d7ba017eefeaf0771
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / popfidelity-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL popfidelity-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 567.8 kB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
bfe2c08e1f80a749ab8d0c8974480c6edee09b6d3bb85d96489ff82d3887b847
BLAKE2b-256 checksum
How to use checksums
370059fc936754ecf4aae6af6f85d9be9008f745f5a229a79b884452461032af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / popfidelity-0.1.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL popfidelity-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Size 509.0 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
73bc125fc76fdf43efea334c50a4def0153c4749124e707223808b511093db67
BLAKE2b-256 checksum
How to use checksums
4e5ce1dabd695a22ee3b21bc8ec5e73e7ad21baf76dc8e49316ec54d9808a4aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / popfidelity-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl

Download URL popfidelity-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl
Size 520.2 kB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
2346a9f31e7fde427ffa3b12f0b331225576f872cfa20b68439891aa73de0313
BLAKE2b-256 checksum
How to use checksums
8e860e24d20d86317768994cc77632c0061f2d2bbdef4ec47242d8f897fcfa56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page