PyDP silently truncates and converts `np.float32` into `int64`, leading to sensitivity underestimation
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 83/100
Línea de trabajo
Empieza por las declaraciones de bindings en src/bindings/PyDP/mechanisms/mechanism.cpp, alrededor de la línea 52, y revisa cómo se registran las sobrecargas para integer y double. Reproduce el comportamiento con el ejemplo proporcionado np.float32 y, después, verifica que los valores np.float32 seleccionen el binding de double y no se trunquen; vuelve a ejecutar las pruebas pertinentes para los bindings de mechanism.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Python
- Estrellas
- 550
- Forks
- 142
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de OpenMined/PyDP
-
Type: New Feature :heavy_plus_sign:
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
-
Type: Question :grey_question:
Dificultad 3/5 1-2 días Aptitud para principiantes 25/100
-
Type: Question :grey_question:
Dificultad 4/5 3-5 días Aptitud para principiantes 32/100
-
Raise different errors based on the error code returned from the DP LibraryPosiblemente ocupada @kalra-mohit la tomó hace 78 días. AbiertoType: Improvement :chart_with_upwards_trend:
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
-
Type: New Feature :heavy_plus_sign:
Dificultad 3/5 1-2 días Aptitud para principiantes 38/100
Todos los issues de OpenMined/PyDP
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Los mantenedores suelen responder en 1 día
-
SR_SECURITY_DESCRIPTOR.fromString drops the SACL when no DACL is presentPosiblemente ocupada @paul7436 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
equinor/fmu-sumo-uploader#302 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
modelscope/evalscope#1821 ·
Los mantenedores suelen responder en 1 día
-
Sanity on ansible-core devel fails: ignore-2.23.txt references the removed import-3.9 testPosiblemente ocupada @yurnov la tomó hoy. Abiertoneeds_triage
Dificultad 1/5 Menos de una hora Aptitud para principiantes 91/100
ansible-collections/kubernetes.core#1275 ·
Los mantenedores suelen responder en 1 día