Boris-2-Preview-1
An early checkpoint of Boris-2, a 144M-parameter base language model from OpenCerebral, trained from scratch on a single NVIDIA V100. This preview is the main run's 50B-token checkpoint with a short learning-rate decay (2.5B tokens) applied. The full run continues to 200B tokens.
This is a base model. It continues text; it does not follow instructions or chat.
Results
Zero-shot, on the float32 weights in this repository: lm-evaluation-harness 0.4.12 for the first four, the leaderboard's own bencharithmark-3.py (unmodified, default settings) for ArithMark-3.
| Benchmark | Metric | Score |
|---|---|---|
| HellaSwag | acc_norm | 45.23 |
| ARC-Easy | acc_norm | 58.38 |
| ARC-Challenge | acc_norm | 29.95 |
| PIQA | acc_norm | 69.21 |
| ArithMark-3 | acc_norm | 37.60 |
| ArithMark-2 | acc | 37.68 |
| Open SLM Index | 27.91 |
The Index is the Open SLM Leaderboard formula: (N(HellaSwag,25) + N(mean(ARC-E, ARC-C),25) + N(PIQA,50) + 0.65 * N(ArithMark-3,25)) / 3.65, with N(v,c) = 100(v-c)/(100-c).
Single-checkpoint scores on these benchmarks move by roughly plus or minus 0.8 Index between neighbouring checkpoints. No checkpoint or seed was selected on these scores: the rule was set before the decay ran, and this is the one checkpoint at its end. The decay data mix was informed by six 40M-token pilot decays on an earlier run, scored on these same benchmarks; the arms differed by less than single-checkpoint noise, and the mix used here combines them rather than taking the top arm.
With ArithMark-3 run in float32 instead of the script's bfloat16 default it scores 37.00, and the Index is 27.80.
For context, using the Open SLM Leaderboard's published figures for every other model:
| Model | Params | Tokens | Index |
|---|---|---|---|
| Boris-2-Preview-1 | 144M | 52.5B | 27.91 |
| cagliostro-v3.5 | 146M | 75.4B | 27.49 |
| SmolLM2-135M | 135M | 2T | 27.13 |
| cagliostro-v3 | 146M | 75B | 26.55 |
| SmolLM-135M | 135M | 600B | 25.74 |
| GPT-X2.5-135M | 135M | 75B | 25.17 |
The decay moved the Index from 25.10 at the 50B checkpoint to 27.91. Most of the gain is HellaSwag (+5.4) and ARC-Easy (+2.7). ArithMark-3 did not improve: the math data in the decay mix did not transfer to its question format, and the full run's decay will be built around that.
Model
| Field | Value |
|---|---|
| Parameters | 143.7M |
| Transformer blocks | 111.9M |
| Token embedding (tied with output) | 16.8M |
| N-gram table | 15.0M |
| Layers | 31 |
| Hidden size | 512 |
| Attention | 8 heads of 64, full multi-head |
| MLP | SwiGLU, inner 1664 |
| Context | 2048 tokens |
| Position encoding | RoPE, theta 10,000 |
| Vocabulary | 32,768 (byte-level BPE, trained for this model) |
Two components differ from a standard decoder:
- Canon layers. Each block applies a causal 3-tap depthwise convolution to the fused query/key/value projection, so every position mixes in the two previous positions before attention.
- N-gram table. An exact lookup on the last two and three token ids (210,938 bigrams and 23,437 trigrams, no hashing) retrieves a learned rank-64 vector that is added to the residual stream before block 2. It is a gather, not a matrix multiply.
Training packed several documents per sequence with attention, Canon and the n-gram lookup all masked at document boundaries. The modeling code reproduces this: a new document starts after every end-of-text token (eos_resets_context in the config).
Usage
from transformers import AutoModelForCausalLM, AutoTokenizer
repo = "opencerebral/Boris-2-Preview-1"
tok = AutoTokenizer.from_pretrained(repo, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(repo, trust_remote_code=True)
x = tok("The water cycle begins when", return_tensors="pt")
y = model.generate(**x, max_new_tokens=40, do_sample=False)
print(tok.decode(y[0], skip_special_tokens=True))
The custom code is plain PyTorch with no extra dependencies. It has no KV cache, so generation recomputes the prefix every step; at this size that is fast enough for sampling and evaluation. Run in float32 or bfloat16. The residual stream is kept in float32 internally because one channel reaches values near the float16 limit.
The converted model was checked against the training code on the same weights: logits match to within 4e-5 in float32, and lm-evaluation-harness reproduces the training evaluator's benchmark scores to within one item.
Training
| Field | Value |
|---|---|
| Tokens | 52.5B (50.0B stable + 2.5B decay) |
| Hardware | 1x NVIDIA V100 32GB |
| Precision | float16 mixed precision, float32 residual stream |
| Batch | 524,288 tokens per step, sequence length 2048 |
| Optimizer | Muon (matrices, lr 0.0025) and AdamW (embedding, n-gram table, norms, Canon; lr 0.003) |
| Weight decay | 0.1 on matrices, embedding and n-gram table, and on Canon from 41B tokens; none on norm gains |
| Schedule | warmup, constant learning rate, then 1-sqrt decay to zero |
| Throughput | about 59,000 tokens per second, using hand-written Volta attention and fused kernels |
Main run data, by tokens: about 89% ClimbMix and 11% FineMath.
Decay data, by tokens:
| Source | Share |
|---|---|
| ClimbMix | 62% |
| Cosmopedia WikiHow-style tutorials | 12% |
| OpenMathInstruct-2 | 10% |
| FineMath | 8% |
| Cosmopedia math | 5% |
| DCLM-Baseline | 3% |
Contamination
No benchmark training, validation or test split was trained on.
- FineMath, OpenMathInstruct-2, Cosmopedia math, Cosmopedia tutorials and DCLM were filtered against every evaluation item with a 13-gram overlap check. The tutorial set had two matching documents out of 179,191 (generic phrases about credit reports and power buttons); both were removed.
- ClimbMix, the bulk of the data, has not been filtered.
- About two thirds of HellaSwag is built from WikiHow articles, and the Cosmopedia tutorials were generated from WikiHow titles. To check whether the HellaSwag gain comes from those topics, the validation items were split by whether their WikiHow article title is also one of the 177,353 tutorial titles (a loose match that puts 43.6% of titled WikiHow items in the overlapping group), and the 50B checkpoint was compared with this one:
| HellaSwag items | n | 50B | Preview-1 | Gain |
|---|---|---|---|---|
| WikiHow, title in the tutorial data | 2,966 | 37.86 | 45.85 | +7.99 ± 1.14 |
| WikiHow, title not in the tutorial data | 3,833 | 37.91 | 44.77 | +6.86 ± 1.05 |
| ActivityNet (no WikiHow link) | 3,243 | 43.82 | 45.14 | +1.33 ± 1.10 |
The two WikiHow groups started level and both gained about 7 to 8 points. The overlapping group gained 1.1 points more, which is within noise (about 1.4 standard errors); halfway through the decay the order was the other way round (+5.53 against +5.71). The gain is a model getting better at how-to text in general, with at most a small topic effect. ActivityNet items, which have nothing to do with WikiHow, moved much less.
Limitations
A 144M-parameter base model trained on 52.5B tokens. It makes factual and arithmetic mistakes, loses track of longer arguments, and repeats itself under greedy decoding. It has no safety tuning. It is a research preview, not a product.
Sample outputs
Greedy decoding, float32, unedited, cut for length. These are the same twelve prompts the cagliostro-v3.5 card uses; all twelve are in samples.json.
| Prompt | Completion |
|---|---|
| To solve 47 + 68, first | add the numbers together: 47 + 68 = 101. Then, divide 101 by 7 ... |
| A prime number is | a positive integer greater than 1 that has no positive divisors other than 1 and itself. |
| Photosynthesis is the process by which | plants and other organisms convert light energy into chemical energy. |
| How to boil an egg: First, | place the egg in a saucepan and cover with cold water. Bring to a boil, then reduce heat and simmer for about 10 minutes. |
| To tie a shoelace, start by | threading the end of the shoelace through the eye of the knot. |
| The water cycle begins when | the sun heats the water in the earth's atmosphere. The water vapor in the air condenses into water droplets. |
| If a train travels 60 miles in 2 hours, its speed is | : (A) 60 mph (B) 60 mph/2 (C) 60 mph/2 ... |
| Sam had 24 apples and gave away 9, so Sam now has | 24 - 9 = 15 apples left. |
| The capital of France is | the capital of the country, which is located in the south of France. The capital city of France is Paris ... |
| Gravity is the force that | pulls objects towards each other. |
| The area of a rectangle is found by | multiplying its length by its width. |
| Plants need sunlight because | they need it to grow. Sunlight is the energy that plants need to grow. (repeats) |
The misses are typical for this size: 47 + 68 comes out as 101, the train question turns into a malformed multiple-choice list, France's capital takes a detour before reaching Paris, and greedy decoding loops on the last prompt.