Downloads · 30 days
29
3% of all-time downloads
sandbreak80sd/llm-350m-instruct-v2
llm-350m-instruct-v2 is a text generation model from sandbreak80sd. Use it when you need the model to write or continue text. The card lists the license as apache-2.0.
This is V2 of a 350M parameter language model I trained from scratch as a personal learning project. V2 improves on V1 by replacing Alpaca-cleaned with OpenHermes-2.5 — 200K GPT-4 generated examples in ChatML format i…
Downloads · 30 days
29
3% of all-time downloads
All-time downloads
1.1K
Public
Parameters
322M
2.5 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors1.3 GB · 52%
From the Hugging Face model README
This is V2 of a 350M parameter language model I trained from scratch as a personal learning project. V2 improves on V1 by replacing Alpaca-cleaned with OpenHermes-2.5 — 200K GPT-4 generated examples in ChatML format instead of 52K GPT-3.5 examples in Alpaca format. Same pretrained base, better finetuning data.
I'm not a researcher. I don't work at a big lab. I just wanted to understand how LLMs actually work by building one. The whole thing ran on a single rented GPU for under $500 total across both versions.
V1 model | Training code | W&B logs
This model requires ChatML format. If you send raw text without the template, the model won't recognize it as an instruction and will produce poor output. This is the single most common issue people hit — configure your inference tool before you test.
The format looks like this:
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
Your question here<|im_end|>
<|im_start|>assistant
Setup instructions for each tool are in the Quick Start section below.
| Benchmark | V1 (Alpaca) | V2 (OpenHermes) | Δ |
|---|---|---|---|
| HellaSwag | 38.40% | 37.60% | -0.80% |
| LAMBADA | 34.00% | 35.30% | +1.30% |
| ARC-Easy | 58.20% | 58.40% | +0.20% |
| ARC-Challenge | 27.76% | 25.42% | -2.34% |
| WinoGrande | 52.80% | 52.40% | -0.40% |
Val loss: 1.3704 vs V1's 1.7189 (20.3% lower)
Benchmark deltas are small and mixed — expected at 350M scale, and sensitive to the prompt format change (Alpaca → ChatML affects loglikelihood scoring). Val loss is the more reliable signal here.
| V1 | V2 | |
|---|---|---|
| Finetune data | yahma/alpaca-cleaned (52K, GPT-3.5) | teknium/OpenHermes-2.5 (200K, GPT-4) |
| Prompt format | Alpaca (### Instruction:) | ChatML (<|im_start|>) |
| Learning rate | 2e-5 | 1e-5 |
| Finetune iters | 1,500 | 4,000 |
| Anti-forgetting blend | 2,500 FineWeb samples | 10,000 FineWeb samples |
| Val loss | 1.7189 | 1.3704 |
Same as V1 — modern LLaMA-style architecture at 350M parameters: RoPE positional encoding, RMSNorm (pre-norm), SwiGLU activations, Grouped Query Attention (4 KV / 16 query heads), 2048 token context, Flash Attention 2, tied embeddings.
Full architecture and pretraining details in the V1 model card.
All requests must be wrapped in ChatML tags. Raw questions without the template will not work correctly.
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
Your question here<|im_end|>
<|im_start|>assistant
This is the most important setup step — skip it and the model will produce bad output.
llm-350m-instruct-v2-q4_k_m.gguf from the Files tab (~197MB)<|im_start|>user\n<|im_end|>\n<|im_start|>assistant\n<|im_end|>\n<|im_start|>system\n<|im_end|>\nrepeat_penalty to 1.1 (prevents repetition loops)The included Modelfile configures ChatML automatically:
# Option 1: Run directly
ollama run sandbreak80sd/llm-350m-instruct-v2
# Option 2: Build from Modelfile (for customization)
# Download Modelfile from the Files tab, then:
ollama create llm-350m-v2 -f Modelfile
ollama run llm-350m-v2 "What is the sun?"
Ollama handles the ChatML template automatically when using the published model.
# Download llm-350m-instruct-v2-q4_k_m.gguf, then:
./llama-cli -m llm-350m-instruct-v2-q4_k_m.gguf \
--prompt "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nWhat is the sun?<|im_end|>\n<|im_start|>assistant\n" \
-n 256 --temp 0.7 --top-p 0.9 --repeat-penalty 1.1 \
--stop "<|im_end|>"
The --stop "<|im_end|>" flag is required — without it the model won't know when to stop generating.
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
tokenizer = AutoTokenizer.from_pretrained("sandbreak80sd/llm-350m-instruct-v2")
model = AutoModelForCausalLM.from_pretrained(
"sandbreak80sd/llm-350m-instruct-v2",
torch_dtype=torch.bfloat16,
device_map="auto",
)
# Always use ChatML format — do not send raw text
prompt = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nWhat is the sun?<|im_end|>\n<|im_start|>assistant\n"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(
**inputs,
max_new_tokens=256,
temperature=0.7,
do_sample=True,
repetition_penalty=1.1,
eos_token_id=tokenizer.convert_tokens_to_ids("<|im_end|>"),
)
print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
Same fundamental limitations as V1 — 350M parameters trained on a hobbyist budget:
repeat_penalty=1.1, the model can loop. Always set this.~$12 for V2 finetuning on g6e.xlarge (L40S GPU). Full project cost including pretraining and V1: ~$310.
@misc{llm-350m-instruct-v2,
author = {Stoner, Brad},
title = {LLM-350M-Instruct-V2: A 350M LLM trained from scratch with OpenHermes-2.5},
year = {2026},
url = {https://huggingface.co/sandbreak80sd/llm-350m-instruct-v2},
note = {Training code: https://github.com/sandbreak80/llm-350m}
}