Modification of the structure

This commit is contained in:
2026-09-22 12:04:35 +03:30
parent 41f0025883
commit 75a73559b5
3 changed files with 42 additions and 19 deletions
+5 -6
View File
@@ -1,11 +1,10 @@
# Local Faster-Whisper (same engine as Pipecat local STT) — no GapGPT.
# Sizes: tiny | base | small | medium | large-v3
# Do NOT use cloud names like whisper-1
# On low-RAM servers prefer: base or tiny
STT_MODEL=base
# Local Faster-Whisper — no GapGPT.
# Persian dictation needs at least small (base/tiny are too inaccurate).
# medium is better if the server has RAM.
STT_MODEL=small
STT_DEVICE=cpu
STT_COMPUTE_TYPE=int8
STT_PROMPT=یادداشت و مکالمهٔ فروش به زبان فارسی. اسامی مشتریان و اصطلاحات کسب‌وکار را دقیق بنویس.
STT_PROMPT=این یک یادداشت فارسی است. لطفاً این مورد را بررسی کنید.
STT_HOST=127.0.0.1
STT_PORT=3040
+32 -12
View File
@@ -46,20 +46,21 @@ def _require_token(header_token: str | None) -> None:
def _model_name() -> str:
"""Map env / legacy cloud names to Faster-Whisper local sizes."""
raw = (_env("STT_MODEL", "base") or "base").lower()
raw = (_env("STT_MODEL", "small") or "small").lower()
legacy = {
"whisper-1": "base",
"whisper": "base",
"whisper-1": "small",
"whisper": "small",
"gpt-4o-transcribe": "small",
"gpt-4o-mini-transcribe": "base",
"gpt-4o-mini-transcribe": "small",
# tiny/base are too weak for Persian dictation
"tiny": "small",
"tiny.en": "small",
"base": "small",
"base.en": "small",
}
if raw in legacy:
return legacy[raw]
allowed = {
"tiny",
"tiny.en",
"base",
"base.en",
"small",
"small.en",
"medium",
@@ -73,7 +74,7 @@ def _model_name() -> str:
"distil-large-v3",
"large-v3-turbo",
}
return raw if raw in allowed else "base"
return raw if raw in allowed else "small"
def _get_model() -> WhisperModel:
@@ -211,19 +212,38 @@ def _ensure_16k(wav_bytes: bytes) -> np.ndarray:
return _resample_audio(audio, rate, 16000)
def _normalize(audio: np.ndarray) -> np.ndarray:
if audio.size == 0:
return audio
peak = float(np.max(np.abs(audio)))
if peak < 1e-4:
return audio
# Bring quiet mic levels up without clipping
gain = min(8.0, 0.9 / peak)
if gain <= 1.05:
return audio
return np.clip(audio * gain, -1.0, 1.0).astype(np.float32)
def _transcribe_local(wav_bytes: bytes) -> str:
model = _get_model()
audio = _ensure_16k(wav_bytes)
audio = _normalize(_ensure_16k(wav_bytes))
initial_prompt = _env(
"STT_PROMPT",
"یادداشت و مکالمهٔ فروش به زبان فارسی. اسامی مشتریان و اصطلاحات کسب‌وکار را دقیق بنویس.",
"این یک یادداشت فارسی است. لطفاً این مورد را بررسی کنید.",
) or None
segments, _info = model.transcribe(
audio,
language="fa",
task="transcribe",
initial_prompt=initial_prompt,
vad_filter=True,
beam_size=5,
best_of=5,
temperature=0.0,
condition_on_previous_text=False,
vad_filter=False,
no_speech_threshold=0.45,
)
parts = [seg.text.strip() for seg in segments if getattr(seg, "text", None)]
return " ".join(p for p in parts if p).strip()
@@ -244,7 +244,11 @@ async function start() {
stream = null;
return;
}
try {
ctx = new Ctor({ sampleRate: 16000 });
} catch {
ctx = new Ctor();
}
await ctx.resume();
sampleRate = ctx.sampleRate || 16000;
source = ctx.createMediaStreamSource(stream);