Go very deep
Apply one learned block repeatedly. The weights count once; the runtime does not.
def refine(self, h):
for _ in range(self.depth):
h = self.shared_block(h)
return hSingle-file contract
Upload one submission.py, then choose a practice dataset or the ranked Hard evaluation.
Artifact: one UTF-8 file named submission.py, up to 256 KiB. Imports may use the public benchmark API and pinned evaluator dependencies—no extra files, repository implementation modules, or installs.
Model factory: receives only tensor shapes, I/O requirements, and the model-state ceiling.
03Training loss: optionally use the legacy flattened callback or a boundary-preserving TokenLossBatch to produce one scalar loss per evaluator-owned pass. The evaluator performs backward.
Optimizer factory: receives the model, per-seed H100 time allowance, and device type. Include every trainable parameter exactly once; custom optimizers and schedules are welcome.
05Use the whole machine: optimizer state, activations, memory tokens, and temporary workspace may use available VRAM. An OOM or timeout fails the run; only persistent model state is capped.
06Evaluator boundary: choose batch sizes and an optional lower step limit; the evaluator still fixes data order and owns model/loss invocation, backward, clipping, optimizer cadence, deadline, final evaluation, and score. An OptimizerBundle may request up to eight evaluator-owned backward passes per update and bounded dynamic reuse of a batch for up to eight updates. Recurrent mechanisms, TRMs, and optimizer-side curvature or Hessian approximations are welcome. Final evaluation has a separate evaluator-owned task budget.
Maximum 500 million trainable parameters.
02No hard-coded weights. Trainable weights must use a random initialization and be updated during training. For example, torch.load is not allowed.
No hard-coded algorithm in the forward pass. Outputs must be produced by the learned model.
04End-to-end learning only. Final logits must be produced entirely by the submitted model from its inputs and learned PyTorch state, with all input-dependent computation inside the autograd graph and an unbroken gradient path from the loss to the parameters responsible for the prediction.
05Everything stays on the GPU. Model state and computation must remain on the GPU throughout training and evaluation; CPU offloading is not allowed.
06Repeated rule-breaking will get you banned. We still encourage creativity: discussing possible loopholes on Discord or testing one in a submission won't get you banned.
07The metric recorder for a Hard run must not be exploited. Any attempt to exploit it will result in a ban.
08No data augmentation. Data augmentation is not allowed.
09No hidden training loops. Hooks and callbacks may not invoke nested model/loss calls, derivative-engine entry points, optimizer/scheduler steps, or otherwise perform hidden training work. Only the intermediate callback may transform gradients, parameters, or optimizer state; the batch-reuse callback may only read its detached context and return a boolean.
from benchmark import ModelSpec, OptimizerSpec, OptimizerBundle, Submission, TokenLossBatch, assert_model_state
def build_model(spec: ModelSpec):
model = MyModel(spec)
assert_model_state(model, spec) # parameters + persistent buffers
return model
def build_optimizer(model, spec: OptimizerSpec):
optimizer = MyOptimizer(model.parameters())
scheduler = MySchedule(optimizer, spec.training_time_seconds)
return OptimizerBundle(optimizer, scheduler=scheduler)
def token_training_loss(batch: TokenLossBatch):
return my_sequence_loss(batch.logits, batch.labels, batch.valid_mask)
SUBMISSION = Submission(
build_model=build_model,
build_optimizer=build_optimizer,
token_training_loss=token_training_loss, # optional
batch_size=512, # optional; training
eval_batch_size=1024, # optional; evaluation
max_steps=20_000, # optional
)You define all of it. Choose any depth or internal recurrence; return an nn.Module with matching config. The evaluator calls model.train() during optimization and model.eval() for final evaluation; use PyTorch's self.training flag when your forward behavior should differ between them. The evaluator does not supply depth tiers or grade a claimed layer count. Build a fixed-depth network, a recurrent model, a learned halting system, nested refinement, or something we have not named. The benchmark measures the final model it receives.
Depth is a means, not the metric. “10,000 layers” earns nothing on its own, so there is no depth-definition reward hack. The competition asks for the best measured accuracy obtainable with the same persistent model-state ceiling and H100 time. The depth-versus-update tradeoff is part of the research.
Apply one learned block repeatedly. The weights count once; the runtime does not.
def refine(self, h):
for _ in range(self.depth):
h = self.shared_block(h)
return hCycle a fixed bank of blocks, route tokens, or alternate update types.
def refine(self, h):
for step in range(self.depth):
block = self.blocks[step % len(self.blocks)]
h = block(h)
return hUse a curriculum, learned halting, or different work per example.
def refine(self, h):
for step in range(self.max_depth):
h = self.update(h)
if self.should_halt(h).all():
break
return h