name-generator-v2 / README.md
aimeri's picture
Fix the list of fantasy kinds
f7a7ecd verified
|
Raw History Blame Contribute Delete
9.63 kB
---
license: apache-2.0
base_model: aimeri/Ministral-3-3B-Base-2512-chatml
base_model_relation: finetune
datasets:
- aimeri/name-generator
language:
- en
library_name: transformers
pipeline_tag: text-generation
tags:
- names
- character-names
- fantasy-names
- creative-writing
- ministral3
- chatml
- unsloth
---
# Name Generator v2
Ask for a name, get one name back and nothing else. A 3.4B fine-tune of Ministral 3 that answers
"a Brazilian man's name" with a real Brazilian name and "a grim name for a dwarven blacksmith" with
an invented one, instead of the handful of names language models keep reaching for (Elara Voss,
Kael Thorne, Dr. Sarah Chen).
GGUF quants (Q8_0, Q6_K, Q5_K_M, Q4_K_M) for llama.cpp, LM Studio and similar:
[aimeri/name-generator-v2-GGUF](https://huggingface.co/aimeri/name-generator-v2-GGUF)
## New in v2
- **Fantasy names.** Elves, dark elves, dwarves, halflings, gnomes, orcs, goblins, giants, dragons,
fae, demons, merfolk, lizardfolk, eldritch beings and vampires, plus fantasy human cultures
modeled on 20 real naming traditions ("a sailor from a Norse-inspired kingdom", "a Persian-inspired
sorcerer"). None of the invented names it was trained on is a real name, a famous fictional
name or a name language models are known to overuse.
- **Tone and role.** Words like grim, gentle, whimsical, noble or ancient change how the name sounds;
roles (blacksmith, queen, assassin) shape the request the way they do in writing.
- **Real names as before.** Same data and recipe as [v1](https://huggingface.co/aimeri/name-generator),
retrained from the base model on the combined set.
## Examples
From the Q8_0 GGUF in llama.cpp: the greedy answer, then the first four distinct samples at
temperature 0.8.
| Request | Greedy | Sampled |
|---|---|---|
| What is a good male Brazilian name? | Lucas Silva | Marcos Silva · Felipe Bortolotto · Lucas Medeiros · Leandro Carvalho |
| Japanese woman's name | Matsumoto Yuka | Ehara Masahiro · Kohno Haruko · Mizuhara Natsuki · Satō Miyako |
| Give me a Russian man's full name | Vladimir Sergeyevich Kolesnikov | Aliocha Dronov · Aleksandr Borisovich Popenko · Viktor Sergeyevich Kolesnikov · Aleksey Borisovich Kolesnikov |
| I need a name for a Mexican grandmother | María Martínez | Florinda Martínez · Candela González · María García · Mariana Delgado |
| A name from the Song dynasty | Zhao Wen | Fu Lan · Zhou Chen · Zheng Xiu · Jin Hao |
| Name for a knight in 12th-century England | William de la Warr | Leofric Cokayne · William Cottingham · William Hotham · Geoffrey Bredon |
| Request | Greedy | Sampled |
|---|---|---|
| Give me an elf name | Gwengiand | Maesthilde · Fien · Giorgoth · Tialnolwen |
| A gentle name for a wood elf healer | Gwolwen | Estio · Fenderniarn · Giorgian · Hailien |
| I need a grim-sounding name for a dwarven blacksmith | Gurg | Thairgil · Gandit Blóblok · Gaurdard Kugurd · Sugaird Blóblaird |
| Orc warlord name | Krokhoth | Baglag · Drukga · Kathgath · Brathash |
| What would a halfling innkeeper be called? | Hilaryn | Beowine Fernby · Lingwood Millpatch · Hesterine · Thirzah Millhedge |
| Name for a whimsical gnome tinkerer | Fleegle | Skok · Fribeb Fublet · Floskunk · Jeblek |
| What would an ancient dragon be called? | Ghurgur | Juhuix · Vithgur · Grimyra · Grúndunth |
| A demon prince's name | Ghathgath | Grulthoz · Zakhokh · Ghaachga · Agrasth |
| Name for a sailor from a Norse-inspired kingdom in my D&D campaign | Kathild | Brider · Surtine · Kragardur · Karlan Kaldahl |
| Persian-inspired name for a sorcerer in my fantasy novel | Sahamir | Khajari · Hagashar · Saharid Khani · Rezizamal |
| Name for a knight in my fantasy novel | Kathar | Ammari Lenz · Havik · Katsumochi · Thurtha |
## Usage
Needs transformers 5.x (the architecture is `Ministral3ForCausalLM`).
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
repo = "aimeri/name-generator-v2"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForCausalLM.from_pretrained(repo, dtype="bfloat16", device_map="auto")
def names(request, n=5, temperature=0.8):
text = tokenizer.apply_chat_template([{"role": "user", "content": request}],
tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device) # adds <s>, as in training
out = model.generate(**inputs, max_new_tokens=24, do_sample=True, temperature=temperature,
num_return_sequences=n)
start = inputs["input_ids"].shape[1]
return [tokenizer.decode(o[start:], skip_special_tokens=True).strip() for o in out]
print(names("Give me a Brazilian woman's name"))
print(names("A gentle name for a wood elf healer"))
```
Two details matter:
- **Render, then tokenize.** The ChatML template emits no `<s>`; the tokenizer adds it when it encodes
the rendered text. `apply_chat_template(..., tokenize=True)` skips it, which is not what the model was
trained on.
- **Plain-string content.** The template trims `content` as a string; a list of `{"type": "text"}`
parts ends up in the prompt as its Python repr.
Through an OpenAI-compatible server (llama.cpp, vLLM, LM Studio) send a single user message with
`max_tokens` around 24. The model ends its turn with `<|im_end|>` (the eos token).
### Getting good names
- **Real names:** name a country or nationality ("Nigerian", "from Peru"), a historical state
("Ottoman Empire", "Song dynasty") or a region ("West African"). Sex and era ("a woman born in the
1950s") narrow it further. Names follow local conventions: family name first for Chinese,
Japanese, Korean, Hungarian and Vietnamese; patronymics in Russian and Ukrainian full names; two
surnames in Spanish and Portuguese full names.
- **Fantasy names:** say what the character is (an elf, a dwarf, a dragon, a demon). For humans, say
it's a fantasy setting (a kingdom, a campaign, a novel), and if you like, what the setting borrows
from ("Norse-inspired"); without a fantasy cue, a request for a human gets a real-world name.
- **Tone and role:** "grim", "gentle", "whimsical", "noble", "ancient", "sinister" and "mysterious"
change the sound of the name; a role ("blacksmith", "queen") reads naturally in the request.
- Sample at temperature 0.7–1.0 and ask once per character. Greedy decoding returns the single most
typical name every time.
## Training
| | |
|---|---|
| Base | [aimeri/Ministral-3-3B-Base-2512-chatml](https://huggingface.co/aimeri/Ministral-3-3B-Base-2512-chatml): the text-only Ministral-3-3B-Base-2512 with `<\|im_start\|>`/`<\|im_end\|>` claimed for ChatML |
| Data | [aimeri/name-generator](https://huggingface.co/datasets/aimeri/name-generator): 13,217 training rows (8,536 real, 4,681 fantasy) and 708 validation rows |
| Method | Supervised fine-tuning with Unsloth and TRL from the base model, full fine-tune, loss on the assistant turn only |
| Hyperparameters | learning rate 1e-5, linear schedule, 5% warmup, 1 epoch (3,305 steps), effective batch size 4, AdamW 8-bit, weight decay 0.001 |
| Software | transformers 5.20.2, Unsloth 2026.10.10 |
Each example pairs a request with one name.
- **Real names** were sampled with namebank from real frequency data (national statistics offices
such as the US SSA and Census, INSEE, ONS, INE, IBGE, PESEL, SSB and SCB; Wikidata people by
citizenship and birth decade; Faker and Mimesis locale lists), by country, sex and birth decade.
- **Fantasy names** were invented by `namebank fantasy`. Each species gets several made-up naming
languages with its own sounds; fantasy humans come from real naming traditions put through
culture-wide sound changes; halflings get compound family names from homely words. Every given
name and family name was checked against all of namebank's real names, a list of names language
models overuse and a list of famous fictional names.
- Ministral-3-3B-Instruct-2512 wrote the requests from each name's metadata. See the dataset card for
details.
## Limitations
- **Fantasy names come from a generator.** The model learned that generator's styles (what elvish or
orcish tends to sound like), not any author's languages: asking for Sindarin or Klingon won't get
you canon names, and some invented names are clumsy.
- **Humans need a fantasy cue.** "A knight in 12th-century England" gets a real name; "a knight in my
fantasy novel" gets an invented one. Vampires sit on the line: "a vampire countess" often gets a
real-world name (Katharina); add "in my fantasy novel" for an invented one.
- **Kinds it wasn't trained on** (angels, tieflings, dragonborn, forest spirits) fall back on what the base
model knows, which can mean a famous name: "a tiefling warlock" can get Lilith.
- **No surname-only answers.** "A Nigerian surname" still gets a full name.
- **Sex can slip** when sampling: asked for a Japanese woman's name, one sample above is a man's.
- **Coverage follows the data.** Where a country has no official name statistics, real names come
from Wikidata's notable people, who skew older, male and elite. Some pairings reflect expatriates
or data errors.
- **Short English requests.** Training used single-turn requests of a sentence or two.
- **Not real people.** Real-world outputs are combinations of real given names and surnames, and
can match a real or historical person by chance. Don't use this to identify people, infer
anyone's background, or make documents.
## License
Apache 2.0, following the base model. The training dataset is CC BY-SA 4.0.