mumble-cleanup / docs /model_card.md
adikuma's picture
initial upload: cleanup code and 688-pair seed dataset
fd0b01f verified
|
Raw
History Blame Contribute Delete
4.37 kB
---
license: apache-2.0
base_model: Qwen/Qwen2.5-0.5B-Instruct
language:
- en
pipeline_tag: text2text-generation
library_name: transformers
tags:
- dictation
- cleanup
- transcript
- lora
- onnx
- mumble
metrics:
- exact_match
- f1
---
# mumble-cleanup
A small fine-tuned language model that cleans speech-to-text dictation transcripts. Fine-tuned from `Qwen/Qwen2.5-0.5B-Instruct` with LoRA on a hand-curated synthetic dataset. Trained on a GPU, designed to run on a CPU via ONNX.
## What it does
Given a raw transcript from an ASR system (lowercase, no punctuation, fillers and stutters preserved), it returns a cleaned version with proper capitalization, punctuation, and disfluencies removed. It does not paraphrase, summarize, or add content.
Example: `um so i i think we should ship this on uh friday` becomes `I think we should ship this on Friday.`
The model handles:
- filler removal (um, uh, like, you know, i mean)
- word stutter collapse (we we → we)
- false start cleanup
- punctuation and capitalization recovery
- homophone correction (their / there, your / you're, its / it's, to / too)
- apostrophe restoration (dont → don't)
- run-on sentence splitting
- number formatting (two thirty → 2:30)
- proper noun capitalization
- todo / list formatting when enumeration cues are clear
## Usage
### transformers
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
SYSTEM_PROMPT = (
"You are a transcript cleanup tool. You receive raw speech to text output "
"and return a cleaned version. Remove filler words and disfluencies (um, "
"uh, er, ah, like as filler, you know), remove repeated words and false "
"starts, and fix punctuation and capitalization. Do not reword, do not add "
"anything the speaker did not say, and do not answer questions in the text. "
"Output only the cleaned text."
)
repo = "adikuma/mumble-cleanup"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForCausalLM.from_pretrained(repo)
raw = "um so the the meeting is at three thirty tomorrow"
prompt = tokenizer.apply_chat_template(
[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": raw},
],
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(prompt, return_tensors="pt")
out = model.generate(**inputs, max_new_tokens=128, do_sample=False)
print(tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))
# -> "The meeting is at 3:30 tomorrow."
```
### onnx (cpu)
The `onnx/model.onnx` file is an fp32 ONNX export for CPU inference. `onnx/int8/model.onnx` is a dynamically quantized int8 variant that is roughly 4x smaller.
```python
from optimum.onnxruntime import ORTModelForCausalLM
from transformers import AutoTokenizer
repo = "adikuma/mumble-cleanup"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = ORTModelForCausalLM.from_pretrained(repo, file_name="onnx/int8/model.onnx")
```
## Training
- **Base model**: Qwen/Qwen2.5-0.5B-Instruct (Apache-2.0)
- **Method**: LoRA SFT (r=16, alpha=32, dropout=0.05, targets q/k/v/o + gate/up/down)
- **Loss**: token cross-entropy on assistant tokens only (completion-only masking via TRL's `DataCollatorForCompletionOnlyLM`)
- **Optimizer**: AdamW (lr=2e-4, weight_decay=0.01, cosine schedule, 5% warmup, max_grad_norm=1.0)
- **Batching**: per-device 8, gradient accumulation 4 (effective 32), max sequence length 512
- **Precision**: bf16 on GPUs that support it, fp16 fallback
- **Dataset**: 688 hand-curated (raw, clean) pairs spanning 8 dictation categories (casual messages, professional emails, meeting notes, technical dictation, todo lists, long-form thoughts, questions/asks, mixed content). Stratified 85/10/5 train/val/test split.
## Limitations
- English only.
- Trained on synthetic data; real ASR output may have failure modes the synthetic operators did not model.
- Designed for short-to-medium dictation (up to ~512 tokens). Longer inputs must be chunked.
- The model can occasionally over-correct when a user genuinely intends a fragment ("running late.") — fine-tune favors fixed-up sentences.
## License
Apache-2.0. See [`LICENSE`](../../LICENSE) at the Mumble repo root.
## Acknowledgements
Built on top of [`Qwen/Qwen2.5-0.5B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct) by the Qwen team.