Metadata-Version: 2.4
Name: gpupulse
Version: 0.3.0
Summary: Local-first experiment journal for the GPUPulse Mac and iPhone apps
Author: GPUPulse
License-Expression: MIT
Project-URL: Homepage, https://gpupulse-monitor.imagewizard2026.chatgpt.site
Project-URL: Documentation, https://gpupulse-monitor.imagewizard2026.chatgpt.site/support
Keywords: gpu,machine-learning,experiment-tracking,pytorch,transformers
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# GPUPulse Python SDK

GPUPulse is a local-first experiment journal for the GPUPulse Mac, iPhone and Android apps. Training writes only to an append-only file; it never waits for the Mac, a network request or a hosted tracking server.

## Five-minute start

### 1. Install

```bash
python -m pip install gpupulse
```

During local development, install this checkout instead:

```bash
python -m pip install -e ./python
```

### 2. Add three calls

```python
import gpupulse

run = gpupulse.init(
    project="lnet",
    name="fair-boundary",
    group="ablation-july",
    tags=["b200", "baseline"],
    notes="First run with the new sampler",
    config={"batch_size": 64, "learning_rate": 1e-4},
)

for step in range(100):
    loss, accuracy = train(step)
    gpupulse.log(
        {"loss": loss, "accuracy": accuracy},
        step=step,
        progress=(step + 1) / 100,
    )

gpupulse.finish()
```

The Mac collector discovers new events over the existing SSH connection. Progress, ETA, live metrics and completion alerts then appear in GPUPulse.

### 3. Confirm the agent

```bash
gpupulse status
gpupulse runs --limit 10
```

The default journal is `~/.gpupulse/journal/events.jsonl`. Override it with `GPUPULSE_JOURNAL`.

## Context manager

```python
from gpupulse import Run

with Run(project="lnet", name="fair-boundary", tags=["nightly"]) as run:
    run.config({"batch_size": 64})
    for step in range(100):
        run.log({"loss": 1 / (step + 1)}, step=step, progress=(step + 1) / 100)
```

Exceptions and SIGTERM are recorded as failures. A normal context exit records success.

## Decorator

```python
import gpupulse

@gpupulse.track(project="research", tags=["quick-check"], inject_run=True)
def train_model(dataset, run=None):
    run.config({"dataset": dataset.name})
    ...
```

Both synchronous and async functions are supported. The original exception is always re-raised after it is journaled.

## PyTorch Lightning

```python
from gpupulse import GPUPulseLightningCallback

trainer = Trainer(callbacks=[
    GPUPulseLightningCallback(
        project="vision",
        name="resnet50",
        group="imagenet-sweep",
        tags=["lightning", "b200"],
    )
])
```

The callback reads `callback_metrics`, `global_step` and `estimated_stepping_batches`. GPUPulse does not import or install Lightning itself.

## Hugging Face Trainer

```python
from gpupulse import GPUPulseTrainerCallback

trainer = Trainer(
    ...,
    callbacks=[GPUPulseTrainerCallback(
        project="llm",
        name="lora-7b",
        tags=["transformers", "lora"],
    )],
)
```

`on_log` values become GPUPulse metrics and `global_step / max_steps` becomes progress.

## Journal operations

```bash
gpupulse status --json
gpupulse runs --project lnet --limit 20 --json
gpupulse export --since 0 --format jsonl
gpupulse prune --keep-days 30
```

Set `retention_days=30` on `Run`, or set `GPUPULSE_RETENTION_DAYS=30`, to prune at most once per day. Pruning changes the cursor generation so a Mac holding an older cursor safely re-reads retained events instead of skipping them.

## Privacy and performance

- No network dependency is added to training.
- Metric calls use a bounded background queue and never wait for disk.
- Config keys containing passwords, secrets, tokens, API keys or credentials are recursively redacted.
- Use `config_allowlist=[...]` when only explicitly approved config keys should be stored.
- SSH credentials, full commands and working directories are never written by this SDK.
