PyDP silently truncates and converts `np.float32` into `int64`, leading to sensitivity underestimation
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 83/100
Direzione di ricerca
Inizia dalle dichiarazioni dei binding in src/bindings/PyDP/mechanisms/mechanism.cpp, intorno alla riga 52, e verifica come vengono registrati gli overload per integer e double. Riproduci il comportamento con l’esempio fornito np.float32, poi verifica che i valori np.float32 selezionino il binding double e non vengano troncati; riesegui i test pertinenti per i binding di mechanism.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
In the code that registers the bindings with the C++ building blocks library, the int64 binding is defined before the double binding. This has a surprising consequence: pybind11, after doing a pass that sees if the input type matches the declared type, it then tries overloads in order with an implicit conversion path. The int caster apparently accepts a np.float32 and silently truncates its input, so values of this type automatically use the int64 binding.
Silent truncation predictably negative consequences on the sensitivity analysis: 0.95 becomes 0 and 1.05 becomes 1, so sensitivity increases unexpectedly. This is observable in PyDP:
import numpy as np
from pydp.algorithms.numerical_mechanisms import LaplaceMechanism
mechanism = LaplaceMechanism(epsilon=1.0, sensitivity=0.1)
print("np.float32, D :", [mechanism.add_noise(np.float32(0.95)) for _ in range(10)])
print("np.float32, D':", [mechanism.add_noise(np.float32(1.05)) for _ in range(10)])
and also affects PipelineDP via add_dp_noise, or VECTOR_SUM with float32 values. This happens even though the value is multiplied by 1.0, maybe to try and cast it to float? Sadly this doesn't work, since 1.0 * np.float32(1.7) still has type np.float32.
Here's a repro for add_dp_noise:
import numpy as np
import pipeline_dp
for name, value in (("D ", np.float32(0.95)), ("D'", np.float32(1.05))):
releases = []
for _ in range(10):
accountant = pipeline_dp.NaiveBudgetAccountant(total_epsilon=1, total_delta=0)
engine = pipeline_dp.DPEngine(accountant, pipeline_dp.LocalBackend())
params = pipeline_dp.aggregate_params.AddDPNoiseParams(noise_kind=pipeline_dp.NoiseKind.LAPLACE, l0_sensitivity=1,
linf_sensitivity=0.1)
result = engine.add_dp_noise([("partition", value)], params)
accountant.compute_budgets()
releases.append(list(result)[0][1])
print(name, releases)
other PipelineDP aggregations (sum, mean, variance) convert to float64 and so aren't vulnerable to this.
This issue doesn't happen with np.float64, because np.float64 is a subclass of Python's native floats (while np.float32 is not). Therefore, the right binding is selected by pybind11 during the first pass.
Registering the double binding first would fix it.
- Lingua principale
- Python
- Stelle
- 550
- Fork
- 142
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di OpenMined/PyDP
-
Type: New Feature :heavy_plus_sign:
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
-
Type: Question :grey_question:
Difficoltà 3/5 1-2 giorni Idoneità per principianti 25/100
-
Type: Question :grey_question:
Difficoltà 4/5 3-5 giorni Idoneità per principianti 32/100
-
Raise different errors based on the error code returned from the DP LibraryForse già presa @kalra-mohit l’ha presa 79 giorni fa. ApertaType: Improvement :chart_with_upwards_trend:
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
-
Type: New Feature :heavy_plus_sign:
Difficoltà 3/5 1-2 giorni Idoneità per principianti 38/100
Tutte le issue di OpenMined/PyDP
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
NVIDIA/earth2studio#1241 ·
I maintainer di solito rispondono entro 3 giorni
-
docs(types): update the collection binding note now that typed collections shipped in pycubrid 1.9.0Apertadocumentation priority: low size: S
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
cubrid-lab/sqlalchemy-cubrid#768 ·
I maintainer di solito rispondono entro 1 giorno
-
bug help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Broken link in index.rstApertadocumentation
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 65/100
ansys/pydpf-core#3547 ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
OktoLabsAI/okto-pulse#114 ·
I maintainer di solito rispondono entro 1 giorno