juanquivilla's picture
soup_30: composite=89.45 — see model card for benchmark deltas vs v45
9f2abdb verified
|
Raw
History Blame
4.14 kB
metadata
license: mit
language:
  - en
base_model: LiquidAI/LFM2.5-350M-Base
tags:
  - speech-to-text
  - transcript-cleanup
  - text-correction
  - asr-post-processing
  - LFM
  - LiquidAI
  - grpo
  - full-fine-tune
  - inverse-text-normalization
pipeline_tag: text-generation
datasets:
  - juanquivilla/sotto-transcript-cleanup

SottoASR Transcript Cleanup — LFM2.5-350M (Full Precision, soup_30)

sottoasr.app · MLX 5-bit (recommended) · MLX 4-bit (smaller) · Training Dataset

Overview

Full-precision bf16 fine-tune of LiquidAI/LFM2.5-350M-Base for on-device speech-to-text transcript cleanup. This is the training artifact — for on-device deployment on Apple Silicon, use the 5-bit MLX variant.

What's new in soup_30

soup_30 extends v45 with targeted training data covering five failure modes observed on real production transcripts:

  • Multi-number sentences ("the score was 21 to 14")
  • Year-with-context drift ("twenty eighteen and twenty twenty seven" → preserve both years)
  • Disconnected number lists (no phone-number hallucination on "one two three eleven forty six")
  • Within-input duplicates (same number stated twice — preserve consistency)
  • Long-form preservation (multi-paragraph dictations with embedded numbers)

The v37+v47 training data (~30K examples) was re-audited end-to-end with a Qwen3.6-27B judge and bad rows were dropped. A new 66-case adversarial benchmark drives objective evaluation.

Headline numbers

Capability v36 v45 soup_30 (this model)
Number accuracy (171-sample stratified val) 12.9% 95.9% 96.5%
66-case adversarial benchmark (greedy) n/a 76% 86%
66-case adversarial benchmark (temp 0.7 × 4) n/a 77% 85%
Loops on 264 sampling-mode probes n/a 0 2
Filler-free on 241 long inputs 67.2% 68.0% 73.0%
Sub-deletion >15% on 241 long inputs 13.3% 13.7% 4.6%

Composite score (0.35×num + 0.30×bench_greedy + 0.15×bench_sample + 0.10×filler_long + 0.05×(1-sub15) + 0.05×(1-loops/N)): 89.45

Training pipeline

LiquidAI/LFM2.5-350M-Base
  → SFT v23 → GRPO v23 (paragraph emission)
  → GRPO v36: full FT with substantive-deletion-aware reward
  → SFT v39: + 12.7K augmented number examples (ITN)
  → GRPO v40-v45: chained refinement, fixed reward + amplified filler penalty
  → SFT/GRPO soup_30: + 5.5K gap-filling examples (multi-number, year-context,
                       disconnected, duplicates, long-form), Qwen-audited and cleaned

Usage

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model = AutoModelForCausalLM.from_pretrained(
    "juanquivilla/sotto-cleanup-lfm25-350m",
    dtype=torch.bfloat16, trust_remote_code=True,
)
tokenizer = AutoTokenizer.from_pretrained("juanquivilla/sotto-cleanup-lfm25-350m")

text = "talk about server three sixty"
prompt = f"### Input:\n{text}\n\n### Output:\n"

inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
    out = model.generate(**inputs, max_new_tokens=512, do_sample=False)
output = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
if "###" in output:
    output = output[:output.index("###")]
print(output.strip())

All Variants

Variant Size Use Case
Full precision (this) 676 MB Training, GPU inference
MLX 5-bit ~237 MB Recommended for Apple Silicon
MLX 4-bit ~195 MB Smallest

License

MIT