expt-logger 0.1.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- expt_logger-0.1.0.dev0/.claude/settings.local.json +7 -0
- expt_logger-0.1.0.dev0/.gitignore +79 -0
- expt_logger-0.1.0.dev0/DEVELOPMENT.md +69 -0
- expt_logger-0.1.0.dev0/PKG-INFO +252 -0
- expt_logger-0.1.0.dev0/README.md +244 -0
- expt_logger-0.1.0.dev0/demo.py +258 -0
- expt_logger-0.1.0.dev0/pyproject.toml +44 -0
- expt_logger-0.1.0.dev0/src/expt_logger/__init__.py +205 -0
- expt_logger-0.1.0.dev0/src/expt_logger/client.py +207 -0
- expt_logger-0.1.0.dev0/src/expt_logger/config.py +5 -0
- expt_logger-0.1.0.dev0/src/expt_logger/run.py +317 -0
- expt_logger-0.1.0.dev0/src/expt_logger/types.py +90 -0
- expt_logger-0.1.0.dev0/src/expt_logger/utils.py +49 -0
- expt_logger-0.1.0.dev0/tests/__init__.py +0 -0
- expt_logger-0.1.0.dev0/tests/test_expt_logger.py +154 -0
- expt_logger-0.1.0.dev0/tests/test_integration.py +508 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Unit test / coverage reports
|
|
34
|
+
htmlcov/
|
|
35
|
+
.tox/
|
|
36
|
+
.nox/
|
|
37
|
+
.coverage
|
|
38
|
+
.coverage.*
|
|
39
|
+
.cache
|
|
40
|
+
nosetests.xml
|
|
41
|
+
coverage.xml
|
|
42
|
+
*.cover
|
|
43
|
+
*.log
|
|
44
|
+
.pytest_cache/
|
|
45
|
+
.hypothesis/
|
|
46
|
+
|
|
47
|
+
# Virtual environments
|
|
48
|
+
.env
|
|
49
|
+
.venv
|
|
50
|
+
env/
|
|
51
|
+
venv/
|
|
52
|
+
ENV/
|
|
53
|
+
env.bak/
|
|
54
|
+
venv.bak/
|
|
55
|
+
|
|
56
|
+
# IDEs
|
|
57
|
+
.vscode/
|
|
58
|
+
.idea/
|
|
59
|
+
*.swp
|
|
60
|
+
*.swo
|
|
61
|
+
*~
|
|
62
|
+
.DS_Store
|
|
63
|
+
|
|
64
|
+
# Type checking
|
|
65
|
+
.mypy_cache/
|
|
66
|
+
.dmypy.json
|
|
67
|
+
dmypy.json
|
|
68
|
+
.pytype/
|
|
69
|
+
|
|
70
|
+
# Ruff
|
|
71
|
+
.ruff_cache/
|
|
72
|
+
|
|
73
|
+
# uv
|
|
74
|
+
uv.lock
|
|
75
|
+
|
|
76
|
+
# Project specific
|
|
77
|
+
*.db
|
|
78
|
+
*.sqlite
|
|
79
|
+
*.sqlite3
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
Install dependencies using uv:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install the package with dev dependencies
|
|
9
|
+
uv sync --dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Running Tests
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
uv run pytest
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
With coverage:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv run pytest --cov=. --cov-report=html
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Linting
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Check code
|
|
28
|
+
uv run ruff check .
|
|
29
|
+
|
|
30
|
+
# Format code
|
|
31
|
+
uv run ruff format .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Type Checking
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv run mypy .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Making Changes
|
|
41
|
+
|
|
42
|
+
1. Make your changes
|
|
43
|
+
2. Run linting: `uv run ruff check . && uv run ruff format .`
|
|
44
|
+
3. Run type checking: `uv run mypy .`
|
|
45
|
+
4. Run tests: `uv run pytest`
|
|
46
|
+
5. Test the demo: `uv run python demo.py`
|
|
47
|
+
|
|
48
|
+
## Building
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
uv build
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Versioning
|
|
55
|
+
To update to an exact version, provide it as a positional argument:
|
|
56
|
+
```bash
|
|
57
|
+
uv version 1.0.0
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
To increase the version of your package semantics, use the --bump option:
|
|
61
|
+
```bash
|
|
62
|
+
uv version --bump dev
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Publishing
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uv publish
|
|
69
|
+
```
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: expt-logger
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
|
+
Summary: Simple experiment logging library
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: httpx>=0.27.0
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# expt_logger
|
|
10
|
+
|
|
11
|
+
Simple experiment tracking for RL training with a W&B-style API.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
**Install:**
|
|
16
|
+
```bash
|
|
17
|
+
uv add expt-logger
|
|
18
|
+
# or
|
|
19
|
+
pip install expt-logger
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Set your API key:**
|
|
23
|
+
```bash
|
|
24
|
+
export EXPT_LOGGER_API_KEY=your_api_key
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Start logging:**
|
|
28
|
+
```python
|
|
29
|
+
import expt_logger
|
|
30
|
+
|
|
31
|
+
# Initialize run with config
|
|
32
|
+
run = expt_logger.init(
|
|
33
|
+
name="grpo-math",
|
|
34
|
+
config={"lr": 3e-6, "batch_size": 8}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Get experiment URLs
|
|
38
|
+
print(f"View experiment: {run.experiment_url}")
|
|
39
|
+
print(f"Base URL: {run.base_url}")
|
|
40
|
+
|
|
41
|
+
# Log RL rollouts with rewards
|
|
42
|
+
expt_logger.log_rollout(
|
|
43
|
+
prompt="What is 2+2?",
|
|
44
|
+
messages=[{"role": "assistant", "content": "The answer is 4."}],
|
|
45
|
+
rewards={"correctness": 1.0, "format": 0.9},
|
|
46
|
+
mode="train"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Log scalar metrics
|
|
50
|
+
expt_logger.log({
|
|
51
|
+
"train/loss": 0.45,
|
|
52
|
+
"train/kl": 0.02,
|
|
53
|
+
"train/reward": 0.85
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
expt_logger.end()
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Core Features
|
|
60
|
+
|
|
61
|
+
### Scalar Metrics
|
|
62
|
+
|
|
63
|
+
Log training metrics with automatic step tracking:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Auto-increment steps (defaults to "train" mode)
|
|
67
|
+
expt_logger.log({"loss": 0.5}) # step 0, train/loss
|
|
68
|
+
expt_logger.log({"loss": 0.4}) # step 1, train/loss
|
|
69
|
+
|
|
70
|
+
# Use slash prefixes for train/eval modes
|
|
71
|
+
expt_logger.log({
|
|
72
|
+
"train/loss": 0.5,
|
|
73
|
+
"eval/loss": 0.6
|
|
74
|
+
}, step=10)
|
|
75
|
+
|
|
76
|
+
# Or set mode explicitly
|
|
77
|
+
expt_logger.log({"loss": 0.5}, mode="eval")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Note:** Metrics default to `"train"` mode when no mode is specified and keys don't have slash prefixes.
|
|
81
|
+
|
|
82
|
+
**Batching metrics** at the same step:
|
|
83
|
+
```python
|
|
84
|
+
expt_logger.log({"metric_a": 1.0}, commit=False)
|
|
85
|
+
expt_logger.log({"metric_b": 2.0}, commit=False)
|
|
86
|
+
expt_logger.log({"metric_c": 3.0}) # commits all three at step 0
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Rollouts (RL-specific)
|
|
90
|
+
|
|
91
|
+
Log conversation rollouts with multiple reward functions:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
expt_logger.log_rollout(
|
|
95
|
+
prompt="Solve: x^2 - 5x + 6 = 0",
|
|
96
|
+
messages=[
|
|
97
|
+
{"role": "assistant", "content": "Let me factor this..."},
|
|
98
|
+
{"role": "user", "content": "Can you verify?"},
|
|
99
|
+
{"role": "assistant", "content": "Sure! (x-2)(x-3) = 0..."}
|
|
100
|
+
],
|
|
101
|
+
rewards={
|
|
102
|
+
"correctness": 1.0,
|
|
103
|
+
"format": 0.9,
|
|
104
|
+
"helpfulness": 0.85
|
|
105
|
+
},
|
|
106
|
+
step=5,
|
|
107
|
+
mode="train"
|
|
108
|
+
)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **Messages format:** List of dicts with `"role"` and `"content"` keys
|
|
112
|
+
- **Rewards format:** Dict of reward names to float values
|
|
113
|
+
- **Mode:** `"train"` or `"eval"` (default: `"train"`)
|
|
114
|
+
|
|
115
|
+
### Configuration
|
|
116
|
+
|
|
117
|
+
Track hyperparameters and update them dynamically:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
run = expt_logger.init(config={"lr": 0.001, "batch_size": 32})
|
|
121
|
+
|
|
122
|
+
# Update config during training
|
|
123
|
+
run.config.lr = 0.0005 # attribute style
|
|
124
|
+
run.config["epochs"] = 100 # dict style
|
|
125
|
+
run.config.update({"model": "gpt2"}) # bulk update
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### API Key & Server Configuration
|
|
129
|
+
|
|
130
|
+
**API Key** (required):
|
|
131
|
+
```bash
|
|
132
|
+
export EXPT_LOGGER_API_KEY=your_api_key
|
|
133
|
+
```
|
|
134
|
+
Or pass directly:
|
|
135
|
+
```python
|
|
136
|
+
expt_logger.init(api_key="your_key")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Custom server URL** (optional, for self-hosting):
|
|
140
|
+
```bash
|
|
141
|
+
export EXPT_LOGGER_BASE_URL=https://your-server.com
|
|
142
|
+
```
|
|
143
|
+
Or:
|
|
144
|
+
```python
|
|
145
|
+
expt_logger.init(base_url="https://your-server.com")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Accessing Experiment URLs
|
|
149
|
+
|
|
150
|
+
Get the experiment URL and base URL from the run object:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
run = expt_logger.init(name="my-experiment")
|
|
154
|
+
|
|
155
|
+
# Get the full experiment URL to view in browser
|
|
156
|
+
print(run.experiment_url)
|
|
157
|
+
# https://expt-platform.vercel.app/experiments/ccf1f879-50a6-492b-9072-fed6effac731
|
|
158
|
+
|
|
159
|
+
# Get the base URL of the tracking server
|
|
160
|
+
print(run.base_url)
|
|
161
|
+
# https://expt-platform.vercel.app
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Reference
|
|
165
|
+
|
|
166
|
+
### `expt_logger.init()`
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
init(
|
|
170
|
+
name: str | None = None,
|
|
171
|
+
config: dict[str, Any] | None = None,
|
|
172
|
+
api_key: str | None = None,
|
|
173
|
+
base_url: str | None = None
|
|
174
|
+
) -> Run
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- `name`: Experiment name (auto-generated if not provided)
|
|
178
|
+
- `config`: Initial hyperparameters
|
|
179
|
+
- `api_key`: API key (or set `EXPT_LOGGER_API_KEY`)
|
|
180
|
+
- `base_url`: Custom server URL (or set `EXPT_LOGGER_BASE_URL`)
|
|
181
|
+
|
|
182
|
+
### `expt_logger.log()`
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
log(
|
|
186
|
+
metrics: dict[str, float],
|
|
187
|
+
step: int | None = None,
|
|
188
|
+
mode: str | None = None,
|
|
189
|
+
commit: bool = True
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- `metrics`: Dict of metric names to values
|
|
194
|
+
- `step`: Step number (auto-increments if not provided)
|
|
195
|
+
- `mode`: Default mode for keys without slashes (default: `"train"`)
|
|
196
|
+
- `commit`: If `False`, buffer metrics until next `commit=True`
|
|
197
|
+
|
|
198
|
+
### `expt_logger.log_rollout()`
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
log_rollout(
|
|
202
|
+
prompt: str,
|
|
203
|
+
messages: list[dict[str, str]],
|
|
204
|
+
rewards: dict[str, float],
|
|
205
|
+
step: int | None = None,
|
|
206
|
+
mode: str = "train"
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
- `prompt`: The prompt text
|
|
211
|
+
- `messages`: List of `{"role": ..., "content": ...}` dicts
|
|
212
|
+
- `rewards`: Dict of reward names to values
|
|
213
|
+
- `step`: Step number (uses current step if not provided)
|
|
214
|
+
- `mode`: `"train"` or `"eval"`
|
|
215
|
+
|
|
216
|
+
### `expt_logger.flush()` / `expt_logger.end()`
|
|
217
|
+
|
|
218
|
+
- `flush()`: Manually send buffered data to server
|
|
219
|
+
- `end()`: Finish the run (called automatically on exit)
|
|
220
|
+
|
|
221
|
+
## Advanced
|
|
222
|
+
|
|
223
|
+
### Context Manager
|
|
224
|
+
|
|
225
|
+
Ensures automatic cleanup:
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
with expt_logger.init(name="my-run") as run:
|
|
229
|
+
expt_logger.log({"loss": 0.5})
|
|
230
|
+
# end() called automatically
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Graceful Shutdown
|
|
234
|
+
|
|
235
|
+
The library handles cleanup on:
|
|
236
|
+
- Normal exit (`atexit`)
|
|
237
|
+
- Ctrl+C (`SIGINT`)
|
|
238
|
+
- `SIGTERM`
|
|
239
|
+
|
|
240
|
+
All buffered data is flushed before exit.
|
|
241
|
+
|
|
242
|
+
## Development
|
|
243
|
+
|
|
244
|
+
For local development, see [DEVELOPMENT.md](DEVELOPMENT.md).
|
|
245
|
+
|
|
246
|
+
Run the demo:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
python demo.py # GRPO-style training simulation
|
|
250
|
+
python demo.py commit # Batching demo
|
|
251
|
+
python demo.py messages # Structured messages demo
|
|
252
|
+
```
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# expt_logger
|
|
2
|
+
|
|
3
|
+
Simple experiment tracking for RL training with a W&B-style API.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
**Install:**
|
|
8
|
+
```bash
|
|
9
|
+
uv add expt-logger
|
|
10
|
+
# or
|
|
11
|
+
pip install expt-logger
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Set your API key:**
|
|
15
|
+
```bash
|
|
16
|
+
export EXPT_LOGGER_API_KEY=your_api_key
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Start logging:**
|
|
20
|
+
```python
|
|
21
|
+
import expt_logger
|
|
22
|
+
|
|
23
|
+
# Initialize run with config
|
|
24
|
+
run = expt_logger.init(
|
|
25
|
+
name="grpo-math",
|
|
26
|
+
config={"lr": 3e-6, "batch_size": 8}
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Get experiment URLs
|
|
30
|
+
print(f"View experiment: {run.experiment_url}")
|
|
31
|
+
print(f"Base URL: {run.base_url}")
|
|
32
|
+
|
|
33
|
+
# Log RL rollouts with rewards
|
|
34
|
+
expt_logger.log_rollout(
|
|
35
|
+
prompt="What is 2+2?",
|
|
36
|
+
messages=[{"role": "assistant", "content": "The answer is 4."}],
|
|
37
|
+
rewards={"correctness": 1.0, "format": 0.9},
|
|
38
|
+
mode="train"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Log scalar metrics
|
|
42
|
+
expt_logger.log({
|
|
43
|
+
"train/loss": 0.45,
|
|
44
|
+
"train/kl": 0.02,
|
|
45
|
+
"train/reward": 0.85
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
expt_logger.end()
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Core Features
|
|
52
|
+
|
|
53
|
+
### Scalar Metrics
|
|
54
|
+
|
|
55
|
+
Log training metrics with automatic step tracking:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# Auto-increment steps (defaults to "train" mode)
|
|
59
|
+
expt_logger.log({"loss": 0.5}) # step 0, train/loss
|
|
60
|
+
expt_logger.log({"loss": 0.4}) # step 1, train/loss
|
|
61
|
+
|
|
62
|
+
# Use slash prefixes for train/eval modes
|
|
63
|
+
expt_logger.log({
|
|
64
|
+
"train/loss": 0.5,
|
|
65
|
+
"eval/loss": 0.6
|
|
66
|
+
}, step=10)
|
|
67
|
+
|
|
68
|
+
# Or set mode explicitly
|
|
69
|
+
expt_logger.log({"loss": 0.5}, mode="eval")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Note:** Metrics default to `"train"` mode when no mode is specified and keys don't have slash prefixes.
|
|
73
|
+
|
|
74
|
+
**Batching metrics** at the same step:
|
|
75
|
+
```python
|
|
76
|
+
expt_logger.log({"metric_a": 1.0}, commit=False)
|
|
77
|
+
expt_logger.log({"metric_b": 2.0}, commit=False)
|
|
78
|
+
expt_logger.log({"metric_c": 3.0}) # commits all three at step 0
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Rollouts (RL-specific)
|
|
82
|
+
|
|
83
|
+
Log conversation rollouts with multiple reward functions:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
expt_logger.log_rollout(
|
|
87
|
+
prompt="Solve: x^2 - 5x + 6 = 0",
|
|
88
|
+
messages=[
|
|
89
|
+
{"role": "assistant", "content": "Let me factor this..."},
|
|
90
|
+
{"role": "user", "content": "Can you verify?"},
|
|
91
|
+
{"role": "assistant", "content": "Sure! (x-2)(x-3) = 0..."}
|
|
92
|
+
],
|
|
93
|
+
rewards={
|
|
94
|
+
"correctness": 1.0,
|
|
95
|
+
"format": 0.9,
|
|
96
|
+
"helpfulness": 0.85
|
|
97
|
+
},
|
|
98
|
+
step=5,
|
|
99
|
+
mode="train"
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- **Messages format:** List of dicts with `"role"` and `"content"` keys
|
|
104
|
+
- **Rewards format:** Dict of reward names to float values
|
|
105
|
+
- **Mode:** `"train"` or `"eval"` (default: `"train"`)
|
|
106
|
+
|
|
107
|
+
### Configuration
|
|
108
|
+
|
|
109
|
+
Track hyperparameters and update them dynamically:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
run = expt_logger.init(config={"lr": 0.001, "batch_size": 32})
|
|
113
|
+
|
|
114
|
+
# Update config during training
|
|
115
|
+
run.config.lr = 0.0005 # attribute style
|
|
116
|
+
run.config["epochs"] = 100 # dict style
|
|
117
|
+
run.config.update({"model": "gpt2"}) # bulk update
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### API Key & Server Configuration
|
|
121
|
+
|
|
122
|
+
**API Key** (required):
|
|
123
|
+
```bash
|
|
124
|
+
export EXPT_LOGGER_API_KEY=your_api_key
|
|
125
|
+
```
|
|
126
|
+
Or pass directly:
|
|
127
|
+
```python
|
|
128
|
+
expt_logger.init(api_key="your_key")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Custom server URL** (optional, for self-hosting):
|
|
132
|
+
```bash
|
|
133
|
+
export EXPT_LOGGER_BASE_URL=https://your-server.com
|
|
134
|
+
```
|
|
135
|
+
Or:
|
|
136
|
+
```python
|
|
137
|
+
expt_logger.init(base_url="https://your-server.com")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Accessing Experiment URLs
|
|
141
|
+
|
|
142
|
+
Get the experiment URL and base URL from the run object:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
run = expt_logger.init(name="my-experiment")
|
|
146
|
+
|
|
147
|
+
# Get the full experiment URL to view in browser
|
|
148
|
+
print(run.experiment_url)
|
|
149
|
+
# https://expt-platform.vercel.app/experiments/ccf1f879-50a6-492b-9072-fed6effac731
|
|
150
|
+
|
|
151
|
+
# Get the base URL of the tracking server
|
|
152
|
+
print(run.base_url)
|
|
153
|
+
# https://expt-platform.vercel.app
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## API Reference
|
|
157
|
+
|
|
158
|
+
### `expt_logger.init()`
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
init(
|
|
162
|
+
name: str | None = None,
|
|
163
|
+
config: dict[str, Any] | None = None,
|
|
164
|
+
api_key: str | None = None,
|
|
165
|
+
base_url: str | None = None
|
|
166
|
+
) -> Run
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- `name`: Experiment name (auto-generated if not provided)
|
|
170
|
+
- `config`: Initial hyperparameters
|
|
171
|
+
- `api_key`: API key (or set `EXPT_LOGGER_API_KEY`)
|
|
172
|
+
- `base_url`: Custom server URL (or set `EXPT_LOGGER_BASE_URL`)
|
|
173
|
+
|
|
174
|
+
### `expt_logger.log()`
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
log(
|
|
178
|
+
metrics: dict[str, float],
|
|
179
|
+
step: int | None = None,
|
|
180
|
+
mode: str | None = None,
|
|
181
|
+
commit: bool = True
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- `metrics`: Dict of metric names to values
|
|
186
|
+
- `step`: Step number (auto-increments if not provided)
|
|
187
|
+
- `mode`: Default mode for keys without slashes (default: `"train"`)
|
|
188
|
+
- `commit`: If `False`, buffer metrics until next `commit=True`
|
|
189
|
+
|
|
190
|
+
### `expt_logger.log_rollout()`
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
log_rollout(
|
|
194
|
+
prompt: str,
|
|
195
|
+
messages: list[dict[str, str]],
|
|
196
|
+
rewards: dict[str, float],
|
|
197
|
+
step: int | None = None,
|
|
198
|
+
mode: str = "train"
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
- `prompt`: The prompt text
|
|
203
|
+
- `messages`: List of `{"role": ..., "content": ...}` dicts
|
|
204
|
+
- `rewards`: Dict of reward names to values
|
|
205
|
+
- `step`: Step number (uses current step if not provided)
|
|
206
|
+
- `mode`: `"train"` or `"eval"`
|
|
207
|
+
|
|
208
|
+
### `expt_logger.flush()` / `expt_logger.end()`
|
|
209
|
+
|
|
210
|
+
- `flush()`: Manually send buffered data to server
|
|
211
|
+
- `end()`: Finish the run (called automatically on exit)
|
|
212
|
+
|
|
213
|
+
## Advanced
|
|
214
|
+
|
|
215
|
+
### Context Manager
|
|
216
|
+
|
|
217
|
+
Ensures automatic cleanup:
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
with expt_logger.init(name="my-run") as run:
|
|
221
|
+
expt_logger.log({"loss": 0.5})
|
|
222
|
+
# end() called automatically
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Graceful Shutdown
|
|
226
|
+
|
|
227
|
+
The library handles cleanup on:
|
|
228
|
+
- Normal exit (`atexit`)
|
|
229
|
+
- Ctrl+C (`SIGINT`)
|
|
230
|
+
- `SIGTERM`
|
|
231
|
+
|
|
232
|
+
All buffered data is flushed before exit.
|
|
233
|
+
|
|
234
|
+
## Development
|
|
235
|
+
|
|
236
|
+
For local development, see [DEVELOPMENT.md](DEVELOPMENT.md).
|
|
237
|
+
|
|
238
|
+
Run the demo:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
python demo.py # GRPO-style training simulation
|
|
242
|
+
python demo.py commit # Batching demo
|
|
243
|
+
python demo.py messages # Structured messages demo
|
|
244
|
+
```
|