Instructions to use nkthebass/tinybrainbot-350mV3-base with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use nkthebass/tinybrainbot-350mV3-base with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="nkthebass/tinybrainbot-350mV3-base") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("nkthebass/tinybrainbot-350mV3-base") model = AutoModelForCausalLM.from_pretrained("nkthebass/tinybrainbot-350mV3-base", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use nkthebass/tinybrainbot-350mV3-base with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "nkthebass/tinybrainbot-350mV3-base" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nkthebass/tinybrainbot-350mV3-base", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/nkthebass/tinybrainbot-350mV3-base
- SGLang
How to use nkthebass/tinybrainbot-350mV3-base with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "nkthebass/tinybrainbot-350mV3-base" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nkthebass/tinybrainbot-350mV3-base", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "nkthebass/tinybrainbot-350mV3-base" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nkthebass/tinybrainbot-350mV3-base", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use nkthebass/tinybrainbot-350mV3-base with Docker Model Runner:
docker model run hf.co/nkthebass/tinybrainbot-350mV3-base
TinyBrainBot 350M V3 β Base
A 348M-parameter decoder-only language model pretrained from scratch on 22.7B tokens, started on a rented 8Γ RTX 5090 node and finished on 2Γ Tesla V100. This is the base (pretrained + fact-annealed) model: a text-completion model with no instruction tuning.
TL;DR: Beats the previous-generation TinyBrainBot 100M V3 base on 5 of 7 standard benchmarks and beats Supra2-100M-Base on all 7, at an average of 43.2 vs 42.2 and 40.0. It also carries an unusual history: ~20B of its 22.7B training tokens were run with every RMSNorm weight frozen at 1.0 by a precision bug. The recovery from that is documented below, because it is the most interesting thing about this model.
Model details
| Parameters | 348,342,912 (~348M) |
| Architecture | Decoder-only transformer, pre-norm, RMSNorm, SwiGLU MLP, RoPE |
| Hidden size | 1152 |
| Layers | 22 |
| Attention heads | 18 query / 6 KV (grouped-query attention), head_dim 64 |
| Context length | 2048 |
| Vocabulary | 32,000 (tbb-32k-v2, tied embeddings) |
| RoPE theta | 10,000 |
| Training tokens | 22.70B |
| Precision | fp16 with fp32 master weights (final phase) |
Evaluation
EleutherAI lm-eval-harness, 0-shot, complete test sets. acc_norm for
HellaSwag/ARC/OpenBookQA/PIQA, acc for WinoGrande/MMLU. Same harness and settings as the
published 100M V3 numbers, so the comparison is like-for-like (base vs base).
| Benchmark | 350M V3 base | 100M V3 base | Supra2-100M-Base |
|---|---|---|---|
| ARC-Easy | 56.6 | 54.7 | 47.8 |
| ARC-Challenge | 33.3 | 30.1 | 24.8 |
| HellaSwag | 35.9 | 32.6 | 36.0 |
| OpenBookQA | 34.6 | 34.0 | 32.0 |
| PIQA | 67.0 | 66.2 | 65.5 |
| WinoGrande | 51.5 | 53.0 | 50.7 |
| MMLU | 23.8 | 25.0 | 23.3 |
| Average | 43.2 | 42.2 | 40.0 |
β 5/7 vs the 100M V3 base, losing only WinoGrande (β1.5) and MMLU (β1.2). β 7/7 vs Supra2-100M-Base (HellaSwag 35.9 vs 36.0 is a 0.1 tie at best).
Benchmark-train-split disclosure
The final data mix contains two small sets built from official train splits of benchmark datasets:
sci-qa-train(0.5%) β SciQ, ARC-Easy/Challenge train, OpenBookQA train + core factshellaswag-train(1.2%) β HellaSwag train, SWAG train
Evaluation uses the test/validation splits, which these never touch, and this is standard practice for small-model training. But the 100M V3 baseline above was trained without them, so the ARC / OpenBookQA / HellaSwag margins are not a like-for-like recipe comparison. Stated here rather than buried: if you want a clean comparison, weight those three tasks accordingly.
Training
Three phases, on rented and owned hardware:
- Cloud pretrain β ~20B tokens on a rented 8Γ RTX 5090 node (Clore.ai), bf16/fp8,
torch.compile, DDP. Cost about $90. - Local extension β continued on 2Γ Tesla V100 (16GB) in fp16, WSD schedule, sequence length 2048, micro-batch 2 Γ grad-accum 32 Γ 2 GPUs = 262,144 tokens/step.
- Fact anneal β two final passes on a knowledge-dense mix (below), 1.23B tokens, LR annealed 5e-5 β 1e-5.
The frozen-norm episode
For its first ~20B tokens this model trained with all 45 RMSNorm weights frozen at exactly
1.0. The cause was precision, not the optimiser: --precision bf16 stored the weights in
bf16 with no fp32 master copy. bf16 has 7 mantissa bits, so near a value of 1.0 the
smallest representable step is ~0.0078, while an Adam update at lr 1e-4 is ~1e-4 β every norm
update rounded straight back to 1.0. Other weights (magnitude ~0.02) have a ~50Γ finer ULP
there and trained normally, so loss fell and nothing looked wrong.
It was found by diffing two consecutive checkpoints: 111/111 non-norm tensors changed, 0/45 norms. Switching to fp16 (which keeps fp32 masters) unfroze them.
They never fully recovered. Measured mean |w β 1| across the RMSNorm weights:
| model | meanΒ·|wβ1| | |---|:--:| | 100M V3 base (never affected) | 0.697 | | 320M V2 base (never affected) | 0.694 | | 350M V3 base (this model) | 0.017 |
After 5.5B tokens of healthy fp16 training the norms had moved 2.5% of the distance a normally-trained model's travel. So this model does its work essentially without learned per-channel scaling β and still beats a 100M trained with it. Treat the results below as a lower bound on what this recipe can do.
Final data mix
Knowledge-dense, 22 sources. Largest: wiki-dense 13%, cosmopedia-openstax 13%,
cosmopedia-stanford 9%, qa-plain 8%, wikipedia-english 7%, gutenberg-clean2 5%,
qa-distill 5%, facts-plain 5%, fineweb-edu 5%. Narrative/commonsense sources total
21.1%; every source was checked to stay under 3 epochs against measured token counts.
Limitations
- Arithmetic is weak. This is a base model with no math tuning; use the math variant.
- MMLU and WinoGrande lag the 100M V3 base. The knowledge-dense anneal did not lift MMLU.
- Repetition loops on greedy decoding beyond ~40 tokens, as is normal at this scale.
- Hallucinates confidently β it will state a wrong country for a landmark under sampling.
- No instruction tuning. It continues text; it does not follow instructions or chat.
Usage
from transformers import AutoModelForCausalLM, AutoTokenizer
m = AutoModelForCausalLM.from_pretrained("nkthebass/tinybrainbot-350mV3-base")
t = AutoTokenizer.from_pretrained("nkthebass/tinybrainbot-350mV3-base")
ids = t("The capital of France is", return_tensors="pt")
print(t.decode(m.generate(**ids, max_new_tokens=30)[0]))
- Downloads last month
- 208