Download code/bayes_lower_bound.py from SabaPivot/repro-distributed-direct-preference-optimization: direct link, hf CLI and curl.
- Browser
- Download file 6.45 kB
-
https://huggingface.co/spaces/SabaPivot/repro-distributed-direct-preference-optimization/resolve/main/code/bayes_lower_bound.py
- Command line
-
hf download hf://spaces/SabaPivot/repro-distributed-direct-preference-optimization/code/bayes_lower_bound.py
-
curl -L -o bayes_lower_bound.py https://huggingface.co/spaces/SabaPivot/repro-distributed-direct-preference-optimization/resolve/main/code/bayes_lower_bound.py
6.45 kB
| #!/usr/bin/env python3 | |
| """Exact finite-prior Bayes-risk certificate for the participation lower bound. | |
| The construction is deliberately small and discrete. For each of E independent | |
| local coordinates, a hidden client-level signal theta is either +kappa or | |
| -kappa. A participating client returns theta plus an independent | |
| Rademacher heterogeneity term, also of magnitude kappa. The learner sees S | |
| clients and estimates theta. A uniform prior over theta and exhaustive | |
| enumeration of all N-client noise assignments and all S-client subsets gives | |
| the Bayes risk. Bayes risk is a lower bound for every estimator under this | |
| finite prior. | |
| All probabilities and risks are computed with Fraction; no floating-point | |
| calculation is used for the certificate. | |
| """ | |
| from __future__ import annotations | |
| import itertools | |
| import json | |
| from collections import defaultdict | |
| from fractions import Fraction | |
| from math import comb | |
| from pathlib import Path | |
| def exact_unit_risk(n_clients: int, sampled: int) -> dict[str, object]: | |
| """Enumerate the two worlds, all noise assignments, and all sample sets. | |
| Values are normalized by kappa, so the returned risk is multiplied by | |
| kappa**2 for an arbitrary positive kappa. The posterior-mean estimator is | |
| Bayes optimal for squared loss. For each observation o with joint masses | |
| p_plus and p_minus, its contribution is | |
| 4 * p_plus * p_minus / (p_plus + p_minus), | |
| which is the exact posterior Bayes risk contribution for theta in {-1,+1}. | |
| """ | |
| if not (1 <= sampled <= n_clients): | |
| raise ValueError("sampled must be in [1, n_clients]") | |
| subsets = tuple(itertools.combinations(range(n_clients), sampled)) | |
| subset_count = len(subsets) | |
| # obs -> [joint mass under theta=+1, joint mass under theta=-1] | |
| masses: dict[tuple[int, ...], list[Fraction]] = defaultdict( | |
| lambda: [Fraction(0), Fraction(0)] | |
| ) | |
| per_world = Fraction(1, 2 * (1 << n_clients) * subset_count) | |
| for theta_index, theta in enumerate((1, -1)): | |
| for noise_mask in range(1 << n_clients): | |
| noise = tuple(1 if (noise_mask >> i) & 1 else -1 for i in range(n_clients)) | |
| values = tuple(theta + z for z in noise) | |
| for subset in subsets: | |
| observation = tuple(values[i] for i in subset) | |
| masses[observation][theta_index] += per_world | |
| risk = Fraction(0) | |
| ambiguous_mass = Fraction(0) | |
| for p_plus, p_minus in masses.values(): | |
| total = p_plus + p_minus | |
| if p_plus and p_minus: | |
| ambiguous_mass += total | |
| risk += Fraction(4) * p_plus * p_minus / total | |
| expected_formula = Fraction(1, 1 << sampled) | |
| if risk != expected_formula: | |
| raise AssertionError((n_clients, sampled, risk, expected_formula)) | |
| return { | |
| "n_clients": n_clients, | |
| "sampled": sampled, | |
| "enumerated_noise_assignments_per_world": 1 << n_clients, | |
| "enumerated_subsets": subset_count, | |
| "joint_world_subset_cases": 2 * (1 << n_clients) * subset_count, | |
| "distinct_observations": len(masses), | |
| "ambiguous_observation_mass": str(ambiguous_mass), | |
| "risk_over_kappa_squared": str(risk), | |
| "risk_over_kappa_squared_decimal": float(risk), | |
| "closed_form_cross_check": str(expected_formula), | |
| } | |
| def main() -> None: | |
| # These N values cover several finite population sizes; every S from one | |
| # client through full participation is enumerated for each one. | |
| population_sizes = (5, 8, 10) | |
| e_values = (1, 2, 4, 8) | |
| kappa_values = (Fraction(1, 4), Fraction(1, 2), Fraction(1), Fraction(2)) | |
| base_rows: list[dict[str, object]] = [] | |
| for n_clients in population_sizes: | |
| for sampled in range(1, n_clients + 1): | |
| base_rows.append(exact_unit_risk(n_clients, sampled)) | |
| # Extend the exact base risks over executed E and kappa regimes. The E | |
| # coordinates are independent, so squared risks add exactly; kappa scales | |
| # the normalized risk by kappa**2. | |
| cells: list[dict[str, object]] = [] | |
| min_ratio: Fraction | None = None | |
| for base in base_rows: | |
| n_clients = int(base["n_clients"]) | |
| sampled = int(base["sampled"]) | |
| unit_risk = Fraction(str(base["risk_over_kappa_squared"])) | |
| for e_local in e_values: | |
| for kappa in kappa_values: | |
| risk = e_local * kappa * kappa * unit_risk | |
| target_scale = Fraction(e_local) * kappa * kappa / sampled | |
| ratio = risk / target_scale | |
| min_ratio = ratio if min_ratio is None else min(min_ratio, ratio) | |
| cells.append( | |
| { | |
| "N": n_clients, | |
| "S": sampled, | |
| "E": e_local, | |
| "kappa": str(kappa), | |
| "bayes_risk": str(risk), | |
| "target_E_kappa2_over_S": str(target_scale), | |
| "ratio_to_target": str(ratio), | |
| } | |
| ) | |
| assert min_ratio is not None | |
| certificate_constant = Fraction(5, 512) | |
| if min_ratio < certificate_constant: | |
| raise AssertionError((min_ratio, certificate_constant)) | |
| result = { | |
| "construction": "two-world Rademacher heterogeneity, exact finite-prior Bayes risk", | |
| "population_sizes": list(population_sizes), | |
| "sample_sizes_per_population": { | |
| str(n): list(range(1, n + 1)) for n in population_sizes | |
| }, | |
| "E_values": list(e_values), | |
| "kappa_values": [str(k) for k in kappa_values], | |
| "base_rows": base_rows, | |
| "executed_parameter_cells": len(cells), | |
| "cells": cells, | |
| "min_ratio_risk_over_E_kappa2_over_S": str(min_ratio), | |
| "finite_family_certificate": f"risk >= ({certificate_constant}) * E*kappa^2/S", | |
| "bayes_optimality": ( | |
| "For squared loss, posterior mean minimizes conditional risk; " | |
| "therefore every estimator has expected risk at least this Bayes risk." | |
| ), | |
| } | |
| out = Path(__file__).with_name("bayes_lower_bound_results.json") | |
| out.write_text(json.dumps(result, indent=2) + "\n") | |
| print(json.dumps({ | |
| "output": str(out), | |
| "base_rows": len(base_rows), | |
| "executed_parameter_cells": len(cells), | |
| "min_ratio": str(min_ratio), | |
| "certificate": result["finite_family_certificate"], | |
| }, sort_keys=True)) | |
| if __name__ == "__main__": | |
| main() | |