Modal Research Exchange

you are

LoRA SFT LR 3e-4 vs 1e-4 on no_robots, Qwen3.5-2B

Succeeded not supported agentcore Qwen/Qwen3.5-2B SFT 1.5 GPU-h budget started 5h ago 44m 00s 2 turns
Redo
Pick where the agent works.

Stock tinker-cookbook chat_sl rank-32 LoRA SFT of Qwen/Qwen3.5-2B on no_robots (batch 32, 60 steps, AdamW, stock linear LR decay) ran on shared Spindle for 3 seeds x 2 LRs, scored on 300 held-out no_robots test examples per arm, using about 33 minutes of Spindle wall-clock in total (pelican). LR 3e-4 beat 1e-4 in every seed but only by a mean of 0.0046 nats/token (95% paired-t CI [0.0029, 0.0064]), inside the spec's +/-0.02 tie band, so the >=0.02 improvement hypothesis is not supported (inconclusive/tie).

Not supported The completed comparison fell inside the spec's tie band, so the claimed effect was not reached. Confidence is limited by: treatment activation unverified; initialization and optimizer verification unverified; evaluator provenance does not show comparable scoring across arms; decision evidence unverified; feasibility evidence incomplete. Reclassified from inconclusive under the direction-plus-confidence rule.

Result token_mean_nll 2 kept from interim updates

baseline mean 2.097 · 3 armstreatment mean 2.092 · 3 arms
Lower is better · Axis from 2.09 to 2.098, not zero
armtoken_mean_nlln_tokenstrain_nlln_eval_examplestrain_nll_drop_step0_to
baseline_lr1e-4_seed02.09659,5032.3123000.3822
baseline_lr1e-4_seed12.09759,5032.6993000.8236
baseline_lr1e-4_seed22.09859,5032.4173000.2253
treatment_lr3e-4_seed02.09159,5032.3123000.4103
treatment_lr3e-4_seed12.09359,5032.6993000.8459
treatment_lr3e-4_seed22.09359,5032.4173000.251
3 more metrics under Evidence, All metrics.
Arms agentcore reported complete: baseline_lr1e-4_seed0, treatment_lr3e-4_seed0, baseline_lr1e-4_seed1, treatment_lr3e-4_seed1, baseline_lr1e-4_seed2, treatment_lr3e-4_seed2
Changes from the spec 3
whatspecran withwhyrecorded
Datasetchat_sl seed=$S flag (does not exist in stock CLI; NoRobotsBuilder shuffles train with fixed seed 0)train split shuffled with seed S (S=0 identical to stock order); both arms of a seed share order; each seed's arms load a shared random LoRA init checkpoint saved via save_state (Spindle rejects create_lora_training_client(seed=...): 'Miles multi-LoRA does not support per-model seeds')Implement the spec's 3 training seeds with matched within-seed init and data order before the run ended
Datasetchat_sl seed=$S flag (absent in stock CLI; NoRobotsBuilder always shuffles train with seed 0)train split shuffled with seed S (S=0 identical to stock order); both arms of a seed share order and load a shared random LoRA init checkpoint saved via save_stateSpindle rejects create_lora_training_client(seed=...) ('Miles multi-LoRA does not support per-model seeds'); this implements 3 seeds with matched within-seed init and data order before the run ended
Datasetchat_sl seed=$S flag (absent in stock CLI; NoRobotsBuilder always shuffles train with seed 0)train split shuffled with seed S (S=0 identical to stock order); both arms of a seed share data order and load a shared random LoRA init checkpoint (save_state) via stock load_checkpoint_pathSpindle rejects create_lora_training_client(seed=...) ('Miles multi-LoRA does not support per-model seeds'); this implements the spec's 3 seeds with matched within-seed init and data order only in the final result

Original hypothesis tested: yes

  • reported only in the final result, not before training went on: dataset
Checks · activation unverified · evaluator invalid · feasibility unknown
Custom implementation correctness: not_applicable
spec.correctness_preflight opts out and no feature it covers is true
Validates executor-reported evidence; autonomous training calls are not blocked by this server.
Executor reported inconclusive; shown as not supported.
Treatment activation: unverified
Not reported: train_nll_drop_step0_to_step10.
executed_learning_rate_treatment
0.0003 needs >= 0.0003 and <= 0.0003 · passed
executed_learning_rate_baseline
0.0001 needs >= 0.0001 and <= 0.0001 · passed
executed_base_model
Qwen/Qwen3.5-2B needs one of Qwen/Qwen3.5-2B · passed
executed_steps
60 needs >= 60 and <= 60 · passed
executed_batch_size
32 needs >= 32 and <= 32 · passed
executed_lora_rank
32 needs >= 32 and <= 32 · passed
train_nll_drop_step0_to_step10
not reported needs >= 0 · missing
Initialization / optimizer verification: unverified
baseline_lr1e-4_seed0: missing or duplicate arm evidence.
Research decision: unverified
Observation file name/hash is not retained for this run.
Evaluator comparability: invalid
Expected evaluators, scores and comparisons.
Evaluator identities and per-arm scores
{
  "evaluators": {
    "fd0cc0dfe17a2cf0b7b7e1d3440d68fe976e570883f8232ea32d9be8bc0794ba": {
      "code_sha256": "8c8453b6bb053c058c6c6a38e98ff2bb2ef3a9c46bf1c090825acbc8508cf083",
      "decoding": {
        "max_tokens": 0,
        "stop": [],
        "temperature": 0
      },
      "items": {
        "manifest_ref": "evaluator_provenance.json"
      },
      "parser": "loss_eval.LossEval('token_mean')",
      "prompt_template": "tinker_cookbook renderer 'qwen3_5', conversation_to_datum(max_length=2048, ALL_ASSISTANT_MESSAGES)"
    }
  },
  "version": 1
}
Held-out loss aggregation
Spec asks for token mean (summed NLL / loss tokens) · run reported token mean (summed NLL / loss tokens)
Checked: every arm used this aggregation on the same tokens and examples, and each value matches its totals.
armvaluetoken meanexample meanloss tokensexamples
baseline_lr1e-4_seed02.0962.0961.97959,503300
treatment_lr3e-4_seed02.0912.0911.97159,503300
Feasibility projection: unknown
Projected costs, not measured GPU usage.
Projected wall time
unknown
Projected GPU allocation
unknown
  • Re-projection required: lora_rank changed or was not recorded
  • Re-projection required: dataset changed or was not recorded
  • Re-projection required: steps changed or was not recorded
  • Re-projection required: arms changed or was not recorded
  • Re-projection required: n_examples changed or was not recorded
  • Re-projection required: n_eval changed or was not recorded
  • Positive recovery reserve not recorded
Timing, sample counts and allocation evidence
{
  "generation_applicability": {
    "check": "generation_audit",
    "enforce": false,
    "features": {
      "generated_training_data": false
    },
    "reasons": [
      "spec.generation_audit opts out and no feature it covers is true"
    ],
    "status": "not_applicable"
  },
  "generation_counts": null,
  "gpu_hours": null,
  "known_gpu_hours": 0,
  "phases": {
    "evaluation": {
      "gpu_hours": null,
      "planned_samples": 2100.0,
      "planned_units": 2100,
      "wall_seconds": 147.0
    },
    "setup": {
      "gpu_hours": null,
      "planned_samples": 0.0,
      "planned_units": 1,
      "wall_seconds": 252.7
    },
    "training": {
      "gpu_hours": null,
      "planned_samples": 11520.0,
      "planned_units": 360,
      "wall_seconds": 711.45
    }
  },
  "problems": [
    "Re-projection required: lora_rank changed or was not recorded",
    "Re-projection required: dataset changed or was not recorded",
    "Re-projection required: steps changed or was not recorded",
    "Re-projection required: arms changed or was not recorded",
    "Re-projection required: n_examples changed or was not recorded",
    "Re-projection required: n_eval changed or was not recorded",
    "Positive recovery reserve not recorded"
  ],
  "record": {
    "config": {
      "base_model": "Qwen/Qwen3.5-2B",
      "batch_size": 32,
      "max_seq_len": 2048,
      "pilot": "2 batch-32 steps + 1 forward of 32"
    },
    "effective_config": {
      "arms": 6,
      "base_model": "Qwen/Qwen3.5-2B",
      "batch_size": 32,
      "max_seq_len": 2048,
      "n_eval": 300,
      "steps": 60
    },
    "generation": null,
    "measurements": {
      "evaluation": {
        "allocation_source": null,
        "gpu_count": null,
        "planned_units": 2100,
        "samples": 300,
        "seconds": 21,
        "units": 300
      },
      "setup": {
        "allocation_source": null,
        "gpu_count": null,
        "planned_units": 1,
        "samples": 0,
        "seconds": 252.7,
        "units": 1
      },
      "training": {
        "allocation_source": null,
        "gpu_count": null,
        "planned_units": 360,
        "samples": 11520,
        "seconds": 711.45,
        "units": 360
      }
    },
    "primary_endpoint": "token_mean held-out NLL (nats/token) on no_robots test[:300] at step 60",
    "recovery": {
      "allocation_source": null,
      "gpu_count": null,
      "seconds": 0
    },
    "source": "preflight_out.json, runs/*/arm_timing.json"
  },
  "recorded_at": 1793748023.8097074,
  "status": "unknown",
  "wall_seconds": null
}
Generated task audit: not applicable
spec.generation_audit opts out and no feature it covers is true
Answer agreement with recorded independent solutions does not establish semantic correctness. Normalized exact overlap does not detect paraphrases.
Spec exp_9574bbb76e
Experiment version
exp_9574bbb76e
Execute the selected saved experiment version.

Hypothesis

For rank-32 LoRA SFT of Qwen/Qwen3.5-2B on no_robots, LR 3e-4 gives at least 0.02 nats/token lower token_mean held-out test NLL than LR 1e-4 after 60 steps at batch size 32.

Success criterion

Let D = baseline token_mean NLL minus treatment token_mean NLL (nats/token) on no_robots test[:300] at step 60, paired by seed. Validated if the simultaneous 95% paired_t interval for D across seeds 0-2 lies entirely above 0.02. Failed if the interval lies entirely below -0.02 (1e-4 better by at least 0.02). Otherwise inconclusive. With a single seed the result is a smoke test only and the decision is inconclusive.

no_robots 60 steps batch 32 LoRA r32 lr 0.0003 90 min wall budget
Method
Run the stock tinker_cookbook.recipes.chat_sl.train recipe against the shared Spindle (base_url=$TINKER_BASE_URL, AdamW, no fork). There are two arms: baseline lr=1e-4 and treatment lr=3e-4. Both use rank 32, batch 32, max_length 2048 and 60 steps. Within each seed both arms see the same data order. Each arm saves sampler/state weights at step 60. A separate eval script then scores the first 300 rows of the no_robots test split with the same renderer and loss mask, using forward() on the step-60 weights. For each example it sums -logprob*weight over loss tokens and counts the loss tokens. The reported value is total NLL over all loss tokens divided by total loss tokens (token_mean). Batch loss:mean values are never averaged. Deviation from the source: the source asks for one seed, but one seed cannot give a valid confidence interval for an unbounded NLL contrast. This spec therefore schedules 3 training seeds (0, 1, 2). If timing allows only 1 seed, the run is reported as a harness smoke test with an inconclusive decision.
Baseline
Identical chat_sl run with learning_rate=1e-4, same model, rank, batch, max_length, steps, seed and data order, and the same eval script.
Full spec
{
  "activation_gate": {
    "applicable": true,
    "checks": [
      {
        "max": 0.0003,
        "measures": "learning_rate passed to optim_step / logged in the treatment run config",
        "metric": "executed_learning_rate_treatment",
        "min": 0.0003
      },
      {
        "max": 0.0001,
        "measures": "learning_rate passed to optim_step / logged in the baseline run config",
        "metric": "executed_learning_rate_baseline",
        "min": 0.0001
      },
      {
        "measures": "model_name in each run's logged config",
        "metric": "executed_base_model",
        "one_of": [
          "Qwen/Qwen3.5-2B"
        ]
      },
      {
        "max": 60,
        "measures": "number of optim_step calls completed per arm",
        "metric": "executed_steps",
        "min": 60
      },
      {
        "max": 32,
        "measures": "examples per optimizer step in each arm",
        "metric": "executed_batch_size",
        "min": 32
      },
      {
        "max": 32,
        "measures": "LoRA rank of each created training client",
        "metric": "executed_lora_rank",
        "min": 32
      },
      {
        "measures": "mean train NLL at step 0 minus step 10 in each arm (training engages)",
        "metric": "train_nll_drop_step0_to_step10",
        "min": 0.0
      }
    ],
    "reason": "The only treatment is the learning rate. The gate confirms that the executed config matches the plan (LR, model, rank, steps, batch) and that training actually moved the adapter, so the arms truly differ in the intended way."
  },
  "arms": [
    {
      "lr": 0.0001,
      "name": "baseline_lr1e-4_seed0",
      "seed": 0
    },
    {
      "lr": 0.0003,
      "name": "treatment_lr3e-4_seed0",
      "seed": 0
    },
    {
      "lr": 0.0001,
      "name": "baseline_lr1e-4_seed1",
      "seed": 1
    },
    {
      "lr": 0.0003,
      "name": "treatment_lr3e-4_seed1",
      "seed": 1
    },
    {
      "lr": 0.0001,
      "name": "baseline_lr1e-4_seed2",
      "seed": 2
    },
    {
      "lr": 0.0003,
      "name": "treatment_lr3e-4_seed2",
      "seed": 2
    }
  ],
  "base_model": "Qwen/Qwen3.5-2B",
  "baseline": "Identical chat_sl run with learning_rate=1e-4, same model, rank, batch, max_length, steps, seed and data order, and the same eval script.",
  "batch_size": 32,
  "budget": {
    "gpu_hours": 1.5,
    "max_wall_minutes": 90
  },
  "command": "for S in 0 1 2; do for LR in 1e-4 3e-4; do python -m tinker_cookbook.recipes.chat_sl.train model_name=Qwen/Qwen3.5-2B base_url=$TINKER_BASE_URL dataset=no_robots learning_rate=$LR lora_rank=32 batch_size=32 max_length=2048 max_steps=60 seed=$S log_path=/tmp/rx-nr-lr$LR-s$S; done; done  # then eval (custom script, scoring only): for each run, load the step-60 weights via ServiceClient(base_url=os.environ['TINKER_BASE_URL']).create_lora_training_client(base_model='Qwen/Qwen3.5-2B', rank=32) + load_state(<step60 path>); build Datums for HuggingFaceH4/no_robots test[:300] with the same renderer/loss mask as chat_sl; out=tc.forward(datums,'cross_entropy').result(); per example nll_i=-sum(lp*w), n_i=sum(w) from out.loss_fn_outputs[i]['logprobs'] and the datum weights; token_mean=sum(nll_i)/sum(n_i); write per-example (nll_i,n_i) JSONL per arm/seed.",
  "correctness_preflight": {
    "reason": "Both arms use the stock chat_sl cross-entropy loss and the stock server AdamW; only the learning rate differs, so there is no custom loss or optimizer path.",
    "required": false
  },
  "dataset": {
    "hf_path": "HuggingFaceH4/no_robots",
    "n_examples": 1920,
    "name": "no_robots",
    "split": "train (training), test[:300] (eval)"
  },
  "decision_rule": {
    "alpha": 0.05,
    "assumptions": {
      "identically_distributed_seed_effects": true,
      "independent_seed_effects": true,
      "normal_seed_effects": true
    },
    "criteria": [
      {
        "id": "primary",
        "margin": 0.02,
        "metric": "token_mean held-out NLL (nats/token) at step 60",
        "weights": {
          "baseline": 1,
          "treatment": -1
        }
      }
    ],
    "estimand": "Reduction in step-60 token_mean held-out NLL on no_robots test[:300] for Qwen3.5-2B rank-32 LoRA SFT from using LR 3e-4 instead of 1e-4; positive favors 3e-4",
    "method": "paired_t",
    "seeds": [
      0,
      1,
      2
    ],
    "unit": "training_seed",
    "version": 1
  },
  "eval": {
    "aggregation": "token_mean",
    "benchmark": "no_robots test split, first 300 examples",
    "metric": "token_mean held-out NLL (nats/token) at step 60",
    "n_examples": 300
  },
  "experiment_features": {
    "adaptive_selection": false,
    "checkpoint_restore": false,
    "custom_loss": false,
    "custom_optimizer": false,
    "generated_training_data": false,
    "heldout_loss": true,
    "learned_generator": false,
    "paired_comparison": true,
    "paired_training_arms": true,
    "warmup_adaptation": false
  },
  "feasibility_check": {
    "gpu_hours": null,
    "known_gpu_hours": 0,
    "phases": {},
    "problems": [
      "Measured feasibility not recorded"
    ],
    "status": "unknown",
    "wall_seconds": null
  },
  "feasibility_required": true,
  "generation_audit": {
    "answer_comparison": "categorical_exact",
    "max_eval_overlaps": 0,
    "max_label_errors": 0,
    "min_sample_size": 100,
    "required": false
  },
  "hypothesis": "For rank-32 LoRA SFT of Qwen/Qwen3.5-2B on no_robots, LR 3e-4 gives at least 0.02 nats/token lower token_mean held-out test NLL than LR 1e-4 after 60 steps at batch size 32.",
  "lora_rank": 32,
  "max_seq_len": 2048,
  "method": "Run the stock tinker_cookbook.recipes.chat_sl.train recipe against the shared Spindle (base_url=$TINKER_BASE_URL, AdamW, no fork). There are two arms: baseline lr=1e-4 and treatment lr=3e-4. Both use rank 32, batch 32, max_length 2048 and 60 steps. Within each seed both arms see the same data order. Each arm saves sampler/state weights at step 60. A separate eval script then scores the first 300 rows of the no_robots test split with the same renderer and loss mask, using forward() on the step-60 weights. For each example it sums -logprob*weight over loss tokens and counts the loss tokens. The reported value is total NLL over all loss tokens divided by total loss tokens (token_mean). Batch loss:mean values are never averaged. Deviation from the source: the source asks for one seed, but one seed cannot give a valid confidence interval for an unbounded NLL contrast. This spec therefore schedules 3 training seeds (0, 1, 2). If timing allows only 1 seed, the run is reported as a harness smoke test with an inconclusive decision.",
  "optimizer": {
    "lr": 0.0003,
    "name": "adam"
  },
  "preflight": {
    "probe": "Before the arms run, create a rank-32 LoRA training client on Qwen/Qwen3.5-2B for each arm config. Run forward on one fixed tokenized no_robots example and check that the initial losses are identical across arms. Take one optim_step with AdamParams(learning_rate=1e-4) and one with 3e-4 on that example. Save weights, reload them, and re-run forward on the fixed batch. Confirm that the first 3 batch ids logged by chat_sl match across arms for the same seed. Fail fast if the max_length or seed flag is rejected.",
    "riskiest_assumption": "The chat_sl recipe honors max_length=2048 and seed so that both arms see the same data order within a seed. The step-60 weights are reloadable for a forward-only eval using the same renderer and loss mask as training.",
    "tuning": "No LR grid is used: the learning rate is itself the decision under test, and both arms use the same AdamW optimizer, steps, batch and data. Nothing is selected on the eval split; the eval is a single fixed step-60 evaluation."
  },
  "primary_endpoint": "token_mean held-out NLL (nats/token) on no_robots test[:300] at step 60",
  "restoration_preflight": {
    "applicable": true,
    "fixed_batch_required": true,
    "groups": [
      {
        "arms": [
          {
            "name": "baseline_lr1e-4_seed0",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0001
            }
          },
          {
            "name": "treatment_lr3e-4_seed0",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0003
            }
          }
        ]
      },
      {
        "arms": [
          {
            "name": "baseline_lr1e-4_seed1",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0001
            }
          },
          {
            "name": "treatment_lr3e-4_seed1",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0003
            }
          }
        ]
      },
      {
        "arms": [
          {
            "name": "baseline_lr1e-4_seed2",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0001
            }
          },
          {
            "name": "treatment_lr3e-4_seed2",
            "optimizer": "adam",
            "optimizer_config": {
              "beta1": 0.9,
              "beta2": 0.95,
              "eps": 1e-08,
              "learning_rate": 0.0003
            }
          }
        ]
      }
    ],
    "reason": "Both arms in each seed are trained from the same base model, so their initial LoRA state and optimizer config must match before the first update. The arms differ only in LR, which is passed at optim_step."
  },
  "steps": 60,
  "success_criterion": "Let D = baseline token_mean NLL minus treatment token_mean NLL (nats/token) on no_robots test[:300] at step 60, paired by seed. Validated if the simultaneous 95% paired_t interval for D across seeds 0-2 lies entirely above 0.02. Failed if the interval lies entirely below -0.02 (1e-4 better by at least 0.02). Otherwise inconclusive. With a single seed the result is a smoke test only and the decision is inconclusive.",
  "title": "LoRA SFT LR 3e-4 vs 1e-4 on no_robots, Qwen3.5-2B",
  "training_type": "sft"
}
Evidence 1

Partial · Download manifest. Recorded files are retained copies; checkpoint references do not include model weights.

Not recorded: script, effective config, predictions, per arm metrics.

Checkpoint references
[
  {
    "arm": "baseline_lr1e-4_seed0",
    "step": 60,
    "uri": "tinker://716daf64-43a3-49cf-9306-cebe87f287b6:train:0/weights/final"
  },
  {
    "arm": "treatment_lr3e-4_seed0",
    "step": 60,
    "uri": "tinker://7c44035a-0da1-426b-b1a3-fed1c79adca2:train:0/weights/final"
  },
  {
    "arm": "baseline_lr1e-4_seed1",
    "step": 60,
    "uri": "tinker://6ad9f90f-fa9d-487a-b444-ddb5df06c956:train:0/weights/final"
  },
  {
    "arm": "treatment_lr3e-4_seed1",
    "step": 60,
    "uri": "tinker://4a7402fb-facb-4a17-84e5-c6a8343fbcd1:train:0/weights/final"
  },
  {
    "arm": "baseline_lr1e-4_seed2",
    "step": 60,
    "uri": "tinker://d821fabd-9797-472c-9f5f-77255afd1c89:train:0/weights/final"
  },
  {
    "arm": "treatment_lr3e-4_seed2",
    "step": 60,
    "uri": "tinker://5951599a-b260-4b0a-a5b1-3b23a996a5f8:train:0/weights/final"
  }
]
All metrics
metricbaseline_lr1e-4_seed0treatment_lr3e-4_seed0baseline_lr1e-4_seed1treatment_lr3e-4_seed1baseline_lr1e-4_seed2treatment_lr3e-4_seed2
token_mean_nll2.0962.0912.0972.0932.0982.093
nll_sum124,714.6124,444.0————
n_tokens59,50359,50359,50359,50359,50359,503
train_seconds_lr1e-471.42—131.9—128.1—
train_nll_step02.3122.3122.6992.6992.4172.417
train_nll_step101.931.902————
n_eval_examples300300300300300300
train_nll_drop_step0_to_step100.38220.41030.82360.84590.22530.251
train_seconds_lr3e-4—123.3—131.1—125.7
D_mean_baseline_minus_treatment
0.004607
D_seed0
0.004549
D_seed1
0.003932
D_seed2
0.00534
D_sd
0.0007057
D_ci95_low
0.002854
D_ci95_high
0.00636
margin
0.02
n_eval_examples_per_arm
300
n_eval_loss_tokens_per_arm
59,503
base_init_token_mean_nll
2.439
total_spindle_wall_minutes
32.6
Interim updates from agentcore (3, first Nov 3, 22:53 UTC)
Artifact references
  • checkpoint · baseline_lr1e-4_seed0 · step 60 · tinker://716daf64-43a3-49cf-9306-cebe87f287b6:train:0/weights/final
  • checkpoint · treatment_lr3e-4_seed0 · step 60 · tinker://7c44035a-0da1-426b-b1a3-fed1c79adca2:train:0/weights/final
  • checkpoint · baseline_lr1e-4_seed1 · step 60 · tinker://6ad9f90f-fa9d-487a-b444-ddb5df06c956:train:0/weights/final
  • checkpoint · treatment_lr3e-4_seed1 · step 60 · tinker://4a7402fb-facb-4a17-84e5-c6a8343fbcd1:train:0/weights/final
  • checkpoint · baseline_lr1e-4_seed2 · step 60 · tinker://d821fabd-9797-472c-9f5f-77255afd1c89:train:0/weights/final
  • checkpoint · treatment_lr3e-4_seed2 · step 60 · tinker://5951599a-b260-4b0a-a5b1-3b23a996a5f8:train:0/weights/final
  • code_revision · code-revision.txt
  1. Nov 3, 23:20 UTC · succeeded · done: baseline_lr1e-4_seed0, treatment_lr3e-4_seed0, baseline_lr1e-4_seed1, treatment_lr3e-4_seed1, baseline_lr1e-4_seed2, treatment_lr3e-4_seed2 · Stock tinker-cookbook chat_sl rank-32 LoRA SFT of Qwen/Qwen3.5-2B on no_robots (batch 32, 60 steps, AdamW, stock linear LR decay) ran on shared Spindle for 3 seeds x 2 LRs, scored on 300 held-out no_…
  2. Nov 3, 23:12 UTC · running · done: baseline_lr1e-4_seed0, treatment_lr3e-4_seed0 · Stock chat_sl LoRA SFT (rank 32, batch 32, 60 steps, linear LR decay) of Qwen/Qwen3.5-2B on no_robots on shared Spindle; seed 0 finished with held-out token_mean NLL 2.09594 (lr 1e-4) vs 2.09139 (lr 3e-4).
  3. Nov 3, 22:53 UTC · running · Preflight running on shared Spindle (Qwen/Qwen3.5-2B served). Spindle rejects per-model LoRA seeds, so each seed uses a saved random-init checkpoint shared by both arms plus a seed-dependent train shuffle.
Artifacts
correctness_preflight
{'required': False, 'paths': []}
correctness_validation
{'status': 'not_applicable', 'required': False, 'checks': [], 'reason': 'spec.correctness_preflight opts out and no feature it covers is true', 'evidence_source': 'executor report; remote execution is not attested', 'applicability': 'not_applicable', 'reported_verdict': 'inconclusive'}
decision
{'version': 1, 'observations_file': {'name': 'scored-observations.jsonl', 'sha256': 'c2f38ca195dd0f65cf275663989a4d756456ed537bb9a51b1737ef6ff2718ca6'}}
decision_validation
{'status': 'unverified', 'issues': ['Observation file name/hash is not retained for this run.'], 'criteria': [], 'outcome_reason': 'insufficient_evidence', 'applicability': {'check': 'decision_rule', 'status': 'required', 'enforce': True, 'reasons': ['experiment_features: paired_comparison is true'], 'features': {'paired_comparison': True, 'adaptive_selection': False}}}
evaluation
{'version': 1, 'evaluators': {'fd0cc0dfe17a2cf0b7b7e1d3440d68fe976e570883f8232ea32d9be8bc0794ba': {'code_sha256': '8c8453b6bb053c058c6c6a38e98ff2bb2ef3a9c46bf1c090825acbc8508cf083', 'prompt_template': "tinker_cookbook renderer 'qwen3_5', conversation_to_datum(max_length=2048, ALL_ASSISTANT_MESSAGES)", 'decoding': {'temperature': 0, 'max_tokens': 0, 'stop': []}, 'parser': "loss_eval.LossEval('token_mean')", 'items': {'manifest_ref': 'evaluator_provenance.json'}}}}
evaluator_validation
{'status': 'invalid', 'issues': ['Expected evaluators, scores and comparisons.'], 'comparisons': []}
feasibility
{'status': 'unknown', 'problems': ['Re-projection required: lora_rank changed or was not recorded', 'Re-projection required: dataset changed or was not recorded', 'Re-projection required: steps changed or was not recorded', 'Re-projection required: arms changed or was not recorded', 'Re-projection required: n_examples changed or was not recorded', 'Re-projection required: n_eval changed or was not recorded', 'Positive recovery reserve not recorded'], 'wall_seconds': None, 'gpu_hours': None, 'known_gpu_hours': 0, 'phases': {'setup': {'wall_seconds': 252.7, 'planned_units': 1, 'planned_samples': 0.0, 'gpu_hours': None}, 'training': {'wall_seconds': 711.45, 'planned_units': 360, 'planned_samples': 11520.0, 'gpu_hours': None}, 'evaluation': {'wall_seconds': 147.0, 'planned_units': 2100, 'planned_samples': 2100.0, 'gpu_hours': None}}, 'generation_counts': None, 'generation_applicability': {'check': 'generation_audit', 'status': 'not_applicable', 'enforce': False, 'reasons': ['spec.generation_audit opts out and no feature it covers is true'], 'features': {'generated_training_data': False}}, 'record': {'config': {'base_model': 'Qwen/Qwen3.5-2B', 'batch_size': 32, 'max_seq_len': 2048, 'pilot': '2 batch-32 steps + 1 forward of 32'}, 'effective_config': {'base_model': 'Qwen/Qwen3.5-2B', 'arms': 6, 'steps': 60, 'batch_size': 32, 'max_seq_len': 2048, 'n_eval': 300}, 'primary_endpoint': 'token_mean held-out NLL (nats/token) on no_robots test[:300] at step 60', 'source': 'preflight_out.json, runs/*/arm_timing.json', 'measurements': {'setup': {'seconds': 252.7, 'units': 1, 'planned_units': 1, 'samples': 0, 'gpu_count': None, 'allocation_source': None}, 'training': {'seconds': 711.45, 'units': 360, 'planned_units': 360, 'samples': 11520, 'gpu_count': None, 'allocation_source': None}, 'evaluation': {'seconds': 21, 'units': 300, 'planned_units': 2100, 'samples': 300, 'gpu_count': None, 'allocation_source': None}}, 'generation': None, 'recovery': {'seconds': 0, 'gpu_count': None, 'allocation_source': None}}, 'recorded_at': 1793748023.8097074}
feasibility_required
True
generation_audit_validation
{'status': 'not_applicable', 'reasons': ['spec.generation_audit opts out and no feature it covers is true'], 'applicability': {'check': 'generation_audit', 'status': 'not_applicable', 'enforce': False, 'reasons': ['spec.generation_audit opts out and no feature it covers is true'], 'features': {'generated_training_data': False}}}
initialization_provenance
{'version': 1, 'note': 'Adapter sha256 unavailable: save_weights_external returns 404 on Spindle (and stalls the client request sequence). Proof is a shared full initialization checkpoint per seed loaded by both arms via create_training_client_from_state; seed-0 pair has bit-identical full initial logprobs on a fixed batch; all pairs have bit-identical step-0 train NLL on the same 32-example batch.', 'groups': {'seed0': {'checkpoint_uri': 'tinker://8ff281af876a6bb849f1395cb6de405e/weights/init-seed0', 'initial_output': {'available': True, 'batch_sha256': '6ff46d26c02471d39a04fa86173632086f809558cd1beb0e50b9306fb7ba6fd4', 'output_sha256': '8a5c5514e09b80a4153feb85b9a72c16e73b0356bef6e0d56bec0d8c620403bf', 'match': True, 'evidence_ref': 'preflight_out.json'}}, 'seed1': {'checkpoint_uri': 'tinker://85df6b5ab377e88eeed4d70230fd33d8/weights/init-seed1', 'initial_output': {'available': False, 'reason': 'only step-0 train NLL captured (identical: 2.6985340118408203)'}}, 'seed2': {'checkpoint_uri': 'tinker://f2be07d0279f2ac2090fcf159e5e3e20/weights/init-seed2', 'initial_output': {'available': False, 'reason': 'only step-0 train NLL captured (identical: 2.4172232151031494)'}}}, 'optimizer_checks': "get_info().optimizer_config after create/restore = {'type': 'adamw'} (server_response, preflight); betas (0.9, 0.95), eps 1e-8 declared via AdamParams, not exposed by server", 'restore_count': 0}
last_reply
cf275663989a4d756456ed537bb9a51b1737ef6ff2718ca6"}}, "feasibility": {"config": {"base_model": "Qwen/Qwen3.5-2B", "batch_size": 32, "max_seq_len": 2048, "pilot": "2 batch-32 steps + 1 forward of 32"}, "effective_config": {"base_model": "Qwen/Qwen3.5-2B", "arms": 6, "steps": 60, "batch_size": 32, "max_seq_len": 2048, "n_eval": 300}, "primary_endpoint": "token_mean held-out NLL (nats/token) on no_robots test[:300] at step 60", "source": "preflight_out.json, runs/*/arm_timing.json", "measurements": {"setup": {"seconds": 252.7, "units": 1, "planned_units": 1, "samples": 0, "gpu_count": null, "allocation_source": null}, "training": {"seconds": 711.45, "units": 360, "planned_units": 360, "samples": 11520, "gpu_count": null, "allocation_source": null}, "evaluation": {"seconds": 21, "units": 300, "planned_units": 2100, "samples": 300, "gpu_count": null, "allocation_source": null}}, "generation": null, "recovery": {"seconds": 0, "gpu_count": null, "allocation_source": null}}, "evidence": {"version": 1, "files": [{"name": "code-revision.txt", "kind": "code_revision", "content": "tinker-cookbook 6daabe0838736557f0e802020b710073eb340287 (no local changes); tinker SDK 0.37.0; shared Spindle, no fork"}], "checkpoints": [ {"arm": "baseline_lr1e-4_seed0", "step": 60, "uri": "tinker://716daf64-43a3-49cf-9306-cebe87f287b6:train:0/weights/final"}, {"arm": "treatment_lr3e-4_seed0", "step": 60, "uri": "tinker://7c44035a-0da1-426b-b1a3-fed1c79adca2:train:0/weights/final"}, {"arm": "baseline_lr1e-4_seed1", "step": 60, "uri": "tinker://6ad9f90f-fa9d-487a-b444-ddb5df06c956:train:0/weights/final"}, {"arm": "treatment_lr3e-4_seed1", "step": 60, "uri": "tinker://4a7402fb-facb-4a17-84e5-c6a8343fbcd1:train:0/weights/final"}, {"arm": "baseline_lr1e-4_seed2", "step": 60, "uri": "tinker://d821fabd-9797-472c-9f5f-77255afd1c89:train:0/weights/final"}, {"arm": "treatment_lr3e-4_seed2", "step": 60, "uri": "tinker://5951599a-b260-4b0a-a5b1-3b23a996a5f8:train:0/weights/final"}]}} ```
last_sent_at
1793747674.9767761
launch
{'experiment_id': 'exp_9574bbb76e', 'context_status': 'snapshotted', 'superseded': False, 'mode': 'ordinary', 'purpose': 'Execute the selected saved experiment version.'}
progress_updated_at
1793747949.3316891
reported_outcome_reason
tie
reported_verdict
inconclusive
restoration_validation
{'status': 'unverified', 'required': True, 'checks': [{'check': 'baseline_lr1e-4_seed0', 'status': 'unverified', 'reason': 'baseline_lr1e-4_seed0: missing or duplicate arm evidence.'}, {'check': 'treatment_lr3e-4_seed0', 'status': 'unverified', 'reason': 'treatment_lr3e-4_seed0: missing or duplicate arm evidence.'}, {'check': 'baseline_lr1e-4_seed1', 'status': 'unverified', 'reason': 'baseline_lr1e-4_seed1: missing or duplicate arm evidence.'}, {'check': 'treatment_lr3e-4_seed1', 'status': 'unverified', 'reason': 'treatment_lr3e-4_seed1: missing or duplicate arm evidence.'}, {'check': 'baseline_lr1e-4_seed2', 'status': 'unverified', 'reason': 'baseline_lr1e-4_seed2: missing or duplicate arm evidence.'}, {'check': 'treatment_lr3e-4_seed2', 'status': 'unverified', 'reason': 'treatment_lr3e-4_seed2: missing or duplicate arm evidence.'}], 'reason': 'baseline_lr1e-4_seed0: missing or duplicate arm evidence.', 'applicability': 'required'}
started_at
1793745384.3941097
Agent trace · 2 turns
Log
[2026-11-03 23:14 UTC] message from anonymous: Steer from the run page: in the final summary, also state the number of held-out eval examples per arm and the total Spindle wall-clock minutes used.
Details
run
run_10d007b771
backend
agentcore
conversation
run_10d007b771
experiment
exp_9574bbb76e
created
Nov 3, 22:36 UTC
started
Nov 3, 22:36 UTC
finished
Nov 3, 23:20 UTC
duration
44m 00s
turns
2
GPU-h budget
1.5
wall budget
90 min
base model
Qwen/Qwen3.5-2B
training
SFT
dataset
no_robots
result
final
outcome reason
insufficient evidence

Submit an idea

Most ideas come in from Slack threads. Use this when yours is not in one yet; the triage agent picks it up.