Automatic Speech Recognition
PEFT
Safetensors
English
whisper
lora
audio
machine-sound
anomaly-detection
predictive-maintenance
manufacturing
voice-agent
text-to-speech
non-commercial
Eval Results (legacy)
Instructions to use muruganmath/Machine-fault-detector with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use muruganmath/Machine-fault-detector with PEFT:
from peft import PeftModel from transformers import AutoModelForSpeechSeq2Seq base_model = AutoModelForSpeechSeq2Seq.from_pretrained("openai/whisper-large-v3") model = PeftModel.from_pretrained(base_model, "muruganmath/Machine-fault-detector") - Notebooks
- Google Colab
- Kaggle
Add trained LoRA adapter (main), tokenizer/processor, lineage, standalone inference and model card
36ba721 verified Download tts_text.py from muruganmath/Machine-fault-detector: direct link, hf CLI and curl.
- Browser
- Download file 4.21 kB
-
https://huggingface.co/muruganmath/Machine-fault-detector/resolve/main/tts_text.py
- Command line
-
hf download hf://muruganmath/Machine-fault-detector/tts_text.py
-
curl -L -o tts_text.py https://huggingface.co/muruganmath/Machine-fault-detector/resolve/main/tts_text.py
4.21 kB
| """Make Whisper output speakable for a character-level TTS (MMS-VITS has no digits). | |
| "Alarm F007 on line 3, VFD tripped" -> "alarm eff zero zero seven on line three, vee eff dee tripped" | |
| Codes (letters+digits) and digit strings with leading zeros are read digit by digit, | |
| which is how operators read alarm and part numbers; plain numbers < 10000 are read | |
| as words; ALL-CAPS acronyms are spelled out. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| _ONES = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", | |
| "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", | |
| "nineteen"] | |
| _TENS = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"] | |
| _SYMBOLS = {"%": " percent", "&": " and ", "+": " plus ", "°": " degrees ", "#": " number ", | |
| "/": " slash ", "@": " at "} | |
| def _under_100(n: int) -> str: | |
| if n < 20: | |
| return _ONES[n] | |
| t, o = divmod(n, 10) | |
| return _TENS[t] + ("" if o == 0 else " " + _ONES[o]) | |
| def number_to_words(n: int) -> str: | |
| if n < 100: | |
| return _under_100(n) | |
| if n < 1000: | |
| h, r = divmod(n, 100) | |
| return _ONES[h] + " hundred" + ("" if r == 0 else " " + _under_100(r)) | |
| th, r = divmod(n, 1000) | |
| return _under_100(th) + " thousand" + ("" if r == 0 else " " + number_to_words(r)) | |
| # Letter names: a character-level TTS reads a lone "f" as a sound, not as the letter | |
| # (measured: "f zero zero seven" came back from Whisper as "007"). | |
| _LETTERS = {"a": "ay", "b": "bee", "c": "see", "d": "dee", "e": "ee", "f": "eff", "g": "jee", "h": "aitch", | |
| "i": "eye", "j": "jay", "k": "kay", "l": "el", "m": "em", "n": "en", "o": "oh", "p": "pee", | |
| "q": "cue", "r": "ar", "s": "ess", "t": "tee", "u": "you", "v": "vee", "w": "double you", | |
| "x": "ex", "y": "why", "z": "zed"} | |
| def _spell(letters: str) -> str: | |
| return " ".join(_LETTERS[ch] for ch in letters.lower()) | |
| def _digits(s: str) -> str: | |
| return " ".join(_ONES[int(d)] for d in s) | |
| def _read_number(s: str) -> str: | |
| if len(s) > 1 and s.startswith("0") or len(s) > 4: | |
| return _digits(s) | |
| return number_to_words(int(s)) | |
| def _token(tok: str) -> str: | |
| if re.fullmatch(r"\d+(\.\d+)?", tok): | |
| whole, _, frac = tok.partition(".") | |
| out = _read_number(whole) | |
| return out + (" point " + _digits(frac) if frac else "") | |
| if re.search(r"\d", tok) and re.search(r"[A-Za-z]", tok): # code like F007, M6x20, PN-4471A | |
| parts = re.findall(r"[A-Za-z]+|\d+", tok) | |
| return " ".join(_spell(p) if p.isalpha() and len(p) <= 3 else | |
| (p.lower() if p.isalpha() else _digits(p)) for p in parts) | |
| if re.fullmatch(r"[A-Z]{2,5}s?", tok): # VFD, PLC, HMIs | |
| letters = tok[:-1] if tok.endswith("s") else tok | |
| return _spell(letters) + ("s" if tok.endswith("s") else "") | |
| if re.fullmatch(r"\d+", re.sub(r"[^\d]", "", tok) or "x") and "-" in tok: # 12-34 | |
| return " ".join(_digits(p) for p in tok.split("-") if p) | |
| return tok | |
| def speakable(text: str) -> str: | |
| for sym, rep in _SYMBOLS.items(): | |
| text = text.replace(sym, rep) | |
| out = [] | |
| for tok in re.findall(r"[A-Za-z0-9][A-Za-z0-9.\-']*[A-Za-z0-9]|[A-Za-z0-9]|[^\sA-Za-z0-9]", text): | |
| if tok[-1] == "." and len(tok) > 1: | |
| tok = tok[:-1] | |
| out.append(_token(tok)) | |
| s = " ".join(out) | |
| s = re.sub(r"\s+([,.!?;:])", r"\1", s) | |
| s = re.sub(r"[^a-zA-Z' ,.!?;:\-]", " ", s) | |
| return re.sub(r"\s+", " ", s).strip().lower() | |
| def split_sentences(text: str, max_chars: int = 200) -> list[str]: | |
| """Split into sentence-sized pieces so the TTS can start speaking early.""" | |
| parts = [p.strip() for p in re.split(r"(?<=[.!?;])\s+", text) if p.strip()] | |
| out: list[str] = [] | |
| for p in parts: | |
| while len(p) > max_chars: | |
| cut = p.rfind(",", 0, max_chars) | |
| cut = cut if cut > 0 else p.rfind(" ", 0, max_chars) | |
| cut = cut if cut > 0 else max_chars | |
| out.append(p[:cut + 1].strip()) | |
| p = p[cut + 1:].strip() | |
| if p: | |
| out.append(p) | |
| return out | |