Instructions to use aimeri/spoomplesmaxx-thrasher-24B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aimeri/spoomplesmaxx-thrasher-24B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="aimeri/spoomplesmaxx-thrasher-24B") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("aimeri/spoomplesmaxx-thrasher-24B") model = AutoModelForCausalLM.from_pretrained("aimeri/spoomplesmaxx-thrasher-24B", 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 aimeri/spoomplesmaxx-thrasher-24B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "aimeri/spoomplesmaxx-thrasher-24B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aimeri/spoomplesmaxx-thrasher-24B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/aimeri/spoomplesmaxx-thrasher-24B
- SGLang
How to use aimeri/spoomplesmaxx-thrasher-24B 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 "aimeri/spoomplesmaxx-thrasher-24B" \ --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": "aimeri/spoomplesmaxx-thrasher-24B", "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 "aimeri/spoomplesmaxx-thrasher-24B" \ --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": "aimeri/spoomplesmaxx-thrasher-24B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use aimeri/spoomplesmaxx-thrasher-24B with Docker Model Runner:
docker model run hf.co/aimeri/spoomplesmaxx-thrasher-24B
license: apache-2.0
base_model: mistralai/Mistral-Small-3.1-24B-Base-2503
library_name: transformers
pipeline_tag: text-generation
tags:
- roleplay
- creative-writing
- chatml
language:
- en
SpoomplesMaxx-Thrasher-24B
"Thrash Metal"
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββ βββββ βββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββ β βββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββ βββ ββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββ ββββββββββ βββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββ β βββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββ ββ βββ ββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββ ββββββββββββ βββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββ β βββ βββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββ βββββ βββββ βββββ ββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββ ββ β β βββ β ββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββ βββ ββββ βββββ βββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββ β β βββββ βββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββ β ββββ βββββββββ βββββββββββββββββ ββββββββββββ
βββββββββββββββββββββββββββββ β β β ββ ββ βββ βββββββββββ βββββββββββββ
βββββββββββββββββββββββββββ β β ββββββ βββββ βββββββββββββ ββββββββββββββ
ββββββββββββββββββββββββββ β βββββββββββββββββββββββββββ ββββββββββββββ
βββββββββββββββββββββββββ βββββββββ ββββ βββββββββββββββ ββββββββββββββββ
ββββββββββββββββββββββββββ ββββ ββββ β βββββββββββββββ βββββββββββββββββββ
βββββββββββββββββββββββββ ββββββββ ββββββββ βββββββββββββ ββββ ββββββββββ
βββββββββββββββββββββββ ββββββββββ βββββββββ βββββββββ β ββββββββ
ββββββββββ ββββββββββ ββββββββββ βββββββββ β β ββββββ βββββββββ
ββββββββββ βββββββ ββ β βββββββββββ ββββββββ β βββββββ ββββββββββββββββ
ββββββββββ ββββββ β βββββββββββββββ ββ β βββββββ ββββββββββββββ
βββββββββββ ββββ β βββββββββββββββ ββββ ββββββββββ ββββββββββββββ
ββββββββββββ βββ ββββββββββββββ βββββββββββββββββββββ βββββββββββββ
ββββββββ ββ ββ β βββββββββββββ ββ βββββββββββββββββββββββ βββββββββββββ
βββββ β β βββββββββ βββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββ β ββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββ β β ββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββ β ββ βββ ββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββ ββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββ β βββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"Thousand-Songed" β Toxostoma rufum, the brown thrasher: holder of the largest documented song repertoire of any North American bird, over a thousand song types. The mockingbird repeats a phrase three times; the thrasher sings each one twice and moves on. Second of the mimids, the family that follows the corvids.
A model that is 100% about roleplay, trained mostly on things that are not roleplay. Measured across the strongest open RP lineage I know (Dans-PersonalityEngine), roughly 590K of its rows are task/reasoning/assistant/world-knowledge data against ~150K of actual roleplay. RP is the product; RP is not the corpus. The RP data teaches the register. Everything else teaches the mind behind it.
Built on Mistral-Small-3.1-24B-Base with the vision tower removed and the chat interface rebuilt from scratch β see "The token surgery" below, because if you have ever bounced off a Mistral model's template, that section is for you.
Who this is for
The accessible mimid. mockingbird at 36B asks a lot of your VRAM; thrasher at 24B (23.6B after the vision strip) is the same recipe in a size that quantizes onto a single 24GB card. If you can run any of the popular 22β24B RP models, you can run this one.
Prompt format
ChatML. On a Mistral base. Yes, really β and not by resizing anything:
FORM <|im_start|>system\n{card}<|im_end|>\n<|im_start|>user\n{text}<|im_end|>\n<|im_start|>assistant\n{reply}<|im_end|>\n
STOPS <|im_end|> (id 21; eos)
BOS <s> (id 1) β added automatically by the tokenizer, not the template
ROLES system / user / assistant / tool
EXAMPLE
<|im_start|>system
You are Bram Hollis, keeper of the Wayward Lantern...<|im_end|>
<|im_start|>user
*I push the door open, dripping wet* Got room for one more?<|im_end|>
<|im_start|>assistant
The template ships embedded (chat_template.jinja + tokenizer_config.json), so vLLM, llama.cpp, MLX, and every frontend that speaks ChatML β which is to say, every RP frontend β picks it up without ceremony.
No thinking. Ever.
thrasher never emits reasoning traces and was never trained on them.
The token surgery
Moving a Mistral base to ChatML was my first barrier the first time I ever tried to use a Mistral model for fine-tuning, so here is the whole recipe, with receipts.
1. There is room in the vocabulary. Mistral's Tekken tokenizer reserves ids 0β999 as a control block; only 0β19 are named. Ids 20β999 are unused <SPECIAL_n> placeholders. So ChatML needs no vocab resize and no embedding-matrix growth: rename <SPECIAL_20> β <|im_start|> and <SPECIAL_21> β <|im_end|> in tokenizer.json (both added_tokens and the vocab), tokenizer_config.json, and special_tokens_map.json. Set eos to <|im_end|>. Done β single-token ids 20 and 21.
2. The claimed rows are dead, and dead eos rows are fatal. The base was pretrained with those placeholders never appearing in data: their embedding rows are exactly 0.0 (measured), their lm_head rows random-scale noise. A model whose eos row is dead never learns to stop β unless you train very long (Hermes cold-claimed on 60B tokens; this SFT is ~1B) or you initialize sensibly. thrasher grafts: <|im_start|> rows β <s>, <|im_end|> rows β </s>, embedding and lm_head. By step 100 of SFT, stop-rate at temperature 0.7 was already 24/24; it stayed 100% at every checkpoint probed.
3. The published tokenizer has a broken pre-tokenizer regex. The known Mistral conversion bug (transformers warns and offers fix_mistral_regex=True β but that fix is in-memory only, and axolotl, llama.cpp, and MLX read tokenizer.json directly). The true Tekken pattern β case-aware word splitting, single-digit number splits β is baked into the shipped file.
4. The vision tower is gone. 222 tensors of Pixtral removed, the language_model. prefix stripped, published as a plain untied MistralForCausalLM. Nothing multimodal remains.
The full prep script (prep_base.py) is in this repo, and the prepped base is its own artifact if you want to start from it: Mistral-Small-3.1-24B-Base-thrasher.
Tool calling
The corpus includes the full Toolmaxx family (58,095 conversations), rendered with tool responses as a plain tool role turn:
<|im_start|>tool\n{tool output}<|im_end|>
Corpus-taught, conversational tool competence β not a structured calling API.
If you need strict function calling, put a schema in the card and validate what comes back.
Key details
BASE mistralai/Mistral-Small-3.1-24B-Base-2503 (Apache 2.0, vision stripped) PARAMS 23.6B dense Β· 40 layers Β· GQA 8 KV heads Β· head_dim 128 Β· hidden 5120 VOCAB 131,072 Β· ChatML on claimed Tekken slots 20/21 Β· zero added tokens CTX trained at 24,576 packed Β· base RoPE (theta 1e9) to 131K CORPUS 667,332 conversations Β· ~1.3B supervised chars Β· 43% RP share LANGUAGE English (non-English filtered at ingest; base priors remain)
Training
Full-parameter SFT, Axolotl, 8ΓH200. One stage. The exact config generator ships in this repo (thrasher_sft_cfg.py):
STEPS 902 (2 epochs) Β· this release = step 600 SEQ 24,576 Β· sample packing (block-masked; packing does not shrink context) BATCH 64 global (micro 1 Γ accum 8 Γ 8 GPUs) OPT AdamW Β· lr 8e-6 cosine Β· 3% warmup Β· wd 0.01 Β· bf16 STACK FSDP2 full-shard Β· activation checkpointing Β· Cut Cross Entropy HEALTH grad_norm 1.2β1.8 the whole run Β· zero spikes Β· memory flat
On context: 24,576 is the longest single training conversation (longer ones were split at turn boundaries with the card re-carried). The base's 131K RoPE survives SFT untouched; the best-trained RP region is the first ~24K, degrading gracefully beyond.
The corpus is mockingbird's, verbatim β the PersonalityEngine V1.3.0 public list plus my own carded-RP, think-stripped-RP, and anti-repetition lanes, same cleaning receipts. Only the template changed. See the mockingbird card for the full corpus story.
How the checkpoint was chosen β and how you can check
Loss did not pick this model. Checkpoints went through two instruments, both published in this repo's eval/: a seeded multi-turn loop/stall battery (six gates, six repeats per episode β single-run numbers on it are noise, and the trend proves it), and blind-judged episodes on four real character cards.
step 100 200 300 450 600 750 900 battery 17 8 13 13 18 10 16 (of 24) stop-rate 100% 100% 100% 100% 100% 100% 100%

The shape is the story: a mid-run dip while style reorganizes under high LR, a peak mid-way through epoch 2, then regression in the deep anneal. Behavioral peak β end of training. Step 600 shipped β highest battery pass rate and the most disciplined judged transcripts (compressed, declarative, no user-impersonation).
The anti-repetition anneal experiments β published, not spun. After training, we annealed checkpoints 600 and 900 on a 7,281-conversation anti-repetition dataset (recipe in that repo), across four blend/base variants plus two task-arithmetic merges. In our measurements, one variant reached zero repeat failures on the battery while regressing on format gates; the merges regressed stop-token reliability; none beat the un-annealed step 600 overall, so step 600 shipped as-is. The raw battery JSONs for every variant are in eval/ β read them and draw your own conclusions rather than taking ours.
Sampling
The shipped generation_config.json is the swept optimum (7 arms Γ 5 seeded battery runs each):
temperature 1.0 Β· min_p 0.05 Β· top_p off
thrasher is the anti-mockingbird in its sampler behavior, which is why we sweep per model instead of inheriting: min_p won here (mockingbird's sweep found min_p looped MORE); and a mild repetition_penalty 1.05 β catastrophic on mockingbird β is a legitimate opt-in on thrasher: in our sweep it eliminated the verbatim-loop tail entirely (max cross-turn Jaccard 0.50 across 20 episodes) at the cost of a rare unfinished turn. If loops bother you more than an occasional run-on, add it. Plain top_p 0.9 at temp 1.0 was the worst repetition arm on this model β don't ship RP muscle memory, sweep.
Known limitation: the loop tail.
Under sustained low-information multi-turn pressure the model can fall into near-verbatim self-repetition β roughly 1β2 episodes in 24 on our battery at shipped settings. The corpus's anti-repetition lane suppresses it; it is not eliminated. The repetition_penalty 1.05 opt-in above removed it entirely in our measurements.
Give it a proper card and it will give you a proper character: the model was fed real character cards (median ~3K chars, p90 ~8.5K) as system messages.
Quickstart
from transformers import AutoModelForCausalLM, AutoTokenizer
model_id = "aimeri/spoomplesmaxx-thrasher-24B"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype="bfloat16", device_map="auto")
messages = [
{"role": "system", "content": "You are Bram Hollis, keeper of the Wayward Lantern... Third person, *asterisk action beats*."},
{"role": "user", "content": "*I push the door open, dripping wet* Got room for one more tonight?"},
]
ids = tok.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device)
out = model.generate(ids, max_new_tokens=400, do_sample=True) # sampler ships in generation_config
print(tok.decode(out[0][ids.shape[-1]:], skip_special_tokens=True))
Quants: GGUF static (Q3/Q4/Q5_K_M) Β· GGUF imatrix (IQ3_XXSβQ4_K_M, own-corpus calibration, imatrix.dat included) Β· MLX 4-bit / 6-bit. Prefer the imatrix quants at 3β4 bit.
The thrasher knows a thousand songs. It only needs the one you hand it.
thrasher is a roleplay and creative-writing model for adults. It stays in character by design β its corpus was scrubbed of mid-scene refusals β so bring your own moderation where your deployment needs it. Not an assistant, not an oracle, not for anything safety-critical.
mimids 02 Β· trained 2026-08 Β· checkpoints at thrasher-v1-ckpts Β· eval instruments, prep scripts, and training config in this repo Β· Apache 2.0