Ala404 commited on
Commit
8a968d8
·
verified ·
1 Parent(s): 9ff04de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -1
app.py CHANGED
@@ -1,5 +1,7 @@
1
  import os
2
  import io
 
 
3
  import torch
4
  import torchaudio
5
  from fastapi import FastAPI, UploadFile, File, HTTPException
@@ -7,12 +9,24 @@ from fastapi.middleware.cors import CORSMiddleware
7
  from transformers import pipeline
8
  from huggingface_hub import login
9
 
 
 
 
 
 
 
 
 
 
 
 
10
  # Set HF_HOME to a writable directory
11
  os.environ['HF_HOME'] = '/app/.cache/huggingface'
12
 
13
  # Handle authentication if token is provided
14
  hf_token = os.getenv("HF_TOKEN")
15
  if hf_token:
 
16
  login(token=hf_token)
17
 
18
  # Initialize FastAPI app
@@ -30,49 +44,75 @@ app.add_middleware(
30
  # Load the pipeline with device set to GPU if available
31
  MODEL_NAME = "STT-Darija-ORG/wav2vec2-xlsr-300m-darija-augmented"
32
  device = 0 if torch.cuda.is_available() else -1
 
 
33
  pipe = pipeline("automatic-speech-recognition", model=MODEL_NAME, device=device)
 
34
 
35
  @app.post("/transcribe")
36
  async def transcribe_audio(file: UploadFile = File(...)):
 
37
  try:
38
  # Read the file content
 
39
  content = await file.read()
40
  if len(content) == 0:
 
41
  raise HTTPException(status_code=400, detail="Uploaded file is empty")
42
 
43
  # Load audio from bytes
 
44
  file_like = io.BytesIO(content)
45
  try:
46
  waveform, sample_rate = torchaudio.load(file_like)
 
47
  except Exception as e:
 
48
  raise HTTPException(status_code=400, detail=f"Invalid audio file: {str(e)}")
 
 
49
 
50
  # Ensure mono audio
51
  if waveform.shape[0] > 1:
 
52
  waveform = waveform[0:1, :] # Take the first channel
53
 
54
  # Resample if necessary
55
  if sample_rate != 16000:
 
 
56
  transform = torchaudio.transforms.Resample(sample_rate, 16000)
57
  waveform = transform(waveform)
 
58
 
59
  # Pass to pipeline
 
 
60
  audio_np = waveform.numpy().flatten()
61
  result = pipe(audio_np)
62
  transcription = result["text"]
 
 
 
 
 
63
 
64
- return {"transcription": transcription}
65
  except HTTPException as e:
 
66
  raise e
67
  except Exception as e:
 
68
  raise HTTPException(status_code=500, detail=f"Transcription failed: {str(e)}")
69
 
70
  @app.get("/health")
71
  async def health_check():
 
72
  return {"status": "healthy", "model": MODEL_NAME}
73
 
74
  @app.get("/")
75
  async def home():
 
76
  return {
77
  "message": "Speech Recognition API",
78
  "endpoints": {
 
1
  import os
2
  import io
3
+ import time
4
+ import logging
5
  import torch
6
  import torchaudio
7
  from fastapi import FastAPI, UploadFile, File, HTTPException
 
9
  from transformers import pipeline
10
  from huggingface_hub import login
11
 
12
+ # Configure logging
13
+ logging.basicConfig(
14
+ level=logging.INFO,
15
+ format='%(asctime)s - %(levelname)s - %(message)s',
16
+ handlers=[
17
+ logging.StreamHandler(),
18
+ logging.FileHandler('transcription.log')
19
+ ]
20
+ )
21
+ logger = logging.getLogger(__name__)
22
+
23
  # Set HF_HOME to a writable directory
24
  os.environ['HF_HOME'] = '/app/.cache/huggingface'
25
 
26
  # Handle authentication if token is provided
27
  hf_token = os.getenv("HF_TOKEN")
28
  if hf_token:
29
+ logger.info("Logging in to Hugging Face with provided token")
30
  login(token=hf_token)
31
 
32
  # Initialize FastAPI app
 
44
  # Load the pipeline with device set to GPU if available
45
  MODEL_NAME = "STT-Darija-ORG/wav2vec2-xlsr-300m-darija-augmented"
46
  device = 0 if torch.cuda.is_available() else -1
47
+ logger.info(f"Loading model {MODEL_NAME} on device: {'GPU' if device == 0 else 'CPU'}")
48
+ start_time = time.time()
49
  pipe = pipeline("automatic-speech-recognition", model=MODEL_NAME, device=device)
50
+ logger.info(f"Model loaded in {time.time() - start_time:.2f} seconds")
51
 
52
  @app.post("/transcribe")
53
  async def transcribe_audio(file: UploadFile = File(...)):
54
+ start_time = time.time()
55
  try:
56
  # Read the file content
57
+ logger.info(f"Received file: {file.filename}, size: {file.size} bytes")
58
  content = await file.read()
59
  if len(content) == 0:
60
+ logger.error("Uploaded file is empty")
61
  raise HTTPException(status_code=400, detail="Uploaded file is empty")
62
 
63
  # Load audio from bytes
64
+ load_start = time.time()
65
  file_like = io.BytesIO(content)
66
  try:
67
  waveform, sample_rate = torchaudio.load(file_like)
68
+ logger.info(f"Audio loaded, sample rate: {sample_rate} Hz, channels: {waveform.shape[0]}, duration: {waveform.shape[1]/sample_rate:.2f} seconds")
69
  except Exception as e:
70
+ logger.error(f"Failed to load audio: {str(e)}")
71
  raise HTTPException(status_code=400, detail=f"Invalid audio file: {str(e)}")
72
+ load_time = time.time() - load_start
73
+ logger.info(f"Audio loading took {load_time:.2f} seconds")
74
 
75
  # Ensure mono audio
76
  if waveform.shape[0] > 1:
77
+ logger.info("Converting multi-channel audio to mono")
78
  waveform = waveform[0:1, :] # Take the first channel
79
 
80
  # Resample if necessary
81
  if sample_rate != 16000:
82
+ logger.info(f"Resampling audio from {sample_rate} Hz to 16000 Hz")
83
+ resample_start = time.time()
84
  transform = torchaudio.transforms.Resample(sample_rate, 16000)
85
  waveform = transform(waveform)
86
+ logger.info(f"Resampling took {time.time() - resample_start:.2f} seconds")
87
 
88
  # Pass to pipeline
89
+ logger.info("Starting transcription")
90
+ transcribe_start = time.time()
91
  audio_np = waveform.numpy().flatten()
92
  result = pipe(audio_np)
93
  transcription = result["text"]
94
+ transcribe_time = time.time() - transcribe_start
95
+ logger.info(f"Transcription completed in {transcribe_time:.2f} seconds, result: {transcription}")
96
+
97
+ total_time = time.time() - start_time
98
+ logger.info(f"Total request processing time: {total_time:.2f} seconds")
99
 
100
+ return {"transcription": transcription, "processing_time_seconds": round(total_time, 2)}
101
  except HTTPException as e:
102
+ logger.error(f"HTTP error: {str(e)}")
103
  raise e
104
  except Exception as e:
105
+ logger.error(f"Unexpected error: {str(e)}")
106
  raise HTTPException(status_code=500, detail=f"Transcription failed: {str(e)}")
107
 
108
  @app.get("/health")
109
  async def health_check():
110
+ logger.info("Health check requested")
111
  return {"status": "healthy", "model": MODEL_NAME}
112
 
113
  @app.get("/")
114
  async def home():
115
+ logger.info("Home endpoint accessed")
116
  return {
117
  "message": "Speech Recognition API",
118
  "endpoints": {