Skip to content

Commit 4811117

Browse files
committed
feat: add OpenEntropy source and ECDF amplifier from PR #4
Integrate OpenEntropy hardware entropy source and ECDF signal amplifier from ereid7's PR #4, with fixes for CI failures: - Move openentropy to optional dependency (was breaking Python 3.10/3.11/3.13) - Fix ruff formatting on openentropy.py and test_openentropy.py - Remove bandit-flagged assert in ecdf.py (invariant enforced by _calibrated) - Add ECDF calibration wiring in processor.py - Optimize _to_numpy with is_cpu check to avoid unnecessary .cpu() calls - Add oe_* config fields, entry point, mypy override, and tests 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent cf38728 commit 4811117

12 files changed

Lines changed: 1088 additions & 2 deletions

File tree

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ All fallback-sourced entropy is flagged in diagnostic logs so downstream analysi
353353
| **System** | `system` | `os.urandom()` — OS cryptographic RNG (fallback/testing) |
354354
| **Timing noise** | `timing_noise` | CPU timing jitter (experimental) |
355355
| **Mock uniform** | `mock_uniform` | Configurable test source with seed/bias |
356+
| **OpenEntropy** | `openentropy` | 63 hardware noise sources (thermal, timing, microarch, GPU) — local, no network |
356357

357358
### Fallback behavior
358359

@@ -367,6 +368,38 @@ Configure with `QR_FALLBACK_MODE`:
367368
- `mock_uniform` — fall back to the mock source
368369
- `error` — raise immediately, no fallback
369370

371+
### OpenEntropy
372+
373+
[OpenEntropy](https://github.com/amenti-labs/openentropy) harvests entropy from 63 hardware noise sources on the local machine — thermal sensors, CPU timing jitter, memory timing, GPU scheduling, and more. No network, no API keys, no gRPC server needed.
374+
375+
Install:
376+
377+
```bash
378+
pip install openentropy
379+
```
380+
381+
Configure:
382+
383+
```bash
384+
export QR_ENTROPY_SOURCE_TYPE=openentropy
385+
export QR_OE_CONDITIONING=raw # raw (research default) | vonneumann | sha256
386+
```
387+
388+
List available sources on your machine:
389+
390+
```python
391+
from openentropy import detect_available_sources
392+
print([s["name"] for s in detect_available_sources()])
393+
```
394+
395+
To sample from specific sources only, set `QR_OE_SOURCES` to a comma-separated list:
396+
397+
```bash
398+
export QR_OE_SOURCES=clock_jitter,dram_row_buffer
399+
```
400+
401+
See [`deployments/openentropy/`](deployments/openentropy/) for the full deployment profile.
402+
370403
### Third-party entropy sources
371404

372405
Any Python package can register entropy sources via entry points:
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# deployments/openentropy/.env
2+
#
3+
# Environment variables for the OpenEntropy native entropy profile.
4+
# Copy this file to .env and edit as needed:
5+
# cp .env.example .env
6+
7+
# --- Hugging Face ---
8+
# Model to serve. Default: Qwen/Qwen2.5-1.5B-Instruct
9+
HF_MODEL=Qwen/Qwen2.5-1.5B-Instruct
10+
# Set this if the model is gated (requires accepting a license).
11+
HF_TOKEN=
12+
13+
# --- Entropy source ---
14+
# OpenEntropy: local hardware entropy (no Docker, native only)
15+
# 63 hardware noise sources: thermal, timing, microarch, GPU, etc.
16+
# Install: pip install openentropy
17+
# Docs: https://github.com/amenti-labs/openentropy
18+
QR_ENTROPY_SOURCE_TYPE=openentropy
19+
20+
# Conditioning mode: raw (research default), vonneumann (debiased), sha256 (crypto)
21+
QR_OE_CONDITIONING=raw
22+
23+
# Comma-separated list of source names to use. Empty = all available sources.
24+
QR_OE_SOURCES=
25+
26+
# Enable parallel collection from multiple sources (faster, more entropy).
27+
QR_OE_PARALLEL=true
28+
29+
# Timeout in seconds for entropy collection.
30+
QR_OE_TIMEOUT=5.0
31+
32+
# Fall back to system entropy if OpenEntropy is unavailable.
33+
QR_FALLBACK_MODE=system
34+
35+
# --- Sampling parameters ---
36+
QR_SAMPLE_COUNT=20480
37+
QR_TEMPERATURE_STRATEGY=fixed
38+
QR_FIXED_TEMPERATURE=0.7
39+
QR_TOP_K=0
40+
QR_TOP_P=1.0
41+
QR_LOG_LEVEL=summary
42+
43+
# --- Ports (host-side) ---
44+
VLLM_PORT=8000
45+
46+
# --- Open WebUI (optional, --profile ui) ---
47+
OPEN_WEBUI_PORT=3000
48+
# Set to true to require login (recommended for shared/public servers).
49+
OPEN_WEBUI_AUTH=false

deployments/openentropy/README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# OpenEntropy Profile
2+
3+
Runs vLLM with qr-sampler using **OpenEntropy** — a local hardware entropy
4+
source that collects noise from 63 hardware sources on Apple Silicon (thermal,
5+
timing, microarchitecture, GPU, etc.). This is a **native-only profile** — no
6+
Docker, no network dependency.
7+
8+
## Why not Docker?
9+
10+
Docker containers cannot access Metal GPU or native hardware entropy sources on
11+
macOS. Apple's Virtualization.framework has no GPU passthrough, and hardware
12+
noise sources (thermal sensors, CPU timing, GPU state) are not exposed to
13+
containerized processes. OpenEntropy requires native execution.
14+
15+
## Quick start
16+
17+
1. Install OpenEntropy and qr-sampler:
18+
19+
```bash
20+
pip install openentropy
21+
pip install -e /path/to/qr-sampler
22+
```
23+
24+
2. Configure your environment:
25+
26+
```bash
27+
cd deployments/openentropy
28+
cp .env.example .env
29+
```
30+
31+
Edit `.env` if needed — set `HF_TOKEN` if using a gated model.
32+
33+
3. Start vLLM:
34+
35+
```bash
36+
source .env
37+
vllm serve $HF_MODEL \
38+
--port $VLLM_PORT \
39+
--logits-processors qr_sampler
40+
```
41+
42+
## Available entropy sources
43+
44+
OpenEntropy provides 63 entropy sources across 13 categories. For the full
45+
catalog with physics explanations, see the
46+
[OpenEntropy Source Catalog](https://github.com/amenti-labs/openentropy/blob/master/docs/SOURCES.md).
47+
48+
List all available sources on your hardware:
49+
50+
```bash
51+
python -c "from openentropy import detect_available_sources; print([s['name'] for s in detect_available_sources()])"
52+
```
53+
54+
Sources span thermal, timing, microarchitecture, GPU, IPC, scheduling, and more.
55+
Some notable ones for research:
56+
57+
| Source | Category | Physical mechanism |
58+
|--------|----------|-------------------|
59+
| `counter_beat` | Thermal | CPU counter vs audio PLL crystal beat frequency |
60+
| `dual_clock_domain` | Microarch | 24 MHz x 41 MHz independent oscillator beat |
61+
| `gpu_divergence` | GPU | Shader warp execution order divergence |
62+
| `dvfs_race` | Microarch | Cross-core DVFS frequency race |
63+
| `clock_jitter` | Timing | Timing jitter between readout paths |
64+
| `dram_row_buffer` | Timing | DRAM row buffer hit/miss timing |
65+
66+
To sample from a specific source, set `QR_OE_SOURCES`:
67+
68+
```bash
69+
export QR_OE_SOURCES=counter_beat
70+
```
71+
72+
## Conditioning modes
73+
74+
OpenEntropy supports three conditioning strategies:
75+
76+
| Mode | Use case | Properties |
77+
|------|----------|-----------|
78+
| `raw` | Research (default) | Preserves hardware noise signal; minimal processing |
79+
| `vonneumann` | Debiased entropy | Von Neumann debiasing; slower, more uniform |
80+
| `sha256` | Cryptographic | SHA-256 hashing; suitable for security-critical applications |
81+
82+
Set `QR_OE_CONDITIONING` in `.env` or override per-request:
83+
84+
```python
85+
# Per-request override
86+
extra_args = {"qr_oe_conditioning": "sha256"}
87+
```
88+
89+
## Parallel collection
90+
91+
By default, `QR_OE_PARALLEL=true` collects from multiple sources simultaneously,
92+
increasing entropy throughput. Set to `false` for sequential collection (slower,
93+
lower memory overhead).
94+
95+
## When to use this profile
96+
97+
- **Consciousness research**: Study whether intent influences quantum-random
98+
processes using native hardware entropy.
99+
- **Local experiments**: No network latency, no external dependencies.
100+
- **Apple Silicon development**: Leverage Metal GPU and native hardware sensors.
101+
- **Research baseline**: Compare hardware entropy against system entropy
102+
(`/dev/urandom`).
103+
104+
## Web UI (optional)
105+
106+
This profile includes [Open WebUI](https://github.com/open-webui/open-webui), a
107+
ChatGPT-style web interface. To use it, you'll need to run it separately (not
108+
included in this native profile):
109+
110+
```bash
111+
docker run -d -p 3000:3000 --name open-webui ghcr.io/open-webui/open-webui:latest
112+
```
113+
114+
Then point it at your vLLM instance running on `localhost:8000`.
115+
116+
A pre-built filter function for controlling qr-sampler parameters from the UI is
117+
available at [`examples/open-webui/`](../../examples/open-webui/). See that
118+
directory's README for import instructions.
119+
120+
## Next steps
121+
122+
Once this profile works, you can:
123+
1. Adjust `QR_OE_SOURCES` to use specific entropy sources.
124+
2. Experiment with different conditioning modes (`raw`, `vonneumann`, `sha256`).
125+
3. Compare results against the `urandom` profile (gRPC-based) or `system` profile
126+
(fallback).
127+
4. Browse the full [OpenEntropy Source Catalog](https://github.com/amenti-labs/openentropy/blob/master/docs/SOURCES.md)
128+
for detailed physics explanations of each entropy source.

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ dev = [
4646
"pre-commit>=4.0",
4747
"bandit>=1.8.0",
4848
]
49+
openentropy = [
50+
"openentropy>=0.10.0",
51+
]
4952

5053
[project.entry-points."vllm.logits_processors"]
5154
qr_sampler = "qr_sampler.processor:QRSamplerLogitsProcessor"
@@ -55,6 +58,7 @@ system = "qr_sampler.entropy.system:SystemEntropySource"
5558
quantum_grpc = "qr_sampler.entropy.quantum:QuantumGrpcSource"
5659
timing_noise = "qr_sampler.entropy.timing:TimingNoiseSource"
5760
mock_uniform = "qr_sampler.entropy.mock:MockUniformSource"
61+
openentropy = "qr_sampler.entropy.openentropy:OpenEntropySource"
5862

5963
[tool.setuptools.packages.find]
6064
where = ["src"]
@@ -98,6 +102,10 @@ ignore_missing_imports = true
98102
module = ["torch", "torch.*"]
99103
ignore_missing_imports = true
100104

105+
[[tool.mypy.overrides]]
106+
module = "openentropy.*"
107+
ignore_missing_imports = true
108+
101109
[tool.coverage.run]
102110
source = ["src/qr_sampler"]
103111
omit = [

src/qr_sampler/amplification/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
"""
77

88
from qr_sampler.amplification.base import AmplificationResult, SignalAmplifier
9+
from qr_sampler.amplification.ecdf import ECDFAmplifier
910
from qr_sampler.amplification.registry import AmplifierRegistry
1011
from qr_sampler.amplification.zscore import ZScoreMeanAmplifier
1112

1213
__all__ = [
1314
"AmplificationResult",
1415
"AmplifierRegistry",
16+
"ECDFAmplifier",
1517
"SignalAmplifier",
1618
"ZScoreMeanAmplifier",
1719
]

0 commit comments

Comments
 (0)