Spaces:
Sleeping
Sleeping
Sasha commited on
Commit ·
d7b1f0b
1
Parent(s): d0dc16f
feat: tune Whisper settings and add word mappings
Browse files- google7181fa1faffcf274.html +1 -0
- local_worker/vod_backfiller.py +5 -2
- local_worker/worker.py +8 -4
- server/server.js +16 -4
google7181fa1faffcf274.html
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
google-site-verification: google7181fa1faffcf274.html
|
local_worker/vod_backfiller.py
CHANGED
|
@@ -37,6 +37,7 @@ TWITCH_CHANNEL = os.getenv("TWITCH_CHANNEL", "winx_prinx").lower()
|
|
| 37 |
WHISPER_MODEL_SIZE = os.getenv("WHISPER_MODEL", "base")
|
| 38 |
WHISPER_DEVICE = os.getenv("WHISPER_DEVICE", "cpu")
|
| 39 |
WHISPER_COMPUTE_TYPE = os.getenv("WHISPER_COMPUTE_TYPE", "int8")
|
|
|
|
| 40 |
|
| 41 |
if not API_KEY:
|
| 42 |
print("[Error] API_KEY is missing in .env! Cannot push data to backend.")
|
|
@@ -257,10 +258,11 @@ def transcribe_vod_audio(vod_id, start_time_iso, model, start_offset=0, end_offs
|
|
| 257 |
beam_size=5,
|
| 258 |
language="ru",
|
| 259 |
temperature=0.0,
|
|
|
|
| 260 |
log_prob_threshold=-0.8,
|
| 261 |
no_speech_threshold=0.6,
|
| 262 |
vad_filter=True,
|
| 263 |
-
vad_parameters=dict(min_silence_duration_ms=500)
|
| 264 |
)
|
| 265 |
|
| 266 |
words_list = []
|
|
@@ -391,7 +393,8 @@ if __name__ == "__main__":
|
|
| 391 |
model = WhisperModel(
|
| 392 |
WHISPER_MODEL_SIZE,
|
| 393 |
device=WHISPER_DEVICE,
|
| 394 |
-
compute_type=WHISPER_COMPUTE_TYPE
|
|
|
|
| 395 |
)
|
| 396 |
transcribe_vod_audio(vod_id, created_at, model)
|
| 397 |
except Exception as e:
|
|
|
|
| 37 |
WHISPER_MODEL_SIZE = os.getenv("WHISPER_MODEL", "base")
|
| 38 |
WHISPER_DEVICE = os.getenv("WHISPER_DEVICE", "cpu")
|
| 39 |
WHISPER_COMPUTE_TYPE = os.getenv("WHISPER_COMPUTE_TYPE", "int8")
|
| 40 |
+
WHISPER_CPU_THREADS = int(os.getenv("WHISPER_CPU_THREADS", "2"))
|
| 41 |
|
| 42 |
if not API_KEY:
|
| 43 |
print("[Error] API_KEY is missing in .env! Cannot push data to backend.")
|
|
|
|
| 258 |
beam_size=5,
|
| 259 |
language="ru",
|
| 260 |
temperature=0.0,
|
| 261 |
+
condition_on_previous_text=False,
|
| 262 |
log_prob_threshold=-0.8,
|
| 263 |
no_speech_threshold=0.6,
|
| 264 |
vad_filter=True,
|
| 265 |
+
vad_parameters=dict(threshold=0.5, min_silence_duration_ms=500)
|
| 266 |
)
|
| 267 |
|
| 268 |
words_list = []
|
|
|
|
| 393 |
model = WhisperModel(
|
| 394 |
WHISPER_MODEL_SIZE,
|
| 395 |
device=WHISPER_DEVICE,
|
| 396 |
+
compute_type=WHISPER_COMPUTE_TYPE,
|
| 397 |
+
cpu_threads=WHISPER_CPU_THREADS
|
| 398 |
)
|
| 399 |
transcribe_vod_audio(vod_id, created_at, model)
|
| 400 |
except Exception as e:
|
local_worker/worker.py
CHANGED
|
@@ -44,6 +44,7 @@ CAPTURE_METHOD = os.getenv("CAPTURE_METHOD", "stream").lower()
|
|
| 44 |
WHISPER_MODEL_SIZE = os.getenv("WHISPER_MODEL", "base")
|
| 45 |
WHISPER_DEVICE = os.getenv("WHISPER_DEVICE", "cpu")
|
| 46 |
WHISPER_COMPUTE_TYPE = os.getenv("WHISPER_COMPUTE_TYPE", "int8")
|
|
|
|
| 47 |
|
| 48 |
# Verify essential secrets
|
| 49 |
if not API_KEY:
|
|
@@ -216,12 +217,13 @@ def chat_sender():
|
|
| 216 |
|
| 217 |
def init_whisper_model():
|
| 218 |
"""Load Faster-Whisper model into memory"""
|
| 219 |
-
print(f"[Whisper] Loading model '{WHISPER_MODEL_SIZE}' on {WHISPER_DEVICE} ({WHISPER_COMPUTE_TYPE})...")
|
| 220 |
# This might take a few minutes on first run as the model downloads
|
| 221 |
model = WhisperModel(
|
| 222 |
WHISPER_MODEL_SIZE,
|
| 223 |
device=WHISPER_DEVICE,
|
| 224 |
-
compute_type=WHISPER_COMPUTE_TYPE
|
|
|
|
| 225 |
)
|
| 226 |
print("[Whisper] Model loaded successfully.")
|
| 227 |
return model
|
|
@@ -240,10 +242,11 @@ def transcribe_audio_segment(model, pcm_bytes):
|
|
| 240 |
beam_size=5,
|
| 241 |
language="ru",
|
| 242 |
temperature=0.0,
|
|
|
|
| 243 |
log_prob_threshold=-0.8,
|
| 244 |
no_speech_threshold=0.6,
|
| 245 |
vad_filter=True, # Voice Activity Detection filters out silence
|
| 246 |
-
vad_parameters=dict(min_silence_duration_ms=500)
|
| 247 |
)
|
| 248 |
|
| 249 |
words_list = []
|
|
@@ -516,10 +519,11 @@ def run_microphone_capture(model):
|
|
| 516 |
beam_size=5,
|
| 517 |
language="ru",
|
| 518 |
temperature=0.0,
|
|
|
|
| 519 |
log_prob_threshold=-0.8,
|
| 520 |
no_speech_threshold=0.6,
|
| 521 |
vad_filter=True,
|
| 522 |
-
vad_parameters=dict(min_silence_duration_ms=500)
|
| 523 |
)
|
| 524 |
words_list = []
|
| 525 |
for segment in segments:
|
|
|
|
| 44 |
WHISPER_MODEL_SIZE = os.getenv("WHISPER_MODEL", "base")
|
| 45 |
WHISPER_DEVICE = os.getenv("WHISPER_DEVICE", "cpu")
|
| 46 |
WHISPER_COMPUTE_TYPE = os.getenv("WHISPER_COMPUTE_TYPE", "int8")
|
| 47 |
+
WHISPER_CPU_THREADS = int(os.getenv("WHISPER_CPU_THREADS", "2"))
|
| 48 |
|
| 49 |
# Verify essential secrets
|
| 50 |
if not API_KEY:
|
|
|
|
| 217 |
|
| 218 |
def init_whisper_model():
|
| 219 |
"""Load Faster-Whisper model into memory"""
|
| 220 |
+
print(f"[Whisper] Loading model '{WHISPER_MODEL_SIZE}' on {WHISPER_DEVICE} ({WHISPER_COMPUTE_TYPE}, threads={WHISPER_CPU_THREADS})...")
|
| 221 |
# This might take a few minutes on first run as the model downloads
|
| 222 |
model = WhisperModel(
|
| 223 |
WHISPER_MODEL_SIZE,
|
| 224 |
device=WHISPER_DEVICE,
|
| 225 |
+
compute_type=WHISPER_COMPUTE_TYPE,
|
| 226 |
+
cpu_threads=WHISPER_CPU_THREADS
|
| 227 |
)
|
| 228 |
print("[Whisper] Model loaded successfully.")
|
| 229 |
return model
|
|
|
|
| 242 |
beam_size=5,
|
| 243 |
language="ru",
|
| 244 |
temperature=0.0,
|
| 245 |
+
condition_on_previous_text=False,
|
| 246 |
log_prob_threshold=-0.8,
|
| 247 |
no_speech_threshold=0.6,
|
| 248 |
vad_filter=True, # Voice Activity Detection filters out silence
|
| 249 |
+
vad_parameters=dict(threshold=0.5, min_silence_duration_ms=500)
|
| 250 |
)
|
| 251 |
|
| 252 |
words_list = []
|
|
|
|
| 519 |
beam_size=5,
|
| 520 |
language="ru",
|
| 521 |
temperature=0.0,
|
| 522 |
+
condition_on_previous_text=False,
|
| 523 |
log_prob_threshold=-0.8,
|
| 524 |
no_speech_threshold=0.6,
|
| 525 |
vad_filter=True,
|
| 526 |
+
vad_parameters=dict(threshold=0.5, min_silence_duration_ms=500)
|
| 527 |
)
|
| 528 |
words_list = []
|
| 529 |
for segment in segments:
|
server/server.js
CHANGED
|
@@ -532,6 +532,18 @@ const STOP_WORDS = new Set([
|
|
| 532 |
'here', 'whats', 'what', 'which', 'who', 'whom', 'whose', 'why', 'how', 'can', 'will', 'just'
|
| 533 |
]);
|
| 534 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 535 |
// Get word frequencies (Voice vs Chat messages from streamer)
|
| 536 |
app.get('/api/stats/words', cacheMiddleware(), async (req, res) => {
|
| 537 |
const streamId = req.query.stream_id ? parseInt(req.query.stream_id) : null;
|
|
@@ -546,8 +558,8 @@ app.get('/api/stats/words', cacheMiddleware(), async (req, res) => {
|
|
| 546 |
for (const w of rawWords) {
|
| 547 |
if (!w || !w.word || typeof w.word !== 'string') continue;
|
| 548 |
let clean = w.word.toLowerCase().trim();
|
| 549 |
-
if (clean
|
| 550 |
-
clean =
|
| 551 |
}
|
| 552 |
|
| 553 |
const isAllowedLength = clean.length >= 3 || clean === 'ну';
|
|
@@ -602,8 +614,8 @@ app.get('/api/stats/words', cacheMiddleware(), async (req, res) => {
|
|
| 602 |
}
|
| 603 |
if (!word) continue;
|
| 604 |
|
| 605 |
-
if (word
|
| 606 |
-
word =
|
| 607 |
}
|
| 608 |
|
| 609 |
const isAllowedLength = word.length >= 3 || word === 'ну';
|
|
|
|
| 532 |
'here', 'whats', 'what', 'which', 'who', 'whom', 'whose', 'why', 'how', 'can', 'will', 'just'
|
| 533 |
]);
|
| 534 |
|
| 535 |
+
// Word mappings/synonyms to group similar pronunciations or typos
|
| 536 |
+
const WORD_MAPPINGS = {
|
| 537 |
+
'блядь': 'блять',
|
| 538 |
+
'петерка': 'пятерка',
|
| 539 |
+
'питерка': 'пятерка',
|
| 540 |
+
'петёрка': 'пятерка',
|
| 541 |
+
'пётерка': 'пятерка',
|
| 542 |
+
'кримбал': 'кримбр',
|
| 543 |
+
'кримбл': 'кримбр',
|
| 544 |
+
'кримбор': 'кримбр'
|
| 545 |
+
};
|
| 546 |
+
|
| 547 |
// Get word frequencies (Voice vs Chat messages from streamer)
|
| 548 |
app.get('/api/stats/words', cacheMiddleware(), async (req, res) => {
|
| 549 |
const streamId = req.query.stream_id ? parseInt(req.query.stream_id) : null;
|
|
|
|
| 558 |
for (const w of rawWords) {
|
| 559 |
if (!w || !w.word || typeof w.word !== 'string') continue;
|
| 560 |
let clean = w.word.toLowerCase().trim();
|
| 561 |
+
if (WORD_MAPPINGS[clean]) {
|
| 562 |
+
clean = WORD_MAPPINGS[clean];
|
| 563 |
}
|
| 564 |
|
| 565 |
const isAllowedLength = clean.length >= 3 || clean === 'ну';
|
|
|
|
| 614 |
}
|
| 615 |
if (!word) continue;
|
| 616 |
|
| 617 |
+
if (WORD_MAPPINGS[word]) {
|
| 618 |
+
word = WORD_MAPPINGS[word];
|
| 619 |
}
|
| 620 |
|
| 621 |
const isAllowedLength = word.length >= 3 || word === 'ну';
|