COSTS — the device certificates and the cost model for v17-K#
What this file is. One place where the numbers that decide whether a Kaggle run may start are written down with their provenance. It holds two device certificate slots: the local RTX 4060 Laptop, which decides every research number, and a Kaggle card, which reproduces and is filled by L2 after the first session. It also holds the dataset hashes every cell count must be read against, and the chunk / quota / failure arithmetic those hashes and certificates support.
Owner of this file: G0.6 / G0.7 (K-CERT, K-COST). Generated by
scripts/k_cert.py → results/k_cert_local.json and scripts/k_cost.py. The
full derivation, with its RED evidence and its caveats, is
99777ab:V17_G06_G07_CERT_COST.md.
PROVENANCE TAGS. [MEASURED] = read off the named box in the named run.
[FITTED] = projected from a law fitted in that run, quoted with its R².
[MODULE] = computed by a named function. [INHERITED] = carried from an
earlier file, cited. [ASSUMED] = not fixed by measurement, with the reason.
Untagged numbers are struck.
0. THE DATASET HASHES — READ THESE BEFORE ANY CELL COUNT#
results/k_data_manifest.json, schema ceq.kdata/1, written by G0.5 at
git_head ab5b48547884e04258276e6e808d5a71ea65f917 — the same commit the local
certificate below was taken at.
| source | kind | SHA-256 | status |
|---|---|---|---|
bed_1 |
generator | f73ca0e60712dec446165131c07576d03173653b14cfdeec9ce1f581bb6881d2 |
PINNED |
bed_k |
generator | 15de94b47ba07e8b2d118deac26306689a7c55d0b243699e7d04e0881a5c56e4 |
PINNED |
bed_m |
generator | 2f282a5d0e9ac412b9644e19969590c0f855e5ccb3db73436364bcb925f7d24d |
PINNED |
enwik8 |
author upload | 2b49720ec4d78c3c9fabaee6e4179a5e997302b3a70029f30f2d582218c024a8 |
PINNED |
lichess_chess_games |
kaggle attach | — | UNPINNED, AWAITING KAGGLE |
lichess_chess_evaluations |
kaggle attach (streamed) | — | UNPINNED, AWAITING KAGGLE |
tinystories_cdla |
kaggle attach | — | UNPINNED, AWAITING KAGGLE |
THREE SOURCES ARE UNPINNED AND NO CELL COUNT OVER THEM IS FINAL. The four PINNED rows are generators and one author upload, hashable from this box. The three Kaggle-attached datasets cannot be hashed until a session attaches them, so any count, split size or token budget derived from
lichess_*ortinystories_cdlain this file or elsewhere is provisional until L2 writes their SHA-256 into the table above. The chunk table in §3 is a steps-per-hour table and does not depend on them; a tokens-to-completion claim does.
1. LOCAL DEVICE CERTIFICATE — FILLED#
Source: results/k_cert_local.json, schema k_cert/1.
| field | value | tag |
|---|---|---|
| box | NVIDIA GeForce RTX 4060 Laptop GPU, sm_8.9, 7.996 GiB | [MEASURED] |
| torch / CUDA | 2.5.1+cu121 | [MEASURED] |
| host | Windows-10-10.0.26200, Python 3.11, torch.set_num_threads(8) |
[MEASURED] |
allow_tf32 (matmul / cudnn) |
False / True |
[MEASURED] |
CUBLAS_WORKSPACE_CONFIG |
:4096:8 |
[MEASURED] |
| run of record | 2026-08-31 22:26:39 local, 523.9 s | [MEASURED] |
| git HEAD at run | ab5b48547884e04258276e6e808d5a71ea65f917 |
[MEASURED] |
1.1 Throughput law [FITTED]#
Median over 3 independent child processes of the median of ≥12 timed steps and
≥3.0 s of timed work, 2 warm-up steps discarded, s = 64, d_model = 16,
torch.randn data, forward + backward + Adam.step.
| arm | law | R² | fitted over |
|---|---|---|---|
softmax |
s/step = exp(−12.1852) · n^0.9963 |
0.999998 | n = 2048…32768 (5 points) |
arm_smprime (workhorse) |
s/step = exp(−10.0187) · n^1.0026 |
1.000000 | n = 2048, 4096, 8192 (3 points) |
arm_smprime is fitted over three points and not five because the other two
are not arm measurements: on this 8 GiB card the arm's caching allocator
reserves 10.578 GiB at n = 16384 and 13.969 GiB at n = 32768, so the driver
pages over PCIe and the loop times the bus. See §1.3.
1.2 Memory law, re-solved against the CUDA allocator [MEASURED] / [FITTED]#
ceq/lm.py::TinyLM, B=4 d=256 L=4 H=4, seq sweep, forward + backward, peak
allocator bytes; two-parameter least squares separating the residual and
operator terms by the seq sweep.
| constant | ceq/sizing.py |
re-solved here | R² | verdict |
|---|---|---|---|---|
C_RESIDUAL (fp32) |
18 | 17.874 | 0.996373 | CONFIRMED, −0.7 % |
C_OPERATOR (fp32) |
3.9 | 3.823 | 0.996373 | CONFIRMED, −2.0 % |
DTYPE_MODES["bf16_autocast"][1] — operator B/elem |
3.4 | 3.341 | 0.999830 | CONFIRMED, −1.7 % |
DTYPE_MODES["bf16_autocast"][0] — residual B/elem |
2.2 | 2.383 | 0.999830 | WRONG, +8.3 %, optimistic |
ceq/sizing.pyIS NOT EDITED BY THIS NODE. The residual bytes/element under bf16 autocast is the one constant that does not reproduce, and it is wrong in the direction that under-predicts memory. Its cost is bounded and stated: at the Q3 chunk shape the module predicts 2.715 GiB and the measured pair gives 2.738 GiB (+0.85 %), andmax_batchis 45 either way, so no decision this round makes moves. It matters where the residual term dominates — many layers, short sequence — which this round does not visit.
1.3 Residency on this card [MEASURED]#
Peak allocated and peak reserved bytes for one forward + backward.
Reserved is what the caching allocator took from the driver, and it is the
quantity that decides residency: at n = 16384 the workhorse arm allocates
6.296 GiB — under the card — while reserving 10.578 GiB from it.
| arm | n | allocated GiB | reserved GiB | operator dtype | resident on 7.996 GiB |
|---|---|---|---|---|---|
softmax |
32768 | 4.032 | 4.908 | float32 @ 4 B |
yes |
arm_smprime |
2048 | 0.814 | 0.988 | complex64 @ 8 B |
yes |
arm_smprime |
4096 | 1.597 | 1.908 | complex64 @ 8 B |
yes |
arm_smprime |
8192 | 3.163 | 3.777 | complex64 @ 8 B |
yes |
arm_smprime |
16384 | 6.296 | 7.504 (10.578 under a training loop) | complex64 @ 8 B |
NO under a training loop |
arm_smprime |
32768 | 12.559 | 13.951 | complex64 @ 8 B |
NO |
1.4 Bar re-certification [MEASURED]#
calibrate_bar(n=4096, s=64, d=24, steps=600, lr=0.02, seed=0) through the
registered e3_t* hooks — r10_capacity_sweep.main()'s exact call. CPU pass at
the shipped defaults; CUDA pass under use_deterministic_algorithms(True),
cudnn.deterministic = True, CUBLAS_WORKSPACE_CONFIG=:4096:8. 20 rows
(4 rungs × 5 clauses); every tolerance quoted from bar_verdict's body or
flipper_tol's default.
| value | |
|---|---|
| verdict, all four rungs, both devices | BAR CALIBRATED |
| worst δ/tol | 8.580 × 10⁻² = 8.58 % at e3_t8 / predict_the_mean |
| the line | 50 % |
| headroom | 5.83× |
| HALT | none |
1.5 0-step RED gate [MEASURED]#
GATE_TOL = 1e-3. 2 arms × 5 values of n_train × 3 seeds = 30 cell shapes,
30 reachable, 30 pass. Worst margin above the 1.0 − GATE_TOL line:
1.957 × 10⁻³, i.e. 1.96× the tolerance.
1.6 Determinism at the arms' reduction length (64) [MEASURED]#
Workhorse arm ceq/arm_smprime.py, 8 repeats, both regimes reported.
| quantity | flag OFF | flag ON |
|---|---|---|
hop (masked cumprod along 64) |
bitwise, max|Δ| = 0.0 | bitwise, max|Δ| = 0.0 |
full forward (hop + a @ x over 64) |
bitwise, max|Δ| = 0.0 | bitwise, max|Δ| = 0.0 |
| gradient | bitwise, max|Δ| = 0.0 | NOT EXECUTABLE |
RuntimeError: cumsum_cuda_kernel does not have a deterministic implementation— raised by the backward ofcumprod, which autograd computes withcumsum. Moving the arm from a prefix scan to a path product did not escape the missing kernel; it moved it from the forward to the backward.
2. KAGGLE DEVICE CERTIFICATE — EMPTY, TO BE FILLED BY L2#
Nothing in this section has been measured. Do not read a number out of it until L2 has replaced this block. Fill it by running, unchanged, on the Kaggle card:
python scripts/k_cert.py --out results/k_cert_kaggle.jsonand then
scripts/k_cost.py --cert results/k_cert_kaggle.json.
| field | value |
|---|---|
| box (P100-16GB or 2×T4-16GB — record which) | ☐ |
| torch / CUDA | ☐ |
allow_tf32 (matmul / cudnn) |
☐ |
CUBLAS_WORKSPACE_CONFIG |
☐ |
| run timestamp, elapsed | ☐ |
| git HEAD at run | ☐ |
softmax throughput law + R² |
☐ |
arm_smprime throughput law + R², and the n it was fitted over |
☐ |
C_RESIDUAL, C_OPERATOR re-solved + R² |
☐ |
DTYPE_MODES["bf16_autocast"] re-solved + R² |
☐ |
residency: largest n at which arm_smprime stays resident |
☐ |
| worst bar δ/tol, and whether it clears 50 % | ☐ |
| 0-step gate: cells reachable / cells passing / worst margin | ☐ |
| determinism at 64, flag OFF: hop / forward / gradient | ☐ |
| determinism at 64, flag ON: hop / forward / gradient | ☐ |
measured s/step at the Q3 chunk shape |
☐ |
| measured checkpoint write seconds and bytes | ☐ |
Reproduction rule. The Kaggle certificate does not replace the local one and
may not be pooled with it — a threshold carried across a device boundary is
MISTAKES.md V-22. It answers one question: does the local box's law describe
the Kaggle card to within the tolerance L2 states before reading it?
3. THE COST MODEL#
From scripts/k_cost.py against results/k_cert_local.json.
Platform limits, [INHERITED] from 99777ab:TRAINING.md:142 citing
README.md:537-544, not re-measurable from this box: 12 h session cap,
30 GPU-h/week, 20 GB (decimal) /kaggle/working, P100-16GB or 2×T4-16GB.
3.1 The 11 h chunk and its 1 h margin#
| component | seconds | tag |
|---|---|---|
import torch + transformers, in a child |
2.74 | [MEASURED] |
ceq.hf.train.preflight |
0.000 | [MEASURED] |
| final checkpoint write, atomic path | 0.609 | [MEASURED] |
| one ragged step at the Q3 shape | 0.299 | [MEASURED] |
| measured floor | 3.6 | |
| pip install of the repo's own requirements | 180 | [ASSUMED] — a Kaggle image already carries torch; this is the repo's extras only, and this box cannot see Kaggle's network |
| dataset attach + corpus build | 300 | [ASSUMED] — G0.5 owns the real number; 300 s is the order the notebook's data cells imply |
| total charged against the margin | 484 | |
| margin available (12 h − 11 h) | 3600 | |
| covered | 7.4× |
3.2 The chunk table — steps in ≤ 11 h, from the refitted law#
alloc is the measured allocated peak; proj resv applies the worst
reserved/allocated ratio measured over this box's resident shapes (1.256)
to it; the budget is ceq/sizing.py::GPUS["T4-16GB"] = 15.0 GiB × 0.90 =
13.50 GiB [MODULE].
| arm | n | s/step | steps / 11 h | alloc GiB | proj resv GiB | T4-16GB |
|---|---|---|---|---|---|---|
arm_smprime |
2,048 | 0.093066 | 425,506 | 0.814 | 1.023 | yes (8 %) |
arm_smprime |
4,096 | 0.186465 | 212,372 | 1.597 | 2.006 | yes (15 %) |
arm_smprime |
8,192 | 0.373597 | 105,996 | 3.163 | 3.973 | yes (29 %) |
arm_smprime |
16,384 | 0.748531 | 52,903 | 6.296 | 7.906 | yes (59 %) — [FITTED], extrapolated |
arm_smprime |
32,768 | 1.499743 | 26,404 | 12.559 | 15.771 | NO (117 %) — [FITTED], extrapolated |
softmax |
2,048 | 0.010162 | 3,896,952 | 0.282 | 0.354 | yes (3 %) |
softmax |
4,096 | 0.020271 | 1,953,546 | 0.532 | 0.668 | yes (5 %) |
softmax |
8,192 | 0.040436 | 979,314 | 1.032 | 1.295 | yes (10 %) |
softmax |
16,384 | 0.080663 | 490,931 | 2.032 | 2.551 | yes (19 %) |
softmax |
32,768 | 0.160907 | 246,104 | 4.032 | 5.063 | yes (38 %) |
| LM (Q3), d512 L8 H8 seq512 batch8 | — | 0.299025 | 132,430 | 3.208 | 4.029 | yes — [MEASURED], not fitted |
One 11 h LM chunk is 132,430 steps = 542,433,280 tokens at 25,728,000
parameters, gradient finite [MEASURED].
THE ROW THAT DECIDES SOMETHING:
arm_smprimeat n = 32,768 — R2's registeredn— projects to 15.771 GiB against a 13.50 GiB T4 budget, 117 %. It does not fit a free Kaggle card, on top of not fitting the local one.
3.3 The weekly quota#
| value | |
|---|---|
| naive 30 / 11 | 2.73 chunks — wrong, it charges nothing for startup |
| billed per chunk | 11.000 h training + 0.134 h startup = 11.134 h |
| whole chunks per week | 2 |
| remainder | 7.731 h, of which 7.597 h is trainable |
| at the Q3 shape | 356,321 steps = 1,459,490,816 tokens per week |
3.4 The failure ledger#
save_every solved — not chosen — from a ≤1 % wall-clock overhead budget:
204 steps, 650 writes per chunk, 395.2 s = 0.998 % of an 11 h chunk.
| kill point | with periodic ckpt (working tree) | without (git HEAD) |
|---|---|---|
| during warm-up, before step 0 | 8.06 GPU-min | 8.06 GPU-min |
| mid-chunk | 1.02 GPU-min | 660.00 GPU-min |
| during a checkpoint write | 1.03 GPU-min | 660.00 GPU-min |
| during the final save | 1.03 GPU-min | 660.00 GPU-min |
What the periodic interface is worth: 647× on a mid-chunk kill, 659 GPU-min, 36.6 % of the entire weekly quota, per kill.
Disk: one checkpoint 0.2877 GiB [MEASURED]; /kaggle/working holds 64;
the four-directory steady state is 6.18 % [INHERITED, V17_G02_G03_CHECKPOINT.md §8].
4. SLOTS OWNED BY OTHER NODES#
V17K_RULINGS.md names two COSTS lines that are not this node's to measure.
They have a place here so they do not land somewhere else:
- RULING 1 — training noise floor. Two identical-seed chunks, |Δ| final loss, measured once, recorded here. ☐ NOT YET MEASURED. Owner: the docs/floor node. This node's §1.6 supplies the half that is measurable without training: bitwise for forward and replay, and the reason the backward cannot be strict.
- RULING 3 — matched params. One line stating that the 0.032 % residual parameter difference is matched and excluded as an explanation by magnitude. ☐ NOT YET WRITTEN. Owner: docs.