Skip to content

one-covenant/crusades

Repository files navigation

Templar Crusades

MFU Crusades on Bittensor - Miners compete to optimize training code for maximum MFU (Model FLOPs Utilization).

How It Works

┌───────────────────────────────────────────────────────────────────────────────── ┐
│                              Crusades FLOW                                       │
│                                                                                  │
│   MINER                        BLOCKCHAIN                      VALIDATOR         │
│     │                                                              │             │
│     │  1. Host train.py at URL                                     │             │
│     │     (Gist, Pastebin, etc)                                    │             │
│     │                                                              │             │
│     ├──▶ 2. Submit URL ─────────▶ set_reveal_commitment            │             │
│     │                             (timelock encrypted)             │             │
│     │                                    │                         │             │
│     │                                    │ (wait reveal_blocks)    │             │
│     │                                    ▼                         │             │
│     │                              3. Decrypted ◀───────────────── ┤ Read        │
│     │                                                              │             │
│     │                                                     4. Download code       │
│     │                                                        from URL            │
│     │                                                              │             │
│     │                                                     5. Runs in Container   │
│     │                                                        (X eval runs)       │
│     │                                                              │             │
│     │                                                     6. Calculate MFU       │
│     │                                                        (median score)      │
│     │                                                              │             │
│     │                                                     7. Set weights         │
│                                                                                  │
└───────────────────────────────────────────────────────────────────────────────── ┘

Quick Start

Prerequisites

# Clone and setup
git clone https://github.com/one-covenant/crusades
cd crusades
curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync

# Create .env (for HuggingFace access)
echo "HF_TOKEN=hf_your_token" > .env

For Miners

1. Setup & Test Locally

# Download model & data for local testing
uv run local_test/setup_benchmark.py

# Test your train.py locally (performance test)
uv run local_test/train.py

# Verify your submission to avoid potential failures during validator checks
uv run local_test/verify.py

2. Host Your Code

Host your train.py at any URL that returns raw code:

  • GitHub Gist (recommended - use secret gist for privacy)
  • Raw GitHub file (use raw.githubusercontent.com)
  • Pastebin or any paste service
  • Any HTTP/HTTPS URL

3. Submit to Crusades

# Submit to mainnet
uv run -m neurons.miner submit "https://gist.github.com/user/gist_id" \
    --wallet.name your_wallet \
    --wallet.hotkey your_hotkey \
    --network finney

# Submit to localnet (testing)
uv run -m neurons.miner submit "https://gist.github.com/user/gist_id" \
    --wallet.name your_wallet \
    --wallet.hotkey your_hotkey \
    --network local

Parameters: --wallet.name, --wallet.hotkey, --network (finney/test/local)


For Validators

See docs/Validator.md for detailed validator setup.


train.py Requirements

Your train.py must implement the inner_steps function. Here's the baseline:

from dataclasses import dataclass
import torch
import torch.nn.functional as F

@dataclass
class InnerStepsResult:
    final_logits: torch.Tensor  # Must be 3D: (batch, seq_len-1, vocab) - NOT None
    total_tokens: int           # Total tokens processed across all steps
    final_loss: float           # Loss value from last training step (must be > 0)

def inner_steps(model, data_iterator, optimizer, num_steps, device):
    total_tokens = 0
    final_logits = None
    final_loss = 0.0

    for step in range(num_steps):
        batch = next(data_iterator)
        batch = batch.to(device)

        input_ids = batch[:, :-1]   # All tokens except last
        labels = batch[:, 1:]       # All tokens except first

        outputs = model(input_ids)
        logits = outputs.logits if hasattr(outputs, "logits") else outputs

        loss = F.cross_entropy(
            logits.reshape(-1, logits.size(-1)),
            labels.reshape(-1),
            ignore_index=-100,
        )

        loss.backward()
        optimizer.step()
        optimizer.zero_grad(set_to_none=True)

        total_tokens += batch.numel()
        final_logits = logits.detach().float()
        final_loss = loss.item()

    return InnerStepsResult(
        final_logits=final_logits,
        total_tokens=total_tokens,
        final_loss=final_loss,
    )

Rules

You MUST:

  • Use the provided optimizer directly (call optimizer.step() and optimizer.zero_grad())
  • Process ALL tokens in each batch (no truncation)
  • Return actual final_logits tensor (not None)
  • Train all model parameters (don't freeze layers)

You MUST NOT:

  • Access optimizer internals (e.g., optimizer.optimizer, optimizer._opt_impl)
  • Truncate or skip parts of input sequences
  • Return None for final_logits
  • Import forbidden modules: gc, ctypes, subprocess, importlib, os, sys, inspect, pickle, signal, threading, multiprocessing, socket, http, io, ast, etc.
  • Modify torch backend settings (cudnn.deterministic, cudnn.benchmark, SDP toggles, set_float32_matmul_precision)
  • Freeze layers or modify requires_grad settings
  • Report inflated token counts
  • Alias the torch module (e.g., import torch as t) — the security scanner only recognizes the literal name torch for allowlisted calls like torch.compile

Note: The validator skips the if __name__ == "__main__": block entirely. Modules like pathlib that are forbidden at the top level can still be imported inside __main__ for local testing.


Configuration

Key settings in hparams/hparams.json:

Setting Default Description
netuid 3 Subnet ID
evaluation_runs 5 Runs per submission (median taken)
eval_steps 5 Training steps per evaluation
benchmark_model_name Qwen/Qwen2.5-3B Model for evaluation
benchmark_batch_size 8 Batch size for evaluation

TUI Dashboard

Monitor crusades activity in real-time with the terminal dashboard.

# Connect to the official Crusades API
uv run -m crusades.tui --url 69.19.137.219:8080

Features

  • Leaderboard with MFU scores
  • Recent submissions and their status
  • MFU history chart
  • Validator status
  • View submission code (after evaluation)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors 4

  •  
  •  
  •  
  •  

Languages