Skip to main content

manifold-scorer

Local acceptance-manifold scoring for implicit RLHF/DPO preference pair generation.

Implementation of the local density scorer from Gerard & Volkova (2026), "Density-Guided Response Optimization."

The idea: posts a community has accepted — upvoted, engaged with, allowed to persist — cluster in coherent, high-density regions of embedding space. That structure encodes community preference without any labels. You fit the scorer on those posts, then use it to rank candidate responses and generate DPO pairs.


Install

pip install manifold-scorer

Usage

1. Embed your community posts

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("sentence-transformers/all-mpnet-base-v2")

# Just your community posts — upvoted comments, replies, whatever they wrote.
# The fact that they exist = they were accepted. No labels needed.
post_embs = model.encode(community_posts, normalize_embeddings=True)  # (N, d)

2. Find a good k (optional but recommended)

from manifold import tune_k

result = tune_k(post_embs)
# prints:
#      k  consistency (rho)
# --------------------------
#     25              0.61
#     50              0.68
#    100              0.71  ←
#    150              0.70
#    200              0.68

best_k = result["best_k"]

3. Fit the scorer

from manifold import ManifoldScorer

scorer = ManifoldScorer(k=best_k)
scorer.fit(post_embs)

4. Generate DPO pairs

# You have prompts and multiple candidate responses per prompt
prompt_embs    = model.encode(prompts, normalize_embeddings=True)     # (N, d)
candidate_embs = model.encode(candidates, normalize_embeddings=True)  # (N, n_cands, d)

pairs = scorer.make_pairs(prompt_embs, candidate_embs, margin_threshold=0.5)

# pairs["mask"] tells you which pairs had strong enough signal
chosen_texts   = [candidates[i][pairs["chosen_idx"][i]]
                  for i in range(N) if pairs["mask"][i]]
rejected_texts = [candidates[i][pairs["rejected_idx"][i]]
                  for i in range(N) if pairs["mask"][i]]

# feed chosen_texts / rejected_texts into your DPO trainer

5. Score a single candidate

score = scorer.score(prompt_emb, candidate_emb)
# log-density — higher means more aligned with community norms

6. Rank candidates for a prompt

ranked_indices = scorer.rank_candidates(prompt_emb, candidate_embs)
best = candidates[ranked_indices[0]]

7. Save / load

scorer.save("my_community.npz")
scorer = ManifoldScorer.load("my_community.npz")

Citation

@article{gerard2026dgro,
  title   = {Density-Guided Response Optimization: Community-Grounded Alignment via Implicit Acceptance Signals},
  author  = {Gerard, Patrick and Volkova, Svitlana},
  journal = {ACM FAccT},
  year    = {2026},
}

Metadata

Release files for manifold-scorer 0.1.2

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

Source distribution (sdist)

Source distribution for manifold-scorer 0.1.2
File Size Uploaded
manifold_scorer-0.1.2.tar.gz 8.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for manifold-scorer 0.1.2
File Interpreter ABI Platform
manifold_scorer-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 15.5 kB

Release files / manifold_scorer-0.1.2.tar.gz

Download URL manifold_scorer-0.1.2.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
16f98fd20ba4ede876e37edf9926d99a61e23d9e4823875ad3ea61938d42325e
BLAKE2b-256 checksum
How to use checksums
5fa3d47d5ac30c686e8f39e35d55f7d9615cce82ab9be3248d7cd5526c545762
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.13

Release files / manifold_scorer-0.1.2-py3-none-any.whl

Download URL manifold_scorer-0.1.2-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd315bc0f6e6ceed4e5e58ec51861c9c70fd26a6f89dfd7061455c55703ec73b
BLAKE2b-256 checksum
How to use checksums
08943589a5750055beeec6d35ad6dee46a3443fb25a3b2639862276bcf5eabde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.13

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 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