generated from mathias/template-go-web
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fb77f5263 | ||
|
|
8eb0358c01 | ||
|
|
2d412790bf | ||
|
|
8539ec3a85 | ||
|
|
c9b22db3b8 | ||
|
|
731673061e | ||
|
|
54b1bc216d | ||
|
|
fa6dcaae0a |
@@ -0,0 +1,75 @@
|
||||
name: Autoresearch Loop
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
fixture:
|
||||
description: 'Fixture name in fixtures/ (without .json)'
|
||||
required: true
|
||||
default: 'phase-a-toy'
|
||||
rq_id:
|
||||
description: 'Run ID — defaults to fixture name if blank'
|
||||
required: false
|
||||
default: ''
|
||||
iters:
|
||||
description: 'Max iterations'
|
||||
required: false
|
||||
default: '3'
|
||||
model:
|
||||
description: 'LiteLLM model override (leave blank for default berget/gemma4-31b)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Autoresearch — ${{ inputs.fixture }}
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 90
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Resolve run ID
|
||||
id: vars
|
||||
run: |
|
||||
RQ_ID="${{ inputs.rq_id }}"
|
||||
[ -z "$RQ_ID" ] && RQ_ID="${{ inputs.fixture }}"
|
||||
echo "rq_id=$RQ_ID" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Clean stale run dir
|
||||
run: rm -rf "runs/${{ steps.vars.outputs.rq_id }}"
|
||||
|
||||
- name: Set up Python venv
|
||||
run: |
|
||||
[ -d .venv ] || python3 -m venv .venv
|
||||
# torch must come from the cu130 wheel index (koala Blackwell sm_120);
|
||||
# requirements.txt deliberately excludes it. Install it first.
|
||||
.venv/bin/pip install -q torch --index-url https://download.pytorch.org/whl/cu130
|
||||
.venv/bin/pip install -q -r requirements.txt
|
||||
|
||||
- name: Scaffold run dir
|
||||
run: |
|
||||
.venv/bin/python scripts/autoresearch_start.py \
|
||||
"fixtures/${{ inputs.fixture }}.json" \
|
||||
"${{ steps.vars.outputs.rq_id }}"
|
||||
|
||||
- name: Run autoresearch loop
|
||||
env:
|
||||
LITELLM_KEY: ${{ secrets.LITELLM_KEY }}
|
||||
LITELLM_BASE: ${{ secrets.LITELLM_BASE }}
|
||||
NTFY_URL: ${{ secrets.NTFY_URL }}
|
||||
run: |
|
||||
ARGS="--run-dir runs/${{ steps.vars.outputs.rq_id }} --iters ${{ inputs.iters }}"
|
||||
[ -n "${{ inputs.model }}" ] && ARGS="$ARGS --model ${{ inputs.model }}"
|
||||
.venv/bin/python loop.py $ARGS
|
||||
|
||||
- name: Upload run artifacts
|
||||
if: always()
|
||||
uses: https://gitea.com/actions/upload-artifact@v3
|
||||
with:
|
||||
name: run-${{ steps.vars.outputs.rq_id }}-${{ github.run_number }}
|
||||
path: |
|
||||
runs/${{ steps.vars.outputs.rq_id }}/STATUS.md
|
||||
runs/${{ steps.vars.outputs.rq_id }}/metrics.json
|
||||
runs/${{ steps.vars.outputs.rq_id }}/program.md
|
||||
retention-days: 30
|
||||
+17
@@ -34,3 +34,20 @@ bin/
|
||||
|
||||
# downloaded + processed market data (track via DVC/MinIO, #10 — not git)
|
||||
data/
|
||||
|
||||
# autoresearch run dirs (ephemeral; each scaffold rebuilds from fixtures/)
|
||||
runs/
|
||||
|
||||
# ephemeral experiment outputs (generated by train.py / loop.py)
|
||||
metrics.json
|
||||
embeddings.json
|
||||
HEARTBEAT
|
||||
STATUS.md
|
||||
|
||||
# python caches
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.pytest_cache/
|
||||
|
||||
# built Go binaries
|
||||
eval
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"strategic_question": "What is the highest-leverage path to a JEPA-based FX tail-risk system that beats a GARCH/EWMA baseline on out-of-sample VaR-breach calibration, given one GPU and a solo researcher?",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "phase-a-toy",
|
||||
"status": "autoresearch-ready",
|
||||
"question": "Improve the OOS linear-probe R² (val_vol_r2) of the HEPA encoder on EUR/USD daily realized vol. The encoder is a small causal transformer trained with VICReg. Vary one hyperparameter or architectural choice per iteration — model size, learning rate, window, patch length, depth, VICReg loss weights — to push val_vol_r2 as high as possible on the 2022-2023 OOS slice.",
|
||||
"candidate_metric": "val_vol_r2"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -84,6 +84,10 @@ def run_train() -> "tuple[float | None, float, str]":
|
||||
t0 = time.time()
|
||||
env = dict(os.environ)
|
||||
env["METRICS_OUT"] = str(METRICS_JSON.resolve())
|
||||
# train.py is copied into the run dir, so sys.path[0] is that run dir — which
|
||||
# has no scripts/. Put the project root (where loop.py + scripts/ live) on
|
||||
# PYTHONPATH so train.py's `from scripts.var_breach import ...` resolves.
|
||||
env["PYTHONPATH"] = str(Path(__file__).resolve().parent) + os.pathsep + env.get("PYTHONPATH", "")
|
||||
try:
|
||||
r = subprocess.run(
|
||||
[sys.executable, str(TRAIN_PY.resolve())],
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"val_vol_r2": 0.3641397896593044,
|
||||
"phase1_r2": 0.3908407688140869,
|
||||
"n_test": 11641,
|
||||
"knobs": {
|
||||
"WINDOW": 120,
|
||||
"PATCH_LEN": 24,
|
||||
"D_MODEL": 128,
|
||||
"DEPTH": 2,
|
||||
"ALPHA": 0.1,
|
||||
"DELTA_T_MAX": 3,
|
||||
"EPOCHS": 300
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
numpy>=2.0
|
||||
pandas>=2.2
|
||||
pyarrow>=16
|
||||
histdata>=1.3 # histdata.com downloader (handles the tk token politely)
|
||||
histdata>=1.1 # histdata.com downloader (1.1 is newest on PyPI; 1.3 never existed)
|
||||
hmmlearn>=0.3 # regime detector (prepare_regime.py, jepa-fx-risk#13)
|
||||
scikit-learn>=1.4 # HMM dependency
|
||||
|
||||
Reference in New Issue
Block a user