Repository navigation
Expand file tree
/
Copy pathDockerfile.lambda
More file actions
94 lines (82 loc) · 5.11 KB
/
Copy pathDockerfile.lambda
File metadata and controls
94 lines (82 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Lambda container image with PyTorch for ensemble model inference
#
# PKT-TB-012: the live New Brain runs INSIDE this night Lambda. Before building,
# extract the brain's runtime subset out of the 4.2 GB research trees into the
# small, deployable staging dir this image bakes:
#
# python -m src.brain.bake_runtime_subset # -> build/brain_bake/
# docker build -f Dockerfile.lambda -t trader-bot:latest .
#
# The bake carves the runtime CODE (forward_inference + its imports), the four
# frozen model files (320 KB), the frozen seed caches (~108 MB), and the parity
# reference out of the prototype trees (DESIGN_DOSSIER reports/03 §0/§2). torch
# 2.1.2 + sklearn 1.3.2 are already in the image, so the brain's inference deps
# need no new heavy layer. At cold start src/brain/freeze.assert_cold_start()
# asserts engine_sha + model_sha against brain/FREEZE_ORB1.json BEFORE any
# inference; a mismatch ABORTS the night (abort-never-degrade).
FROM public.ecr.aws/lambda/python:3.11
# Upgrade pip first
RUN pip install --upgrade pip
# Install core dependencies with pre-built wheels (avoid compilation)
# Order matters: numpy first, then packages that depend on it
RUN pip install --no-cache-dir --only-binary=:all: \
numpy==1.26.4 \
pandas==2.1.4 \
pyarrow==14.0.2
# Install PyTorch CPU-only (pre-built wheel)
RUN pip install --no-cache-dir torch==2.1.2 --index-url https://download.pytorch.org/whl/cpu
# Install scikit-learn. PINNED to 1.7.2 (PKT-TB-012): the frozen M4 model
# (models_out_007/m4_evt_a/model.pkl) was pickled under sklearn >= 1.7 (where the
# LogisticRegression `multi_class` attribute was removed). Loading it under the
# old 1.3.2 hit "no attribute multi_class" and aborted the brain nightly. 1.8.0
# needs python>=3.12 (would break the torch 2.1.2 cp311 wheel); 1.7.2 is the
# newest py3.11 build and ALSO lacks multi_class, so it loads the model. 1.7.2
# requires only numpy>=1.22 (numpy stays 1.26.4 — torch 2.1.2 compatible);
# re-pinned here so the install can never drag numpy to 2.x. The in-Lambda parity
# self-check (mu/disp_z/p_exceed vs the frozen reference) is the correctness gate:
# any cross-version numeric divergence ABORTS the night (fail-safe to incumbent).
RUN pip install --no-cache-dir --only-binary=:all: scikit-learn==1.7.2 "numpy==1.26.4"
# Copy requirements and install remaining Lambda deps
COPY requirements-lambda.txt ./
RUN pip install --no-cache-dir -r requirements-lambda.txt
# Copy application code (includes src/brain: the two-stage engine + the live
# cutover runtime — the live brain is the engine, NOT tilt_adapter).
COPY src/ ${LAMBDA_TASK_ROOT}/src/
COPY training/models/ ${LAMBDA_TASK_ROOT}/training/models/
# Configuration files read by publish_artifacts (chart_markers, etc.) and the
# cutover switch config/brain.active.json (live/shadow) + the frozen champion
# static table config/champion_freeze_20260611.json.
COPY config/ ${LAMBDA_TASK_ROOT}/config/
# The frozen brain contract (PKT-TB-010) — asserted at cold start.
COPY brain/FREEZE_ORB1.json ${LAMBDA_TASK_ROOT}/brain/FREEZE_ORB1.json
# trader-bot-core: the clean-rebuild kernel. NOT wired into the live night path
# (that happens at the P9 cutover); baked here so the governed reality-test diag
# branches (e.g. source='feeds-diag', PKT-…-FEEDS-YAHOO-PRIMARY) can exercise the
# rebuilt modules from the real AWS-IP Lambda context.
COPY trader-bot-core/ ${LAMBDA_TASK_ROOT}/trader-bot-core/
# PKT-TB-012: bake the extracted runtime subset (run `python -m
# src.brain.bake_runtime_subset` first). The bake MIRRORS the repo-relative
# layout (runs/pkt_tb_007.../{shadow,prototype}, runs/pkt_tb_006.../prototype +
# its dicts/models/reference/seed-caches), so every module's path constants
# (REPO/PROTO7/TB6_PROTO/MODELS/…) resolve byte-for-byte inside the image. The
# WRITABLE state tree is redirected to /tmp at runtime (BRAIN_STATE_DIR); the
# read-only seed caches (~108 MB) are copied in at cold start.
COPY build/brain_bake/ ${LAMBDA_TASK_ROOT}/
# The frozen brain's forward-inference entry dir (production_forecaster honors this).
ENV BRAIN_RUNTIME_SUBSET=${LAMBDA_TASK_ROOT}/runs/pkt_tb_007_orthogonal_brain/shadow
# Writable working tree for the brain (Lambda /var/task is read-only).
ENV BRAIN_STATE_DIR=/tmp/brain_state
# Shadow-publish file logging -> /tmp (SHADOW dir is on the read-only /var/task).
ENV SHADOW_LOG_DIR=/tmp/shadow_logs
# Deterministic inference (the 2e-3 mu parity tolerance absorbs benign FP drift).
ENV OMP_NUM_THREADS=1
ENV MKL_NUM_THREADS=1
# P9 CUTOVER: production now runs the clean-spine thin router (trader-bot-core/
# app/handler.py), not the legacy src.handler. The clean-core package namespace
# roots at trader-bot-core/ (app, engine, decide, lines, monitors, store, forecast,
# feeds, adapter, challenger), and its modules also import src.utils.* exactly as
# the baked brain resolves them — so BOTH trader-bot-core/ and the task root go on
# the path (mirrors trader-bot-core/tests/conftest.py: _CORE + _REPO on sys.path).
ENV PYTHONPATH="${LAMBDA_TASK_ROOT}/trader-bot-core:${LAMBDA_TASK_ROOT}"
# Set the handler — the clean thin router (P9 cutover; was src.handler.lambda_handler).
CMD ["app.handler.lambda_handler"]