Compare commits

..

1 Commits

Author SHA1 Message Date
svlqd 5cb7b14705 stash commit - wip 2026-06-25 00:30:59 +03:00
12 changed files with 102 additions and 26 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"python-envs.defaultEnvManager": "ms-python.python:conda",
"python-envs.defaultPackageManager": "ms-python.python:conda"
}
+3
View File
@@ -13,3 +13,6 @@ dependencies:
- python=3.12 - python=3.12
- customtkinter - customtkinter
- openai - openai
- pip:
- vosk
+4 -2
View File
@@ -1,7 +1,7 @@
from transcription.audio import Audio from transcription.audio import Audio
from transcription.preprocessing.audio_preprocessor import AudioPreprocessor from transcription.preprocessing.audio_preprocessor import AudioPreprocessor
from transcription.preprocessing.splitter import Splitter from transcription.preprocessing.splitter import Splitter
from transcription.engines.whisper import WhisperEngine from transcription.engines.whisper_engine import WhisperEngine
from transcription.configuration import Configuration from transcription.configuration import Configuration
# maybe inherit from AudioTranscription and rename to something like WhisperTranscription? # maybe inherit from AudioTranscription and rename to something like WhisperTranscription?
@@ -19,11 +19,13 @@ class AudioTranscription:
# self.logger = logger # self.logger = logger
self.audio = Audio() self.audio = Audio()
self.preprocessor = AudioPreprocessor() self.preprocessor = AudioPreprocessor(16000)
self.splitter = Splitter( self.splitter = Splitter(
chunkSize=config.chunkSize, chunkSize=config.chunkSize,
batchSize=config.batchSize, batchSize=config.batchSize,
) )
self.engine = WhisperEngine( self.engine = WhisperEngine(
modelName=config.modelName, modelName=config.modelName,
language=self.language, language=self.language,
+2 -2
View File
@@ -7,8 +7,8 @@ class Configuration:
# add new models # add new models
device: str = "cuda" device: str = "cuda"
modelName: str = "openai/whisper-large-v2" modelName: str = "openai/whisper-large-v2"
chunkSize: int = 30 chunkSize: int = 30 ## in seconds
batchSize: int = 16 batchSize: int = 16 ## in batches
dataType: str = "torch.float16" dataType: str = "torch.float16"
_dtype_map = { _dtype_map = {
+11
View File
@@ -0,0 +1,11 @@
import torch
from abc import ABC, abstractmethod
class BaseEngine(ABC):
@abstractmethod
def loadModel(self) -> None:
pass
@abstractmethod
def unloadModel(self) -> None:
pass
@@ -1,30 +1,18 @@
import torch from transcription.engines.BaseEngine import BaseEngine
from abc import ABC, abstractmethod
class BaseEngine(ABC): class BatchSTTEngine(BaseEngine):
def __init__( def __init__(
self, self,
modelName: str, modelName: str,
language: str, language: str,
dType: torch.dtype, dType: torch.dtype,
device: str device: str
): ) -> None:
self.modelName = modelName self.modelName = modelName
self.device = device self.device = device
self.language = language self.language = language
self.dType = dType self.dType = dType
@abstractmethod @abstractmethod
def loadModel(self) -> None: def transcribeBatch(self) -> None:
pass
@abstractmethod
def unloadModel(self) -> None:
pass
@abstractmethod
def transcribeBatch(
self,
batch
) -> str:
pass pass
+5
View File
@@ -0,0 +1,5 @@
from transcription.engines.BaseEngine import BaseEngine
class StreamingSTTEngine(BaseEngine):
def __init__(self) -> None:
...
+53
View File
@@ -0,0 +1,53 @@
from transcription.engines.BaseEngine import BaseEngine
import wave, json
from vosk import Model, KaldiRecognizer
"""
import wave
import json
import sys
from multiprocessing.dummy import Pool
from vosk import Model, KaldiRecognizer
model = Model("en-us")
def recognize(line):
uid, fn = line.split()
wf = wave.open(fn, "rb")
rec = KaldiRecognizer(model, wf.getframerate())
text = ""
while True:
data = wf.readframes(1000)
if len(data) == 0:
break
if rec.AcceptWaveform(data):
jres = json.loads(rec.Result())
text = text + " " + jres["text"]
jres = json.loads(rec.FinalResult())
text = text + " " + jres["text"]
return uid + text
def main():
p = Pool(8)
texts = p.map(recognize, open(sys.argv[1], encoding="utf-8").readlines())
print ("\n".join(texts))
main()
"""
class VoskEngine(BaseEngine):
TARGET_SAMPLING_RATE = 16000
def loadModel(self) -> None:
...
def unloadModel(self) -> None:
...
def transcribeBatch(
self,
batch,
) -> str:
...
@@ -4,9 +4,11 @@ import torch
import gc import gc
from transformers import WhisperForConditionalGeneration, WhisperProcessor from transformers import WhisperForConditionalGeneration, WhisperProcessor
from transcription.engines.base_engine import BaseEngine from transcription.engines.BatchSTT import BatchSTT
class WhisperEngine(BaseEngine): class WhisperEngine(BatchSTT):
TARGET_SAMPLING_RATE = 16000
def loadModel(self) -> None: def loadModel(self) -> None:
self.processor = WhisperProcessor.from_pretrained(self.modelName) self.processor = WhisperProcessor.from_pretrained(self.modelName)
self.model = WhisperForConditionalGeneration.from_pretrained( self.model = WhisperForConditionalGeneration.from_pretrained(
@@ -31,7 +33,7 @@ class WhisperEngine(BaseEngine):
inputs = self.processor( inputs = self.processor(
batch, batch,
sampling_rate=16000, sampling_rate=self.TARGET_SAMPLING_RATE,
return_tensors="pt", return_tensors="pt",
padding=True, padding=True,
) )
@@ -7,6 +7,9 @@ class AudioPreprocessor:
# for different models in future # for different models in future
# def __init__(self, model): # def __init__(self, model):
# pass # pass
def __init__(self, target_sr: int) -> None:
self.TARGET_SAMPLING_RATE = target_sr
def _resample( def _resample(
self, self,
+4 -3
View File
@@ -1,11 +1,14 @@
import torch import torch
from typing import List from typing import List
from logging import Logger
# TODO: add logging here
class Splitter: class Splitter:
def __init__( def __init__(
self, self,
chunkSize: int, chunkSize: int,
batchSize: int, batchSize: int,
# logger: Logger
) -> None: ) -> None:
self.chunkSize = chunkSize * 16000 # 16 kHz after resampling self.chunkSize = chunkSize * 16000 # 16 kHz after resampling
self.batchSize = batchSize self.batchSize = batchSize
@@ -19,7 +22,7 @@ class Splitter:
chunksCount = (totalSamples + self.chunkSize - 1) // self.chunkSize chunksCount = (totalSamples + self.chunkSize - 1) // self.chunkSize
chunks: List = [] chunks: List = []
# tqdm or something here? # tqdm for logger or something here?
for chunkNum in range(chunksCount): for chunkNum in range(chunksCount):
start = chunkNum * self.chunkSize start = chunkNum * self.chunkSize
end = min((chunkNum + 1) * self.chunkSize, totalSamples) end = min((chunkNum + 1) * self.chunkSize, totalSamples)
@@ -34,11 +37,9 @@ class Splitter:
chunks: List, chunks: List,
) -> List: ) -> List:
batches: List = [] batches: List = []
for i in range(0, len(chunks), self.batchSize): for i in range(0, len(chunks), self.batchSize):
batch = chunks[i : i + self.batchSize] batch = chunks[i : i + self.batchSize]
batches.append(batch) batches.append(batch)
return batches return batches
def split( def split(
+4
View File
@@ -0,0 +1,4 @@
import time
class Time: