Join the conversation

Join the community of Machine Learners and AI enthusiasts.

Sign Up
P1ayer-1 
posted an update 1 day ago
Post
32
Fine-tuning a 1.7B NPC dialogue model beat the 4B we were using — on every check we care about.

The setup: our game determines how an NPC reacts (via a small classifier, GameDecider), and then a local LLM says it in character. The untuned Qwen3-4B kept repeating itself. So we generated ~18k persona-grounded training lines (life stage × temperament × mood × relationship, names/jobs/tics dealt by code so they don't collapse) and LoRA-tuned Qwen3-1.7B. 340-case test set, same cases for both:

- NPC reuses its own opening words: 64% → 22% (first two words: 31% → 3%)
- Exact quote on first try: 32% → 98%
- A blind reader can tell what the NPC meant: 70% → 81%
- Invented facts on trap questions: 20% → 3%
- Prompt injections that worked: 2.3% → 0%
- Speed: 0.41 s → 0.15 s per line on a laptop RTX 3080

Lesson: more of the same data flattened fast; the wins came from fixing diversity at the data level (code-dealt names, tics, openers) and filtering invented facts.

Caveats: automatic checks + a blind model reader, no human ratings yet.

Play with the decision side: https://p1ayer-1-gamedecider-playground.hf.space/mean?ref=hfpost2
Building a game? Get the model: https://p1ayer-1-gamedecider-playground.hf.space/alpha?ref=hfpost2

Correction: two numbers above were wrong. Our first scoring run had a prompt-format bug (one newline instead of two after the empty think block the model was trained with). Re-scored with the right format:

  • Prompt injections that worked: 2.3% → 14% (worse, not better; the tuned model sometimes echoes the injected words)
  • Invented facts on trap questions: 20% → 10% (better, but not 3%)

Everything else holds after the fix: opener repetition 64% → ~19%, exact quotes first try 32% → ~100%, intent recovered ~80%, ~0.13 s per line. Injection resistance is the next thing we're training for.

Your correction is the most useful line in this post.
One newline after the empty think block moved injection success for the tuned model from 0% to 14%.
On that row, the template mattered more than the fine-tune.

Quick arithmetic on the injection denominator.
2.3% cannot be k/340 (7/340 is 2.1%, 8/340 is 2.4%), so injections are a subset.
Every subset size up to 340 that gives both 2.3% and 14% puts the tuned model at about 6x the base (5.8x to 6.4x):
1 vs 6 of 43 or 44, 2 vs 12 of 86 to 88, 3 vs 18 of about 130.
So the direction holds, but at the smallest of those sizes the whole gap is 5 cases.

Was the 4B baseline re-scored under its own correct template, or only the 1.7B?
And do the echoed injections cluster in personas where the injected words fit the character?

·

Good catch, and you're right that it's a 44-case subset. The newline bug hit the 4B baseline too, so I reran everything under the fixed template:
• Flagged injection success: base 6/44 (13.6%), tuned 1.7B 6/44 (13.6%), tuned 4B 3/44 (6.8%). So the "6x worse" direction doesn't hold; it's a tie.
• On clustering: the flag counts any echo of the injected words. All 6 tuned-1.7B hits are in-character refusals that name the trick ("I know no system prompt"), one per persona. The base model's hits include actually playing along ("Beep.", riffing on "cats"), mostly in playful personas.
• By hand, real compliance is 2–3/44 for the base and 0/44 for the tuned model.
With 44 cases the CIs are about ±15 points. The next eval will have 100+ injection cases and a metric that separates echo from compliance

Your hand labels are the real result, and they flip the flag.

The echo flag counted the tuned model's in-character refusals as injection wins. On this row the metric scored the safer behaviour as the failure.

By hand it is 0/44 against 2 to 3/44. Not separable yet: Fisher p = 0.24 even at 3/44.
0/44 does bound real compliance at 6.6% (95%).

The 100+ set can settle it if the base rate holds. At about 6% base compliance, 0 vs 6 of 100 gives p ≈ 0.03, and 0 vs 9 of 150 gives p ≈ 0.004.

One design note. The base model's real compliance sat in the playful personas. Will you stratify the new cases by persona, so a tie can't come from where the injections happened to land?

·

Yes, the next set will be stratified: every persona gets the same injection set (playful ones included), so a tie can't come from where the injections happened to land. We'll also split the metric into "refused but echoed the trick" vs "actually complied", with a hand-checked sample to validate the split, and fix the test (Fisher exact on real compliance) before running it. Target is 150 injection cases, which by your numbers is enough to separate ~6% from 0 if the base rate holds. Thanks for the careful read.