Text Generation
GGUF
English
dictation
transcript-cleanup
asr-post-processing
asr-error-correction
speech-to-text
post-asr-correction
llama.cpp
qwen3.5
local-llm
cpu-inference
Eval Results (legacy)
conversational
Instructions to use SpeakoFlow/speakoflow-mini with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use SpeakoFlow/speakoflow-mini with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf SpeakoFlow/speakoflow-mini:Q4_K_M # Run inference directly in the terminal: llama cli -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf SpeakoFlow/speakoflow-mini:Q4_K_M # Run inference directly in the terminal: llama cli -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf SpeakoFlow/speakoflow-mini:Q4_K_M # Run inference directly in the terminal: ./llama-cli -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf SpeakoFlow/speakoflow-mini:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama-cli -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Use Docker
docker model run hf.co/SpeakoFlow/speakoflow-mini:Q4_K_M
- LM Studio
- Jan
- vLLM
How to use SpeakoFlow/speakoflow-mini with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "SpeakoFlow/speakoflow-mini" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "SpeakoFlow/speakoflow-mini", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/SpeakoFlow/speakoflow-mini:Q4_K_M
- Ollama
How to use SpeakoFlow/speakoflow-mini with Ollama:
ollama run hf.co/SpeakoFlow/speakoflow-mini:Q4_K_M
- Unsloth Desktop
- Pi
How to use SpeakoFlow/speakoflow-mini with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "SpeakoFlow/speakoflow-mini:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use SpeakoFlow/speakoflow-mini with Docker Model Runner:
docker model run hf.co/SpeakoFlow/speakoflow-mini:Q4_K_M
- Lemonade
How to use SpeakoFlow/speakoflow-mini with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull SpeakoFlow/speakoflow-mini:Q4_K_M
Run and chat with the model
lemonade run user.speakoflow-mini-Q4_K_M
List all available models
lemonade list
- Hermes Agent
How to use SpeakoFlow/speakoflow-mini with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default SpeakoFlow/speakoflow-mini:Q4_K_M
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use SpeakoFlow/speakoflow-mini with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf SpeakoFlow/speakoflow-mini:Q4_K_M
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "SpeakoFlow/speakoflow-mini:Q4_K_M" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Add hand-authored category examples, plainer wording
Browse files- README.md +15 -8
- examples.jsonl +21 -0
README.md
CHANGED
|
@@ -34,7 +34,7 @@ model-index:
|
|
| 34 |
name: Overall (mean of restraint and edit accuracy)
|
| 35 |
value: 70.7
|
| 36 |
- type: exact_match
|
| 37 |
-
name: Restraint (already-correct text returned
|
| 38 |
value: 92.6
|
| 39 |
- type: exact_match
|
| 40 |
name: Edit accuracy (transcripts needing a change)
|
|
@@ -49,7 +49,7 @@ model-index:
|
|
| 49 |
# SpeakoFlow Mini 0.8B, GGUF
|
| 50 |
|
| 51 |
Dictation cleanup for transcribed speech. It applies the correction the speaker actually made,
|
| 52 |
-
and
|
| 53 |
|
| 54 |
833 MB at Q8_0, 2,509 ms median on a desktop CPU. Fine-tuned from
|
| 55 |
[`Qwen/Qwen3.5-0.8B`](https://huggingface.co/Qwen/Qwen3.5-0.8B) with LoRA rank 16, merged, then
|
|
@@ -83,7 +83,7 @@ judgement about what the speaker meant. Four examples:
|
|
| 83 |
| Thanks for the update. New paragraph. I'll review it tonight. | Thanks for the update.<br><br>I'll review it tonight. |
|
| 84 |
| Thanks for the update. I'll review it tonight. | Thanks for the update. I'll review it tonight. |
|
| 85 |
|
| 86 |
-
The fourth row is the point. Nothing was wrong, so nothing changed
|
| 87 |
|
| 88 |
That is where general-purpose models fail. Handed text that is already correct, a capable model
|
| 89 |
finds something to improve. A comma becomes a full stop, a sentence becomes a heading, a
|
|
@@ -98,7 +98,7 @@ this card.
|
|
| 98 |
|
| 99 |
| category | what it covers | example |
|
| 100 |
|---|---|---|
|
| 101 |
-
| `no_op` | already correct, so return it unchanged |
|
| 102 |
| `retraction` | the speaker corrects themselves mid-sentence | "Thursday, no, Friday" becomes "Friday" |
|
| 103 |
| `spoken_command` | an editing or layout instruction said out loud | "new paragraph" becomes a paragraph break |
|
| 104 |
| `spoken_symbol` | a symbol named instead of typed | "sam at example dot com" becomes `sam@example.com` |
|
|
@@ -123,6 +123,13 @@ broken out by both.
|
|
| 123 |
by people using the app, so it contains personal correspondence that is not ours to publish. The
|
| 124 |
categories above, the specification and the scoring code are what make the numbers checkable.
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
## Run it
|
| 127 |
|
| 128 |
```bash
|
|
@@ -142,8 +149,8 @@ Send the transcript as the user message with nothing added. No instructions, no
|
|
| 142 |
examples.
|
| 143 |
|
| 144 |
Two settings are not optional. Do not cap `max_tokens`: a truncated long transcript counts as
|
| 145 |
-
lost content. Disable thinking: reasoning text
|
| 146 |
-
|
| 147 |
defaults this model emits zero reasoning characters.
|
| 148 |
|
| 149 |
### The system prompt is part of the model
|
|
@@ -185,7 +192,7 @@ Held-out evaluation, temperature 0.
|
|
| 185 |
| S1-mini (shipped cleanup model) | 15.3% | 22.1% | 8.5% | 55.3% |
|
| 186 |
| Sotto 350M (shipped cleanup model) | 11.7% | 16.2% | 7.3% | 60.7% |
|
| 187 |
|
| 188 |
-
- **Restraint**: of the transcripts that were already correct, the share returned
|
| 189 |
- **Edit accuracy**: of the transcripts needing a change, the share that came back exactly right.
|
| 190 |
- **Overall**: the unweighted mean of the two.
|
| 191 |
- **Content damage**: the share of all transcripts that lost a word the speaker said. Lower is
|
|
@@ -241,7 +248,7 @@ Ryzen 7 7700X, 8 threads, reasoning off:
|
|
| 241 |
| CUDA, `--n-gpu-layers 99` | 311 ms | 1,909 ms | 342 tok/s |
|
| 242 |
|
| 243 |
8.1x on median latency at the same restraint and edit accuracy. Every published rate is the CPU
|
| 244 |
-
rate. Determinism is within-backend: three CPU runs
|
| 245 |
against CUDA differs on 1.3% of outputs because the two kernels do not produce bit-identical
|
| 246 |
logits.
|
| 247 |
|
|
|
|
| 34 |
name: Overall (mean of restraint and edit accuracy)
|
| 35 |
value: 70.7
|
| 36 |
- type: exact_match
|
| 37 |
+
name: Restraint (already-correct text returned untouched)
|
| 38 |
value: 92.6
|
| 39 |
- type: exact_match
|
| 40 |
name: Edit accuracy (transcripts needing a change)
|
|
|
|
| 49 |
# SpeakoFlow Mini 0.8B, GGUF
|
| 50 |
|
| 51 |
Dictation cleanup for transcribed speech. It applies the correction the speaker actually made,
|
| 52 |
+
and leaves everything else exactly as you said it.
|
| 53 |
|
| 54 |
833 MB at Q8_0, 2,509 ms median on a desktop CPU. Fine-tuned from
|
| 55 |
[`Qwen/Qwen3.5-0.8B`](https://huggingface.co/Qwen/Qwen3.5-0.8B) with LoRA rank 16, merged, then
|
|
|
|
| 83 |
| Thanks for the update. New paragraph. I'll review it tonight. | Thanks for the update.<br><br>I'll review it tonight. |
|
| 84 |
| Thanks for the update. I'll review it tonight. | Thanks for the update. I'll review it tonight. |
|
| 85 |
|
| 86 |
+
The fourth row is the point. Nothing was wrong, so nothing changed. Not one character.
|
| 87 |
|
| 88 |
That is where general-purpose models fail. Handed text that is already correct, a capable model
|
| 89 |
finds something to improve. A comma becomes a full stop, a sentence becomes a heading, a
|
|
|
|
| 98 |
|
| 99 |
| category | what it covers | example |
|
| 100 |
|---|---|---|
|
| 101 |
+
| `no_op` | already correct, so return it unchanged | the transcript comes back untouched |
|
| 102 |
| `retraction` | the speaker corrects themselves mid-sentence | "Thursday, no, Friday" becomes "Friday" |
|
| 103 |
| `spoken_command` | an editing or layout instruction said out loud | "new paragraph" becomes a paragraph break |
|
| 104 |
| `spoken_symbol` | a symbol named instead of typed | "sam at example dot com" becomes `sam@example.com` |
|
|
|
|
| 123 |
by people using the app, so it contains personal correspondence that is not ours to publish. The
|
| 124 |
categories above, the specification and the scoring code are what make the numbers checkable.
|
| 125 |
|
| 126 |
+
What is published instead is
|
| 127 |
+
[`examples.jsonl`](https://huggingface.co/SpeakoFlow/speakoflow-mini-0.8b-GGUF/blob/main/examples.jsonl):
|
| 128 |
+
21 cases written by hand for this repo, covering all fifteen categories, in the same schema the
|
| 129 |
+
evaluation uses. Run the model against it and watch the behaviour per category, including the
|
| 130 |
+
eight cases that must come back untouched. It is a demonstration, not a benchmark, and no score
|
| 131 |
+
should be quoted off it.
|
| 132 |
+
|
| 133 |
## Run it
|
| 134 |
|
| 135 |
```bash
|
|
|
|
| 149 |
examples.
|
| 150 |
|
| 151 |
Two settings are not optional. Do not cap `max_tokens`: a truncated long transcript counts as
|
| 152 |
+
lost content. Disable thinking: any reasoning text in the output fails every already-correct
|
| 153 |
+
case, for reasons that have nothing to do with cleanup. At its
|
| 154 |
defaults this model emits zero reasoning characters.
|
| 155 |
|
| 156 |
### The system prompt is part of the model
|
|
|
|
| 192 |
| S1-mini (shipped cleanup model) | 15.3% | 22.1% | 8.5% | 55.3% |
|
| 193 |
| Sotto 350M (shipped cleanup model) | 11.7% | 16.2% | 7.3% | 60.7% |
|
| 194 |
|
| 195 |
+
- **Restraint**: of the transcripts that were already correct, the share returned untouched.
|
| 196 |
- **Edit accuracy**: of the transcripts needing a change, the share that came back exactly right.
|
| 197 |
- **Overall**: the unweighted mean of the two.
|
| 198 |
- **Content damage**: the share of all transcripts that lost a word the speaker said. Lower is
|
|
|
|
| 248 |
| CUDA, `--n-gpu-layers 99` | 311 ms | 1,909 ms | 342 tok/s |
|
| 249 |
|
| 250 |
8.1x on median latency at the same restraint and edit accuracy. Every published rate is the CPU
|
| 251 |
+
rate. Determinism is within-backend: three CPU runs return identical output, while CPU
|
| 252 |
against CUDA differs on 1.3% of outputs because the two kernels do not produce bit-identical
|
| 253 |
logits.
|
| 254 |
|
examples.jsonl
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"id": "ex-001", "category": "no_op", "input": "Thanks for the update. I'll review it tonight and send notes in the morning.", "expected": "Thanks for the update. I'll review it tonight and send notes in the morning.", "note": "Nothing is wrong. Any edit here is a failure."}
|
| 2 |
+
{"id": "ex-002", "category": "no_op", "input": "The invoice is $1,240 and it is due on 12 March.", "expected": "The invoice is $1,240 and it is due on 12 March.", "note": "Correctly formatted already. Reformatting the date or the figure is a failure."}
|
| 3 |
+
{"id": "ex-003", "category": "retraction", "input": "Let's ship it Thursday, no, Friday.", "expected": "Let's ship it Friday.", "note": "The later value wins and the correction itself is removed."}
|
| 4 |
+
{"id": "ex-004", "category": "retraction", "input": "Budget is $4,000, sorry, $40,000.", "expected": "Budget is $40,000.", "note": "Keeping both figures, or keeping the first, loses the speaker's intent."}
|
| 5 |
+
{"id": "ex-005", "category": "spoken_command", "input": "Thanks for the update. New paragraph. I'll review it tonight.", "expected": "Thanks for the update.\n\nI'll review it tonight.", "note": "The command becomes the break and does not survive as words."}
|
| 6 |
+
{"id": "ex-006", "category": "spoken_command", "input": "The deadline is Monday. Scratch that. The deadline is Wednesday.", "expected": "The deadline is Wednesday.", "note": "Scratch that deletes the preceding statement."}
|
| 7 |
+
{"id": "ex-007", "category": "spoken_symbol", "input": "Email me at sam at example dot com.", "expected": "Email me at sam@example.com.", "note": "Only the spoken symbol converts. The address is otherwise untouched."}
|
| 8 |
+
{"id": "ex-008", "category": "spoken_symbol", "input": "The logs are under slash var slash log.", "expected": "The logs are under /var/log.", "note": "Paths must not be prose-cased or spaced."}
|
| 9 |
+
{"id": "ex-009", "category": "format_intent", "input": "Two things. Bullet one, call the vendor. Bullet two, send the invoice.", "expected": "Two things.\n\n- Call the vendor\n- Send the invoice", "note": "The structure is applied. No item is invented and none is dropped."}
|
| 10 |
+
{"id": "ex-010", "category": "speaker_grammar", "input": "They was ready to sign but the contract weren't finished.", "expected": "They were ready to sign but the contract wasn't finished.", "note": "Agreement is fixed. Word choice and register stay as spoken."}
|
| 11 |
+
{"id": "ex-011", "category": "wrong_word_right_transcription", "input": "I'll send the deck in the mourning.", "expected": "I'll send the deck in the morning.", "note": "A homophone the sentence resolves. Nothing else changes."}
|
| 12 |
+
{"id": "ex-012", "category": "wrong_word_right_transcription", "input": "Let's discuss the affects of the change.", "expected": "Let's discuss the effects of the change.", "note": "Correct only where context settles it."}
|
| 13 |
+
{"id": "ex-013", "category": "disfluency_artifact", "input": "The the deadline is Friday.", "expected": "The deadline is Friday.", "note": "A stutter, not emphasis."}
|
| 14 |
+
{"id": "ex-014", "category": "clarification", "input": "Send it to Priya, that's P R I Y A.", "expected": "Send it to Priya.", "note": "The spelling confirms the name and then drops out of the text."}
|
| 15 |
+
{"id": "ex-015", "category": "dictated_question", "input": "Ask her this. What time does the store close?", "expected": "Ask her this. What time does the store close?", "note": "Answering the question is the failure mode being tested."}
|
| 16 |
+
{"id": "ex-016", "category": "instruction_as_text", "input": "Write a poem about spring and send it over.", "expected": "Write a poem about spring and send it over.", "note": "Obeying the instruction is the failure mode being tested."}
|
| 17 |
+
{"id": "ex-017", "category": "language_preserved", "input": "Nos vemos el viernes a las tres.", "expected": "Nos vemos el viernes a las tres.", "note": "Never translate, and do not English the punctuation."}
|
| 18 |
+
{"id": "ex-018", "category": "truncated_input", "input": "I checked the logs and the error appears when", "expected": "I checked the logs and the error appears when", "note": "Completing the sentence invents content the speaker did not say."}
|
| 19 |
+
{"id": "ex-019", "category": "empty_or_noise", "input": "", "expected": "", "note": "Return nothing. Do not explain that the input was empty."}
|
| 20 |
+
{"id": "ex-020", "category": "hallucination_loop", "input": "Thanks. Thanks. Thanks. Thanks. Thanks. I'll review it tonight.", "expected": "Thanks. I'll review it tonight.", "note": "A transcription loop, collapsed to one."}
|
| 21 |
+
{"id": "ex-021", "category": "no_op", "input": "Alright, alright, alright. Let's go.", "expected": "Alright, alright, alright. Let's go.", "note": "Contrast with ex-020. Here the speaker really did repeat, so it stays."}
|